📜 ⬆️ ⬇️

Innovations language SystemVerilog

image

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:


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.
image
 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; 


image
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 


image
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/systemverilog
2. "SystemVerilog For Design Second Edition" by Stuart Sutherland

Source: https://habr.com/ru/post/221265/


All Articles