概述
本文以异步时序计数器为例,用Verilog实现以\(JK\)触发器组成的8421BCD码十进制异步计数器,并用ModelSim软件进行仿真验证.
电路分析
实现8421BCD码十进制计数器可分为同步时序和异步时序,分析方法类似,本文采用较为简单的异步时序进行讲解,关于同步时序实现方法可以参考相关资料.
下图为异步时序实现的该计数器的逻辑电路图.
可以根据逻辑电路图写出激励方程
\[\begin{cases}J_0=K_0=1\\J_1=\overline{Q_3^n},K_1=1\\J_2=K_2=1\\J_3=Q_1^nQ_2^n,K_3=1\end{cases}\tag{*}
\]
\]
将\((*)\)式带入\(JK\)触发器的特征方程可得该电路的状态方程
\[\begin{cases}Q_0^{n+1}=\overline{Q_0^n}\cdot CP\\Q_1^{n+1}=\overline{Q_3^n}\overline{Q_1^n}Q_n^n\\Q_2^{n+1}=\overline{Q_2^n}Q_1^n\\Q_3^{n+1}=\overline{Q_3^n}Q_2^nQ_1^nQ_0^n\end{cases}\tag{**}
\]
\]
设定\(Q_3^nQ_2^nQ_1^nQ_0^n=0000\)为初始状态,按照\((**)\)式可写出状态转移表
可见这是一个模值为\(10\)的计数器,下面讨论能否自启动,将未使用的六个状态一同考虑在内,可得完整的状态转移图
可见此电路可以自启动.(上图中箭头旁的\(/0\)和\(/1\)非本例内容,可忽略)
至此该电路的逻辑已经基本摸清,下面可以开始用代码实现了.
代码实现
首先给出同步复位\(JK\)触发器的实现代码
module JK
(input CK
,input RST
,input J
,input K
,output reg Q
);
always@(negedge CK)
if(RST)
Q<=0;
else
case({J,K})
2'b00:Q<=Q;
2'b01:Q<=1'b0;
2'b10:Q<=1'b1;
default:Q<=~Q;
endcase
endmodule
接下来通过例化模块可轻松地实现逻辑电路,通过之前推导地逻辑表达式,编写代码如下
module Cnt8421
(input CK
,input RST
,output[3:0]Q
);
JK FFI(CK,RST,1,1,Q[0]);
JK FFII(Q[0],RST,~Q[3],~Q[3],Q[1]);
JK FFIII(Q[1],RST,1,1,Q[2]);
JK FFIV(Q[0],RST,Q[1]&Q[2],Q[3],Q[3]);
endmodule
至此已完成电路功能实现.
下面进行仿真验证,仿真文件如下
`timescale 1 ns/ 1 ns
module Cnt8421_vlg_tst;
reg CK=0,RST=1;
wire[3:0]Q;
Cnt8421 UUT(CK,RST,Q);
initial#1 RST=0;
always#1 CK<=~CK;
endmodule
非常简单的仿真文件,逻辑就是一开始先按下复位键令电路初始化,然后开始随着时钟边沿进行计数操作,波形如下图
可见电路功能正常,验证无误.
参考文献
[1] 刘培植.《数字电路与逻辑设计(第2版)》[M].北京:北京邮电大学出版社.2013.205