
This article shows some of the innovations of the SystemVerilog language in the field of data organization compared to Verilog-2001 for the synthesized subset of the language.
The history of SystemVerilog is quite lengthy and foggy. Starting after the adoption of the Verilog-95 standard, it became known as Verilog-2001. However, the language was not very suitable for verification; engineers use the languages of the “E” family - VERA, Testbuider. In its current form, SystemVerilog appeared after 2005. Now, synthesis and modeling tools such as Quartus II, ISE, ModelSim / QuestaSim confidently support SystemVerilog. The standard is called IEEE 1800-2012.
')
Note This article has long been written, but not published. I hope it will be useful for beginners.SystemVerilog brought many new interesting designs to Verilog’s world:
- C-lile syntax
- OOP
- Structures, queues, dynamic arrays, enumerations
- Type cast
- Monitoring program behavior with foreach, return, break, continue, etc.
- Semaphores, mailboxes.
- Interfaces
- Assertions
Universal logic type.
Now there is no need to choose between reg and wire, logic is used everywhere. The synthesizer itself decides what to do (hello VHDL signal).
Type Initialization
Improved type initialization capabilities have become available in SystemVerilog. Now no need to write
reg [63:0] data = 64'hFFFFFFFFFFFFFFFF;
You can do just this:
reg [63:0] data = '1;
The data = '0 record initializes the vector with zeros, and the data =' bz - the third state
Enum types
Finally, the state machine can be described like this
enum {WAITE, LOAD, STORE} State, NextState; always_ff @(posedge clock, negedge resetN) if (!resetN) State <= WAITE; else State <= NextState; always_comb begin case (State) WAITE: NextState = LOAD; LOAD: NextState = STORE; STORE: NextState = WAITE; endcase end
In addition, values can be assigned to the enumerated type:
enum {ONE = 1,FIVE = 5,TEN = 10 } state;
By default, the enum value is assigned an int value. However, you can write like this
// enumerated type with a width of 1 bit.
// can take only two states
enum bit {TRUE, FALSE} Boolean; // 2 . // enum logic [1:0] {WAITE, LOAD, READY} state;
To print the value of the name of the enumerated type, use the following construction:
$display("\nCurrent state is %s (%b)", State.name);
Strukruta
You can declare structures as follows:
struct { int a, b; // 32-bit variables opcode_t opcode; // user-defined type logic [23:0] address; // 24-bit variable bit error; // 1-bit 2-state var. } Instruction_Word;
For structures supported typedef declaration
typedef struct { // structure definition logic [31:0] a, b; logic [ 7:0] opcode; logic [23:0] address; } instruction_word_t; instruction_word_t IW; // structure allocation
By default, the structure is presented as unpacked. The packed keyword allows the structure to be packed.
struct packed { logic valid; logic [ 7:0] tag; logic [31:0] data; } data_word;
In this form, it is represented as a vector. Therefore, such constructions are possible.

data_word.tag = 8'hf0; data_word[39:32] = 8'hf0; //
Union union
A union is a memory value that can store different types of data, but only one at a time.
The syntax is completely C-like.
union { int i; int unsigned u; } data; ... data.i = -5; $display("data is %d", data.i); data.u = -5; $display("now data is %d", data.u);
Packed unions are of the greatest practical interest. They use a fixed number of bits to represent different types.
Information recorded through one type can be read in another form (another type). For example:
typedef struct packed { logic [15:0] source_address; logic [15:0] destination_address; logic [23:0] data; logic [ 7:0] opcode; } data_packet_t; union packed { data_packet_t packet; // packed structure logic [7:0][7:0] bytes; // packed array } dreg;

Since the union is packed, the information is aligned, so the data recorded through logic [7: 0] can be read through data_packet_t
initial begin logic [15:0] src, dst; for (i = 0; i <= N; i = i + 1) begin dreg.bytes[i] <= byte_in; //store as bytes end src = dreg.source_address; dst = dreg.destination_address; end
Packaged array
SystemVerilog allows you to create multi-dimensional packed arrays
logic [3:0][7:0] data; // 2-D packed array logic [1:0][3:0][7:0] data; // 3-D packed array
The IEEE standard defines how this element should be stored in memory. For example, to describe
logic [3:0][7:0] data; // 2-D packed array

Since the array is stored in memory as a vector, it is permissible to use all the same operations as on vectors
logic [3:0][15:0] a, b, result; // packed arrays result = (a << 1) + b;
Access to a vector can be either element-wise, or including the whole dimension (s). The so-called array slice.
logic [1:0][1:0][7:0] a; // 3-D packed array a[1][1][0] = 1'b0; // a = 32'hF1A3C5E7; // a[1][0][3:0] = 4'hF; // a[0] = 16'hFACE; //
To copy the contents of one array to another, you can use direct access or over slices.
bit [1:0][15:0] a; //32 , bit 0 1 logic [3:0][7:0] b; //32 , logic O,1,Z,X logic [15:0] c; // 16 logic [39:0] d; // 40 b = a; // 32 32 c = a; // 16 d = a; // 8
Bibliography
1.
www.asic-world.com/systemverilog2. "SystemVerilog For Design Second Edition" by Stuart Sutherland