SystemVerilog https://www.verilogpro.com/category/systemverilog/ Verilog and Systemverilog Resources for Design and Verification Thu, 29 Sep 2022 07:58:36 +0000 en-US hourly 1 https://wordpress.org/?v=6.5.2 98068679 SystemVerilog Arrays, Flexible and Synthesizable https://www.verilogpro.com/systemverilog-arrays-synthesizable/ https://www.verilogpro.com/systemverilog-arrays-synthesizable/#comments Tue, 10 Oct 2017 17:00:44 +0000 http://www.verilogpro.com/?p=607 In my last article on plain old Verilog Arrays, I discussed their very limited feature set. In comparison, SystemVerilog arrays have greatly expanded capabilities both for writing synthesizable RTL, and for writing non-synthesizable test benches. In this article, we’ll take a look at the synthesizable features of SystemVerilog Arrays we can use when writing design ... Read more

The post SystemVerilog Arrays, Flexible and Synthesizable appeared first on Verilog Pro.

]]>
In my last article on plain old Verilog Arrays, I discussed their very limited feature set. In comparison, SystemVerilog arrays have greatly expanded capabilities both for writing synthesizable RTL, and for writing non-synthesizable test benches. In this article, we’ll take a look at the synthesizable features of SystemVerilog Arrays we can use when writing design RTL.

Packed vs Unpacked SystemVerilog Arrays

Verilog had only one type of array. SystemVerilog arrays can be either packed or unpacked. Packed array refers to dimensions declared after the type and before the data identifier name. Unpacked array refers to the dimensions declared after the data identifier name.

bit [7:0] c1;         // packed array of scalar bit
real      u [7:0];    // unpacked array of real

int Array[0:7][0:31]; // unpacked array declaration using ranges
int Array[8][32];     // unpacked array declaration using sizes

Packed Arrays

A one-dimensional packed array is also called a vector. Packed array divides a vector into subfields, which can be accessed as array elements. A packed array is guaranteed to be represented as a contiguous set of bits in simulation and synthesis.

Packed arrays can be made of only the single bit data types (bit, logic, reg), enumerated types, and other packed arrays and packed structures. This also means you cannot have packed arrays of integer types with predefined widths (e.g. a packed array of byte).

Unpacked arrays

Unpacked arrays can be made of any data type. Each fixed-size dimension is represented by an address range, such as [0:1023], or a single positive number to specify the size of a fixed-size unpacked array, such as [1024]. The notation [size] is equivalent to [0:size-1].

Indexing and Slicing SystemVerilog Arrays

Verilog arrays could only be accessed one element at a time. In SystemVerilog arrays, you can also select one or more contiguous elements of an array. This is called a slice. An array slice can only apply to one dimension; other dimensions must have single index values in an expression.

Multidimensional Arrays

Multidimensional arrays can be declared with both packed and unpacked dimensions. Creating a multidimensional packed array is analogous to slicing up a continuous vector into multiple dimensions.

When an array has multiple dimensions that can be logically grouped, it is a good idea to use typedef to define the multidimensional array in stages to enhance readability. But notice the order of the dimensions become a little confusing.

bit [3:0] [7:0] joe [0:9] // 10 elements of 4 8-bit bytes
                          // (each element packed into 32 bits)

typedef bit [4:0] bsix;   // multiple packed dimensions with typedef
bsix [9:0] v5;            // equivalent to bit[9:0][4:0] v5 - thanks Yunsung!

typedef bsix mem_type [0:3]; // array of four unpacked 'bsix' elements
mem_type ba [0:7];           // array of eight unpacked 'mem_type' elements
                             // equivalent to bit[4:0] ba [0:7][0:3] - thanks Yunsung!

SystemVerilog Array Operations

SystemVerilog arrays support many more operations than their traditional Verilog counterparts.

+: and -: Notation

When accessing a range of indices (a slice) of a SystemVerilog array, you can specify a variable slice by using the [start+:increment width] and [start-:decrement width] notations. They are simpler than needing to calculate the exact start and end indices when selecting a variable slice. The increment/decrement width must be a constant.

bit signed [31:0] busA [7:0]; // unpacked array of 8 32-bit vectors
int busB [1:0];               // unpacked array of 2 integers
busB = busA[7:6];             // select a 2-vector slice from busA
busB = busA[6+:2];            // equivalent to busA[7:6]; typo fixed, thanks Tomer!

Assignments, Copying, and other Operations

SystemVerilog arrays support many more operations than Verilog arrays. The following operations can be performed on both packed and unpacked arrays.

