Lesson 04: Verilog Scalar, Vector, and Array
A net or reg declaration without a range specification is considered 1-bit wide and is a scalar.
wire nor_o; // Single bit scalar net reg parity; // Single bot scalar variable
Vector (Packed Array)
If a range is specified, then the net or reg becomes a multibit entity known as a vector. A vector is also called a packed array.
The syntax of vector:
- BIT_INDEXLEFT < BIT_INDEXRIGHT: Big-endian bit order.
- BIT_INDEXLEFT > BIT_INDEXRIGHT: Little-endian bit order.
The sequence of a multiple-bits binary stored in memory is called bit-order. There are two types of bit-orders:
- Big-Endian Bit Order: The most significant bit is stored at the lowest bit address.
- Little-Endian Bit Order: The least significant bit is stored at the lowest bit address.
Most digital systems use the little-endian bit-order to store binary numbers, which means the bit 0 value is stored in index=0 location.
Vectors are indexed from BIT_INDEXLEFT to BIT_INDEXRIGTH, that range gives the ability to address individual bits in a vector. Vectors can be declared for all types of net data types and reg data types. Specifying vectors for , , , and data types is illegal. Vector nets and registers are treated as unsigned values.
reg [3:0] a; // Little-Endina Bit-Order reg [0:3] b; // Big-Endian Bit-Order wire c; a = 4'b1100; // a = 0, a = 0, a = 1, a = 1 b = 4'b1100; // b = 1, b = 1, b = 0, a = 0 c = (a == b); // c = 1
Single Unit Select
The vector can be assigned as single units.
reg [7:0] address; // 8-bit vector reg variable [7, 6, 5, 4, 3, 2, 1, 0] address = 8'b1010_1111; // Assign 10101111 to address variable
Any bit in a vectored variable can be individually selected and assigned a new value, as known in the below example. This is called a bit select.
reg [7:0] address; // 8-bit vector reg variable [7, 6, 5, 4, 3, 2, 1, 0] address = 1; // Assign 1 to bit 0 of address address = 1; // Assign 1 to bit 4 of address address = 1; // illegal: index 8 does not exist in address variable
If the bit-select is out of the address bounds or the bit-select is x or z, then the value returned by reference shall be x.
The selection of the range of contiguous bits is called the part selected. There are two types of part-selects.
- Fixed Part-Select
- Indexed Part-Select
A fixed part-select of a vector reg or net is given with the following syntax:
reg [7:0] address; address[7:5] = 3'b101; // bits 7 to 5 will be replaced by the new value 'b101 --> fixed-select
An indexed part-select of a vector net, vector variable is given with the following syntax:
reg [7:0] data; data[5+:3] = 3'b010; // starting bit = 5, width = 3 ==> data[7:5]
reg [255:0] data1; // Little-endian bit order notation reg [0:255] data2; // Big-endian bit order notation reg [7:0] byte; // Using a variable part-select, one can choose parts byte = data1[31-:8]; // starting bit = 31, width =8 => data1[31:24] byte = data1[24+:8]; // starting bit = 24, width =8 => data1[31:24] byte = data2[31-:8]; // starting bit = 31, width =8 => data1[24:31] byte = data2[24+:8]; // starting bit = 24, width =8 => data1[24:31] // The starting bit can also be a variable. The width has to be constant. // Therefore, one can use the variable part-select in a loop to select all bytes of the vector for (i = 0; i <= 31; i = i + 1) byte = data1[(i*8)+:8]; // Sequence is [7:0], [15:8], ..., [255:248] // Can initialize a part of the vector data1[(byteNum*8)+:8] = 8'b0; // If byteNum = 1, clear 8 bits [15:8]
Multi-Dimension Vector (Multiple Packed Array Dimensions) is a SystemVerilog feature,
// Multiple Packed Array on support by SystemVerilog reg [0:2][0:2][0:2] rgb; rgb = 1'b0; // Assign one bit rgb = 3'h0A; // Assign one element reg = 9'hbcd; // Assign slice reg = 27'h01234; // Assign entire array as vector
An array declaration of a net or variable can be either scalar or vector. It is also called an unpacked array.
A multi-dimensional array can be declared by having multiple dimensions after the array declaration. Each fixed-size dimension is represented by an address range, such as [0:1023].
SystemVerilog also supports a single value range, which is a single positive number to specify the size of a fixed-size array, such as . The notation size is equivalent to [0:size-1].
reg m1 [0:11]; // m1 is an scalar reg array of depth=12, each 1-bit wide reg [7:0] m2 [0:3]; // m2 is an 8-bit vector array reg with a depth=4 reg [7:0] m3 [0:1][0:3]; // m3 is an 8-bit vector 2D array rows=2, cols=4 each 8-bit wide // Single value range allowed only in SystemVerilog. reg [7:0] m4  // m4 is an 8-bit vectore array with 128 rows ==> same as reg [7:0] m4 [0:127];
In C language, arrays are indexed from 0 by integers or converted to pointers. The whole array can be initialized, and each element must be read or separately written in procedural statements.
In Verilog, arrays are indexed from INDEXFIRST to INDEXLAST. To access the array, the index number for every dimension has to be specified to access a particular element of an array. It can be an expression of other variables. The following statements are shown examples of accessing the array.
m1 = 1; // Illegal - m1 is an array. All elements in m1 can not be assigned in a single assignment m1 = 1'b0; // Assign 0 to m1 first element m2 = 8'hE2; // Assign 0xE2 to index=0 m2 = 8'h1A; // Assign 0x1A to index=2 m3 = 8'hBB; // Assign 0xBB to rows=1 cols=2 m3 = 8'hCC; // assign 0xCC to rows=0 cols=0