Verilog HDL Behavioral Modeling Part-V

来源:互联网 发布:什么软件可以看港片 编辑:程序博客网 时间:2024/04/20 13:40

   ../images/main/bullet_green_ball.gifProcedural Block Control //过程块的控制  

Procedural blocks become active at simulation time zero. Use level sensitive event controls to control the execution of a procedure.

过程块在仿真时刻0开始执行。使用电平触发事件控制,控制一个过程的执行。

  

space.gif

  
  1 module dlatch_using_always();  2 reg q;  3   4 reg d, enable;  5   6 always @ (d or enable)  7 if (enable) begin  8   q = d;   9 end 10  11 initial begin 12   $monitor (" ENABLE = %b D = %b  Q = %b",enable,d,q); 13    #1  enable = 0; 14    #1  d = 1; 15    #1  enable = 1; 16    #1  d = 0; 17    #1  d = 1; 18    #1  d = 0; 19    #1  enable = 0; 20    #10  $finish; 21 end 22  23 endmodule
You could download file dlatch_using_always.v here  

space.gif

  

Any change in either d or enable satisfies the event control and allows the execution of the statements in the procedure. The procedure is sensitive to any change in d or enable.

d 或者enable的任何变化能够满足事件的控制并且过程中语句的执行。这个过程在d或者enable的任何变化时都能触发。

  

space.gif

 ../images/main/bulllet_4dots_orange.gifCombo Logic using Procedural Coding // 组合逻辑和过程控制  

To model combinational logic, a procedure block must be sensitive to any change on the input. There is one important rule that needs to be followed while modeling combinational logic. If you use conditional checking using "if", then you need to mention the "else" part. Missing the else part results in a latch. If you don't like typing the else part, then you must initialize all the variables of that combo block as soon as it enters.

为了建模组合逻辑,一个过程块必须能够感应到输入的任何变化。这是为组合逻辑建模的时,必须遵循的一条重要规则。如果你使用if条件测试,你也必须提到else部分。缺少else部分,将导致一个闭锁错误。如果你不喜欢输入else部分,那么一旦你进入一个组合逻辑块时,你必须初始化所有的变量。

  

space.gif

 ../images/main/bullet_star_pink.gifExample - One bit Adder //一位加法器举例  

space.gif

  
  1 module adder_using_always ();  2 reg a, b;  3 reg sum, carry;   4   5 always @ (a or b)   6 begin   7   {carry,sum} = a + b;   8 end  9  10 initial begin  11   $monitor (" A = %b B = %b CARRY = %b SUM = %b",a,b,carry,sum); 12    #10  a = 0;  13    b = 0;  14     #10  a = 1;  15     #10  b = 1;  16     #10  a = 0;  17     #10  b = 0;  18     #10  $finish;  19 end   20    21 endmodule
You could download file adder_using_always.v here  

space.gif

  

The statements within the procedural block work with entire vectors at a time.

过程块中语句每次都作用于整个向量。

  

space.gif

 ../images/main/bullet_star_pink.gifExample - 4-bit Adder //四位加法器  

space.gif

  
  1 module adder_4_bit_using_always ();  2 reg[3:0] a, b;  3 reg [3:0] sum;  4 reg carry;  5   6 always @ (a or b)   7 begin   8   {carry,sum} = a + b;   9 end  10  11 initial begin 12   $monitor (" A = %b B = %b CARRY = %b SUM = %b",a,b,carry,sum); 13    #10  a = 8; 14    b = 7; 15     #10  a = 10; 16     #10  b = 15; 17     #10  a = 0;  18     #10  b = 0;  19     #10  $finish;  20 end 21    22 endmodule  
You could download file adder_4_bit_using_always.v here  

space.gif

 ../images/main/bullet_star_pink.gifExample - Ways to avoid Latches - Cover all conditions //避免闭锁的方法:覆盖了所有的条件  

space.gif

  
  1 module avoid_latch_else ();  2   3 reg q;  4 reg enable, d;  5   6 always @ (enable or d)  7 if (enable) begin  8   q = d;  9 end else begin 10   q = 0; 11 end 12  13 initial begin 14   $monitor (" ENABLE = %b  D = %b Q = %b",enable,d,q); 15    #1  enable = 0; 16    #1  d = 0; 17    #1  enable = 1; 18    #1  d = 1; 19    #1  d = 0; 20    #1  d = 1; 21    #1  d = 0; 22    #1  d = 1; 23    #1  enable = 0; 24    #1  $finish; 25 end 26  27 endmodule
You could download file avoid_latch_else.v here  

space.gif

 ../images/main/bullet_star_pink.gifExample - Ways to avoid Latches - Snit the variables to zero //避免闭锁的方法: 将变量归0  

