2.3 Verilog Data Types
Classification Verilog Tutorial
The two most commonly used data types in Verilog are wires and registers, with other types being understood as extensions or auxiliary to these two.
Wires
The wire type represents the physical connections between hardware elements, continuously driven by the output ends of the devices it is connected to. If there is no driving element connected to a wire type variable, the default value is generally "Z". Example is as follows:
Example
wire interrupt;
wire flag1, flag2;
wire gnd = 1'b0;
There are other wire types, including wand, wor, wri, triand, trior, trireg, etc. These data types are not used very frequently, and are not introduced here.
Registers (reg)
The register (reg) is used to represent storage elements, which will maintain the original value of the data until it is overwritten. Declaration example is as follows:
Example
reg clk_temp;
reg flag1, flag2;
For example, in an always block, a register may be synthesized into an edge-triggered flip-flop, and in combinational logic, it may be synthesized into a wire type variable. Registers do not require a driving source and do not necessarily require a clock signal. During simulation, the value of a register can be rewritten at any time through assignment operations. Example is as follows:
Example
reg rstn;
initial begin
rstn = 1'b0;
#100;
rstn = 1'b1;
end
Vectors
When the bit width is greater than 1, wire or reg can be declared in the form of a vector. Example is as follows:
Example
reg [3:0] counter; //Declare a 4-bit wide register counter
wire [32-1:0] gpio_data; //Declare a 32-bit wide wire variable gpio_data
wire [8:2] addr; //Declare a 7-bit wide wire variable addr, with a bit width range of 8:2
reg [0:31] data; //Declare a 32-bit wide register variable data, with the most significant bit being 0
For the above vectors, we can specify a certain bit or several adjacent bits for use in other logic. Example is as follows:
Example
wire [9:0] data_low = data[0:9];
addr_temp[3:2] = addr[8:7] + 1'b1;
Verilog supports variable vector domain selection, for example:
Example
reg [31:0] data1;
reg [7:0] byte1 [3:0];
integer j;
always@* begin
for (j=0; j<=3;j=j+1) begin
byte1[j] = data1[(j+1)*8-1 : j*8];
//Assign data1[7:0]...data1[31:24] to byte1[0][7:0]...byte[3][7:0] in sequence
end
end
Verilog also supports fixed bit width vector domain selection access after specifying the bit position.
-[bit+: width] : Increment from the starting bit position, with a width of width.
-[bit-: width] : Decrement from the starting bit position, with a width of width.
Example
//The following two assignments are equivalent
A = data1[31-: 8];
A = data1[31:24];
//The following two assignments are equivalent
B = data1[0+ : 8];
B = data1[0:7];
When recombining signals into a new vector, you need to use curly braces. For example:
Example
wire [31:0] temp1, temp2;
assign temp1 = {byte1[0][7:0], data1[31:8]}; //Data concatenation
assign temp2 = {32{1'b0}}; //Assign a 32-bit value of 0
Integer, Real, and Time Register Variables
Integer, real, and time data types are also considered register types.
Integer (integer)
The integer type is declared with the