一个很好的解释阻塞赋值与非阻塞赋值的例子

本文通过具体的Verilog代码示例对比了阻塞赋值与非阻塞赋值的区别,阐述了两者在综合过程中的不同表现,并讨论了它们在实际应用中的注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个很好的解释阻塞赋值与非阻塞赋值的例子

复制代码
 1 module bnbasm  (/*AUTOARG*/
 2    // Outputs
 3    q1, q2,
 4    // Inputs
 5    clk_osc
 6    ) ;
 7    input clk_osc;
 8    output [7:0] q1,q2;
 9 
10    reg [7:0] q1,q2;
11    always @(posedge clk_osc)
12      begin
13      q1=q1+8'd1;
14      q2=q1;
15      end
16 endmodule //
复制代码

 

这段代码综合出的RTL模型为:
将过程块中的赋值语句改成非阻塞赋值:
1    always @(posedge clk_osc)
2      begin
3      q1<=q1+8'd1;
4      q2<=q1;
5      end

 

则综合出来的RTL模型为:
 
  阻塞语句和非阻塞语句的认识是教科书上的:阻塞赋值语句在所在的块中是按从上到下执行,而非阻塞赋值为并发执行。难理解的地方在于阻塞赋值的“从上到下执行”,这个说法很容易会被理解成时间上的先后顺序,会认为这些赋值语句之前会有延时存在。但是这个延时是指的什么延时,怎么安排的这些延时,会往这方面去想,觉得哪里都不合理,因此会产生疑惑。
  仔细观察两个RTL模型,就感觉恍然大悟,原来阻塞赋值的“从上到下执行”是通过空间逻辑结构来实现的,延时什么的根本跟这个没有关系。
  至于通常的说法“组合逻辑使用阻塞赋值,时序逻辑使用非阻塞幅值”并不是准确的。阻塞赋值跟非阻塞赋值的混用也有可能会是设计的需要,至于Quartus里面对两种赋值混用的报警,设计者应该检查下是不是无意的行为,因为这个可能是会导致意外的结果的。
 
注:初学verilog的时候没有多关注这些小细节,没有多使用RTL viewer这些有用的工具,以后还是要多补补课啊。
《Verilog HDL 应用程序设计实例精讲》是一本好书啊,感觉比夏宇闻的那本入门书好多了。
### FPGA中阻塞非阻塞的概念及区别 在FPGA开发过程中,Verilog HDL中的阻塞赋值(blocking assignment)和非阻塞赋值(non-blocking assignment)是非常重要的概念。它们不仅影响代码的行为逻辑,还决定了最终合成后的硬件电路特性。 #### 阻塞赋值的特点 阻塞赋值使用`=`操作符,在程序执行时会立即完成变量的更新过程。这意味着当前语句被执行后,后续语句可以立刻访问到最新的变量[^1]。 例如: ```verilog always @(posedge Clk) begin C1 = D; C2 = C1; end ``` 在这个例子中,C1被赋予D的新之后,紧接着C2会被赋予此时已经更新过的C1[^3]。 这种行为通常用于组合逻辑的设计,因为其顺序依赖关系能够很好地模拟实际的组合门延迟效果。 #### 非阻塞赋值的特点 非阻塞赋值则采用`<=`操作符,所有的右侧表达式的计算都在同一时刻发生,而左侧目标寄存器的实际写入发生在整个块结束之前。因此,即使在同一进程中存在多个相互关联的操作也不会互相干扰。 考虑如下代码片段: ```verilog always @(posedge Clk) begin out <= d + c; d <= a + b; end ``` 这里d的新不会即时反映给out;相反,当该进程完成后才会应用这些变化。这样的机制非常适合于同步时序逻辑建模,因为它更贴近真实世界里触发器的工作原理——即所有输入信号的变化都应在下一个时钟沿才生效[^2]。 #### 使用场景分析 - **阻塞赋值**适用于描述纯组合逻辑路径的情况,比如算术运算单元或者状态解码部分。由于它能清晰展现因果链条上的数据流动方向,所以有助于提高可读性和调试效率。 - 对应地,**非阻塞赋值**更适合处理涉及存储元件(如寄存器阵列)及其间交互作用的情形。特别是在多级流水线架构下运用广泛,确保各级之间传递的数据保持一致性非常重要^。 总结来说,理解并合理选用这两种不同类型的赋值形式对于构建既高效又稳定的数字系统模型而言不可或缺. ```verilog // 示例:非阻塞赋值实现简单计数器 module counter ( input wire clk, input wire reset, output reg [7:0] count ); always @(posedge clk or posedge reset) begin if (reset) count <= 8&#39;d0; // 复位操作 else count <= count + 1; // 增加计数 end endmodule ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值