非阻塞赋值
本课属于 Coddy Verilog 学习旅程的“基础知识”单元。第 50 课,共 90 课。
在上一课中,我们介绍了阻塞赋值(=),它会逐步执行。现在我们来介绍非阻塞赋值(<=),它会同时并行执行。
非阻塞赋值使用 <= 运算符。它被称为“非阻塞”,因为它不会阻塞下一条语句的执行。一个代码块中的所有非阻塞赋值都会同时执行。
语法:
variable <= expression;何时使用非阻塞赋值
非阻塞赋值(<=)用于时序逻辑:这类电路使用时钟并具有存储功能。输出只会在时钟边沿(通常是上升沿)变化。
时序逻辑示例:
- 触发器
- 寄存器
- 计数器
- 状态机
- 移位寄存器
Verilog 示例:
initial begin
a <= 5; // 已安排执行,但尚未执行
b <= a + 2; // 已安排执行,使用 a 的旧值
c <= b * 3; // 已安排执行,使用 b 的旧值
end所有三个赋值都使用旧值同时进行。时间步结束时,所有更新会一起发生。
始终块中的非阻塞赋值(时序逻辑)
非阻塞赋值用于时序逻辑:使用时钟并具有存储功能的电路(触发器、寄存器、计数器)。
always @(posedge clk) begin
q <= d; // 在时钟边沿,q 获取 d 的值
count <= count + 1; // 在时钟边沿,count 加 1
end这两个赋值会同时发生,并使用时钟沿到来之前的值。
总结
| 规则 | 说明 |
|---|---|
顺序逻辑使用 <= | always @(posedge clk) |
组合逻辑使用 = | always @(*) |
| 非阻塞赋值会并行执行 | 所有赋值会同时发生 |
| 值会在时间步结束时更新 | 不会立即更新 |
挑战
完成非阻塞赋值
添加缺失的非阻塞赋值,让这个 2 位移位寄存器正常工作。
工作原理:
- 每个时钟沿到来时,
q1获取d q2获取q1的旧值
要做什么:
- 将
d赋给q1(非阻塞) - 将
q1赋给q2(非阻塞)
亲手试试
module shift_register (
input clk,
input reset,
input d,
output reg q1,
output reg q2
);
always @(posedge clk or posedge reset) begin
if (reset) begin
q1 <= 0;
q2 <= 0;
end else begin
// TODO:添加移位逻辑
// 第 1 步:用非阻塞赋值将 d 赋给 q1
// 第 2 步:用非阻塞赋值将 q1 赋给 q2
end
end
endmodule这节课包含一个小测验。开始学习即可作答,并记录你的进度。
基础知识中的所有课
自己练习: Verilog 在线编译器