1. Verilog赋值机制深度解析
在FPGA开发中,Verilog的阻塞赋值(=)和非阻塞赋值(<=)是最基础也最容易踩坑的概念。很多初学者在时序逻辑设计中,因为混淆这两种赋值方式导致电路功能异常。我们先从一个典型场景切入:
verilog复制always @(posedge clk) begin
a = b + 1; // 阻塞赋值
b <= a; // 非阻塞赋值
c = a;
end
这个简单的代码块里藏着三个关键陷阱:
- 阻塞赋值会立即改变左值并影响后续语句
- 非阻塞赋值的右值采样时机有特殊规则
- 混合使用时执行顺序可能违反直觉
重要提示:在同一个always块中混用两种赋值方式是极其危险的编码风格,实际项目中应避免这种写法。这里仅用于教学演示。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 阻塞赋值的工作原理
2.1 立即生效特性
阻塞赋值使用=运算符,其核心特点是语句执行时立即更新左值。用硬件思维理解,它模拟的是组合逻辑的行为:
verilog复制a = b + 1; // 相当于在电路中直接连了条加法器路径
执行过程:
- 实时计算右值表达式(b+1)
- 立即将结果写入左值变量(a)
- 后续语句将使用更新后的a值
2.2 顺序执行陷阱
阻塞赋值的"阻塞"体现在它会阻塞后续语句的执行,直到当前赋值完成。这会导致微妙的时序问题:
verilog复制// 危险示例:
always @(posedge clk) begin
a = b;
b = a; // 形成组合逻辑环路!
end
这个代码实际上实现的是交换寄存器值的功能,但综合后会生成锁存器而非预期的触发器,可能导致亚稳态。
3. 非阻塞赋值的运行机制
3.1 延迟更新特性
非阻塞赋值使用<=运算符,其核心特点是右值采样与左值更新分离:
verilog复制b <= a; // 右值a采样于过程块开始时,更新在块结束时
执行分两个阶段:
- 采样阶段:在always块开始时立即采样右值(a的旧值)
- 更新阶段:在always块结束时统一更新所有非阻塞赋值的左值
3.2 硬件对应关系
非阻塞赋
