掌握 D 锁存器:设计、工作原理与关键差异
触发器在时钟的上升沿或下降沿捕获输入数据。关键在于,时钟沿之后直到下一个时钟沿之前,输入数据的任何变化都不会反映在输出上。而 锁存器 则不在时钟沿捕获,而是只要使能引脚有效,输出就跟随输入。
设计
本例构建一个具有三个输入和一个输出的锁存器。输入 d 为数据(0 或 1),rstn 为低电平有效复位,en 为使能信号,用于将输入数据锁存到输出。复位低电平有效意味着当该输入为 0 时复位生效。输出 q 的值由 d、en 和 rstn 决定。
module d_latch (
input d, // 1位数据输入
input en, // 1位使能输入
input rstn, // 1位低电平有效复位
output reg q // 1位数据输出
);
// 此 always 块在 en/rstn/d 任一变化时触发
// 若复位有效则输出为 0
// 否则只要使能为高,输出 q 跟随输入 d
always @ (en or rstn or d)
if (!rstn) q <= 0;
else if (en) q <= d;
endmodule
注意 always 块的敏感列表包含更新输出所需的所有信号。该块在敏感列表中任一信号值变化时触发。且 q 仅在 en 为高时获取 d 的值,因此是 正极性 锁存器。
原理图
测试平台
module tb_latch;
// 声明驱动设计的变量
reg d;
reg en;
reg rstn;
reg [2:0] delay;
reg [1:0] delay2;
integer i;
// 实例化设计并连接测试平台信号
d_latch dl0 (
.d (d),
.en (en),
.rstn (rstn),
.q (q)
);
// 此 initial 块构成测试激励
initial begin
$monitor ("[%0t] en=%0b d=%0b q=%0b", $time, en, d, q);
// 1. 初始化测试平台变量
d <= 0;
en <= 0;
rstn <= 0;
// 2. 释放复位
#10 rstn <= 1;
// 3. 随机改变 d 和使能
for (i = 0; i < 5; i=i+1) begin
delay = $random;
delay2 = $random;
#(delay2) en <= ~en;
#(delay) d <= i;
end
end
endmodule
为了使测试平台以更随机的方式置位和释放信号,我们声明了一个 3 位的 reg 变量 delay,可取 0 到 7 的值。然后用 delay 变量延迟 d 和 en 的赋值,使每次循环产生不同模式。
输出
仿真日志
ncsim> run [0] en=0 d=0 q=0 [11] en=1 d=0 q=0 [18] en=0 d=0 q=0 [19] en=0 d=1 q=0 [20] en=1 d=1 q=1 [25] en=1 d=0 q=0 [27] en=0 d=0 q=0 [32] en=0 d=1 q=0 [33] en=1 d=1 q=1 [34] en=1 d=0 q=0 ncsim: *W,RNQUIE: Simulation is complete.
点击图片可放大查看。
Verilog
- 共射极放大器:设计、测量与负反馈技术
- 构建可作运放的高增益差分放大器:电流镜像优化设计
- 精密电压跟随器:掌握运放反馈实现精准信号跟踪
- 同相放大器:构建、测试与掌握运放增益控制
- 使用4511七段解码器:实用BCD显示教程
- C# 基础:输入输出核心技巧完全指南
- 掌握 C++ 输入输出:cin/cou 完整实战指南
- C 语言输入输出(I/O)精通:scanf() 与 printf() 详解
- C++ 流精通:cout、cin、cerr、clog 实战指南
- C 语言输入输出完全掌握:标准 I/O 与格式化控制
- 精通Python输入输出与模块导入:实战指南
- 精通 Java 输入输出:打印、读取与格式化数据