space.gif

  
  1 module avoid_latch_init ();  2   3 reg q;  4 reg enable, d;  5   6 always @ (enable or d)  7 begin  8   q = 0;  9   if (enable) begin 10     q = d; 11   end 12 end 13  14 initial begin 15   $monitor (" ENABLE = %b  D = %b Q = %b",enable,d,q); 16    #1  enable = 0; 17    #1  d = 0; 18    #1  enable = 1; 19    #1  d = 1; 20    #1  d = 0; 21    #1  d = 1; 22    #1  d = 0; 23    #1  d = 1; 24    #1  enable = 0; 25    #1  $finish; 26 end 27  28 endmodule
You could download file avoid_latch_init.v here  

space.gif

 ../images/main/bulllet_4dots_orange.gif

Sequential Logic using Procedural Coding //时序逻辑使用过程编码 

  

To model sequential logic, a procedure block must be sensitive to positive edge or negative edge of clock. To model asynchronous reset, procedure block must be sensitive to both clock and reset. All the assignments to sequential logic should be made through nonblocking assignments.

为了为时序逻辑建模,一个过程块必须能够感应到时钟的正沿和负沿。为了构建异步复位,过程块必须能够感知到clock和reset。

时序逻辑中任何赋值语句必须是非阻塞的赋值语句。

  

space.gif

  

Sometimes it's tempting to have multiple edge triggering variables in the sensitive list: this is fine for simulation. But for synthesis this does not make sense, as in real life, flip-flop can have only one clock, one reset and one preset (i.e. posedge clk or posedge reset or posedge preset).

有时,在触发表中的多边沿值触发的变量是迷惑的:这是对simulation非常好。但对于综合确实讲不通的。在真实的环境中,触发器只有一个时钟,一个复位和一个预置位。(如clk的上升沿or reset上升沿或者preset上升沿)

  

space.gif

  

One common mistake the new beginner makes is using clock as the enable input to flip-flop. This is fine for simulation, but for synthesis, this is not right.

一个新手常犯的普遍错是使用clock时钟信号使能触发器的输入。对于simulation是成功的,但是对于综合却是不正确的。

  

space.gif

    

space.gif

 ../images/main/bullet_star_pink.gifExample - Bad coding - Using two clocks //错误的编码使用两个时钟  

space.gif

  
  1 module wrong_seq();  2   3 reg q;  4 reg clk1, clk2, d1, d2;  5   6 always @ (posedge clk1 or posedge clk2)  7 if (clk1) begin  8   q <= d1;  9 end else if (clk2) begin 10   q <= d2; 11 end 12  13 initial begin 14   $monitor ("CLK1 = %b CLK2 = %b D1 = %b D2 %b Q = %b",  15     clk1, clk2, d1, d2, q); 16   clk1 = 0; 17   clk2 = 0; 18   d1 = 0; 19   d2 = 1; 20    #10  $finish; 21 end 22  23 always 24   #1  clk1 = ~clk1; 25   26 always 27  #1.9 clk2 = ~clk2; 28  29 endmodule
You could download file wrong_seq.v here  

space.gif

 ../images/main/bullet_star_pink.gifExample - D Flip-flop with async reset and async preset //d触发器的异步reset和异步preset  

space.gif

  
  1 module dff_async_reset_async_preset();  2   3 reg clk,reset,preset,d;  4 reg  q;  5   6 always @ (posedge clk or posedge reset or posedge preset)  7 if (reset) begin  8   q <= 0;  9 end else if (preset) begin 10   q <= 1; 11 end else begin 12   q <= d; 13 end 14  15 // Testbench code here 16 initial begin 17   $monitor("CLK = %b RESET = %b PRESET = %b D = %b Q = %b", 18     clk,reset,preset,d,q); 19   clk    = 0; 20    #1  reset  = 0; 21   preset = 0; 22   d      = 0; 23    #1  reset = 1; 24    #2  reset = 0; 25    #2  preset = 1; 26    #2  preset = 0; 27   repeat (4) begin 28      #2  d      = ~d; 29   end 30    #2  $finish; 31 end 32  33 always 34   #1  clk = ~clk; 35  36 endmodule
You could download file dff_async_reset_async_preset.v here  

space.gif

 ../images/main/bullet_star_pink.gifExample - D Flip-flop with sync reset and sync preset // d触发器使用同步reset和同步的preset  

space.gif

  
  1 module dff_sync_reset_sync_preset();  2   3 reg clk,reset,preset,d;  4 reg  q;  5   6 always @ (posedge clk)  7 if (reset) begin  8   q <= 0;  9 end else if (preset) begin 10   q <= 1; 11 end else begin 12   q <= d; 13 end 14  15 // Testbench code here 16 initial begin 17   $monitor("CLK = %b RESET = %b PRESET = %b D = %b Q = %b", 18     clk,reset,preset,d,q); 19   clk    = 0; 20    #1  reset  = 0; 21   preset = 0; 22   d      = 0; 23    #1  reset = 1; 24    #2  reset = 0; 25    #2  preset = 1; 26    #2  preset = 0; 27   repeat (4) begin 28      #2  d      = ~d; 29   end 30    #2  $finish; 31 end 32  33 always 34   #1  clk = ~clk; 35  36 endmodule
