阻塞非阻塞使用,initial assign always区别

本文探讨了组合逻辑电路中阻塞赋值的应用,与时序逻辑中非阻塞赋值的对比,以及在不同情境下的使用规则。重点介绍了initial指令的用途和wire与reg的区别,以及如何在always块中正确处理同步与异步时序逻辑。

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

组合逻辑:输出只是当前输入逻辑电平的函数(有延时),与电路的原始状态无关。当前电路输入信号任何一个发生改变,输出都将发生改变。
时序逻辑:输出不仅是当前输入电平的函数,还与目前电路的状态有关。 

同步时序:表示状态的寄存器组只能在唯一确定的触发条件发生时刻改变。
异步时序:表示触发条件由多个控制因素组成,如一个触发器的输出连接到另一个触发器的时钟就是异步时序逻辑。

阻塞赋值是按序执行计算等号右边的值并同时赋给左边变量,当前语句完成才能执行下一句

所谓阻塞的概念是指在同一个always块中,其后面的赋值语句从概念上(即使不设定延迟)是在前一句赋值语句结束后再开始赋值的。 

非阻塞赋值是并行执行各语句同时执行,注意如果begin——end中存在非阻塞赋值,由于非阻塞是并发执行的,这时就不是一条一条执行的,有点类似fork——join块语句。

 当执行“x=next_x;”时,x会立即的到next_x的值。而下一句“y=x;”必须等到“x=next_x;”执行完毕才能被执行。由于这两条语句都没有延迟(相当于导线),导致他们的等价语句为“y=next_x;”。时序逻辑用《=

① 在组合逻辑电路描述中采用阻塞赋值
② 时序逻辑描述,采用非阻塞赋值方式赋值

initial不可综合,一般是用在程序模块最开始初始化数据用,对寄存器、输出等变量进行清零等工作。特别是在testbench中应用非常普遍,

wire对应于连续赋值,如assign; reg对应于过程赋值,如always,initial;wire型变量综合出来一般情况下是一根导线。 reg变量在always中有两种情况: (1)always @(a or b or c)形式的,即不带时钟边沿的,综合出来还是组合逻辑,此时用阻塞赋值。; (2)always @(posedge clk)形式的,即带有边沿的,综合出来一般是时序逻辑,会包含触发器(Flip-Flop)

在组合电路always语句块里面,output信号必须定义为reg,不能用wire,如果只是assign语句,左侧必须为net类型(例如,wire),右侧wire和reg都可以。wire表示connection,reg表示variable,其实有两种意思,一种是时序电路的register,一种是组合电路的logic,verilog语法没有仔细地区分,造成一些误解,其实组合电路里面的应该定义成logic类型

设计中,输入信号一般来说不能判断出上一级是寄存器输出还是组合逻辑输出,对于本级来说,就当成一根导线,即wire型。而输出信号则由自己来决定是reg还是组合逻辑输出,wire和reg型都可以。但一般的,整个设计的外部输出(即最顶层模块的输出),要求是reg输出,这比较稳定、扇出能力好。

#1: 当为时序逻辑建模,使用“非阻塞赋值”。
#2: 当为锁存器(latch)建模,使用“非阻塞赋值”。
#3: 当用always块为组合逻辑建模,使用“阻塞赋值”
#4: 当在同一个always块里面既为组合逻辑又为时序逻辑建模,使用“非阻塞赋值”。
#5: 不要在同一个always块里面混合使用“阻塞赋值”和“非阻塞赋值”。
#6: 不要在两个或两个以上always块里面对同一个变量进行赋值。
#7: 使用$strobe以显示已被“非阻塞赋值”的值。
#8: 不要使用#0延迟的赋值。