A       = B;       // reading and writing the array
A[i:j]  = B[i:j];  // reading and writing a slice of the array
A[x+:c] = B[y+:d]; // reading and writing a variable slice of the array
A[i]    = B[i];    // accessing an element of the array
A       == B;      // equality operations on the array
A[i:j]  != B[i:j]; // equality operations on slice of the array

Packed Array Assignment

A SystemVerilog packed array can be assigned at once like a multi-bit vector, or also as an individual element or slice, and more.

logic [1:0][1:0][7:0] packed_3d_array;

always_ff @(posedge clk, negedge rst_n)
  if (!rst_n) begin
    packed_3d_array <= '0;      // assign 0 to all elements of array
  end
  else begin
    packed_3d_array[0][0][0]   <= 1'b0;         // assign one bit
    packed_3d_array[0][0]      <= 8'h0a;        // assign one element
    packed_3d_array[0][0][3:0] <= 4'ha;         // assign part select
    packed_3d_array[0]         <= 16'habcd;     // assign slice
    packed_3d_array            <= 32'h01234567; // assign entire array as vector
  end

Unpacked Array Assignment

All or multiple elements of a SystemVerilog unpacked array can be assigned at once to a list of values. The list can contain values for individual array elements, or a default value for the entire array.

logic [7:0] a, b, c;
logic [7:0] d_array[0:3];
logic [7:0] e_array[3:0]; // note index of unpacked dimension is reversed
                          // personally, I prefer this form
logic [7:0] mult_array_a[3:0][3:0];
logic [7:0] mult_array_b[3:0][3:0];

always_ff @(posedge clk, negedge rst_n)
  if (!rst_n) begin
    d_array <= '{default:0};      // assign 0 to all elements of array
  end
  else begin
    d_array        <= '{8'h00, c, b, a}; // d_array[0]=8'h00, d_array[1]=c, d_array[2]=b, d_array[3]=a
    e_array        <= '{8'h00, c, b, a}; // e_array[3]=8'h00, e_array[2]=c, e_array[1]=b, d_array[0]=a
    mult_array_a   <= '{'{8'h00, 8'h01, 8'h02, 8'h03},
                        '{8'h04, 8'h05, 8'h06, 8'h07},
                        '{8'h08, 8'h09, 8'h0a, 8'h0b},
                        '{8'h0c, 8'h0d, 8'h0e, 8'h0f}}; // assign to full array
    mult_array_b[3] <= '{8'h00, 8'h01, 8'h02, 8'h03}; // assign to slice of array
  end

Conclusion

This article described the two new types of SystemVerilog arrays—packed and unpacked—as well as the many new features that can be used to manipulate SystemVerilog arrays. The features described in this article are all synthesizable, so you can safely use them in SystemVerilog based RTL designs to simplify coding. In the next part of the SystemVerilog arrays article, I will discuss more usages of SystemVerilog arrays that can make your SystemVerilog design code even more efficient. Stay tuned!

Resources

Sample Source Code

The accompany source code for this article is a toy example module and testbench that illustrates SystemVerilog array capabilities, including using an array as a port, assigning multi-dimensional arrays, and assigning slices of arrays. Download and run it to see how it works!

[lab_subscriber_download_form download_id=11].

The post SystemVerilog Arrays, Flexible and Synthesizable appeared first on Verilog Pro.

]]>
https://www.verilogpro.com/systemverilog-arrays-synthesizable/feed/ 36 607
Verilog reg, Verilog wire, SystemVerilog logic. What’s the difference? https://www.verilogpro.com/verilog-reg-verilog-wire-systemverilog-logic/ https://www.verilogpro.com/verilog-reg-verilog-wire-systemverilog-logic/#comments Tue, 02 May 2017 17:00:40 +0000 http://www.verilogpro.com/?p=499 The difference between Verilog reg and Verilog wire frequently confuses many programmers just starting with the language (certainly confused me!). As a beginner, I was told to follow these guidelines, which seemed to generally work: Use Verilog reg for left hand side (LHS) of signals assigned inside in always blocks Use Verilog wire for LHS ... Read more

The post Verilog reg, Verilog wire, SystemVerilog logic. What’s the difference? appeared first on Verilog Pro.

]]>
The difference between Verilog reg and Verilog wire frequently confuses many programmers just starting with the language (certainly confused me!). As a beginner, I was told to follow these guidelines, which seemed to generally work:

  • Use Verilog reg for left hand side (LHS) of signals assigned inside in always blocks
  • Use Verilog wire for LHS of signals assigned outside always blocks

