verilog 中非阻塞赋值,for循环

非阻塞赋值的例子:新赋值不会影响当前always中执行的语句,因为其综合成寄存器,有效输入是时钟上升沿到达前的数据。

reg c,b;

always@(posedge clk)

begin

b <= a;

c <= b;

end

aa


非阻塞赋值语句简述为:在一个always 块中,语句是并行执行的

module nonblockingassignment (clk ,q1,q2);
    input clk;
    output [2:0] q1,q2;
    reg[2:0] q1,q2;
    always @ (posedge clk)
    begin
    q1<=q1+3'b1;
    q2<=q1;
    end
    endmodule


寄存器是clk边沿触发,在clk边沿时更新寄存器输出,根据其时钟特性,在clk脉冲到来前,输入值就必须提前到达寄存器输入端。所以在新的clk时更新的输入值不可能影响到寄存器输出。这也就是always中的非阻塞赋值不会影响同一clk中其他的非阻塞赋值。

以下是使用阻塞和非阻塞赋值应遵循的一些基本原则,这些原则有利于防止竞态(race condition)的发生。

1)当用always块来描述组合逻辑(combinational logic)时,即不是由clk触发的应当使用阻塞赋值。

1 always@(sel or a or b) begin
2   case (sel)
3     2'b00 : c = a;
4     2'b01 : c = b;
5   endcase
6 end

(2)对于时序逻辑(sequential logic)的描述和建模,即由clk触发的应当使用非阻塞赋值。

reg c,b;
always@(posedge clk)
begin
b <= a;
c <= b;
end

(3)在同一个always模块中,不要混合使用阻塞赋值和非阻塞赋值,对同一变量既进行阻塞赋值,又进行非阻塞赋值,在综合时会出错。所以在由clk触发的always中全部使用非阻塞赋值,电平触发的always中使用阻塞赋值,把阻塞赋值和非阻塞赋值分在不同的always中书写。

(4)尽量不要再在多个不同的always块中对同一变量赋值。

(5)使用$strobe显示使用非阻塞赋值的变量。


verilog中的for循环和C语言中的for循环不一样,表示的是电路的硬件行为,循环几次,就是将相同的电路复制几次!

integer i; //be careful, i should be integer!

  for(i = 0;i <= 7 ;i = i+1)begin
   if(data_in[i])
    data_out[i] <= 1;
   else
    data_out[i] <= 1'bz; 
  end

上面的语句就是相当于8个选择器

assign data_out[0] =  data_in[0]?1:1'bz;

``````

assign data_out[7] = data_in[7]?1:1'bz;

因为for loop是复制电路行为,所以互相之间并行,可将其放在always中或者generate模块中。在两种模块中的i类型与赋值方式均不同,示例如下。

Example:

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 08/14/2014 11:10:33 AM
// Design Name: 
// Module Name: top
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////
module top(
  input clk,
  input[7:0] data,
  output reg[7:0] q //for always,reg q
  //output [7:0] q //for generate,net q

    );
    
    integer i;     //always format                                             
    always@(posedge clk)     begin       
        for(i=0;i<8;i=i+1)begin
            q[i]<=data[i];                              
        end    
     end         
    
  /*  genvar i; //generate format 
    generate
        for(i=0;i<8;i=i+1)begin
        assign    q[i]=data[i];                              
        end    
     endgenerate*/
    
endmodule                               


由RTL图可知,生成了八个register。

对于loop中的 integer i: integer类型一般只是用于loop,其他时候基本不用此类型,其默认是32bit。


阅读更多

没有更多推荐了,返回首页