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. ```
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. ```
reg [7:0]      addr;         // 8-bit reg variable [7, 6, 5, 4, 3, 2, 1, 0]

addr  = 1;                // assign 1 to bit 0 of addr
addr  = 0;                // assign 0 to bit 3 of addr
addr  = 1;                // illegal : bit8  does not exist in addr
```

## Part-selects 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.

```

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
```

## You may also like:

 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.