Welcome ! This website will help YOU (recent graduates/professionals) learn verification languages like SystemVerilog and UVM. Register for free and access more content !

Verilog needs to represent individual bits as well as groups of bits. For example, a single bit sequential element is a flip-flop. However a 16-bit sequential element is a register that can hold 16 bits. For this purpose, Verilog has scalar and vector nets and variables.

Scalar and Vector

A net or reg declaration without a range specification is considered 1-bit wide and is a scalar. If a range is specified, then the net or reg becomes a multibit entity known as a vector.

scalar and vector in verilog
 
  wire       o_nor;           // single bit scalar net
  wire [7:0]  o_flop;          // 8-bit vector net
  reg         parity;          // single bit scalar variable
  reg  [31:0] addr;            // 32 bit vector variable to store address
 

The range gives the ability to address individual bits in a vector. The most significant bit of the vector should be specified as the left hand value in the range while the least significant bit of the vector should be specified on the right.

 
  wire  [msb:lsb]   name;
  integer           my_msb;
 
  wire [15:0]        priority;      // msb = 15, lsb = 0
  wire [my_msb: 2]   prior;         // illegal
 

A 16 bit wide net called priority will be created in the example above. Note that the msb and lsb should be a constant expression and cannot be substituted by a variable. But they can be any integer value - positive, negative or zero; and the lsb value can be greater than, equal to or less than msb value.

Bit-selects

Any bit in a vectored variable can be individually selected and assigned a new value as shown below. This is called as a bit-select. If the bit-select is out of bounds or the bit-select is x or z, then the value returned will be x.

bit-select in verilog
 
  reg [7:0]      addr;         // 8-bit reg variable [7, 6, 5, 4, 3, 2, 1, 0]
 
  addr [0] = 1;                // assign 1 to bit 0 of addr
  addr [3] = 0;                // assign 0 to bit 3 of addr
  addr [8] = 1;                // illegal : bit8  does not exist in addr
 

Part-selects

part-select in verilog

A range of contiguous bits can be selected and is known as a part-select. There are two types of part-selects, one with a constant part-select and another with an indexed part-select.

 
  reg [31:0]    addr;
 
  addr [23:16] = 8'h23;         // bits 23 to 16 will be replaced by the new value 'h23 -> constant part-select
 

Having a variable part-select allows it to be used effectively in loops to select parts of the vector. Although the starting bit can be varied, the width has to be constant.

[<start_bit> +: <width>]     // part-select increments from start-bit
[<start_bit> -: <width>]     // part-select decrements from start-bit
 
module des;
  reg [31:0]  data;
  int         i;
 
  initial begin
    data = 32'hFACE_CAFE;
    for (i = 0; i < 4; i++) begin
      $display ("data[8*%0d +: 8] = 0x%0h", i, data[8*i +: 8]);
    end
 
    $display ("data[7:0]   = 0x%0h", data[7:0]);
    $display ("data[15:8]  = 0x%0h", data[15:8]);
    $display ("data[23:16] = 0x%0h", data[23:16]);
    $display ("data[31:24] = 0x%0h", data[31:24]);
  end
 
endmodule
 
Simulation Log
ncsim> run
data[8*0 +: 8] = 0xfe              // ~ data [8*0+8 : 8*0]
data[8*1 +: 8] = 0xca              // ~ data [8*1+8 : 8*1]
data[8*2 +: 8] = 0xce              // ~ data [8*2+8 : 8*2]
data[8*3 +: 8] = 0xfa              // ~ data [8*3+8 : 8*3]

data[7:0]   = 0xfe
data[15:8]  = 0xca
data[23:16] = 0xce
data[31:24] = 0xfa
ncsim: *W,RNQUIE: Simulation is complete.

Common Errors

 
module tb;
   reg [15:0]    data;
 
   initial begin
      $display ("data[0:9] = 0x%0h", data[0:9]);   // Error : Reversed part-select index expression ordering
   end
endmodule
 

Was this article helpful ?



You consent to our cookies if you continue to use our website. To know more about cookies, see our privacy policy. I accept cookies from this site.

Agree