<think>好的,我现在要回答用户关于Verilog中非阻塞赋值阻塞赋值的区别的问题。首先,我需要回顾一下自己对这些概念的理解,并参考提供的引用资料来确保准确性。 首先,阻塞赋值非阻塞赋值在Verilog中是两种不同的赋值方式,主要用于过程(如alwaysinitial)中。根据引用[1],非阻塞赋值只能用于寄存器类型的变量,并且只能在过程使用,而连续赋值(assign语句)必须使用阻塞赋值。这一点很重要,因为用户可能在使用这两种赋值方式时遇到语法错误,需要明确它们的适用场景。 接下来,引用[3]详细解释了阻塞赋值的工作原理。阻塞赋值使用“=”符号,其特点是顺序执行,即在同一个always中,前一条语句执行完成后才会执行下一条。这类似于C语言中的顺序执行,适用于组合逻辑的设计。例如,在组合逻辑中,使用阻塞赋值可以确保信号立即更新,便于逻辑门的模拟。 而非阻塞赋值使用“<=”符号,其特点是并行执行。引用[4]提到,非阻塞赋值的执行分为两步:首先计算右侧的表达式,然后在时间步结束时更新左侧的变量。这意味着在同一个always中,所有的非阻塞赋值语句的右侧表达式都是同时计算的,不会相互阻塞。这在时序逻辑中特别有用,如触发器之间的信号传递,可以避免竞争冒险问题。 用户提供的引用[5]指出,当多个过程使用阻塞赋值并且存在相互依赖时,执行顺序的不确定性可能导致竞争。例如,两个always使用阻塞赋值,并且依赖于对方的变量,此时仿真结果可能不一致。而非阻塞赋值通过延迟更新,确保所有右侧表达式在同一时间步开始前计算,从而避免了这种竞争。 此外,引用[4]中的实验对比了两种赋值方式在仿真中的结果。使用阻塞赋值时,由于执行顺序的随机性,可能导致输出不确定;而使用非阻塞赋值时,所有变量在同一时间点更新,结果更稳定。这进一步验证了在时序逻辑中使用非阻塞赋值的重要性。 现在需要将这些点组织成一个清晰的回答,分点说明区别、应用场景仿真差异。同时,根据用户要求生成相关问题,可能需要包括语法差异、仿真影响、设计原则等。 需要确保回答中正确引用资料,例如在讨论竞争冒险时引用[4][5],在语法规则时引用[1][3]。同时,要使用中文,并遵循格式要求,如数学表达式用$...$,独立公式用$$...$$,但当前问题可能不涉及数学表达式,所以可能不需要使用。 最后,生成的相关问题应覆盖用户可能感兴趣的扩展内容,如设计原则、优化方法、实际应用案例等。</think>### 非阻塞赋值 vs 阻塞赋值 在 Verilog 中的区别 在Verilog中,**阻塞赋值(`=`)** **非阻塞赋值(`<=`)** 是两种关键赋值方式,主要区别体现在 **执行顺序、时序逻辑实现仿真行为** 上。以下是详细对比: --- #### 1. **语法与执行方式** - **阻塞赋值(`=`)** 执行时立即更新左侧变量,且同一`always`内的后续语句需等待当前赋值完成才能执行[^3]。 示例: ```verilog always @(posedge clk) begin a = b; // 立即更新a的值 c = a; // 使用更新后的a值赋值给c end ``` 此处`c`的赋值基于`a`的最新值,类似于顺序执行的软件代码。 - **非阻塞赋值(`<=`)** 所有右侧表达式同时计算,左侧变量在时间步结束时统一更新[^4]。 示例: ```verilog always @(posedge clk) begin a <= b; // 仅计算b的值,暂不更新a c <= a; // 使用a的旧值赋值给c end ``` 此处`c`的赋值基于`a`的原始值,两条语句的右侧表达式并行计算。 --- #### 2. **应用场景** - **阻塞赋值** 适用于 **组合逻辑**,如组合电路建模[^3]: ```verilog always @(*) begin sum = a + b; // 立即计算并传递结果 carry = (a & b) | (sum & cin); end ``` - **非阻塞赋值** 适用于 **时序逻辑**,如触发器寄存器[^4]: ```verilog always @(posedge clk) begin q1 <= d; // 时钟边沿触发后统一更新 q2 <= q1; // 使用q1的旧值 end ``` --- #### 3. **仿真行为差异** - **阻塞赋值可能导致竞争冒险** 若多个`always`共享变量且使用阻塞赋值,执行顺序的随机性会导致结果不确定[^5]: ```verilog // 两个always竞争更新y1y2 always @(posedge clk) y1 = y2; always @(posedge clk) y2 = y1; ``` 仿真结果可能为`00`或`11`,取决于执行顺序[^4]。 - **非阻塞赋值避免竞争** 所有赋值在时间步结束时统一更新,消除顺序依赖[^4]: ```verilog always @(posedge clk) y1 <= y2; always @(posedge clk) y2 <= y1; ``` 每个时钟周期`y1``y2`同时翻转(如`01`→`10`→`01`)。 --- #### 4. **设计原则** - **组合逻辑**:使用阻塞赋值(`=`),确保信号即时更新。 - **时序逻辑**:使用非阻塞赋值(`<=`),避免竞争冒险[^4]。 - **混合逻辑**:优先使用非阻塞赋值,保持时序一致性[^4]。 - **禁止多驱动**:避免在多个`always`中对同一变量赋值[^4]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值