Then when I adopted SystemVerilog for writing RTL designs, I was told everything can now be “type logic”. That again generally worked, but every now and then I would run into a cryptic error message about variables, nets, and assignment.

So I decided to find out exactly how these data types worked to write this article. I dug into the language reference manual, searched for the now-defunct Verilog-2005 standard document, and got into a bit of history lesson. Read on for my discovery of the differences between Verilog reg, Verilog wire, and SystemVerilog logic.

Verilog data types, Verilog reg, Verilog wire

Verilog data types are divided into two main groups: nets and variables. The distinction comes from how they are intended to represent different hardware structures.

A net data type represents a physical connection between structural entities (think a plain wire), such as between gates or between modules. It does not store any value. Its value is derived from what is being driven from its driver(s). Verilog wire is probably the most common net data type, although there are many other net data types such as tri, wand, supply0.

A variable data type generally represents a piece of storage. It holds a value assigned to it until the next assignment. Verilog reg is probably the most common variable data type. Verilog reg is generally used to model hardware registers (although it can also represent combinatorial logic, like inside an always@(*) block). Other variable data types include integer, time, real, realtime.

Almost all Verilog data types are 4-state, which means they can take on 4 values:

  • 0 represents a logic zero, or a false condition
  • 1 represents a logic one, or a true condition
  • X represents an unknown logic value
  • Z represents a high-impedance state

Verilog rule of thumb 1: use Verilog reg when you want to represent a piece of storage, and use Verilog wire when you want to represent a physical connection.

Assigning values to Verilog reg, Verilog wire

Verilog net data types can only be assigned values by continuous assignments. This means using constructs like continuous assignment statement (assign statement), or drive it from an output port. A continuous assignment drives a net similar to how a gate drives a net. The expression on the right hand side can be thought of as a combinatorial circuit that drives the net continuously.

Verilog variable data types can only be assigned values using procedural assignments. This means inside an always block, an initial block, a task, a function. The assignment occurs on some kind of trigger (like the posedge of a clock), after which the variable retains its value until the next assignment (at the next trigger). This makes variables ideal for modeling storage elements like flip-flops.

Verilog rule of thmb 2: drive a Verilog wire with assign statement or port output, and drive a Verilog reg from an always block. If you want to drive a physical connection with combinatorial logic inside an always@(*) block, then you have to declare the physical connection as Verilog reg.

SystemVerilog logic, data types, and data objects

SystemVerilog introduces a new 2-state data type—where only logic 0 and logic 1 are allowed, not X or Z—for testbench modeling. To distinguish the old Verilog 4-state behaviour, a new SystemVerilog logic data type is added to describe a generic 4-state data type.

What used to be data types in Verilog, like wire, reg, wand, are now called data objects in SystemVerilog. Wire, reg, wand (and almost all previous Verilog data types) are 4-state data objects. Bit, byte, shortint, int, longint are the new SystemVerilog 2-state data objects.

There are still the two main groups of data objects: nets and variables. All the Verilog data types (now data objects) that we are familiar with, since they are 4-state, should now properly also contain the SystemVerilog logic keyword.

wire my_wire;                       // implicitly means "wire logic my_wire" 
wire logic my_wire;                 // you can also declare it this way
wire [7:0] my_wire_bus;             // implicitly means "wire logic[15:0] my_wire_bus" 
wire logic [7:0] my_wire_logic_bus; // you can also declare it this way
reg [15:0] my_reg_bus;              // implicitly means "reg logic[15:0] my_reg_bus" 
//reg logic [15:0] my_reg_bus;        // but if you declare it fully, VCS 2014.10 doesn't like it

There is a new way to declare variables, beginning with the keyword var. If the data type (2-state or 4-state) is not specified, then it is implicitly declared as logic. Below are some variable declaration examples. Although some don’t seem to be fully supported by tools.

  // From the SV-2012 LRM Section 6.8
  var byte my_byte;    // byte is 2-state, so this is a variable
  //  var v;           // implicitly means "var logic v;", but VCS 2014.10 doesn't like this
  var logic v;         // this is okay
  //  var [15:0] vw;   // implicitly means "var logic [15:0] vw;", but VCS 2014.10 doesn't like this
  var logic [15:0] vw; // this is okay
  var enum bit {clear, error} status; // variable of enumerated type
  var reg r;                          // variable reg

