HOME

    Electronics Directory Articles/ Tutorials eBooks

About Us

FORUM Links Contact Us
   

SystemVerilog Tutorial PART VI: by Abhiram Rao

SystemVerilog Array Examples

 

     <Previous    Page       Next>

Associative Arrays Example:

This example shows the following System Verilog features:

* Classes

* Associative arrays of class instances

This example shows how handles to class objects work. The example has an associative array of class objects with the index to the array being a string.

When a new class instance is assigned to the array, what is really stored in the array is a handle to the class object (a pointer in C terms). Executing the run.do script will run two simulation. The first simulation will run without calling the "new" class method between each array assignment.

In this run you will notice that the value of each element in the array is the same even though three different values have been assigned. This is correct behavior as all three elements of the array hold the same handle to the class instance. The values you get, are the current values in the class.The second run actually calls the "new" class method between each assignment to the array. By doing this, you create new handles. Each element in the array is a different handle and represents the values in the class instance at that specific time. Notice the results of this run. They are the three different values that were assigned.

 module top; 

    class nam_dat;

        string name;

        int data;

    endclass:nam_dat

    class men_reg;

        // associative array of nam_dat with string index

        nam_dat reg_fields[string];

        task add_field (input nam_dat field);

            reg_fields[field.name] = field;

        endtask:add_field

    endclass:men_reg

    nam_dat field;

    men_reg foo = new;

    string s;

 

    initial begin

        // Create the First field

        field = new;

        field.name = "Verilog";

        field.data = 99;

        //Assign field to dynamic array foo

        foo.add_field(field);

        `ifdef FIELD

            field = new;

        `endif

        // Create the Second Field

        field.name = "Systemverilog";

        field.data = 199;

        foo.add_field(field);

        `ifdef FIELD

            field = new;

        `endif

        // Create the Third Field

        field.name = "VHDL";

        foo.add_field(field);

        if ( foo.reg_fields.first( s ) )

            do

                $display( "%s : %d\n", s, foo.reg_fields[ s ] );

            while (foo.reg_fields.next(s) );

    end

 

endmodule

Dynamic Arrays Example:

This example shows the following SystemVerilog features:

* Classes

* Dynamic arrays of class instances

This example demonstrates how to model a parameterized dynamic 2-dimensional array of classes. The package "DynPkg" contains declarations for several classes. The first class called "CELL" has several random variables and a constraint on those variables. The next class declaration "ROW" creates a dynamic array of the first class "CELL". The third class "FRAME" creates a dynamic array of the class "ROW". The "FRAME" class also includes a parameterized constructor function for sizing the overall dimensions of the array. The important thing to note about calls to "new" in FRAME's "new" function is that some are for initializing the dynamic arrays and others are for constructing the class instances. The first "new" method:

R_Array = new[DEPTH];

creates a dynamic array of size "DEPTH" with each element of "R_Array" being an object handle to a class instance of "ROW". However at this point each of these handles is set to NULL.Since the elements of the dynamic arrays are "classes" they must be constructed with "new" individually. The first "for" loop is used to iterate through each element in the "R_Array". The first "new" method inside that "for" loop constructs each instance of the "ROW" class. The second "new" method is called with "WIDTH" and created a dynamic array of "CELL" class instances call "C_Array".

As with the "R_Array", each handle to the class instance needs to be constructed. Another "for" loop is used to iterate through each element of "C_Array" and call the "new" method. Finally, in the module "top", an instance of "FRAME" is created and the constructor is passed the arguments (3,3) thus creating a 3x3 dynamic array of the class "CELL". The initial block in the top level module then simply calls the built-in randomize function and prints out these random values.

package DynPkg;

 class CELL;

   rand bit [3:0] A, B, C;

   constraint C1 {

           A inside{[0:7]}; // Constrain A & B to avoid

           B inside{[0:7]}; // overflow on C

           C == B + A ;

              }

 endclass

 

 class ROW;

      rand CELL C_Array[]; // dynamic array of CELL

 endclass

 class FRAME;

   rand ROW R_Array[]; // dynamic array of ROW

   function new (int DEPTH, int WIDTH) ;

        R_Array = new[DEPTH]; // initialize ROW array

        for(int i = 0; i < DEPTH; i++)

        begin

              R_Array[i] = new; // construct each ROW inst

              R_Array[i].C_Array = new[WIDTH]; // initialize CELL array

              for(int j = 0; j < WIDTH; j++) 

                   R_Array[i].C_Array[j] = new; // construct each CELL inst

        end

   endfunction

  endclass

endpackage

 

SystemVerilog Dynamic Array of Classes Example - Top level

 

module top;

   import DynPkg::*;

   FRAME FR;

   int result;

   initial

   begin

     // create an instance of dynamic 3x3 array & randomize

     FR = new(3,3);

     result = FR.randomize();

     // print header

     $display(" A B C");

     $display("---------------------------");

     // print out values of array

     for(int i = 0; i < 3; i++)

     begin

       for(int j = 0; j < 3; j++)

       $display("CELL[%0d][%0d] = %b %b %b",i, j,

          FR.R_Array[i].C_Array[j].A, FR.R_Array[i].C_Array[j].B,          FR.R_Array[i].C_Array[j].C);

      $display("");

     end

   end

endmodule

 

Simple SystemVerilog Queue Example - Parameterized 2-state FIFO

This example shows the following SystemVerilog features:

* Queues

* Queue methods

The example is a simple FIFO that is modeled with a SystemVerilog queue. The width and depth of the FIFO are controlled using parameters. Pushing and popping data in and out of the FIFO as well as checking the number of elements in the FIFO is done using queue methods.

The queue is also modeled using SystemVerilog 2-state int and bit types. Where bus contention and net resolution are not a concern, 2-state types can improve performance.

In verification environment, the queues can used for scoreboarding purpose.

`timescale 1ns / 1ns

 module FIFO #(parameter int DEPTH = 31, parameter int WIDTH = 8) (

      input bit [WIDTH-1:0] DATA,

      input bit CLK, RSTb, WENb, RENb,

      output bit FULL, EMPTY,

      output bit [WIDTH-1:0] Q);

      bit [WIDTH-1:0] mem [$:DEPTH];

 

      // FIFO write

      always @(posedge CLK, negedge RSTb)

           if (RSTb == 0)

           mem = '{};

           else if (WENb == 0 && mem.size() < DEPTH)

           mem.push_back(DATA);

           // FIFO read

           always @(posedge CLK)

                if (RENb == 0 && mem.size() > 0)

                Q <= mem.pop_front();

                // FIFO control flags

                assign EMPTY = (mem.size() == 0) ? 1 : 0;

                assign FULL = (mem.size() == DEPTH) ? 1 : 0;

 endmodule

 <Previous    Page       Next>

Home   |    About Us   |   Articles/ Tutorials   |   Downloads   |   Feedback   |   Links   |   eBooks   |   Privacy Policy
Copyright 2005-2007 electroSofts.com.
webmaster@electroSofts.com