SystemVerilog is an extension to Verilog and is also used as an HDL. Verilog has reg
and wire
data-types to describe hardware behavior. Since verification of hardware can become more complex and demanding, datatypes in Verilog are not sufficient to develop efficient testbenches and testcases. Hence SystemVerilog has extended Verilog by adding more C like data-types for better encapsulation and compactness.
Click here to refresh Verilog Data Types
The image shown below is a comprehensive list of the major basic data types available in SystemVerilog.
Comments
// This is a one-line comment
/* This is a multiple line comment.
Since this line is within the block comment symbols, it is a comment.
*/
/* Another multiple line comment
// A nested one-line comment inside a block comment is fine.
But a block comment cannot be nested in another block comment.
*/
Value System
Following are the four states that a variable or net can hold
0 | Logic state 0 - variable/net is at 0 volts |
1 | Logic state 1 - variable/net is at some value > 0.7 volts |
x or X | Logic state X - variable/net has either 0/1 - we just don't know |
z or Z | Logic state Z - net has high impedence - maybe the wire is not connected and is floating |
Enhanced (') Literal
Verilog allowed a vector to be easily left padded with 0, Z or X, but not for 1. This can be a limitation as shown in the example below when WIDTH parameter is scaled up.
parameter WIDTH = 8;
reg [WIDTH-1:0] m_var;
m_var = 'h0; // Fills all bits of m_var with 0
m_var = 'hZ; // Fills all bits of m_var with Z
m_var = 'hX; // Fills all bits of m_var with X
m_var = 'h1; // Only LSB is 1 making the value of m_var = 8'b0000_0001
m_var = {WIDTH{1'b1}}; // Workaround - Use concatenation operator to club together as many 1s required
SystemVerilog allows the fill value to be specified without needing to indicate a binary, octal, or hexadecimal radix. Additionally, the fill value can now also be set to a logic 1.
module tb;
reg [7:0] m_var1;
reg [15:0] m_var2;
initial begin
m_var1 = '1;
m_var2 = '1;
$display("m_var1=0x%0h m_var2=0x%0h", m_var1, m_var2);
// This does not work - Radix must be specified !
//m_var1 = 'F0;
//m_var2 = 'cafe;
end
endmodule
xcelium> run m_var1=0xff m_var2=0xffff xmsim: *W,RNQUIE: Simulation is complete.
Floating Point/Exponential Numbers
Sets fixed point format. eg 2.8 or exponent format (eg 7.2e6)
module tb;
real pi; // Declared to be of type real
real freq;
initial begin
pi = 3.14; // Store floating point number
freq = 1e6; // Store exponential number
$display ("Value of pi = %f", pi);
$display ("Value of pi = %0.3f", pi);
$display ("Value of freq = %0d", freq);
end
endmodule
ncsim> run Value of pi = 3.140000 Value of pi = 3.140 Value of freq = 1000000.000000 ncsim: *W,RNQUIE: Simulation is complete.
Strings
// Strings can be split into multiple lines [for visual appeal] by the using "" character
// This does not split the string into multiple lines in the output
// Result: New York is an awesome place.So energetic and vibrant.
$display ("New York is an awesome place.
So energetic and vibrant.");
// Strings can be split to be displayed in multiple lines using "
"
/* Result:
New York is an awesome place.
So energetic and vibrant.
*/
$display ("New York is an awesome place.
So energetic and vibrant.");
// To store a string literal in an integral type, each character will require 8 bits
byte myLetter = "D";
bit [7:0] myNewLine = "
";
// "Hello World" has 11 characters and each character requires 8-bits
bit [8*17:1] myMessage = "Hello World";
string myMessage2 = "Hello World"; // Uses "string" data type
Click here to learn more about SystemVerilog Strings
Structures
A structure
represents a collection of data-types that are stored together and be referenced via the structure variable.
// Create a structure to store "int" and "real" variables
// A name is given to the structure and declared to be a data type so
// that this name "s_money" can be used to create structure variables
typedef struct {
int coins;
real dollars;
} s_money;
// Create a structure variable of type s_money
s_money wallet;
wallet = '{5, 19.75}; // Assign direct values to a structure variable
wallet = '{coins:5, dollars:19.75}; // Assign values using member names
wallet = '{default:0}; // Assign all elements of structure to 0
wallet = s_money'{int:1, dollars:2}; // Assign default values to all members of that type
// Create a structure that can hold 3 variables and initialize them with 1
struct {
int A, B, C;
} ABC = '{3{1}}; // A = B = C = 1
// Assigning an array of structures
s_money purse [1:0] = '{'{2, 4.25}, '{7,1.5}};
Click here to learn more about Structures
Fixed Arrays
An array is a variable to store different values in contiguous locations.
module tb;
// The following two representations of fixed arrays are the same
// myFIFO and urFIFO have 8 locations where each location can hold an integer value
// 0,1 | 0,2 | 0,3 | ... | 0,7
int myFIFO [0:7];
int urFIFO [8];
// Multi-dimensional arrays
// 0,0 | 0,1 | 0,2
// 1,0 | 1,1 | 1,2
int myArray [2][3];
initial begin
myFIFO[5] = 32'hface_cafe; // Assign value to location 5 in 1D array
myArray [1][1] = 7; // Assign to location 1,1 in 2D array
// Iterate through each element in the array
foreach (myFIFO[i])
$display ("myFIFO[%0d] = 0x%0h", i, myFIFO[i]);
// Iterate through each element in the multidimensional array
foreach (myArray[i])
foreach (myArray[i][j])
$display ("myArray[%0d][%0d] = %0d", i, j, myArray[i][j]);
end
endmodule
ncsim> run myFIFO[0] = 0x0 myFIFO[1] = 0x0 myFIFO[2] = 0x0 myFIFO[3] = 0x0 myFIFO[4] = 0x0 myFIFO[5] = 0xfacecafe myFIFO[6] = 0x0 myFIFO[7] = 0x0 myArray[0][0] = 0 myArray[0][1] = 0 myArray[0][2] = 0 myArray[1][0] = 0 myArray[1][1] = 7 myArray[1][2] = 0 ncsim: *W,RNQUIE: Simulation is complete.
Click here to learn more about SystemVerilog Arrays
Void
The void
data-type represents non-existing data, and can be specified as the return type of functions and tasks to indicate no return value.
function void display ();
$display ("Am not going to return any value");
endfunction
task void display ();
#10 $display ("Me neither");
endtask
real to int Conversion
Real numbers will be converted to integers by rounding the real number to the nearest integer instead of truncating it. If the fractional part is exactly 0.5, it will be rounded away from zero. Explicit conversion can be specified using casting or using system tasks. Directly assigning a real value to an integral type will also round instead of truncate.
// Casting will perform rounding
int'(2.0 * 3.0)
shortint'({8'hab, 8'hef})
// Using system tasks will truncate
integer $rtoi ( real_val )
real $itor ( int_val)