Don’t worry too much about the var keyword. It was added for language preciseness (it’s what happens as a language evolves and language gurus strive to maintain backward-compatibility), and you’ll likely not see it in an RTL design.

I’m confused… Just tell me how I should use SystemVerilog logic!

After all that technical specification gobbledygook, I have good news if you’re using SystemVerilog for RTL design. For everyday usage in RTL design, you can pretty much forget all of that!

The SystemVerilog logic keyword standalone will declare a variable, but the rules have been rewritten such that you can pretty much use a variable everywhere in RTL design. Hence, you see in my example code from other articles, I use SystemVerilog logic to declare variables and ports.

module my_systemverilog_module
(
  input  logic       clk,
  input  logic       rst_n,
  input  logic       data_in_valid,
  input  logic [7:0] data_in_bus,
  output logic       data_out_valid, // driven by always_ff, it is a variable
  output logic [7:0] data_out_bus,   // driven by always_comb, it is a variable
  output logic       data_out_err    // also a variable, driven by continuous assignment (allowed in SV)
);

  assign data_out_err = 1'b1; // continuous assignment to a variable (allowed in SV)
//  always_comb data_out_err = 1'b0; // multiple drivers to variable not allowed, get compile time error

  always_comb data_out_bus = <data_out_bus logic expression>;
  always_ff @(posedge clk, negedge rst_n)
    if (!rst_n)
      data_out_valid <= 1'b0;
    else
      data_out_valid <= <data_out_valid logic expression>;
  
endmodule

When you use SystemVerilog logic standalone this way, there is another advantage of improved checking for unintended multiple drivers. Multiple assignments, or mixing continuous and procedural (always block) assignments, to a SystemVerilog variable is an error, which means you will most likely see a compile time error. Mixing and multiple assignments is allowed for a net. So if you really want a multiply-driven net you will need to declare it a wire.

In Verilog it was legal to have an assignment to a module output port (declared as Verilog wire or Verilog reg) from outside the module, or to have an assignment inside the module to a net declared as an input port. Both of these are frequently unintended wiring mistakes, causing contention. With SystemVerilog, an output port declared as SystemVerilog logic variable prohibits multiple drivers, and an assignment to an input port declared as SystemVerilog logic variable is also illegal. So if you make this kind of wiring mistake, you will likely again get a compile time error.

SystemVerilog rule of thumb 1: if using SystemVerilog for RTL design, use SystemVerilog logic to declare:

  • All point-to-point nets. If you specifically need a multi-driver net, then use one of the traditional net types like wire
  • All variables (logic driven by always blocks)
  • All input ports
  • All output ports

If you follow this rule, you can pretty much forget about the differences between Verilog reg and Verilog wire! (well, most of the time)

Conclusion

When I first wondered why it was possible to always write RTL using SystemVerilog logic keyword, I never expected it to become a major undertaking that involved reading and interpreting two different specifications, understanding complex language rules, and figuring out their nuances. At least I can say that the recommendations are easy to remember.

I hope this article gives you a good summary of Verilog reg, Verilog wire, SystemVerilog logic, their history, and a useful set of recommendations for RTL coding. I do not claim to be a Verilog or SystemVerilog language expert, so please do correct me if you felt I misinterpreted anything in the specifications.

References

Sample Source Code

The accompanying source code for this article is a SystemVerilog design and testbench toy example that demonstrates the difference between using Verilog reg, Verilog wire, and SystemVerilog logic to code design modules. Download the code to see how it works!

[lab_subscriber_download_form download_id=8].

The post Verilog reg, Verilog wire, SystemVerilog logic. What’s the difference? appeared first on Verilog Pro.

]]>
https://www.verilogpro.com/verilog-reg-verilog-wire-systemverilog-logic/feed/ 16 499
SystemVerilog Struct and Union – for Designers too https://www.verilogpro.com/systemverilog-structures-unions-design/ https://www.verilogpro.com/systemverilog-structures-unions-design/#comments Tue, 17 Jan 2017 18:00:28 +0000 http://www.verilogpro.com/?p=455 SystemVerilog struct (ure) and union are very similar to their C programming counterparts, so you may already have a good idea of how they work. But have you tried using them in your RTL design? When used effectively, they can simplify your code and save a lot of typing. Recently, I tried incorporating SystemVerilog struct ... Read more

