Verilog Data Types
Data Types
Values and Strength
-
Values
- 0 : represents a logic zero, or a false condition
- 1 : represents a logic one, or a true condition
- x : represents an unknown logic value
- z : represents a high-impedance state
-
Strength
- Strongest signal prevails
- Useful for switch level modelling and not for RTL
- When two signals with opposite value and same strength combine, the resulting value is x
By default every variable will have 'x' value. In case of tristate buffer it will have high impedance 'z'.
Strength levels are used in switch level modeling using cmos for building the circuit and not used for rtl.
Numbers
<size>'<base><number>
-
size = number of bits
-
base = binary(b), octal(o), decimal(d), hexadecimal(h)
-
number = 0-9, a-f, x, z
-
For example:
4'b0010
-
12'o43xz
will be expanded like:
4 3 x z
100 011 xxx zzz
-
Underscores improve readability eg.
32’h a_bc_2
is the same as32’b 1010_1011_1100_0010
-
Zero, X and Z extension
4'b1
is the same as4'b 0001
4'bx1
is the sameas4'b xxx1
4'bz1
s the same as4'b zzzl
-
Unsized numbers will have by default 32 bit
'h4a
is the same as32'b 0000_0000_0100_1010
NET and REG
Data types in Verilog are divided into NETS and Registers.
Nets - (net Data Type)
The nets variables represent the physical connection between structural entities. These variables do not store values (except trireg); have the value of their drivers which changes continuously by the driving circuit. Some net data types are wire, tri, wor, trior, wand, triand, tri0, tri1, supply0, supply1 and trireg. wire is the most frequently used type. A net data type must be used when a signal is:
- driven by the output of some device
- declared as an input or in-out port
- on the left-hand side of a continuous assignment
Declaration and Assignment:
wire A, B, C
assign C = A & B
By default all the ports are wire datatype
- Nets are continuously driven by combinational logic
Regs - (reg Data Type)
The register variables are used in procedural blocks which store values from one assignment to the next. An assignment statement in a procedure acts as a trigger that changes the value of the data storage element. Some register data types are: reg, integer, time and real.
Reg is used for describing logic, integer for loop variables and calculations, real in system modules, and time and realtime for storing simulation times in test benches.
- Using reg does not means we will get physical hardware Registers. It depends on coding style not on the datatype.
- Assignments — Registers and nets can be mixed
Port Assignments
- Input, Output and Inout - by default are wire datatype
Integers Data Type
- Integers store values as signed quantities
- Mostly synthesizable
- Arithmetic operations performed on integer variables produces 2's compliment result
- Procedural assignments shall be used to trigger value changes in integers
Real Data Type
-
Allows decimal and scientific notation
-
Example:
0.210, 3.1415, 4.6e-2, -2.5
-
Not synthesizable
-
Declaration and Assignment:
real real_num; integer int_num; real_num = 67.9 int_num = real_num; <-- will roundoff to 68
Time Data Type
-
For storing and manipulating simulation time quantities
-
Not synthesizable, useful for testbench implementation
-
Declaration and Assignment:
time sim_time; sim_time = $time; <-- current simulation time will be assigned to variable sim_time
-
The time variables behave same as a reg of at least 64 bits, with the least significant bit being bit 0
-
The time variables are unsigned quantities, and unsigned arithmetic is performed on them
Vectors
- Represent Buses
- Slices - range direction must be same as vector
For example:
reg [3:0] z_bus;
wherez_bus[3]
=MSB andz_bus[0]
=LSB
Scalar Array is an array of one 1-bit data type. Ex – reg a[3:0] - This is an array of size 4 and where each element can hold 1-bit data. Vector Array is an array of vectors. As we have seen earlier vectors are nothing but a group of 1-bit data types combined to increase the size of data type. Ex – reg [3:0] a [7:0] - This is an array of size 8, where each element can hold 4-bit reg data.
Arrays
-
Arrays for variables types (reg, integer, time,real,realtime) are possible.
-
Net Arrays:
reg my_reg [0:5]; // Declares an array of 6, 1 bit registers
my_reg[2] = 1'b1; //Assigns value 1 to the 3rd element of array
reg arrayb [7:0] [0:255]; // Declares a two dimensional array of
// one bit registers
arrayb[1][0] = 0; // Assigns 0 to the bit referenced by indices [1] [0]
wire w_array [7:0] [5:0]; // Declares a two dimensional array of wires
integer inta[1:64]; // Declares an array of 64 integer values
reg [1:n] rega; //n bit register (vector)
reg rega [1:n]; //array of n, 1 bit registers
- Horizontal = vector, Vertical = array
Memory
- A one dimensional array with elements of type reg
- Used to model ROMs, RAM, and reg files
reg [7:0] mema [0:255]; // declares a memory mema of 256 8-bit
// registers. The indices are 0 to 255
mema[1] = 0
- An n-bit reg can be assigned a value in a single assignment, but a complete memory cannot.
- Use for loop to initialize the whole memory
Parameters
- Parameters are not variables, they are constants
module ram (clk,rst,din,radd,wadd,dout);
parameter dt_width = 8; // Defines dt width as a constant value 8
parameter ad_depth = 256; // Defines ad depth as a constant value 256
...
reg [(dt_width - 1) : 0] mem [(ad_depth - 1) : 0];
// Declaring a 256X8 memory using parameters
...
endmodule
- The parameter override values have to be contiguous, that is any parameter cannot be skipped during override
- Overriding a module's parameter values during initialization
module ram (clk,rst,din, radd wadd,dout) ;
parameter dt_width = 8;
parameter ad_depth = 256;
...
reg [(dt_width - 1):0] mem [(ad_depth-1):0];
...
endmodule
//Assignment by ordered list
module system(...);
input rst,clk;
output dout, done;
//Overriding dt_width only
ram #( 16 ) MEM1 (.clk(clk),.rst(rst),...);
//Overriding both dt_width and ad_depth
ram #( 16, 512) MEM2 (.clk(clk),.rst(rst),...):
endmodule
// Assignment by name
module system(...);
input rstrclks 5
output dout, done;
//Overriding dt_width only
ram #( .dt_width(16) ) MEM1 (.clk(clk),.rst(rst),...):
//Overriding ad_depth only
ram #( .ad_depth(512) ) MEM2 (.clk(clk),.rst(rst),...):
//Overriding both dt_width and ad_depth
ram #(.dt_width(16), .ad_depth(1024) ) MEM3 (.clk(clk),...):
endmodule
String
- A string is a sequence of characters enclosed by double quotes ("") and contained on a single line
- 8-bit ASCII value represents one character
reg [8*12:1] string_reg;
// 13 characters requires a 8*12, or 96 bits wide reg
string_reg="Some text...";