SystemVerilog Struct

SystemVerilog Struct

The SystemVerilog struct groups the data types of multiple types. The entire group can be referenced as a whole, or the individual data type can be referenced by name.

Struct Syntax

Struct is defined with the Struct keyword followed by variables of multiple data type with in the curly braces.

  typedef struct packed {
    type_1 var_1;
    type_2 var_2;
    type_3 var_3; 
  } struct_name; 

SystemVerilog Packed Struct

Struct defined with the keyword Packed is referred as packed struct
Only packed data types and integer data types are allowed with in the packed struct

Packed Struct example

In the below example, variable of bit type are grouped in the struct.

module struct_tb;
  
  typedef struct packed {
    bit [7:0]  addr;
    bit        valid;
    bit [31:0] data; 
  } mem_pkt; 
  
  mem_pkt pkt;
  
  initial begin 
    
    // Initializing Struct
    pkt = '{8'h6, 1'b1, 32'hC001_0FAB};
    $display ("pkt = %p", pkt);
    
    // Change the struct field value
    pkt.addr = 8'h8;
    $display ("pkt = %p", pkt);
   
    // Change the struct field value
    pkt.data = 32'hFFF0_0FFF;
    $display ("pkt = %p", pkt);
  end  
endmodule 

Simulator Output

pkt = '{addr:'h6, valid:'h1, data:'hc0010fab}
pkt = '{addr:'h8, valid:'h1, data:'hc0010fab}
pkt = '{addr:'h8, valid:'h1, data:'hfff00fff}

Click to execute on   

SystemVerilog UnPacked Struct

By default struct is of Unpacked type, i.e struct without Packed keyword.

Packed Struct example

In the below example, byte, enum and bit types are grouped in the struct.

module struct_tb;
  
  typedef enum logic {INVALID_PKT,VALID_PKT} pkt_type;
  
  typedef struct packed {
    byte       addr;
    pkt_type   valid;
    bit [31:0] data; 
  } mem_pkt; 
  
  mem_pkt pkt;
  
  initial begin 
    
    // Initializing Struct
    pkt = '{8'h6, VALID_PKT, 32'hC001_0FAB};
    $display ("pkt = %p", pkt);
    
    // Change the struct field value
    pkt.addr = 8'h8;
    $display ("pkt = %p", pkt);
   
    // Change the struct field value
    pkt.valid = INVALID_PKT;
    $display ("pkt = %p", pkt);
  end  
endmodule 

Simulator Output

pkt = '{addr:'h6, valid:VALID_PKT, data:'hc0010fab}
pkt = '{addr:'h8, valid:VALID_PKT, data:'hc0010fab}
pkt = '{addr:'h8, valid:INVALID_PKT, data:'hc0010fab}

Click to execute on   

difference between struct and array systemverilog

SystemVerilog struct and array difference

  • Array groups the elements of same data type
  • Struct groups the elements of different data type

Array


Collection of variables of same data type.

  int        addr[10]; //Array of int type          
  bit [31:0] data[63];  //Array of bit type 



Struct

Collection of variables of different data types.

  typedef enum logic {INVALID_PKT,VALID_PKT} pkt_type;
  
  typedef struct packed {
    byte       addr;
    pkt_type   valid;
    bit [31:0] data; 
  } mem_pkt; 

For detailed description refer to,

SystemVerilog dpi

SystemVerilog DPI C++

SystemVerilog DPI (Direct Programming Interface) is an interface which can be used to interface SystemVerilog with foreign languages. These Foreign languages can be C, C++, SystemC as well as others.

DPI allows the user to easily call functions of other language from SystemVerilog and to export SystemVerilog functions, so that they can be called in other languages.

Advantage of DPI is,  it allows to make use of the code exists in other languages.

DPI Import and export methods

Import Method

The methods (functions/tasks) implemented in Foreign language can be called from SystemVerilog and such methods are called Import methods.

Export methods

The methods implemented in SystemVerilog can be called from Foreign language such methods are called Export methods.

It is allowed to transfer the data between two languages through arguments passing and return.

DPI Declaration

Import Declaration

import “DPI-C” function int calc_parity (input int a);

Export Declaration

export “DPI-C” my_cfunction = function myfunction;

SystemVerilog DPI Example

Calling C++ method from SystemVerilog file

//----------------------------------------------
// SystemVerilog File
//----------------------------------------------
module dpi_tb;

  import "DPI-C" function void c_method();
  
  initial
  begin
    $display("Before calling C Method");
    c_method();
    $display("After calling C Method");
  end
  
endmodule

//----------------------------------------------
// C++ file
//----------------------------------------------
#include stdio.h
#include stdlib.h

extern "C" void c_method() {

  printf("     Hello World...!\n");

}

Simulator Output

Before calling C Method
[C-Prog]   Hello World...!
After calling C Method

