⭐本专栏针对FPGA进行入门学习,从数电中常见的发器逻辑代数讲起,结合Verilog HDL语言学习与仿真,主要对组合逻辑电路与时序逻辑电路进行分析与设计,对状态机FSM进行剖析与建模 。 🔥文章和代码已归档至【Github仓库:hardware-tutorial】,需要的发器朋友们自取 。或者公众号【AIShareLab】回复 FPGA 也可获取 。发器
把 CP 有效沿到来之前电路的状态称为现态,用 Q n Q^n Qn表示。
把 CP 有效沿到来之后,电路所进入的发器新状态称为次态,用 Q n + 1 Q^{n+1} Qn+1表示。
0 | 0 | 0 |
0 | 1 | 0 |
1 | 0 | 1 |
1 | 1 | 1 |
Q n + 1 = D Q^{n+1} = D Qn+1=D
由于直接置1和清零时跟CP信号无关,所以称置1、清零操作是发器异步置1和异步清零。
直接置1和直接清零的发器过程如下:
(1) 当 S ˉ D = 0 \bar{S}_{D}=0 SˉD=0, R ˉ D = 1 \bar{R}_{D}=1 RˉD=1 时, 使得 Y 1 = 1 Y_{1}=1 Y1=1 , S ˉ = Y 1 ⋅ C P ⋅ R ˉ D ‾ = C P ‾ \bar{S}=\overline{Y_{1} \cdot C P \cdot \bar{R}_{D}}=\overline{C P} Sˉ=Y1⋅CP⋅RˉD=CP, R ˉ = S ˉ ⋅ C P ⋅ Y 4 ‾ = 1 \quad \bar{R}=\overline{\bar{S} \cdot C P \cdot Y_{4}}=1 Rˉ=Sˉ⋅CP⋅Y4=1 ,于是 Q = 1 Q=1 Q=1, Q ˉ = 0 \bar{Q}=0 Qˉ=0 , 即将输出 Q 直接置 1 。
(2) 当 S ˉ D = 1 \bar{S}_{\mathrm{D}}=1 SˉD=1,发器 R ˉ D = 0 \bar{R}_{\mathrm{D}}=0 RˉD=0 时, 使得 S ˉ = 1 \bar{S}=1 Sˉ=1 , 于是 Q = 0 Q=0 Q=0, Q ˉ = 1 \bar{Q}=1 Qˉ=1 , 即将输出 Q 直接清零 。
所谓同步清零是指在清零输入信号有效,并且CP的有效边沿(如上升沿)到来时,才能将触发器清零。
(a) 实现同步清零的发器方案之一
(b) 实现同步清零的方案之二
功能:
Q n + 1 = C E ‾ ⋅ Q n + C E ⋅ D Q^{n+1}=\overline{C E} \cdot Q^{n}+C E \cdot D Qn+1=CE⋅Qn+CE⋅D 逻辑符号
例1.试对图所示的带有异步清零和异步置位的边沿D触发器进行建模。
有异步输入端的发器D触发器
//版本1:module Set_Rst_DFF (Q, Q_, D, CP, Rd_, Sd_); output Q,Q_;input D,CP,Rd_,Sd_;wire Y1,Y2,Y3,Y4,Y5,Y6;assign #5 Y1 = ~(Sd_ & Y2 & Y4);assign #5 Y2 = ~(Rd_ & CP & Y1);assign #5 Y3 = ~(CP & Y2 & Y4);assign #5 Y4 = ~(Rd_ & Y3 & D );assign #5 Y5 = ~(Sd_ & Y2 & Y6);assign #5 Y6 = ~(Rd_ & Y3 & Y5);assign Q = Y5;assign Q_= Y6;endmodule版本1: 根据该图使用连续赋值语句来建模,在assign语句中的#5表示给每个与非门加5个单位时间的传输延迟。
//版本2module Set_Rst_DFF_bh (Q,发器 Q_, D, CP, Rd_, Sd_); output reg Q;output Q_;input D,CP,Rd_,Sd_;assign Q_= ~Q;always @(posedge CP or negedge Sd_ or negedge Rd_) if (~Sd_) //等同于: if (Sd_== 0)Q <= 1'b1; else if (~Rd_) Q <= 1'b0; else Q <= D;endmodule版本2的特点:
采用功能描述风格,使用always和if-else对输出变量赋值 。
negedge Sd_是一个异步事件,它与if(~Sd_)必须匹配,negedge Rd_是另一个异步事件,它与if(~Rd_)必须匹配,这是语法规定 。
注意,如果置1事件、置0事件和时钟事件同时发生,则置1事件的优先级别最高 、置0事件的次之,时钟事件的优先级最低 。
例2 具有同步清零功能的上升沿D触发器。
例4 试用功能描述风格对图所示电路进行建模(2分频电路) ,并给出仿真结果。
解:(1)设计块:使用always和if-else语句对输出变量赋值,其代码如下。
(2)激励块:给输入变量赋值 。
`timescale 1 ns/ 1 nsmodule test_2Divider();reg CP, Rd_; wire Q;//调用(例化)设计块_2Divider U1 ( .CP(CP), .Q(Q),.Rd_(Rd_) );initial begin //产生复位信号Rd_Rd_ = 1'b0;Rd_ = #2000 1'b1;#8000 $stop;end always begin //产生时钟信号CPCP = 1'b0;CP = #500 1'b1;#500;end endmodule(3)仿真波形(用ModelSim)
由图可知,时钟CP的周期为1000ns,在2000ns之前,清零信号Rd_有效,输出Q被清零