转自: http://blog.21ic.com/user1/5983/archives/2011/83385.html
两个要点:
×在描述组合逻辑的always块中用阻塞赋值,则综合成组合逻辑的电路结构。
×在描述时序逻辑的always块中用非阻塞赋值,则综合成时序逻辑的电路结构。
为了更好地理解上述要点,我们需要对Verilog 语言中的阻塞赋值和非阻塞赋值的功能和执行时间上的差别有深入的了解。为了解释问题方便下面定义两个缩写字:
RHS – 方程式右手方向的表达式或变量可分别缩写为: RHS表达式或RHS变量。 LHS – 方程式左手方向的表达式或变量可分别缩写为: LHS表达式或LHS变量。
IEEE Verilog标准定义了有些语句有确定的执行时间,有些语句没有确定的执行时间。若有两条或两条以上语句准备在同一时刻执行,但由于语句的排列次序不同(而这种排列次序的不同是IEEE Verilog标准所允许的), 却产生了不同的输出结果。这就是造成Verilog模块冒险和竞争现象的原因。为了避免产生竞争,理解阻塞和非阻塞赋值在执行时间上的差别是至关重要的。
阻塞赋值
阻塞赋值操作符用等号(即 = )表示。为什么称这种赋值为阻塞赋值呢?这是因为在赋值时先计算等号右手方向(RHS)部分的值,这时赋值语句不允许任何别的Verilog语句的干扰,直到现行的赋值完成时刻,即把RHS赋值给 LHS的时刻,它才允许别的赋值语句的执行。一般可综合的阻塞赋值操作在RHS不能设定有延迟,(即使是零延迟也不允许)。从理论上讲,它与后面的赋值语句只有概念上的先后,而无实质上的延迟。 若在RHS 加上延迟,则在延迟期间会阻止赋值语句的执行, 延迟后才执行赋值,这种赋值语句是不可综合的,在需要综合的模块设计中不可使用这种风格的代码。
阻塞赋值的执行可以认为是只有一个步骤的操作:
计算RHS并更新LHS,此时不能允许有来自任何其他Verilog语句的干扰。 所谓阻塞的概念是指在同一个always块中,其后面的赋值语句从概念上(即使不设定延迟)是在前一句赋值语句结束后再开始赋值的。
如果在一个过程块中阻塞赋值的RHS变量正好是另一个过程块中阻塞赋值的LHS变量,这两个过程块又用同一个时钟沿触发,这时阻塞赋值操作会出现问题,即如果阻塞赋值的次序安排不好,就会出现竞争。若这两个阻塞赋值操作用同一个时钟沿触发,则执行的次序是无法确定的。下面的例子可以说明这个问题。
[例1]. 用阻塞赋值的反馈振荡器
module fbosc1 (y1, y2, clk, rst);
output y1, y2;
input clk, rst;
reg y1, y2;
always @(posedge clk or posedge rst)
if (rst) y1 = 0; // reset
else y1 = y2;
always @(posedge clk or posedge rst)
if (rst) y2 = 1; // preset
else y2 = y1;
endmodule
按照IEEE Verilog 的标准,上例中两个always块是并行执行的,与前后次序无关。如果前一个always块的复位信号先到0时刻,则y1 和y2都会取1,而如果后一个always块的复位信号先到0时刻,则y1 和y2都会取0。这清楚地说明这个Verilog模块是不稳定的会产生冒险和竞争的情况。
非阻塞赋值
非阻塞赋值操作符用小于等于号 (即 <= )表示。为什么称这种赋值为非阻塞赋值?这是因为在赋值操作时刻开始时计算非阻塞赋值符的RHS表达式,赋值操作时刻结束时更新LHS。在计算非阻塞赋值的RHS表达式和更新LHS期间,其他的Verilog语句,包括其他的Verilog非阻塞赋值语句都能同时计算RHS表达式和更新LHS。非阻塞赋值允许其他的Verilog语句同时进行操作。非阻塞赋值的操作可以看作为两个步骤的过程:
1) 在赋值时刻开始时,计算非阻塞赋值RHS表达式。
2) 在赋值时刻结束时,更新非阻塞赋值LHS表达式。
非阻塞赋值操作只能用于对寄存器类型变量进行赋值,因此只能用在"initial"块和"always"块等过程块中。非阻塞赋值不允许用于连续赋值。下面的例子可以说明这个问题:
[例2]. 用非阻塞赋值的反馈振荡器
module fbosc2 (y1, y2, clk, rst);
output y1, y2;
input clk, rst;
reg y1, y2;
always @(posedge clk or posedge rst)
if (rst) y1 <= 0; // reset
else y1 <= y2;
always @(posedge clk or posedge rst)
if (rst) y2 <= 1; // preset
else y2 <= y1;
endmodule
同样,按照IEEE Verilog 的标准,上例中两个always块是并行执行的,与前后次序无关。无论哪一个always块的复位信号先到, 两个always块中的非阻塞赋值都在赋值开始时刻计算RHS表达式,,而在结束时刻才更新LHS表达式。所以这两个always块在复位信号到来后,在always块结束时 y1为0而y2为1是确定的。从用户的角度看这两个非阻塞赋值正好是并行执行的。
---------------------------------------------------------------------------
掌握可综合风格的Verilog模块编程的八个原则会有很大的帮助。在编写时牢记这八个要点可以为绝大多数的Verilog用户解决在综合后仿真中出现的90-100% 的冒险竞争问题。
1) 时序电路建模时,用非阻塞赋值。
2) 锁存器电路建模时,用非阻塞赋值。
3) 用always块建立组合逻辑模型时,用阻塞赋值。
4) 在同一个always块中建立时序和组合逻辑电路时,用非阻塞赋值。
5) 在同一个always块中不要既用非阻塞赋值又用阻塞赋值。
6) 不要在一个以上的always块中为同一个变量赋值。
7) 用$strobe系统任务来显示用非阻塞赋值的变量值
8) 在赋值时不要使用 #0 延迟
分享到:
相关推荐
在Verilog的设计中,正确使用阻塞赋值( Blocking Assignment)和非阻塞赋值(Non-blocking Assignment)是至关重要的。这两种赋值方式对硬件的时序行为和功能仿真有直接影响,因此了解它们的区别和正确的使用场合...
4. 对于锁存器(latch)的建模,有时也需要使用非阻塞赋值,但这种用法需要特别小心,因为锁存器在某些情况下可能引入不期望的存储特性。 通过仿真实例,如test1模块,可以清晰地看到不同赋值方式对输出out1~out4的...
### 阻塞与非阻塞赋值:深入理解Verilog中的关键概念 #### 引言 在硬件描述语言(Verilog HDL)的设计中,阻塞与非阻塞赋值是两个非常重要的概念。它们直接影响着代码的执行顺序以及模块的行为特性。本文将详细...
在 FPGA 设计中,阻塞和非阻塞赋值是两个不同的概念,它们在 Verilog HDL 中的使用方式和执行机制都有所不同。阻塞赋值对应的电路结构往往与触发沿没有关系,只与输入电平的变化有关系,而非阻塞赋值对应的电路结构...
Verilog数字系统设计中深入理解阻塞和非阻塞赋值的用法。
在Verilog HDL语音中,信号有两种赋值方式:阻塞赋值和非阻塞赋值。阻塞赋值的操作符为“=”,非阻塞赋值的操作符为“”。阻塞赋值是一种同步赋值方式,指的是赋值语句完成后,块才结束。非阻塞赋值是一种异步赋值...
阻塞赋值使用“=”操作符,非阻塞赋值使用“”操作符。 阻塞赋值的特点是,赋值语句完成后,块才结束,b 的值在赋值语句执行完后立刻改变。在时序逻辑中使用时,可能会产生意想不到的结果。阻塞赋值操作可以看成是...
在Testbench中,尽管非阻塞赋值的使用可能不会直接影响最终电路的功能,但为了确保测试的准确性和可预测性,最好遵循正确的编程习惯。在描述时序逻辑时使用“”,描述组合逻辑时使用“=”。这样做不仅可以帮助避免...
Verilog有两种赋值方式:阻塞赋值(=)和非阻塞赋值()。阻塞赋值用于顺序逻辑,非阻塞赋值则用于并行逻辑,防止信号竞争。 6. **运算符**: Verilog包含丰富的算术、逻辑、位操作和比较运算符,如+、-、*、/、&...
4. **高级特性**:Verilog 2005引入了一些新特性,如非阻塞赋值(non-blocking assignments)、动态数组、位操作、接口(interfaces)和系统任务。这些增强了语言的表达能力和灵活性。 5. **时序分析**:手册详细...
7. Verilog语言中阻塞和非阻塞赋值:Verilog语言中阻塞和非阻塞赋值是指在赋值语句中使用blocking和non-blocking赋值符号来控制赋值的执行顺序。 8. Verilog语言中常见的错误:Verilog语言中常见的错误包括语法错误...
本文档《可编程逻辑器件编程技术:Verilog HDL基础2:逻辑设计.pdf》主要涵盖了Verilog HDL中关于阻塞赋值与非阻塞赋值、always块语法原则、赋值语法原则、组合逻辑电路设计、时序逻辑电路设计以及时钟同步状态机...
2. **赋值操作**:Verilog有两种赋值方式,非阻塞赋值()和阻塞赋值(=)。非阻塞赋值在并行执行时防止数据竞争,而阻塞赋值通常用于顺序逻辑。 3. **模块**:模块是Verilog的基本构造单元,代表硬件电路的一部分...
同时,书中也会涵盖一些高级特性,如任务(task)、函数(function)、非阻塞赋值(non-blocking assignment)等,这些都是进行高效并发设计的关键。 在理解了Verilog语言之后,读者将学习如何进行FPGA设计流程,这...
8. **高级特性**:包括任务(task)和函数(function)的使用,非阻塞赋值(non-blocking assignments)的理解,以及系统Verilog的扩展等,这些都是进阶的学习点。 9. **案例分析**:通过解决练习题,学习者能更好...
本文将根据所给文件内容,深入解析Verilog语言中的一些基础知识点,包括连续赋值与过程赋值的区别、initial和always构造中的赋值差异、阻塞与非阻塞赋值的用法、任务与函数的不同、参数的使用和覆盖规则等。...
EDA实验涉及的是电子设计自动化(EDA)领域,主要围绕Verilog语言的基础知识展开。Verilog是一种硬件描述语言,用于描述数字系统的逻辑行为,可用于设计、验证和模拟集成电路。以下是Verilog的一些关键知识点: 1. ...
Verilog HDL作为一种广泛应用于数字系统设计的语言,其语法特性中的**阻塞赋值**与**非阻塞赋值**对于理解和编写高质量的Verilog代码至关重要。 **1.1 阻塞赋值(`=`)** - **定义**: 当使用阻塞赋值时,赋值操作...
在本“verilog 例子”压缩包中,你将找到一系列的示例,这些示例涵盖了Verilog语言的基础到高级用法,对学习和理解Verilog语言非常有帮助。 首先,让我们从基础开始。Verilog的基本语法结构包括模块、变量声明、...
8.4.3 非阻塞性过程赋值 71 8.4.4 连续赋值与过程赋值的比较 72 8.5 if 语句 73 8.6 case语句 74 8.7 循环语句 76 8.7.1 forever 循环语句 76 8.7.2 repeat 循环语句 76 8.7.3 while 循环语句 77 8.7.4 for 循环语句...