Verilog HDL阻塞与非阻塞的几个例子!

关于阻塞和非阻塞语句的7大原则:

原则1: 时序电路建模时,用非阻塞赋值。
原则2: 用always块写组合逻辑时,采用阻塞赋值。

原则3: 在同一个always块中不要同时使用非阻塞赋值和阻塞赋值。
原则4: 锁存器电路建模时,用非阻塞赋值。
原则5: 在同一个always块中同时建立时序和组合逻辑电路时,用非阻塞赋值。
原则6:    严禁在多个always块中对同一变量赋值。

原则7: 在程序中最好不要同时对同一变量既用阻塞赋值又用非阻塞赋值。

 

注意:对同一变量进行多次非阻塞赋值,变量值由最后一个赋值决定。

 

实例:

1、阻塞赋值(1)

module block_clk(clk,a,b,c);
  input clk;
  output a,b,c;
  
  reg [3:0] a,b,c;
  
  initial
    begin
      a=0;
      b=0;
      c=0;
    end
  
  always @(posedge clk)
    begin
      a=a+1;
      b=a-c;
    end
    
  always @(posedge clk)
    begin
      c=a;
    end
    
endmodule
  


b的结果始终为2,a与c的差值为1。因为b的结果等于加1赋值之后的a值减c,而c的值始终等于a上一个周期的值。

功能仿真波形如下:

打开Tool->Netlist Viewer->RTL Viever查看综合出的电路如图:

      由于clk相同,a、b、c触发器的赋值是同时进行的,只不过计算b值用到的a值取(a+1),这里可以理解为先执行“a=a+1”语句,再执行“b=a-c”语句,两语句只有概念上(功能上)的先后,没有时间上(延时)的先后。

2、阻塞赋值(2)

     做简单的修改

module block_clk(clk,a,b,c);
  input clk;
  output a,b,c;
  
  reg [3:0] a,b,c;
  
  initial
    begin
      a=0;
      b=0;
      c=0;
    end
  
  always @(posedge clk)
    begin
      a=a+1;
    end
    
  always @(posedge clk)
    begin
      b=a-c;
    end
    
  always @(posedge clk)
    begin
      c=a;
    end
    
endmodule
  


b的结果变为了1,a与c的差值保持不变为1。“b=a-c”和“c=a”中a、c的值均为触发上升沿到来之前的值(即上一个周期的值)。

综合出来的电路图:

功能仿真波形:

3、下面几种代码综合后的结果和上面2的结果一样

 

module block_clk(clk,a,b,c);
  input clk;
  output a,b,c;
  
  reg [3:0] a,b,c;
  
  initial
    begin
      a<=0;
      b<=0;
      c<=0;
    end //初始化赋值也可以用阻塞赋值
  
  always @(posedge clk)
    begin
      a<=a+1;
    end
    
  always @(posedge clk)
    begin
      b<=a-c;
    end
    
  always @(posedge clk)
    begin
      c<=a;
    end
    
endmodule


 

module block_clk(clk,a,b,c);
  input clk;
  output a,b,c;
  
  reg [3:0] a,b,c;
  
  initial
    begin
      a<=0;
      b<=0;
      c<=0;
    end  //初始化赋值也可以用阻塞赋值  
  always @(posedge clk)
    begin
      a<=a+1;
      b<=a-c;
      c<=a;
    end
   
endmodule

 

4、阻塞赋值(3)

      在一个always块中连续的阻塞赋值只有概念上(功能上)的先后,没有时间上(延时)的先后。

module block_clk(clk,a,b,c);
  input clk;
  output a,b,c;
  
  reg [3:0] a,b,c;
  
  initial
    begin
      a=0;
      b=0;
      c=0;
    end  
  
  always @(posedge clk)
    begin
      a=a+1;
      b=a-c;
      c=a;
    end
     
endmodule
  

综合后电路图如下:

功能仿真波形:

 

5、下面两种方式综合后的结果相同

module block_clk(clk,a,b,c);
  input clk;
  output a,b,c;
  
  reg [3:0] a,b,c;
  
  initial
    begin
      a=0;
      b=0;
      c=0;
    end  
  
  always @(posedge clk)
    begin
      a<=a+1;
    end
    
  always @(a)
    begin
      b=a+1;
      c=b+1;
    end
   
endmodule
 

   

module block_clk(clk,a,b,c);
  input clk;
  output a,b,c;
  
  reg [3:0] a,b,c;
  
  initial
    begin
      a=0;
      b=0;
      c=0;
    end  
  
  always @(posedge clk)
    begin
      a<=a+1;
    end
    
  always @(a)
    begin
      b<=a+1;
      c<=b+1;
    end
   
endmodule

综合后电路图如下:
 

功能仿真波形如下:

 

上面两种代码综合出来的结果都一样,似乎在组合逻辑中使用非阻塞语句没有意义,因此一般的在组合逻辑中就直接使用阻塞语句

参考文献:
[1]  http://blog.chinaunix.net/uid-24203478-id-3031286.html

[2]  Verilog数字系统设计教程,第二版,夏宇闻。


 

 


 

 

 




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值