写在前面:本章将理解 RS/D 锁存器的概念,了解 RS/D/JK 触发器的概念,使用 Verilog 实现各种锁存器 (Latch) 和翻转器 (Flip-Flop),并通过 FPGA 验证用 Verilog 的实现。
本章目录:
Ⅰ. 前置知识回顾
0x00 锁存器(Latch)
0x01 RS 触发器(RS Flip-Flop)
0x02 D 触发器(D Flip-Flop)
0x03 JK Flip-Flop(JK 触发器)
0x04 设置时间和保持时间
Ⅱ. 练习
0x00 RS Flip-Flop
0x01 D Flip-Flop
设置时间:设置时间是指在上升或下降沿发生之前接受输入值所需的最小时间。
换句话说,它是在切换发生之前维持输入值以确保其准确识别的最小时间。
它表示确定输入值是高电平还是低电平所需的最小时间。
保持时间:在具有前沿触发器的D触发器中,当时钟值下降为0后,D值必须保持稳定一段时间,
以防止内存中出现垃圾值。将D值保持稳定所需的时间称为保持时间。
换句话说,它是在上升或下降沿发生后,为准确输出输出值所需的最小时间。
通过 Verilog 模拟结果来完成 Truth Table (B) 的空白部分 (按输入顺序排列):
Design source:
`timescale 1ns / 1ps
module RSFF(
input clk,
input S,
input R,
input CLR,
output Q,
output Qp
);
reg Q;
always @(posedge !clk) begin
if(CLR) Q<=1'b0;
else begin
if((S==1'b0)&&(R==1'b0)) Q<=Q;
else if((S==1'b0)&&(R==1'b1)) Q<=1'b0;
else if((S==1'b1)&&(R==1'b0)) Q<=1'b1;
else if((S==1'b1)&&(R==1'b1)) Q<=1'bx;
end
end
assign Qp = ~Q;
endmodule
Testbench:
`timescale 1ns / 1ps
module RSFF_tb;
reg clk, S, R, CLR;
wire Q, Qp;
RSFF u_RSFF(
.clk(clk ),
.S(S ),
.R(R ),
.CLR(CLR ),
.Q(Q ),
.Qp(Qp )
);
initial clk = 1'b0;
initial CLR = 1'b1;
initial S = 1'b0;
initial R = 1'b0;
always clk = #50 ~clk;
always@(CLR) begin
CLR = #125 ~CLR;
end
always@(S) begin
S = #175 ~S;
S = #50 ~S;
end
always@(R) begin
R = #375 ~R;
R = #50 ~R;
end
always@(R) begin
R = #575 ~R;
R = #50 ~R;
end
always@(S) begin
S = #675 ~S;
S = #50 ~S;
end
always@(R) begin
R = #675 ~R;
R = #50 ~R;
end
initial begin
#800
$finish;
end
endmodule
运行结果如下:
真值表:
Schematic:
通过仿真表现 Timing Diagram,将 Latch 与 Flip-Flop 的仿真结果相比较:
Design source:
`timescale 1ns / 1ps
module DFF(
input clk,
input D,
input CLR,
output Q,
output Qp
);
reg Q;
always @(posedge !clk) begin
if(CLR) Q<=1'b0;
else begin
if((D==1'b0)) Q<=1'b0;
else if((D==1'b1)) Q<=1'b1;
end
end
assign Qp = ~Q;
endmodule
Testbench:
`timescale 1ns / 1ps
module DFF_tb;
reg clk, D, CLR;
wire Q, Qp;
DFF u_DFF(
.clk(clk ),
.D(D ),
.CLR(CLR ),
.Q(Q ),
.Qp(Qp )
);
initial clk = 1'b0;
initial CLR = 1'b1;
initial D = 1'b0;
always clk = #50 ~clk;
always@(CLR) begin
CLR = #125 ~CLR;
end
always@(D) begin
D = #375 ~D;
D = #50 ~D;
end
always@(D) begin
D = #575 ~D;
D = #50 ~D;
end
always@(D) begin
D = #675 ~D;
D = #50 ~D;
end
initial begin
#800
$finish;
end
endmodule
运行结果如下:
Schematic:
[ 笔者 ] 王亦优
[ 更新 ] 2023.5.16
❌ [ 勘误 ] /* 暂无 */
[ 声明 ] 由于作者水平有限,本文有错误和不准确之处在所难免,
本人也很想知道这些错误,恳望读者批评指正!
参考资料 Introduction to Logic and Computer Design, Alan Marcovitz, McGrawHill, 2008 Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. . 百度百科[EB/OL]. []. https://baike.baidu.com/. |