2-state Data Types
The 2-state data types, such as bit
and int
, can only represent two values: 0 and 1. This simplification reduces memory usage during simulation, as each bit requires only one bit of storage instead of two bits needed for the 4-state types (which include 0, 1, X for unknown, and Z for high impedance). This leads to faster simulation performance due to lower memory overhead and reduced complexity in handling states.
Data Type | Size | Signed Range | Unsigned Range | Description |
---|---|---|---|---|
bit | 1-bit | 0 and 1 | 2-state variable | |
byte | 8-bit | -27 to 27-1 | 0 to 28-1 | 2-state variable, similar to C char |
shortint | 16-bit | -215 to 215-1 | 0 to 216-1 | 2-state variable, similar to C short int |
int | 32-bit | -231 to 231-1 | 0 to 232-1 | 2-state variable, similar to C int |
longint | 64-bit | -263 to 263-1 | 0 to 264-1 | 2-state variable, similar to C long int |
Such 2-state types are suitable for modeling at more abstract levels than RTL, such as system level and transaction level. For instance, when modeling a network packet with a header that indicates the packet length, the length should be a numeric value rather than X or Z.
When a 4-state value is converted to a 2-state value, unknown (X) or high-impedance (Z) bits shall be converted to zeros.
module tb;
bit [3:0] var_b; // Declare a 4-bit variable of type "bit"
logic [3:0] x_val; // Declare a 4-bit variable of type "logic"
initial begin
x_val = 4'b01zx;
// If a logic type or any 4-state variable assigns its value to a "bit" type
// variable, then X and Z get converted to zero
var_b = x_val;
$display ("x_val=%b var_b = %b", x_val, var_b);
end
endmodule
xcelium> run
x_val=01zx var_b = 0100
xmsim: *W,RNQUIE: Simulation is complete.
bit
The bit
type is a 2-state data type that can represent binary values, default being 0. The bit type is commonly used in testbenches and other verification code where the additional states (X and Z) are not needed. A range specification ([MSB:LSB]) should be provided to make it represent and store multiple bits.
module tb;
bit var_a; // Declare a 1 bit variable of type "bit"
bit [3:0] var_b; // Declare a 4 bit variable of type "bit"
logic [3:0] x_val; // Declare a 4 bit variable of type "logic"
initial begin
// Initial value of "bit" data type is 0
$display ("Initial value var_a=%0b var_b=0x%0h", var_a, var_b);
// Assign new values and display the variable to see that it gets the new values
var_a = 1;
var_b = 4'hF;
$display ("New values var_a=%0b var_b=0x%0h", var_a, var_b);
// If a "bit" type variable is assigned with a value greater than it can hold
// the left most bits are truncated. In this case, var_b can hold only 4 bits
// and hence 'h481 gets truncated leaving var_b with only 'ha;
var_b = 16'h481a;
$display ("Truncated value: var_b=0x%0h", var_b);
end
endmodule
ncsim> run Initial value var_a=0 var_b=0x0 New values var_a=1 var_b=0xf Truncated value: var_b=0xa ncsim: *W,RNQUIE: Simulation is complete.
byte
The byte
data type is defined as an 8-bit signed integer. It uses two's complement representation, enabling it to store both positive and negative values. The range for a byte is from -128 to 127. The byte data type is useful for applications where memory efficiency is important, such as in large arrays or when representing small integer values.
module tb;
byte m_var_s; // By default signed, and can represent positive and negative numbers
initial begin
#10 m_var_s = 0; // assign 0
#20 m_var_s = 2**7 - 1; // assign 127
#30 m_var_s = 2**7; // assign 128
#40 m_var_s = 2**8 - 1; // assign 255
end
initial
$monitor("[%0t] m_var_s = 'd%0d (0x%0h)", $time, m_var_s, m_var_s);
endmodule
xcelium> run [0] m_var_s = 'd0 (0x0) [30] m_var_s = 'd127 (0x7f) [60] m_var_s = 'd-128 (0x80) [100] m_var_s = 'd-1 (0xff) xmsim: *W,RNQUIE: Simulation is complete.
shortint
A shortint
in SystemVerilog is a 2-state, 16-bit signed integer data type.
module tb;
shortint m_var_s; // By default signed, and can represent positive and negative numbers
initial begin
#10 m_var_s = 0; // assign 0
#20 m_var_s = 2**15 - 1; // assign 127
#30 m_var_s = 2**15; // assign 128
#40 m_var_s = 2**16 - 1; // assign 256
end
initial
$monitor("[%0t] m_var_s = 'd%0d (0x%0h)", $time, m_var_s, m_var_s);
endmodule
xcelium> run [0] m_var_s = 'd0 (0x0) [30] m_var_s = 'd32767 (0x7fff) [60] m_var_s = 'd-32768 (0x8000) [100] m_var_s = 'd-1 (0xffff) xmsim: *W,RNQUIE: Simulation is complete.
int
A int
in SystemVerilog is a 2-state, 32-bit signed integer data type.
module tb;
int m_var_s; // By default signed, and can represent positive and negative numbers
initial begin
#10 m_var_s = 0;
#20 m_var_s = 2**31 - 1;
#30 m_var_s = 2**31;
#40 m_var_s = 2**32 - 1;
end
initial
$monitor("[%0t] m_var_s = 'd%0d (0x%0h)", $time, m_var_s, m_var_s);
endmodule
xcelium> run [0] m_var_s = 'd0 (0x0) [30] m_var_s = 'd2147483647 (0x7fffffff) [60] m_var_s = 'd-2147483648 (0x80000000) [100] m_var_s = 'd-1 (0xffffffff) xmsim: *W,RNQUIE: Simulation is complete.
longint
A longint
in SystemVerilog is a 2-state, 64-bit signed integer data type.
module tb;
longint m_var_s; // By default signed, and can represent positive and negative numbers
initial begin
#10 m_var_s = 0;
#20 m_var_s = 2**63 - 1;
#30 m_var_s = 2**63;
#40 m_var_s = 2**64 - 1;
end
initial
$monitor("[%0t] m_var_s = 'd%0d (0x%0h)", $time, m_var_s, m_var_s);
endmodule
xcelium> run [0] m_var_s = 'd0 (0x0) [30] m_var_s = 'd9223372036854775807 (0x7fffffffffffffff) [60] m_var_s = 'd-9223372036854775808 (0x8000000000000000) [100] m_var_s = 'd-1 (0xffffffffffffffff) xmsim: *W,RNQUIE: Simulation is complete.
Signed and Unsigned
Signed data types can represent both positive and negative values, whereas unsigned data types can only represent non-negative values (zero and positive numbers). Signed data types use one bit (MSB) for the sign, which reduces the maximum positive value that can be represented compared to unsigned types of the same bit width. This means that while both signed and unsigned types may have the same number of bits, the unsigned type has a larger range of positive values.
Example
The sign can be explicitly defined using the keywords signed
and unsigned
.
module tb;
byte s_byte; // By default byte is signed
byte unsigned u_byte; // Byte is set to unsigned
initial begin
$display ("Size s_byte=%0d, u_byte=%0d", $bits(s_byte), $bits(u_byte));
// Assign the "assumed" maximum value to both variables
#1 s_byte = 'h7F;
u_byte = 'h7F;
// Increment by 1, and see that s_byte rolled over to negative because
// byte is signed by default. u_byte keeps increasing because it is
// unsigned and can go upto 255
#1 s_byte += 1;
u_byte += 1;
// Assign 255 (8'hFF) to u_byte -> this is the max value it can hold
#1 u_byte = 'hFF;
// Add 1 and see that it rolls over to 0
#1 u_byte += 1;
end
initial begin
$monitor ("[%0t ns] s_byte=%0d u_byte=%0d", $time, s_byte, u_byte);
end
endmodule
ncsim> run Size s_byte=8, u_byte=8 [0 ns] s_byte=0 u_byte=0 [1 ns] s_byte=127 u_byte=127 [2 ns] s_byte=-128 u_byte=128 [3 ns] s_byte=-128 u_byte=255 [4 ns] s_byte=-128 u_byte=0 ncsim: *W,RNQUIE: Simulation is complete.
Understanding the difference between signed and unsigned data types is crucial for effective programming and hardware design. It allows developers to choose the right representation for their data needs while optimizing memory usage and ensuring data integrity.
Sign Cast
They can be converted into one another by casting.
module tb;
shortint m_var_s; // By default signed, and can represent positive and negative numbers
shortint unsigned m_var_us; // Explicitly set to 'unsigned' and represents only positive numbers
initial begin
m_var_us = 2**16 - 1;
m_var_s = -1;
// Convert an unsigned variable value to a signed variable value by casting
$display("m_var_us=%0d m_var_us=%0d", signed' (m_var_us), m_var_us);
$display("m_var_s=%0d m_var_s=%0d", unsigned' (m_var_s), m_var_s);
end
endmodule
Operations on unsigned integers can be faster in some cases since there’s no need to handle sign bits during arithmetic operations and can lead to more efficient code execution.
xcelium> run m_var_us=-1 m_var_us=65535 m_var_s=65535 m_var_s=-1 xmsim: *W,RNQUIE: Simulation is complete.