Blocking and Nonblocking assignment


Blocking and Nonblocking assignment

Blocking assignments are executed in the order they are coded, hence they are sequential. Since they block the execution of next statement, till the current statement is executed, they are called blocking assignments. Assignment are made with "=" symbol.

Example a = b;

Nonblocking assignments are executed in parallel. Since the execution of next statement is not blocked due to execution of current statement, they are called nonblocking statement. Assignments are made with "<=" symbol.


Example a <= b;

Note: Correct way to spell 'nonblocking' is 'nonblocking' and not 'non-blocking'.

Example - blocking and nonblocking

 
module blocking_nonblocking();
 
reg a,b,c,d;
// Blocking Assignment
initial begin
  #10 a = 0;
  #11 a = 1;
  #12 a = 0;
  #13 a = 1;
end
 
initial begin
  #10 b <= 0;
  #11 b <= 1;
  #12 b <= 0;
  #13 b <= 1;
end
 
initial begin
   c = #10 0;
   c = #11 1;
   c = #12 0;
   c = #13 1;
end
 
initial begin
   d <= #10 0;
   d <= #11 1;
   d <= #12 0;
   d <= #13 1;
end
 
initial begin
  $monitor("TIME = %g A = %b B = %b C = %b D = %b",$time, a, b, c, d);
  #50 $finish;
end
 
endmodule

assign and deassign

The assign and deassign procedural assignment statements allow continuous assignments to be placed onto registers for controlled periods of time. The assign procedural statement overrides procedural assignments to a register. The deassign procedural statement ends a continuous assignment to a register.

force and release

Another form of procedural continuous assignment is provided by the force and release procedural statements. These statements have a similar effect on the assign-deassign pair, but a force can be applied to nets as well as to registers.

One can use force and release while doing gate level simulation to work around reset connectivity problems. Also can be used insert single and double bit errors on data read from memory.

Conditional Statements

The Conditional Statement if-else

if - else statement controls the execution of other statements. In programming language like c, if - else controls the flow of program. When more than one statement needs to be executed for an if condition, then we need to use begin and end as seen in earlier examples.

Syntax : if

if (condition)

statements;

Syntax : if-else

if (condition)

statements;

else

statements;

Syntax : nested if-else-if

if (condition)

statements;

else if (condition)

statements;

................

................

else

statements;

Example- simple if

module simple_if();
 
reg latch;
wire enable,din;
always @ (enable or din)
if (enable) begin
  latch <= din;
end  
 
endmodule

Example- if-else

module if_else();
reg dff;
wire clk,din,reset;
 
always @ (posedge clk)
if (reset) begin
  dff <= 0;
end else  begin
  dff <= din;
end
 
endmodule


Example-nested-if-else-if
module nested_if();
 
reg [3:0] counter;
reg clk,reset,enable, up_en, down_en;
 
