Verilog: Continuous & Procedural Assignments

Continuous Assignment

Continuous assignment is used to drive a value on to a net in dataflow modeling. The net can be a vector or scalar, indexed part select, constant bit or part select of a vector. Concatenation is also supported with scalar vector types.

module Conti_Assignment (addr1,addr2,wr,din,valid1,valid2,dout);
  input [31:0] addr1,addr2;
  input [31:0] din;
  output [31:0] dout;
  input valid1,valid2,wr;
  
  wire valid;
  wire [31:0] addr;
  
  //Net (scalar) continuous assignment
  assign valid = valid1 | valid2;
  
  //Vector continuous assignment
  assign addr[31:0] = addr1[31:0] ^ addr2[31:0];
  
  //Part select & Concatenation in Continuous assignment
  assign dout[31:0] = (valid & wr) ? {din[31:2],2'b11} : 32'd0;
  
endmodule

Regular & Implicit Assignment

Regular continuous assignment means, the declaration of a net and its continuous assignments are done in two different statements. But in implicit assignment, continuous assignment can be done on a net when it is declared itself. In the below example, `valid` is declared as wire during the assignment. If signal name is used to the left of the continuous assignment, an implicit net declaration will be inferred. In the below code `dout` is not declared as net, but it is inferred during assignment.

module Implicit_Conti_Assignment (addr1,addr2,wr,din,valid1,valid2,dout);
  input [31:0] addr1,addr2;
  input [31:0] din;
  output [31:0] dout;
  input valid1,valid2,wr;
  
  
  //Net (scalar) Implict continuous assignment
  wire valid = (valid1 | valid2);
  
  //Implicit net declaration -dout 
  assign dout[31:0] = (valid & wr) ? {din[31:2],2'b11} : 32'd0;
  
endmodule

Procedural Assignment

We have already seen that continuous assignment updates net, but procedural assignment update values of reg, real, integer or time variable. The constant part select, indexed part select and bit select are possible for vector reg.

There are two types of procedural assignments called blocking and non-blocking. Blocking assignment, as the name says, gets executed in the order statements are specified. The “=” is the symbol used for blocking assignment representation. Non-blocking assignment allows scheduling of assignments. It will not block the execution. The symbol “<=" is used for non-blocking assignment representation and mainly used for concurrent data transfers. Following example shows the differences in the simulation result by using blocking and non-blocking assignments.

/*
module Nonblocking_Assignment (addr1,addr2,wr,din,valid1,valid2,data,aout);
  input [31:0] addr1,addr2;
  input [31:0] din;
  output [31:0] data,aout;
  input valid1,valid2,wr;
  
  reg [31:0] data,aout, addr;
  reg valid;
  
  always @(addr1,addr2,wr,din,valid1,valid2) begin
     valid <= (valid1 | valid2);
     addr <= (addr1[31:0] | addr2[31:0]);
     data <= (valid & wr) ? {din[31:2],2'b11} : 32'd0;
     aout <= wr ? addr: {addr1[15:0],addr2[31:16]};
  end
  initial
     $monitor($time,"NON-BLOCKING: Values valid1=%b, valid2=%b, wr=%b, addr1=%d, addr2=%d, data=%d, aout=%d", valid1,valid2,wr,addr1,addr2,data,aout);
endmodule
*/
module Blocking_Assignment (addr1,addr2,wr,din,valid1,valid2,data,aout);
  input [31:0] addr1,addr2;
  input [31:0] din;
  output [31:0] data,aout;
  input valid1,valid2,wr;
  
  reg [31:0] data,aout, addr;
  reg valid;
  
  always @(addr1,addr2,wr,din,valid1,valid2) begin
     valid = (valid1 | valid2);
     addr = (addr1[31:0] | addr2[31:0]);
     data = (valid & wr) ? {din[31:2],2'b11} : 32'd0;
     aout = wr ? addr : {addr1[15:0],addr2[31:16]};
     $monitor($time,"BLOCKING: Values valid1=%b, valid2=%b, wr=%b, addr1=%d, addr2=%d, data=%d, aout=%d", valid1,valid2,wr,addr1,addr2,data,aout);
  end
endmodule

module test;
 reg valid1,valid2,wr;
 reg [31:0] addr1,addr2,din;
 wire [31:0] data,aout;
 
 Blocking_Assignment Block_Assign(addr1,addr2,wr,din,valid1,valid2,data,aout);
 
 //Nonblocking_Assignment Nonblock_Assign(addr1,addr2,wr,din,valid1,valid2,data,aout);
 
 initial begin
  valid1 = 0;
  valid2 = 0;
  addr1 = 32'd12;
  addr2 = 32'd36;
  din = 32'd198;
  wr = 1;
  
  #5 valid1 = 1;
  #10 valid1 = 0; valid2 = 1;
  #10 addr1 = 32'd0; addr2 = 32'd0;
  #5 wr = 0;
  #12 wr = 1;
 
 end
 
endmodule

/*
ncsim> run
                   0NON-BLOCKING: Values valid1=0, valid2=0, wr=1, addr1=        12, addr2=        36, data=         X, aout=         x
                   5NON-BLOCKING: Values valid1=1, valid2=0, wr=1, addr1=        12, addr2=        36, data=         0, aout=        44
                  15NON-BLOCKING: Values valid1=0, valid2=1, wr=1, addr1=        12, addr2=        36, data=       199, aout=        44
                  25NON-BLOCKING: Values valid1=0, valid2=1, wr=1, addr1=         0, addr2=         0, data=       199, aout=        44
                  30NON-BLOCKING: Values valid1=0, valid2=1, wr=0, addr1=         0, addr2=         0, data=         0, aout=         0
                  42NON-BLOCKING: Values valid1=0, valid2=1, wr=1, addr1=         0, addr2=         0, data=       199, aout=         0
ncsim: *W,RNQUIE: Simulation is complete.
*/

/*
ncsim> run
                   0BLOCKING: Values valid1=0, valid2=0, wr=1, addr1=        12, addr2=        36, data=         0, aout=        44
                   5BLOCKING: Values valid1=1, valid2=0, wr=1, addr1=        12, addr2=        36, data=       199, aout=        44
                  15BLOCKING: Values valid1=0, valid2=1, wr=1, addr1=        12, addr2=        36, data=       199, aout=        44
                  25BLOCKING: Values valid1=0, valid2=1, wr=1, addr1=         0, addr2=         0, data=       199, aout=         0
                  30BLOCKING: Values valid1=0, valid2=1, wr=0, addr1=         0, addr2=         0, data=         0, aout=         0
                  42BLOCKING: Values valid1=0, valid2=1, wr=1, addr1=         0, addr2=         0, data=       199, aout=         0
ncsim: *W,RNQUIE: Simulation is complete.
ncsim> exit
*/

3 comments on “Verilog: Continuous & Procedural Assignments

Leave a Reply to Badrinaryanan Cancel reply

Your email address will not be published. Required fields are marked *