The post SystemVerilog Struct and Union – for Designers too appeared first on Verilog Pro.

]]>
SystemVerilog struct (ure) and union are very similar to their C programming counterparts, so you may already have a good idea of how they work. But have you tried using them in your RTL design? When used effectively, they can simplify your code and save a lot of typing. Recently, I tried incorporating SystemVerilog struct and union in new ways that I had not done before with surprisingly (or not surprisingly?) good effect. In this post I would like to share with you some tips on how you can also use them in your RTL design.

What is a SystemVerilog Struct (ure)?

A SystemVerilog struct is a way to group several data types. The entire group can be referenced as a whole, or the individual data type can be referenced by name. It is handy in RTL coding when you have a collection of signals you need to pass around the design together, but want to retain the readability and accessibility of each separate signal.

When used in RTL code, a packed SystemVerilog struct is the most useful. A packed struct is treated as a single vector, and each data type in the structure is represented as a bit field. The entire structure is then packed together in memory without gaps. Only packed data types and integer data types are allowed in a packed struct. Because it is defined as a vector, the entire structure can also be used as a whole with arithmetic and logical operators.

An unpacked SystemVerilog struct, on the other hand, does not define a packing of the data types. It is tool-dependent how the structure is packed in memory. Unpacked struct probably will not synthesize by your synthesis tool, so I would avoid it in RTL code. It is, however, the default mode of a structure if the packed keyword is not used when defining the structure.

SystemVerilog struct is often defined with the typedef keyword to give the structure type a name so it can be more easily reused across multiple files. Here is an example:

typedef enum logic[15:0]
{
  ADD = 16'h0000,
  SUB = 16'h0001
} my_opcode_t;

typedef enum logic[15:0]
{
  REG = 16'h0000,
  MEM = 16'h0001
} my_dest_t;

typedef struct packed
{
  my_opcode_t  opcode; // 16-bit opcode, enumerated type
  my_dest_t    dest; // 16-bit destination, enumerated type
  logic [15:0] opA;
  logic [15:0] opB;
} my_opcode_struct_t;

my_opcode_struct_t cmd1;

initial begin
  // Access fields by name
  cmd1.opcode <= ADD;
  cmd1.dest <= REG;
  cmd1.opA <= 16'h0001;
  cmd1.opB <= 16'h0002;

  // Access fields by bit position
  cmd1[63:48] <= 16'h0000
  cmd1[47:32] <= 16'h0000;
  cmd1[31:16] <= 16'h0003;
  cmd1[15: 0] <= 16'h0004;

  // Assign fields at once
  cmd1 <= '{SUB, REG, 16'h0005, 16'h0006};
end

What is a SystemVerilog Union?

A SystemVerilog union allows a single piece of storage to be represented different ways using different named member types. Because there is only a single storage, only one of the data types can be used at a time. Unions can also be packed and unpacked similarly to structures. Only packed data types and integer data types can be used in packed union. All members of a packed (and untagged, which I’ll get to later) union must be the same size. Like packed structures, packed union can be used as a whole with arithmetic and logical operators, and bit fields can be extracted like from a packed array.

A tagged union is a type-checked union. That means you can no longer write to the union using one member type, and read it back using another. Tagged union enforces type checking by inserting additional bits into the union to store how the union was initially accessed. Due to the added bits, and inability to freely refer to the same storage using different union members, I think this makes it less useful in RTL coding.

Take a look at the following example, where I expand the earlier SystemVerilog struct into a union to provide a different way to access that same piece of data.

typedef union packed
{
  my_opcode_struct_t opcode_s; // "fields view" to the struct
  logic[1:0][31:0] dword; // "dword view" to the struct
} my_opcode_union_t;

my_opcode_union_t cmd2;

initial begin
  // Access opcode_s struct fields within the union
  cmd2.opcode_s.opcode = ADD;
  cmd2.opcode_s.dest = REG;
  cmd2.opcode_s.opA = 16'h0001;
  cmd2.opcode_s.opB = 16'h0002;

  // Access dwords struct fields within the union
  cmd2.dword[1] = 32'h0001_0001; // opcode=SUB, dest=MEM
  cmd2.dword[0] = 32'h0007_0008; // opA=7, opB=8
end

Ways to Use SystemVerilog Struct in a Design

There are many ways to incorporate SystemVerilog struct into your RTL code. Here are some common usages.

Encapsulate Fields of a Complex Type

One of the simplest uses of a structure is to encapsulate signals that are commonly used together into a single unit that can be passed around the design more easily, like the opcode structure example above. It both simplifies the RTL code and makes it more readable. Simulators like Synopsys VCS will display the fields of a structure separately on a waveform, making the structure easily readable.