always @ (posedge clk)
// If reset is asserted
if (reset == 1'b0) begin
   counter <= 4'b0000; 
// If counter is enable and up count is asserted
end else if (enable == 1'b1 && up_en == 1'b1) begin
   counter <= counter + 1'b1;
// If counter is enable and down count is asserted
end else if (enable == 1'b1 && down_en == 1'b1) begin
   counter <= counter - 1'b1;
// If counting is disabled
end else begin
   counter <= counter; // Redundant code 
end
 

The Case Statement

The case statement compares an expression to a series of cases and executes the statement or statement group associated with the first matching case:

  • case statement supports single or multiple statements.
  • Group multiple statements using begin and end keywords.

Syntax of a case statement is given below,

case ()

<> : <>

<> : <>

.....

default : <>

endcase

Example- case

module mux (a,b,c,d,sel,y);

input a, b, c, d; 
input [1:0] sel; 
output y; 
reg y;
always @ (a or b or c or d or sel) 
case (sel) 
  0 : y = a; 
  1 : y = b; 
  2 : y = c; 
  3 : y = d; 
  default : $display("Error in SEL"); 
endcase 
    
endmodule


Example- case without default

module mux_without_default (a,b,c,d,sel,y);
input a, b, c, d; 
input [1:0] sel; 
output y; 
reg y;
 
always @ (a or b or c or d or sel) 
case (sel) 
  0 : y = a; 
  1 : y = b; 
  2 : y = c; 
  3 : y = d; 
  2'bxx,2'bx0,2'bx1,2'b0x,2'b1x,
  2'bzz,2'bz0,2'bz1,2'b0z,2'b1z : $display("Error in SEL");
endcase 
 
endmodule


Example- case with x and z

module case_xz(enable);
input enable;
 
always @ (enable)
case(enable)
  1'bz : $display ("enable is floating"); 
  1'bx : $display ("enable is unknown"); 
  default : $display ("enable is %b",enable); 
endcase 
 
endmodule

The casez and casex statement

Special versions of the case statement allow the x ad z logic values to be used as "don't care":

  • casez : Treats z as don't care.
  • casex : Treats x and z as don't care.

Example- casez

module casez_example();
reg [3:0] opcode;
reg [1:0] a,b,c;
reg [1:0] out;
 
always @ (opcode or a or b or c)
casez(opcode)
  4'b1zzx : begin // Don't care about lower 2:1 bit, bit 0 match with x
              out = a; 
              $display("@%0dns 4'b1zzx is selected, opcode %b",$time,opcode);
            end
  4'b01?? : begin
              out = b; // bit 1:0 is don't care
              $display("@%0dns 4'b01?? is selected, opcode %b",$time,opcode);
            end
  4'b001? : begin  // bit 0 is don't care
              out = c;
              $display("@%0dns 4'b001? is selected, opcode %b",$time,opcode);
            end
  default : begin
              $display("@%0dns default is selected, opcode %b",$time,opcode);
            end
endcase

Example- casex

module casex_example();

reg [3:0] opcode;
reg [1:0] a,b,c;
reg [1:0] out;
 
always @ (opcode or a or b or c)
casex(opcode)
  4'b1zzx : begin // Don't care  2:0 bits
              out = a; 
              $display("@%0dns 4'b1zzx is selected, opcode %b",$time,opcode);
            end
  4'b01?? : begin // bit 1:0 is don't care
              out = b; 
              $display("@%0dns 4'b01?? is selected, opcode %b",$time,opcode);
            end
  4'b001? : begin // bit 0 is don't care
              out = c;
              $display("@%0dns 4'b001? is selected, opcode %b",$time,opcode);
            end
  default : begin
              $display("@%0dns default is selected, opcode %b",$time,opcode);
            end
endcase 
 

Looping Statements

Looping statements appear inside procedural blocks only; Verilog has four looping statements like any other programming language.

  • forever
  • repeat
  • while
  • for

The forever statement

The keyword forever is used to express this loop. The loop does not contain any expression and executes continually, until the $finish task is encountered. Normally we use forever statements in initial blocks.

Syntax: forever <>

One should be very careful in using a forever statement: if no timing construct is present in the forever statement, simulation could hang. The code below is one such application, where a timing construct is included inside a forever statement.

Example

module forever_example ();

reg clk;
 
initial begin
  #1 clk = 0; 
  forever begin
    #5 clk = !clk; 
  end
end 
initial begin
  $monitor ("Time = %d  clk = %b",$time, clk);
  #100 $finish;
end
 
endmodule
 

The repeat statement

The keyword repeat is used for thi sloop. The repeat construct executes the loop a fixed number of times. A repeat construct cannot be used to loop on a general logical expression. The repeat loop executes <> a fixed <> of times.

Syntax: repeat (<>) <>

Example- repeat

module repeat_example();
reg  [3:0] opcode;
reg  [15:0] data;
reg        temp;
 
always @ (opcode or data)
begin
  if (opcode == 10) begin
    // Perform rotate
    repeat (8) begin 
      #1 temp = data[15];
      data = data <<>
      data[0] = temp;   
    end 
  end
end
// Simple test code
initial begin
   $display (" TEMP  DATA");
   $monitor (" %b     %b ",temp, data);
   #1 data = 18'hF0;
   #1 opcode = 10;
   #10 opcode = 0;
   #1 $finish;
end
 
endmodule
 

The while loop statement

The keyword while is used to specify this loop. The while loop executes as long as an <> evaluates as true. If the loop is entered when the while-expression is false, the loop is not executed at all. This is the same as in any other programming language.

Syntax: while (<>) <>

Example- while

module while_example();
reg [5:0] loc;
reg [7:0] data;
always @ (data or loc)
begin
  loc = 0;
  // If Data is 0, then loc is 32 (invalid value)
  if (data == 0) begin
    loc = 32;
  end else begin
    while (data[0] == 0) begin
      loc = loc + 1;
      data = data >> 1;
    end
  end 
  $display ("DATA = %b   LOCATION = %d",data,loc);
end
 
initial begin
  #1 data = 8'b11;
  #1 data = 8'b100;
  #1 data = 8'b1000;
  #1 data = 8'b1000_0000;
  #1 data = 8'b0;
  #1 $finish;
end
endmodule

The for loop statement

The for loop is the same as the for loop used in any other programming language.

  • Executes an <> once at the start of the loop.
  • Executes the loop as long as an <> evaluates as true.
  • Executes a <> at the end of each pass through the loop.

Syntax: for (<>; <>, <>) <>

Note: Verilog does not have ++ operator as in the case of C language.

Example – For

module for_example();
integer i;
reg [7:0] ram [0:255];
initial begin
  for (i = 0; i < i =" i">
    #1 $display(" Address = %g  Data = %h",i,ram[i]);
    ram[i] <= 0; // Initialize the RAM with 0
    #1 $display(" Address = %g  Data = %h",i,ram[i]);
  end
  #1 $finish;
end
 
endmodule