Click to execute on   

Calling SystemVerilog method from C++ file

//----------------------------------------------
// SystemVerilog File
//----------------------------------------------
module dpi_tb;

  export "DPI-C" function sv_method;
  import "DPI-C" context function void c_method();
  
  initial
  begin
    $display("Before calling C Method");
    c_method();
    $display("After calling C Method");
  end
  
  function void sv_method();
    $display("  [SV-Prog]  Hello World...!");
  endfunction
endmodule

//----------------------------------------------
// C++ file
//----------------------------------------------
#include stdio.h
#include iostream
#include svdpi.h

using namespace std;

extern "C" void sv_method();
extern "C" void c_method() {

  printf("  [C-Prog]   Hello World...!\n");
  sv_method();
}

Simulator Output

Before calling C Method
[C-Prog]   Hello World...!
[SV-Prog] Hello World...!
After calling C Method

Click to execute on   

SystemVerilog Print enum as String

SystemVerilog print enum name

As we know enum defines a set of named values.
refer to SystemVerilog enum for detailed description.

Printing or displaying the enum name is easy for debug, by using enum method “name”, enum name can be displayed.

module enum_datatype;
  //declaration
  typedef enum int { red=0, green=1, blue=4, yellow, white=6, black=9 } Colors;
  
  Colors color;
  
  initial begin
    color = 4;
    $display("Colors  ::  Value of %0s is \t= %0d",color.name(),color);
  end
endmodule

Simulator Output

Colors :: Value of blue is = 4

Click to execute on   

SystemVerilog enum of logic bit int

SystemVerilog enum of logic bit int

This section provides the examples to declare SystemVerilog enum of logic type, enum of bit type and  enum of int type

enum of logic type example

module enum_datatype;
  //declaration
  enum logic [3:0] { red=0, green=1, blue=4, yellow, white=6, black=9 } Colors;
  
  initial begin
    Colors = Colors.first;
    for(int i=0;i < 6;i++) begin
      $display("Colors  ::  Value of %0s is \t= %0d",Colors.name(),Colors);
      Colors = Colors.next;
    end
  end
endmodule

Simulator Output

Colors :: Value of red is = 0
Colors :: Value of green is = 1
Colors :: Value of blue is = 4
Colors :: Value of yellow is = 5
Colors :: Value of white is = 6
Colors :: Value of black is = 9

Click to execute on   

enum of bit type example

module enum_datatype;
  //declaration
  enum bit [3:0] { red=0, green=1, blue=4, yellow, white=6, black=9 } Colors;
  
  initial begin
    Colors = Colors.first;
    for(int i=0;i < 6;i++) begin
      $display("Colors  ::  Value of %0s is \t= %0d",Colors.name(),Colors);
      Colors = Colors.next;
    end
  end
endmodule

Simulator Output

Colors :: Value of red is = 0
Colors :: Value of green is = 1
Colors :: Value of blue is = 4
Colors :: Value of yellow is = 5
Colors :: Value of white is = 6
Colors :: Value of black is = 9

Click to execute on   

enum of int type example

module enum_datatype;
  //declaration
  enum int { red=0, green=1, blue=4, yellow, white=6, black=9 } Colors;
  
  initial begin
    Colors = Colors.first;
    for(int i=0;i < 6;i++) begin
      $display("Colors  ::  Value of %0s is \t= %0d",Colors.name(),Colors);
      Colors = Colors.next;
    end
  end
endmodule

Simulator Output

Colors :: Value of red is = 0
Colors :: Value of green is = 1
Colors :: Value of blue is = 4
Colors :: Value of yellow is = 5
Colors :: Value of white is = 6
Colors :: Value of black is = 9

Click to execute on   

SystemVerilog enum cast

SystemVerilog enum casting

Assigning a variable to enum type is illegal, below example shows assigning variable to enum type.

Assigning variable to enum

module enum_datatype;
  //declaration
  typedef enum int { red=0, green=1, blue=4, yellow, white=6, black=9 } Colors;
  
  Colors color;
  
  initial begin
    color = 4;
    $display("Colors  ::  Value of %0s is \t= %0d",color.name(),color);
  end
endmodule

Simulator Output

Warning-[ENUMASSIGN] Illegal assignment to enum variable
testbench.sv, 11
enum_datatype, "color = 4;"
Only expressions of the enum type can be assigned to an enum variable.
The type int is incompatible with the enum 'Colors'
Expression: 4
Use the static cast operator to convert the expression to enum type.
Colors :: Value of blue is = 4

Click to execute on   

enum casting

In the above example we have seen that assigning variable to enum type is illegal, this can be overcome by using casting.

Below example shows using cast to assign variable to enum type.