If you need to use the same structure in multiple modules, a tip is to put the definition of the structure (defined using typedef) into a SystemVerilog package, then import the package into each RTL module that requires the definition. This way you will only need to define the structure once.

SystemVerilog Struct as a Module Port

A module port can have a SystemVerilog struct type, which makes it easy to pass the same bundle of signals into and out of multiple modules, and keep the same encapsulation throughout a design. For example a wide command bus between two modules with multiple fields can be grouped into a structure to simplify the RTL code, and to avoid having to manually decode the bits of the command bus when viewing it on a waveform (a major frustration!).

Using SystemVerilog Struct with Parameterized Data Type

A structure can be used effectively with modules that support parameterized data type. For example if a FIFO module supports parameterized data type, the entire structure can be passed into the FIFO with no further modification to the FIFO code.

module simple_fifo
(
  parameter type DTYPE = logic[7:0],
  parameter      DEPTH = 4
)
(
  input  logic                      clk,
  input  logic                      rst_n,
  input  logic                      push,
  input  logic                      pop,
  input  DTYPE                      data_in,
  output logic[$clog2(DEPTH+1)-1:0] count,
  output DTYPE                      data_out
);
  // rest of FIFO design
endmodule

module testbench;
  parameter MY_DEPTH = 4;

  logic clk, rst_n, push, pop, full, empty;
  logic [$clog2(MY_DEPTH+1)-1:0] count;
  my_opcode_struct_t data_in, data_out;

  simple_fifo
  #(
    .DTYPE (my_opcode_struct_t),
    .DEPTH (MY_DEPTH)
  )
  my_simple_fifo (.*);
endmodule

Ways to Use SystemVerilog Union in a Design

Until very recently, I had not found a useful way to use a SystemVerilog union in RTL code. But I finally did in my last project! The best way to think about a SystemVerilog union is that it can give you alternative views of a common data structure. The packed union opcode example above has a “fields view” and a “dword view”, which can be referred to in different parts of a design depending on which is more convenient. For example, if the opcode needs to be buffered in a 64-bit buffer comprised of two 32-bit wide memories, then you can assign one dword from the “dword view” as the input to each memory, like this:

my_opcode_union_t my_opcode_in, my_opcode_out;

// Toy code to assign some values into the union
always_comb begin
  my_opcode_in.opcode_s.opcode = ADD;
  my_opcode_in.opcode_s.dest   = REG;
  my_opcode_in.opcode_s.opA    = 16'h0001;
  my_opcode_in.opcode_s.opB    = 16'h0002;
end

// Use the "dword view" of the union in a generate loop
generate
  genvar gi;
  for (gi=0; gi<2; gi=gi+1) begin : gen_mem
    // instantiate a 32-bit memory
    mem_32 u_mem
    (
      .D (my_opcode_in.dword[gi]),
      .Q (my_opcode_out.dword[gi]),
      .*
    );
  end // gen_mem
endgenerate

In my last project, I used a union this way to store a wide SystemVerilog struct into multiple 39-bit memories in parallel (32-bit data plus 7-bit SECDED encoding). The memories were divided this way such that each 32-bit dword can be individually protected by SECDED encoding so it is individually accessible by a CPU. I used a “dword view” of the union in a generate loop to feed the data into the SECDED encoders and memories. It eliminated alot of copying and pasting, and made the code much more concise!

Conclusion

SystemVerilog struct and union are handy constructs that can encapsulate data types and simplify your RTL code. They are most effective when the structure or union types can be used throughout a design, including as module ports, and with modules that support parameterized data types.

Do you have another novel way of using SystemVerilog struct and union? Leave a comment below!

References

[lab_subscriber_download_form download_id=6].

The post SystemVerilog Struct and Union – for Designers too appeared first on Verilog Pro.

]]>
https://www.verilogpro.com/systemverilog-structures-unions-design/feed/ 4 455
Dual-Clock Asynchronous FIFO in SystemVerilog https://www.verilogpro.com/asynchronous-fifo-design/ https://www.verilogpro.com/asynchronous-fifo-design/#comments Mon, 07 Dec 2015 18:00:34 +0000 http://www.verilogpro.com/?p=199 Apology for the lack of updates, but I have been on a rather long vacation to Asia and am slowly getting back into the rhythm of work and blogging. One of my first tasks after returning to work was to check over the RTL of an asynchronous FIFO in Verilog. What better way to relearn ... Read more

The post Dual-Clock Asynchronous FIFO in SystemVerilog appeared first on Verilog Pro.

]]>