基于FPGA的可校正的万年历的设计与实现

 

一、前言

        前几天看完了一本书上的课后习题,需要设计一个万年历,但是竟然没有课后答案,很是遗憾,于是就自己写了一个支持通过按键的方式来设置初值的万年历程序。

 

二、功能介绍

        FPGA芯片为 Cyclone IV EP4CE15F23C8N ,用了八个数码管,分别对应年份(4个数码管)、月份(2个数码管)、天数(2个数码管);4个按键,一个系统复位按键,一个按键+,一个按键-,这两个按键均用于设置万年历的初值,一个确认按键。

        系统上电之后,八个数码管显示为全零的状态,然后连续按下按键+ 9次,8个数码管的最右边的显示为9,再按下确认按键,表示第一个数码管的初值已经设置结束,现在可以设置第二个数码管的初值,再按下按键+ 2次,从右往左第一个数码管显示为9,第二个数码管显示的值为2,表征设置的天数的初值为29日,按下确认按键,表示第二个数码管的初值设置结束,可以进行第三个数码管的初值的设置,如按下按键+ 7次,即表征这个月份是7月。以此类推,每设置好一个数码管的初值,均需要按一次确认按键,按下8次确认按键之后,表示初值已经设置结束,此时FPGA板卡即可按照预期要求进行运转。

       如8个数码管的初值为:2021 07 29,那么板卡将会在这个初值的基础上继续进行运行,到了2021年7月31天的最后1秒钟,数码管数字跳转为2021 08 01。

 

三、顶层模块

        1、 从上图中可以看到整个设计一共有5个输入信号,分别是:

                   clk:系统时钟信号,频率为50MHz;

                   rst_n:系统复位信号,低电平有效;

                   key0:按键+,通过按键的形式来预置初值;

                   key1:按键-,通过按键的形式来预置初值;

                   key2:确认按键,通过按键的形式来确定预置的初值;

        输出信号只有两个:

                seg[7:0]:数码管段选信号;

                sel[7:0]:数码管位选信号;

2、各个模块的介绍

        第一个模块:key_filter,这个模块实现的功能是按键消抖,这个模块的实现方式这里不做介绍;

        第二个模块:verify,这个模块主要是获取并锁存通过按键输入的初值,其核心是由一个序列机来实现,在确认信号计数的值不同时,锁存下每个确认信号的值所对应的值,如当确认信号为1时,锁存的是天的个位的值,当确认信号计数的值为8时,锁存的年的千分位的值;

        第三个模块:count_runnian,这个模块由组合逻辑实现,实现的功能是判断出当前的年份是否是闰年,闰年的二月是29天,平年的二月是28天,这里需要做出区别;

        第四个模块:count_test_Rev:这个模块是计数模块,其实现的功能是将预置的初值以合适的方式放入到对应的计数器中,在计数器启动之后,整个系统能在设置的初值的基础上正常运行;

        第五个模块:disp,这个模块是显示模块,本质上是一个数码管的动态扫描;

 

四、总结

        基于FPGA的万年历的设计一共用了700行左右的代码来实现,整体来说还是比较容易实现的,这个设计的难点在于如何将预置的初值合适的加载到计算天数、月份、年份的计数器中,这里是使用了异步复位,同步置数的方式来实现预置初值。

        这个例程比较容易应用到如 可定时的数字时钟、可定时的数字闹钟等需要通过外部按键来预置初值的各种设计中。

 

五、效果展示

 

 

 

        

  

 

posted @ 2021-07-30 09:31  青河  阅读(1059)  评论(0编辑  收藏  举报