module enum_datatype;
  //declaration
  typedef enum int { red=0, green=1, blue=4, yellow, white=6, black=9 } Colors;
  
  Colors color;
  
  initial begin
    $cast(color,4);
    $display("Colors  ::  Value of %0s is \t= %0d",color.name(),color);
  end
endmodule

Simulator Output

Colors :: Value of blue is = 4

Click to execute on   

SystemVerilog logic vs wire

SystemVerilog logic vs wire

Wire is verilog datatype whereas logic is SystemVerilog data type.

Logic:
SystemVerilog logic data type is 4-state data type

Wire:
Verilog wire also 4-state data type, wire is used to connect input and output ports of a module instantiation together with some other element in your design

Assertions in SystemVerilog

SystemVerilog Assertions

Assertions are primarily used to validate the behavior of a design. An assertion is a check embedded in design or bound to a design unit during the simulation. Warnings or errors are generated on the failure of a specific condition or sequence of events.

Assertions are used to,

  • Check the occurrence of a specific condition or sequence of events.
  • Provide functional coverage.

There are two kinds of assertions:

  • Immediate Assertions
  • Concurrent Assertions

Immediate Assertions:

Immediate assertions check for a condition at the current simulation time.

An immediate assertion is the same as an if..else statement with assertion control. Immediate assertions have to be placed in a procedural block definition.

Syntax

label: assert(expression) action_block;
  • The optional statement label (identifier and colon) creates a named block around the assertion statement
  • The action block is executed immediately after the evaluation of the assert expression
  • The action_block specifies what actions are taken upon success or failure of the assertion

action_block;

pass_statement; else fail_statement;
  • The pass statement is executed if the expression evaluates to true
  • The statement associated with else is called a fail statement and is executed if the expression evaluates to false
  • Both pass and fail statements are optional
  • Since the assertion is a statement that something must be true, the failure of an assertion shall have a severity associated with it. By default, the severity of an assertion failure is an error.
  • Other severity levels can be specified by including one of the following severity system tasks in the fail statement:
    • $fatal is a run-time fatal.
    • $error is a run-time error.
    • $warning is a run-time warning, which can be suppressed in a tool-specific manner.
    • $info indicates that the assertion failure carries no specific severity.
  • If an assertion fails and no else clause is specified, the tool shall, by default call $error.

Below are the different forms of immediate assertion syntax with and without optional items

//With Pass and Fail statement; Fail verbosity info;
assert(expression) $display(“expression evaluates to true”); else $display(“expression evaluates to false”);

//Only With Pass statement;
assert(expression) $display(“expression evaluates to true”);

//With Pass and Fail statement; Fail verbosity fatal;
assert(expression) $display(“expression evaluates to true”); else $fatal(“expression evaluates to false”);

//Only With Fail statement; Multiple statements in Faile condition and Fail verbosity fatal;
assert(expression)
      else begin
        …….
        …….
        $fatal(“expression evaluates to false”);
      end

//Only With Fail statement; Fail verbosity warning;
assert(expression) else $warning(“expression evaluates to false”);

//With Label and Fail statement; Fail verbosity warning;
label: assert(expression) else $warning(“expression evaluates to false”);

Immediate assertion example

Below is the simple immediate assertion,

always @(posedge clk) assert (a && b);

Below is the wave diagram for the above assertion.
Condition (a && b) will be checked at every posedge of the clock, failure in the condition leads to an assertion failure.

SystemVerilog Assertions
SystemVerilog Assertions
module asertion_ex;
  bit clk,a,b;
  
  //clock generation
  always #5 clk = ~clk; 
  
  //generating 'a'
  initial begin 
    a=1;
    b=1;
    #15 b=0;
    #10 b=1;
        a=0;
    #20 a=1;
    #10;
    $finish;
  end
  
  //Immediate assertion
  always @(posedge clk) assert (a && b);

endmodule

Simulator Output

Immediate Assertions Waveform
Immediate Assertions Waveform
ncsim: *E,ASRTST (./testbench.sv,23): (time 15 NS) Assertion asertion_ex.__assert_1 has failed
ncsim: *E,ASRTST (./testbench.sv,23): (time 25 NS) Assertion asertion_ex.__assert_1 has failed
ncsim: *E,ASRTST (./testbench.sv,23): (time 35 NS) Assertion asertion_ex.__assert_1 has failed
Simulation complete via $finish(1) at time 55 NS + 0

Click to execute on   

Concurrent Assertions:

Concurrent assertions check the sequence of events spread over multiple clock cycles.

  • The concurrent assertion is evaluated only at the occurrence of a clock tick
  • The test expression is evaluated at clock edges based on the sampled values of the variables involved
  • It can be placed in a procedural block, a module, an interface or a program definition
   c_assert:  assert property(@(posedge clk) not(a && b));

The Keyword differentiates the immediate assertion from the concurrent assertion is “property.”

❮ Previous Next ❯