过程赋值:用于对reg型变量赋值,改变寄存器的值或为以后排定改变。

     语法

{阻塞性(blocking)赋值}

     RegisterLValue = [ TimingControl] Expression;

{非阻塞性(non-blocking)赋值}

RegisterLValue <= [ TimingControl] Expression;

     阻塞:在本语句中“右式计算”和“左式更新”完全完成之后,才开始执行下一条语句;

     非阻塞:当前语句的执行不会阻塞下一语句的执行。

     过程赋值右边的表达式在赋值执行的时候算出。如果没有内部赋值延时,左边的寄存器由于阻塞性赋值将立即更新,而非阻塞性赋值则下一个仿真周期才更新左边的寄存器。如果有内部赋值延时,左边的寄存器只在发生内部赋值延时后更新。

     例如对于阻塞性赋值:

  • 当执行赋值语句时,算出右边的表达式的值,但左边的值不更新,直到产生定时控制事件或延时(称为“内部赋值延时”)。
  • 直到左边被更新后(即经过内部赋值延时后)阻塞性赋值才完成。begin-end块中的下一个语句直到此时才开始执行。

    结合编程语句区分如下:

    • 非阻塞(non-blocking) 赋值语句(b<= a):     

       - 块内的赋值语句同时赋值;    

       - b的值被赋成新值a的操作, 是与块内其他赋值语句同时完成的;    

       - 建议在可综合风格的模块中使用非阻塞赋值。

     • 阻塞(blocking) 赋值语句(b = a):    

       - 完成该赋值语句后才能做下一句的操作;    

       - b的值立刻被赋成新值a;    

       - 硬件没有对应的电路,因而综合结果未知。

     阻塞赋值和非阻塞赋值如果使用不当会存在冒险和竞争现象,必须按照下面两条准则:

     1)在描述组合逻辑的always块中使用阻塞赋值,则综合组合逻辑的电路结构;

     2)在描述时序逻辑的always块中使用非阻塞赋值,则综合时序逻辑的电路结构。

     在时钟沿触发的always块中,如果用非阻塞赋值语句对reg型变量赋值;或者当reg型变量经过多次循环其值仍保持不变,则会在综合中生成触发器。若不想生成触发器,而希望用reg型变量生成组合逻辑,则应使用电平触发。在组合逻辑中,阻塞赋值只与电平有关,往往和触发沿没有关系,可以将其看成并行执行的;在时序逻辑中,非阻塞赋值是并行执行的;因此,优秀的HDL设计,其内部语句也是并行执行的。

 

     非阻塞赋值与阻塞赋值示例:

     1. 非阻塞赋值方式

 1 module nonblocking(input clk, 
 2                    input a,
 3                    output reg c); 
 4 reg b;
 5 
 6 always @(posedge clk) begin
 7     b <= a;
 8     c <= b;
 9 end
10 
11 endmodule
non-blocking

相关文章:

  • 2021-09-07
  • 2021-12-15
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-09-03
  • 2022-12-23
猜你喜欢
  • 2021-05-13
  • 2022-12-23
  • 2021-11-30
  • 2021-06-16
相关资源
相似解决方案