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

来源:互联网 发布:php 通过身份证号码 编辑:程序博客网 时间:2024/05/18 09:01

关于阻塞和非阻塞语句的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数字系统设计教程,第二版,夏宇闻。


 

 


 

 

 




原创粉丝点击