接下来系列的博文作者将巡礼最近碰到的数字集成电路课设中的一些经典有趣的电路模块,系列文章将会根据笔者进度持续更新:
文章目录
提示:
前言
阅前提示:本篇文章不仅涉及状态机、時锺的设计,还使用到了之前所写过的一些设计模块如按键的下降沿小消抖检测等。
在文初先附上所调用到笔者之前关于简单12H数字时钟模块和下降沿检测模块的分析:
一、项目描述与功能
本次项目的基础模块是一个12H的数字时钟,具体来讲它具有以下几种功能:
-
计时:整个项目基于一个数字时钟,秒針/分針/时針的功能与现實中时钟的功能无异。时针在计满12:59:59之后下一個时间为1:00:00(效果见下图:)。
除此之外,这个数字时钟还能够区分上午(am)和下午(pm),11:59:59之后自动会从am进入pm或是从pm進入am(效果如下):
-
报时:时钟计时到整点時,会自動报时,实验中使用一个输出信号端口ring,它在整点置高并且维持5個时钟周期(见下图)以模拟实际生活中时钟整点“滴~~~~”报时:
-
四位密码锁:密码为4位,笔者将其设置为“1124”,设想一个小的密码锁,只有将其破解后才能進入时钟的调节时间功能(此时是一个等待态)。注意:这些密码按键的有效持续时间都是10個時锺周期,10個時锺内如若没有其它键按下就会自动恢复最初的無按键正常计时状态,上次按键操作示为无效操作。
-
调时:数字时钟具有两种时间调节模式,一是时针分针秒針的切换模式,二是具体的时间加1计数模式。
- 此时若按一次key_in键则调节秒针,按下两次key_in键调节分針,三次则为时針,再一次按下则回到正常计时状态同时時锺会从之前设置好的时间开始继续计時。
- 每按下一次key_in键(此时進入時針/分針/秒針的具体调节),再按下key_cnt键则会开始從00开始進行加一调节,假设我们要调的秒数为15s,则需要按下15次key_cnt;
- 其它细节功能
- 按键的有效時長:密码输入键(dt_in)以及进行時分秒调时切换按键(key_in)其有效时间都是10個時锺周期(如果以实际时间计时即为十秒),也就是说按键按下後如果在10s内没有進一步的按键操作则视为此按键无效,回到正常计時状態;时间调节计数按键(key_cnt)的有效持续时间是15個時锺周期(15s);
- 由于在硬件设计仿真時无法直接模仿到按键,无法区分按键输入是数据"0"还是無输入的“0”,因此在设计時暂时可使用的密码数为1-9,在实际操作中,这种限制很容易被解决,只需将moore状态机改成mealy状态机同时将按键的按下输入key与键码值使用数据流描述assign做一個与门逻辑的设计即可。
二、各模块原理与代码实现
1.時锺模块
(1)底层BCD加法器
普通计数器的设计并不复杂,但是此题的底层BCD计数器需要能够在更高一个层级的60进制和12进制计数器中使用,因此我们还需要給这个加法器加上其它的功能,如复位清零和计满重载。这里有一個需要重點关注的地方是:
無論是12H的時锺还是24H的数字時锺作为顶层模块,其计满进位都不是0! 12:59:59的下一个进位数据不是00:00:00而是1:00:00,而为了保证两種计数器都使用同一个底层的BCD模块,我们必须加上计满重载的数据端口,端口输入值由高层次的60进制or12进制時锺内部设定。
- 根据上述思路我们可以写出下面代码,其波形可自行验证(此部分比较简单):
(2)60进制计数器和12进制计数器
1.这两个部分设计比较简单,由于在底层已经写好了BCD加法器的各种复位和重装载功能,现只需要为其输入端口书写逻辑同时赋值重装载和复位信号的数据端即可。如:
- 60进制的复位高低位都是4‘b0000,计满重置高低位依旧是4’b0000;(见如下代码)
- 而12进制的复位端数据是12(reset之后是12:00:00),高位是4’b0001/低位时4’b0010 ;计满重装载的装载数据是1(12:59:59的下一个時锺是1:00:00),高位是4’b0000/低位是4’b0001(见下图):
(3)完整時锺模块的描述
顶层模块主要进行两个60进制时钟和12进制時锺的例化,同时设置其各自的复位端,原理并不复杂,可参考笔者之前的分析(简单的12H数字时