You could download file dff_sync_reset_sync_preset.v here  

space.gif

 ../images/main/bulllet_4dots_orange.gifA procedure can't trigger itself //过程块不能触发自己  

One cannot trigger the block with a variable that block assigns value or drives. 

block不能通过复制或者驱动一个变量来触发自己。

  

space.gif

  
  1 module trigger_itself();  2   3 reg clk;  4   5 always @ (clk)  6    #5  clk =  ! clk;   7     8 // Testbench code here  9 initial begin 10   $monitor("TIME = %d  CLK = %b",$time,clk); 11   clk = 0; 12    #500  $display("TIME = %d  CLK = %b",$time,clk); 13   $finish; 14 end 15  16 endmodule
You could download file trigger_itself.v here  

space.gif

 ../images/main/bulllet_4dots_orange.gifProcedural Block Concurrency //过程块的并发性  

If we have multiple always blocks inside one module, then all the blocks (i.e. all the always blocks and initial blocks) will start executing at time 0 and will continue to execute concurrently. Sometimes this leads to race conditions, if coding is not done properly.

如果你有多个always块在一个module中,那么所有的块都在时间0时刻开始执行(如所有的always block 和initial 块)并且将继续并发执行。有时,如果编码不合理的话,将会导致竞争条件。

  

space.gif

  
  1 module multiple_blocks ();  2 reg a,b;  3 reg c,d;   4 reg clk,reset;  5 // Combo Logic  6 always @ ( c)  7 begin  8   a = c;  9 end 10 // Seq Logic 11 always @ (posedge clk) 12 if (reset) begin 13   b <= 0; 14 end else begin 15   b <= a & d; 16 end 17  18 // Testbench code here 19 initial begin 20   $monitor("TIME = %d CLK = %b C = %b D = %b A = %b B = %b", 21     $time, clk,c,d,a,b); 22   clk = 0; 23   reset = 0; 24   c = 0; 25   d = 0; 26    #2  reset = 1; 27    #2  reset = 0; 28    #2  c = 1; 29    #2  d = 1; 30    #2  c = 0; 31    #5  $finish; 32 end 33 // Clock generator 34 always  35   #1  clk = ~clk; 36      37 endmodule
You could download file multiple_blocks.v here  

space.gif

 ../images/main/bulllet_4dots_orange.gif

Race condition // 竞争条件 

  

space.gif

  
  1 module race_condition();  2 reg b;  3   4 initial begin  5   b = 0;  6 end    7      8 initial begin  9   b = 1; 10 end 11  12 endmodule
You could download file race_condition.v here  

space.gif

  

In the code above it is difficult to say the value of b, as both blocks are supposed to execute at same time. In Verilog, if care is not taken, a race condition is something that occurs very often.

在上面的这个代码中,很难确定d的值,因为上述代码本来应该同时执行的。

在Verilog HDL编码中,如果不小心的话,很容易导致竞争条件的发生。

  

space.gif

 ../images/main/bullet_green_ball.gifNamed Blocks //命名块  

space.gif

  

Blocks can be named by adding : block_name after the keyword begin. Named blocks can be disabled using the 'disable' statement.

block可以被命名通过在begin关键字后添加block_name。 命名块可以被取消使能通过disable语句。

  

space.gif

 ../images/main/bulllet_4dots_orange.gif

Example - Named Blocks //命名语句块 

  

space.gif

  
  1 // This code find the lowest bit set  2 module named_block_disable();  3   4 reg [31:0] bit_detect;  5 reg [5:0]  bit_position;  6 integer i;  7   8 always @ (bit_detect)  9 begin : BIT_DETECT 10   for (i = 0; i < 32 ; i = i + 1) begin 11      // If bit is set, latch the bit position 12      // Disable the execution of the block 13      if (bit_detect[i] == 1) begin 14         bit_position = i; 15         disable BIT_DETECT; 16      end  else begin 17         bit_position = 32; 18      end 19   end 20 end 21  22 // Testbench code here 23 initial begin 24   $monitor(" INPUT = %b  MIN_POSITION = %d", bit_detect, bit_position); 25    #1  bit_detect = 32'h1000_1000; 26    #1  bit_detect = 32'h1100_0000; 27    #1  bit_detect = 32'h1000_1010; 28    #10  $finish; 29 end 30  31 endmodule
You could download file named_block_disable.v here  

space.gif

  

In the example above, BIT_DETECT is the named block and it is disabled whenever the bit position is detected.

the above original link:http://www.asic-world.com/verilog/vbehave5.html