Featured post

Top 5 books to refer for a VHDL beginner

VHDL (VHSIC-HDL, Very High-Speed Integrated Circuit Hardware Description Language) is a hardware description language used in electronic des...

Showing posts with label SystemVerilog Tutorial. Show all posts
Showing posts with label SystemVerilog Tutorial. Show all posts

Saturday, 19 November 2016

Transaction Recording In Verilog Or System Verilog

As there is not yet a standard for transaction recording in Verilog or VHDL, ModelSim includes a set of system tasks to perform transaction recording into a WLF file. Transaction modeling allows users to raise the level of description, analysis and debugging of their designs to the transaction level. A transaction represents a transfer of high-level data or control information between the test bench and the design under test (DUT) over an interface or any sequence of signal transitions recorded in the simulation database as a transaction.


The API is the same for Verilog and SystemVerilog. As stated previously, the name "Verilog" refers both to Verilog and SystemVerilog unless otherwise noted.
The recording APIs for Verilog and VHDL are a bit simpler than the SCV API. Specifically, in Verilog and VHDL:
  • There is no database object as there is in SCV; the database is always WLF format (a .wlf file).
  • There is no concept of begin and end attributes All attributes are recorded with the system task $add_attribute() or add_attribute.

  • Your design code must free the transaction handle once the transaction is complete and all use of the handle for relations or attribute recording is complete. (In most cases, SystemC designs ignore this step since SCV frees the handle automatically.)
A transaction has a begin time, an end time, and attributes. Examples of transactions include read operations, write operations, and packet transmissions. The transaction level is the level at which many users think about the design, so it is the level at which you can verify the design most effectively.

Transactions are recorded on a stream. A stream is a collection of transactions, recorded over time. A stream has a name, and usually exists somewhere within the test bench hierarchy – for example a driver might have a stream which represents all the transactions that have occurred on that driver. Each driver defines a collection of attributes ( transaction items ) which are defined by users, and which are meaningful to the transaction. The values of attributes are set for each transaction. Finally, transactions can be linked to each other. A link has a direction and a user-defined name, and specifies a relation between the two transactions.


module top;
    integer stream, tr;
    initial begin
        stream = $create_transaction_stream("Stream");
        #10;
        tr = $begin_transaction(stream, "Tran1");
        $add_attribute(tr, 10, "beg");
        $add_attribute(tr, 12, "special");
        $add_attribute(tr, 14, "end");
        #4;
        $end_transaction(tr);
        $free_transaction(tr);
    end

endmodule

Here,

1. $create_transaction_stream() is used to define a transaction stream. You can use this system task to create one or more stream objects.

 module top;
        integer hStream

        initial begin
            hStream = $create_transaction_stream("stream", "transaction");
            .
            .
        end
        .
        .
    endmodule

2. $begin_transaction is used to start a transaction by providing a valid handle of the transaction as shown below.


integer hTrans;
.
.
 hTrans = $begin_transaction(hstream, "READ");


In this example, we begin a transaction named "READ" on the stream already created. The $begin_transaction system function accepts other parameters to specify: the start time for the transaction, and any relationship information, including its designation as a phase transaction.
The return value is the handle for the transaction. It is needed to end the transaction or record attribute.

3. $end_transaction has a single required argument – the handle of the transaction that is to be ended. It also has a single optional argument, the time in the past that this transaction ended. After a transaction has been ended, the transaction handle can still be used to add attributes and create relations.

$end_transaction( handle transaction [, time endTime])

4. $free_transaction has a single argument – the handle of the transaction to be deleted. Once a transaction is deleted the handle becomes invalid. It cannot be used in any other recording interfaces.

$free_transaction (handle transaction)

5. $add_attribute has two required arguments – a transaction handle on which the attribute is to be created and the attribute that is to be recorded. There is one optional argument of type string named attributeName. This attributeName specifies an alias name for the attribute. If not specified, the name used for the attribute is the actual name of the SystemVerilog object.

$add_attribute( handle transaction,  object attributeValue  [, string attributeName])

6. $add_relation has three arguments – the first two are the two transaction handles which are related. The third argument is the string name of the relation.

$add_relation( handle sourceTransaction,  handle targetTransaction,  string relationshipName)

Sunday, 1 March 2015

SystemVerilog Associative Arrays

In previous post we learn in detail about SystemVerilog Dynamic arrays which is useful for dealing with contiguous collections of variables whose number changes dynamically. Now consider if the size of array is unknown then how much size will you allocate to array?

An Associative array is one to use when the size of the collection is unknown or the data space is sparse. So the associative arrays are mainly used to model the sparse memories. In the associative arrays the storage is allocated only when we use it not initially like in dynamic arrays. Associative arrays can be assigned only to another Associative array of a compatible type and with the same index type.

Another main difference between Associative array and normal arrays is in that in assoc arrays the arrays index can be any scalar value. 

Properties of Associative arrays:
  • Dynamically allocated, non-contiguous elements
  • Accessed with integer, or string index, single dimension
  • Great for sparse arrays with wide ranging index
  • Array functions: exists, first, last, next, prev
Declaration Syntax:

data_type array_name [ index_type ];

Where,
data_type : data type of the array element. This can be any type that is allowed for Fixed Arrays
array_name : name of the array being declared.
index_type : data type to be used as index

Example : Associative array declaration

int array_name[*];//Wildcard index. can be indexed by any integral datatype.
int array_name [string];// String index
int array_name [some_Class];// Class index
int array_name [integer];// Integer index
typedef bit signed [4:1] Nibble;
int array_name [Nibble]; // Signed packed array

Accessing the Associative arrays
SystemVerilog provides various in-built methods to access, analyze and manipulate the associative arrays.
  • num() or size() returns the number of entries in the associative arrays.
  • delete() removes the entry from specified index.
  • exist() checks weather an element exists at specified index of the given associative array.
  • first() assigns to the given index variable the value of the smallest/first index in the associative array. Returns 0 if array is empty; else returns 1.
  • last() assigns to the given index variable the value of the largest/last index in the associative array. Returns 0 if array is empty; else returns 1.
  • next() finds the entry whose index is greater than the given index. If next entry exists then the index variable is assigned to the index of next entry and returns 1. Otherwise the index is unchanged and the function returns 0.
  • previous() finds the entry whose index is smaller than the given index. If previous entry exists then the index variable is assigned to the index of previous entry and returns 1. Otherwise the index is unchanged and the function returns 0.

Example : Associative Arrays in-built methods

// SystemVerilog Associative arrays
module associative_array ();
 
 integer associative_array [integer];
 
 integer i;
 
 initial begin
   // Add element array
   associative_array[100] = 101;
   $display ("value stored in 100 is %d", associative_array[100]);
   associative_array[1]   = 100;
   $display ("value stored in 1   is %d", associative_array[1]);
   associative_array[50]   = 99;
   $display ("value stored in 50  is %d", associative_array[50]);
   associative_array[250] = 22;
   $display ("value stored in 250 is %d", associative_array[250]);
   // Print the size of array
   $display ("size of array is %d", associative_array.num());
   // Check if index 2 exists
   $display ("index 2 exists   %d", associative_array.exists(2));
   // Check if index 100 exists
   $display ("index 100 exists %d", associative_array.exists(100));
   // Value stored in first index
   if (associative_array.first(i)) begin
     $display ("value at first index %d value %d", i, associative_array[i]);
   end
   // Value stored in last index
   if (associative_array.last(i)) begin
     $display ("value at last index  %d value %d", i,  associative_array[i]);
   end
   // Delete the first index
   associative_array.delete(100);
   $display ("Deleted index 100");
   // Value stored in first index
   if (associative_array.first(i)) begin
     $display ("value at first index %d value %d", i, associative_array[i]);
   end
    #1  $finish;
 end
 
 endmodule

Simulation Result:
value stored in 100 is 101
value stored in 1 is 100
value stored in 50 is 99
value stored in 250 is 22
size of array is 4
index 2 exists 0
index 100 exists 1
value at first index 1 value 100
value at last index 250 value 22
Deleted index 100
value at first index 1 value 100

Try simulation yourself here

Now as you know that we can use any data type as index of associative arrays, below are the things to keep in mind while using different index datatypes.

1. Integer or int index : While using integer in associative arrays, following rules need to be kept in mind.

  • A 4-state index containing X or Z is invalid.
  • Indices smaller than integer are sign extended to 32 bits.
  • The ordering is signed numerical.
  • Indices can be any integral expression.
  • Indices are signed.
  • Example: int array_name [ integer ];

2. String index : While using string in associative arrays, following rules need to be kept in mind.

  • An empty string "" index is valid.
  • The ordering is lexicographical (lesser to greater).
  • Indices can be strings or string literals of any length.
  • Example: int array_name [ string ];

3. Class index : While using class in associative arrays, following rules need to be kept in mind.
  • A null index is valid.
  • The ordering is deterministic but arbitrary.
  • Indices can be objects of that particular type or derived from that type.
  • Example: int array_name [ some_Class ];

4. Wild Character index : While using wild characters in associative arrays, following rules need to be kept in mind.
  • A 4-state Index containing X or Z is invalid.
  • Indices are unsigned.
  • Indexing expressions are self-determined; signed indices are not sign extended.
  • The ordering is numerical (smallest to largest).
  • A string literal index is auto-cast to a bit-vector of equivalent size.
  • The array can be indexed by any integral data type.
  • Example: int array_name [*];

Friday, 30 January 2015

SystemVerilog Linked Lists

Linked lists and arrays are similar since they both store collections of data. The terminology is that arrays and linked lists store "elements" on behalf of "client" code. The specific type of element is not important since essentially the same structure works to store elements of any type. One way to think about linked lists is to look at how arrays work and think about alternate approaches.

The List package implements a classic list data-structure, and is analogous to the STL (Standard Template Library) List container that is popular with C++ programmers. The container is defined as a parametrized class, meaning that it can be customized to hold data of any type. The List package supports lists of any arbitrary predefined type, such as integer, string, or class object. First declare the Linked list type and then take instances of it. SystemVerilog has many methods to operate on these instances. 

A double linked list is a chain of data structures called nodes. Each node has 3 members, one points to the next item or points to a null value if it is last node, one points to the previous item or points to a null value if it is first node and other has the data. 

Difference between Queue and Linked list:

A queue can pretty much do anything a linked listed can do, and more efficiently. The only case where a linked list might be more efficient is when you need to join two lists together, or insert one list in the middle of another list. A queue is very efficient for adding one element at a time.

Previous : SystemVerilog Queue
Next :

Thursday, 29 January 2015

SystemVerilog Queue

Queue is a variable size, ordered collection of homogeneous elements which can grow and shrink. The size of a queue is variable similar to a dynamic array, but a queue may be empty with no element and it is still a valid data structure. Queues can be used as LIFO (Last In First Out) Buffer or FIFO (First In First Out) type of buffers.

Syntax:
A queue is declared simply by putting a $ as the size of an array.
integer my_q[$];

You can initialize a queue at the place of its variable declaration:
integer my_q[$] = {1, 3, 5};

You can also set up an upper limit of index for a queue (a bounded queue):
integer my_q[$:127];

Since index of an array can only be non-negative, the maximum number of elements for the queue in the above case is 128 (i.e., 0 through 127).

Each element in the queue is identified by an ordinal number that represents its position within the queue, with 0 representing the first element and $ represents the last element.

Bounded Queues
Size of a queue can be limited by giving the last index (i.e. upper bound) as follows

int queueA[$:99]; // A queue whose maximum size is 100 integers 

These are called bounded queues.It will not have an element whose index is higher than the queue’s declared upper bound. Operators on bounded queue can be applied exactly the same way as unbounded queues, except that, result should fall in the upper bound limit.

The size of the queue is variable similar to dynamic array but queue may be empty with zero element and still its a valid data structure.

Queues and dynamic arrays have the same assignment and argument passing semantics. Also, queues support the same operations that can be performed on unpacked arrays and use the same operators and rules except as defined below:


// SystemVerilog Queue Operations
int q[$] = { 2, 4, 8 }; 
int p[$]; 
int e, pos; 
e = q[0]; // read the first (leftmost) item 
e = q[$]; // read the last (rightmost) item 
q[0] = e; // write the first item 
p = q; // read and write entire queue (copy) 
q = { q, 6 }; // insert '6' at the end (append 6) 
q = { e, q }; // insert 'e' at the beginning (prepend e) 
q = q[1:$]; // delete the first (leftmost) item 
q = q[0:$-1]; // delete the last (rightmost) item 
q = q[1:$-1]; // delete the first and last items 
q = {}; // clear the queue (delete all items) 
q = { q[0:pos-1], e, q[pos,$] }; // insert 'e' at position pos 
q = { q[0:pos], e, q[pos+1,$] }; // insert 'e' after position pos 

Queue Methods:

Queues also provides several built-in methods to access/modify queue. Below we have list down all such methods.
  • The size() method returns the number of items in the queue. If the queue is empty, it returns 0. 
  • The insert() method inserts the given item at the specified index position. 
  • The delete() method deletes the item at the specified index. 
  • The pop_front() method removes and returns the first element of the queue. 
  • The pop_back() method removes and returns the last element of the queue. 
  • The push_front() method inserts the given element at the front of the queue. 
  • The push_back() method inserts the given element at the end of the queue. 

// SystemVerilog Queue Methods
module queue_methods();

// Queue is declated with $ in array size
  integer queue[$] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
integer i;

initial begin
  $display ("Initial elements in the queue");
  print_queue;
  // Insert new element at begin of queue
  queue = {11, queue};
  $display ("new element added using concatenation");
  print_queue;
  // Insert using method at beginning
  queue.push_front(12);
  $display ("new element added using push_front");
  print_queue;
  // Insert using method at end
  queue.push_back(12);
  $display ("new element added using push_back");
  print_queue;
  // Using insert to insert, here 6 is index
  // and 13 is value
  queue.insert(6,13);
  $display ("new element added using insert(index,value)");
  print_queue;
  // get first queue element method at begining
  i = queue.pop_front();
  $display ("element poped using pop_front");
  print_queue;
  // get last queue element method at end
  i = queue.pop_back();
  $display ("element poped using pop_end");
  print_queue;
  // Use delete method to delete element at index 4 in queue
  queue.delete(10);
  $display ("deleted element at index 10");
  print_queue;
  #1 $finish;
end

  // Method to print queue
task print_queue;
  integer i;
  $write("Queue contains ");
  for (i = 0; i < queue.size(); i ++) begin
    $write (" %g", queue[i]);
  end
  $write("\n");
endtask

endmodule

Results:
Initial elements in the queue
Queue contains  0 1 2 3 4 5 6 7 8 9 10
new element added using concatenation
Queue contains  11 0 1 2 3 4 5 6 7 8 9 10
new element added using push_front
Queue contains  12 11 0 1 2 3 4 5 6 7 8 9 10
new element added using push_back
Queue contains  12 11 0 1 2 3 4 5 6 7 8 9 10 12
new element added using insert(index,value)
Queue contains  12 11 0 1 2 3 13 4 5 6 7 8 9 10 12
element poped using pop_front
Queue contains  11 0 1 2 3 13 4 5 6 7 8 9 10 12
element poped using pop_end
Queue contains  11 0 1 2 3 13 4 5 6 7 8 9 10
deleted element at index 10
Queue contains  11 0 1 2 3 13 4 5 6 7 9 10

Try simulation yourself here

Hope you get the idea how to declare and use the SystemVerilog Queues. Next we will learn about Linked lists, array methods and we will compare the array types in SystemVerilog.

Previous : SystemVerilog Associative Arrays
Next : SystemVerilog Linked Lists

Wednesday, 28 January 2015

SystemVerilog Dynamic Arrays

In this SystemVerilog Tutorial so far we have seen basic array type i.e. SystemVerilog Fixed arrays, as its size is set at compile time. 

Now what if you don't know the size of array until run-time? 

You may wish to set the size of array run-time and wish to change the size dynamically during run time. 

For example an IP packet varies length from one packet to other packet. In verilog, for creating such packet, array with maximum packet size is declared and only the number of elements which are require for small packets are used and unused elements are waste of memory. 

SystemVerilog overcomes this problem and provides us dynamic arrays. 

Following are the features of SystemVerilog Dynamic arrays :

1. Size of dynamic array can be set at runtime.
2. Previously set size of the dynamic array can be changed runtime without loosing the previous contents.

Hence, dynamic array is unpacked array whose size can be allocated run time along with the option to resize.

Declaration of SystemVerilog Dynamic Arrays :
Dynamic arrays are declared with empty word subscript [ ].


1
2
3
integer dyn_array_1[];
integer dyn_array_1[];
integer multi_dime_dyn_array[][]; 

Allocating size of Dynamic Array :
As seen above the dynamic array is declared with empty word subscript [ ], which means you do not wish to allocate size at compile time, instead, you specify the size at runtime.

The dynamic arrays used builtin function new[ ] to allocate the storage and initialize the newly allocated array.


// SystemVerilog Dynamic arrays
module dyn_arr;
  int dyn[], d2[];             // Empty dynamic arrays
  initial begin
    dyn = new[5];              // Allocate 5 elements
    foreach (dyn[j]) begin
      dyn[j] = j;              // Initialize the elements
      $display("j = %0d dyn = %0d",j,dyn[j]); 
    end
    $display("Copy the dynamic array");
    
    // Copy a dynamic array
    d2 = dyn;
    $display("dyn[0] = %0d d2[0] = %0d",dyn[0],d2[0]);
    
    $display("Modify contents of copy");
    // Modify the copy
    d2[0] = 5;                 
    $display("dyn[0] = %0d d2[0] = %0d",dyn[0],d2[0]);
    
    $display ("Extend the array length and check previous content");
    // Expand and copy
    dyn = new[20](dyn);
    $display("dyn[4] = %0d", dyn[4]);
    
    $display ("Extend the array length and check previous content");
    // Allocate 100 new integers. Old values will lost
    dyn = new[100];    
    $display ("dyn[4] = %0d", dyn[4]);
    // Delete all elements
    dyn.delete;   
  end
endmodule

Simulation result :
j = 0 dyn = 0
j = 1 dyn = 1
j = 2 dyn = 2
j = 3 dyn = 3
j = 4 dyn = 4
Copy the dynamic array
dyn[0] = 0 d2[0] = 0
Modify contents of copy
dyn[0] = 0 d2[0] = 5
Extend the array length and check previous content
dyn[4] = 4
Extend the array length and check previous content
dyn[4] = 0

Run Simulation

Methods associated with Dynamic arrays :

.size() : Returns the size of dynamic array. We can also use system task $size() method instead of .size() method.

.delete() : SystemVerilog also provides .delete() method clears all the elements yielding an empty array (zero size).


Previous : Fixed Size Arrays
Next : Associative Arrays

Tuesday, 27 January 2015

SystemVerilog Fixed Arrays

Let's talk about most used data type - Arrays. An array is a collection of data elements having the same type. Individual elements are accessed by index using a consecutive range of integers. However there are some type of arrays allows to access individual elements using non consecutive values of any data types. SystemVerilog Arrays offers several flavors of arrays beyond the single-dimension, fixed-size Verilog-1995 arrays. Many enhancement have been made to these classic arrays. Arrays can be classified as
  • Fixed Arrays or Fixed-Sized Arrays (sometimes known as static arrays) whose size cannot be changed once declared. 
  • Dynamic arrays which can be resized run time.

Declaring and initializing fixed-size array
Verilog requires that the low and high array limits must be given in the declaration. Almost all arrays use a low index of 0, so SystemVerilog lets you use the shortcut of just giving the array size, similar to C:

Example 1 : Declaring and using SystemVerilog fixed-sized arrays

int data[0:15];  // 16 ints [0]..[15]
int address[16]; // 16 ints [0]..[15]
address[15] = 1; // Set last array element


You can create multidimensional fixed-size arrays by specifying the dimensions after the variable name. This makes an unpacked array; we will take a look for packed arrays later. The following example creates several two-dimensional arrays of integers, 8 entries by 4, and sets the last entry to 1.

Example 2 : Declaring and using multidimensional fixed-sized array

int array2 [0:7][0:3]; // Verbose declaration
int array3 [8][4];     // Compact declaration
array2[7][3] = 1;      // Set last array element

SystemVerilog stores each element on a longword (32-bit) boundary. So a byte, shortint, and int are all stored in a single longword, while a longint is stored in two longwords. (Simulators frequently store four-state types such as logic and integer in two or more longwords.)

Example 3 : SystemVerilog Unpacked Array Declaration

bit [7:0] unpacked_array[3]; // Unpacked array

Unpacked array declared above is stored as shown below


You can initialize an array using an array literal that is an apostrophe and curly braces. Using this array literal you can set some or all elements at once. Also its easy to replicate values by putting a count before the curly braces. Below we have shown example to initialize the systemverilog fixed arrays

Example 4 : Initialize SystemVerilog Array

int ascend[4] = {0,1,2,3}; // Initialize 4 elements
int decend[5];
int array[2][3] = {{0,1,2}, {3,4,5}};
descend = {4,3,2,1,0}; // Set 5 elements
descend[0:2] = {5,6,7}; // Set first 3 elements
ascend = {4{8}}; // Four values of 8

Basic Array Operations
The most common way to manipulate an array is with a for or foreach loop. In below example the variable "i" is declared local to the for loop. To get the size of array we can use system function $size that returns the size of array. For foreach loop statement, you specify the array name and an index in square brackets and Systemverilog automatically steps through all the elements of the array. The index variable is local to the loop.

Example 5 : Access the arrays using for and foreach loops

// SystemVerilog For and Foreach loop to access arrays
module array_loops;
  initial begin
    bit [31:0] src[5], dst[5];
    for (int i=0; i<$size(src); i++) begin
      src[i] = i;
      $display("src[%0d] = %0d", i, src[i]); 
    end
    foreach (dst[j]) begin
      dst[j] = src[j] * 2; // dst doubles src values
      $display("dst[%0d] = %0d", j, dst[j]); 
    end
  end
endmodule

Simulation Results:
src[0] = 0
src[1] = 1
src[2] = 2
src[3] = 3
src[4] = 4
dst[0] = 0
dst[1] = 2
dst[2] = 4
dst[3] = 6
dst[4] = 8

Now in below example note that for SystemVerilog multidimensional arrays the syntax is not as you might expected. Instead of listing each subscript in separate square brackets – [i][j] – they are combined with a comma – [i,j].

Example 6: SystemVerilog Accessing Multidimensional Arrays using Foreach loop


// SystemVerilog For and Foreach loop to access arrays
module array_loops;
  int md[2][3];
  initial begin
    $display("Initial value:");
    foreach (md[i,j]) // Yes, this is the right syntax
      $display("md[%0d][%0d] = %0d", i, j, md[i][j]);
    $display("New value:");
    md = '{{9, 8, 7}, {default:5}}; // Replicate last 3 values
    foreach (md[i,j]) // Yes, this is the right syntax
      $display("md[%0d][%0d] = %0d", i, j, md[i][j]);
    end
endmodule

Simulation Results:
Initial value:
md[0][0] = 0
md[0][1] = 0
md[0][2] = 0
md[1][0] = 0
md[1][1] = 0
md[1][2] = 0
New value:
md[0][0] = 9
md[0][1] = 8
md[0][2] = 7
md[1][0] = 5
md[1][1] = 5
md[1][2] = 5

Packed arrays :


Before knowing what exactly packed and unpacked arrays are, lets also see how you can know which array is what, just by their declaration. 

Packed arrays have an object name comes before size declaration. 
For example: bit [3][7] a;

As specified previously unpacked array have an object name comes after size declaration. 
For example: bit a[3];

For some data types, you may want both to access the entire value and also divide it into smaller elements. For example, you may have a 32-bit register that sometimes you want to treat as four 8-bit values and at other times as a single, unsigned value. A SystemVerilog packed array is treated as both an array and a single value. Packed arrays can be made of only the single bit data types (bit, logic, reg) and recursively other packed arrays and packed structures. It is stored as a contiguous set of bits with no unused space, unlike an unpacked array.

Packed Array Example 
The packed bit and word dimensions are specified as part of the type, before the variable name. These dimensions must be specified in the [lo:hi] format. The variable bytes is a packed array of four bytes, which are stored in a single longword.


1
bit [3:0] [7:0] bytes; // 4 bytes packed into 32-bits

Packed Array Layout



You can mix packed and unpacked dimensions. You may want to make an array that represents a memory that can be accessed as bits, bytes, or long words. In Example 2-14, barray is an unpacked array of three packed elements.


Declaration of mixed packed and unpacked arrays


1
bit [3:0] [7:0] barray [3]; // Packed: 3x32-bit

The variable bytes is a packed array of four bytes, which are stored in a single longword. barray is an array of three of these elements.


With a single subscript, you get a longword of data, barray[2]. With two subscripts, you get a byte of data, barray[0][3]. With three subscripts, you can access a single bit, barray[0][1][6]. Note that because one dimension is specified after the name, barray[3], that dimension is unpacked, so you always need to use at least one subscript.

Choosing Between Packed and Unpacked Array

Which should you choose — packed or unpacked array?
A packed array is handy if you need to convert to and from scalars. For example, you might need to reference a memory as a byte or as a longword. The above array barray can handle this requirement. Only fixed-size arrays can be packed, not dynamic arrays, associative arrays, or queues.

If you need to wait for a change in an array, you have to use a packed array. Perhaps your testbench might need to wake up when a memory changes value, so you want to use the @ operator. But this is only legal with scalar values and packed arrays. Using the earlier examples, you can block on the variable lw, and barray[0], but not the entire array barray unless you expand it: @(barray[0] or barray[1] or barray[2]).

Previous : Net Type
Next : Dynamic Arrays

Monday, 26 January 2015

SystemVerilog Net Type

In Verilog, Net data types are used to model physical connections. They do not store values (there is only one exception - trireg, which stores a previously assigned value). The net data types have the value of their drivers. If a net variable has no driver, then it has a high-impedance value (z).

Verilog allows you to use nets without defining them, a feature called implicit nets. This shortcut helps net-listing tools and lazy designers, but is guaranteed to cause problems if you ever
misspell a net name in your SystemVerilog code. The solution is to disable this language feature with the Verilog-2001 compile directive: ‘default_nettype none. Put this (without a period) before the first module in your Verilog code. Any implicit net will cause a compilation error.

Previous : SystemVerilog Strings
Next : Fixed Size Array

Sunday, 25 January 2015

SystemVerilog Strings

String data type is used for storing strings, the size is dynamic and string data types come with build in methods. If you have ever tried to use a Verilog reg variable to hold a string of characters, your suffering is over with this post. The SystemVerilog string type holds variable-length strings. String literals are packed arrays of a width that is a multiple of 8 bits which hold ASCII values i.e. an individual character is of type byte. The elements of a string of length N are numbered 0 to N-1. Note that, unlike C, there is no null character at the end of a string, and any attempt to use the character “\0” is ignored.


string StringName = "VLSI Encyclopedia";

Strings use dynamic memory allocation, so you do not have to worry about running out of space to store the string. Example 1 shows various string operations.

Below is the list of string methods :
  • str.len() returns the length of the string, i.e., the number of characters in the string. 
  • str.putc(i, c) replaces the ith character in str with the given integral value. 
  • str.getc(i) returns the ASCII code of the ith character in str. 
  • str.toupper() returns a string with characters in str converted to uppercase. 
  • str.tolower() returns a string with characters in str converted to lowercase. 
  • str.compare(s) compares str and s, and return value. This comparison is case sensitive. 
  • str.icompare(s) compares str and s, and return value .This comparison is case insensitive. 
  • str.substr(i, j) returns a new string that is a substring formed by index i through j of str. 
  • str.atoi() returns the integer corresponding to the ASCII decimal representation in str. 
  • str.atoreal() returns the real number corresponding to the ASCII decimal representation in str. 
  • str.itoa(i) stores the ASCII decimal representation of i into str (inverse of atoi). 
  • str.hextoa(i) stores the ASCII hexadecimal representation of i into str (inverse of atohex). 
  • str.bintoa(i) stores the ASCII binary representation of i into str (inverse of atobin). 
  • str.realtoa(r) stores the ASCII real representation of r into str (inverse of atoreal)

Example 1: SystemVerilog String Methods


// SystemVerilog Strings
module str; 
  string S1; 
  string S2; 
  initial begin 
    S1 = "VLSI "; 
    S2 = "Encyclopedia"; 
    $display(" %d ",S1.len() ); 
    $display(" %s ",S2.getc(5) ); 
    $display(" %s ",S1.tolower); 
    $display(" %s ",S2.toupper); 
    $display(" %d ",S2.compare(S1) ); 
    $display(" %d ",S1.compare("VLSI") ); 
    $display(" %s ",S1.substr(2,3) ); S1 = "111"; 
    $display(" %d ",S1.atoi() ); 
  end 
endmodule 

Simulation Result :

 5
 l
 vlsi
 ENCYCLOPEDIA
 -17
 1
 SI
 111

Pattern Matching of SystemVerilog Strings
In below example we have used a method to match the strings in SystemVerilog.

Example 2 : Pattern matching


// SystemVerilog String Pattern Matching
 
program main; 
  string S1,S2; 
  initial begin 
    S1 = "String matching in SystemVerilog"; 
    S2 = "String"; 
    if(match(S1,S2)) 
      $display(" S2 : %s : found in :%s:",S2,S1); 

    S2 = "SystemVerilog"; 
    if(match(S1,S2)) 
      $display(" S2 : %s : found in :%s:",S2,S1); 

    S2 = "String matching"; 
    if(match(S1,S2)) 
      $display(" S2 : %s : found in :%s:",S2,S1); 

    S2 = "matching in "; 
    if(match(S1,S2)) 
      $display(" S2 : %s : found in :%s:",S2,S1); 

    S2 = "String matching in SystemVerilog"; 
    if(match(S1,S2)) 
      $display(" S2 : %s : found in :%s:",S2,S1); 
  end 
endprogram

function match(string s1,s2); 
  int len1,len2; 
  len1 = s1.len(); 
  len2 = s2.len(); 
  match = 0 ; 
  if( len2 > len1 ) 
    return 0; 
  for(int i = 0;i < len1 - len2 + 1; i ++) 
    if( s1.substr(i,i+len2 -1) == s2) 
  return 1; 
endfunction

Simulation Results:
 S2 : String : found in :String matching in SystemVerilog:
 S2 : SystemVerilog : found in :String matching in SystemVerilog:
 S2 : String matching : found in :String matching in SystemVerilog:
 S2 : matching in  : found in :String matching in SystemVerilog:
 S2 : String matching in SystemVerilog : found in :String matching in SystemVerilog:

SystemVerilog operations
There are variety of operations associated with SystemVerilog strings that you can perform to manipulate the  combination of string variables and string literals. Below are the basic operation that can be performed on strings.

1. Checking equality of two strings : S1 == S2
Checks whether the two strings are equal. Checking equality results 1 if they are equal and 0 if they are unequal. Both strings can be of type string. Or one of them can be a string literal. If both operands are string literals, the operator is the same Verilog equality operator as for integer types.

Example 3 : Checking Equality

// SystemVerilog Strings Equality
module str; 
  string S1 = "VLSI Encyclopedia"; 
  string S2 = "VLSI Encyclopedia";
  string S3 = "vlsi encyclopedia";
  initial begin 
    if(S1 == S2) 
      $display(" S1 and S2 are equal"); 
    else 
      $display(" S1 and S2 are not equal"); 
    if(S1 == S3) 
      $display(" S1 and S3 are equal"); 
    else 
      $display(" S1 and S3 are not equal"); 
  end 
endmodule 

Simulation Results 
S1 and S2 are equal
S1 and S3 are not equal

2. Checking equality of two strings : S1 != S2
Reverse to the equality operation this operation results 0 if two strings are equal and 1 if they are unequal.

Example 4: Checking Inequality

// SystemVerilog Strings Equality
module str; 
  string S1 = "VLSI Encyclopedia"; 
  string S2 = "VLSI Encyclopedia";
  string S3 = "vlsi encyclopedia";
  initial begin 
    if(S1 != S2) 
      $display(" S1 and S2 are not equal"); 
    else 
      $display(" S1 and S2 are equal"); 
    if(S1 != S3) 
      $display(" S1 and S3 are not equal"); 
    else 
      $display(" S1 and S3 are equal"); 
  end 
endmodule 

Simulation Results 
S1 and S2 are equal
S1 and S3 are not equal

3. Concatenation of strings : {S1, S2, S3,...,Sn}
To concatenate two or more strings, specify the string variable inside {} each separated by comma",". Each operand can be of type string or a string literal.

Example 5 : Concatenation


// SystemVerilog Strings Concatenation
module str; 
  string S1, S2, S3, S4, S5; 
  initial begin 
    S1 = "Con"; 
    S2 = "cate"; 
    S3 = ""; 
    S4 = "na"; 
    S5 = "tion"; 
    $display(" %s ",{S1,S2,S3,S4,S5}); 
  end 
endmodule 

Simulation Results
Concatenation

4. Replication of Strings : {N{S1}}
The result of replication is a string containing N concatenated copies of S1. N is the multiplier ans S1 can be of string type or string literal.

Example 6 : Replication

// SystemVerilog Strings Replication
module str; 
  string S1, S2; 
  initial begin 
    S1 = "w"; 
    S2 = ".vlsiencyclopedia.com"; 
    $display(" %s ",{{3{S1}},S2}); 
  end 
endmodule 

Simulation Results :
www.vlsiencyclopedia.com

5. String Indexing : S1[Index]
It returns a byte, an ASCII code at the given Index. Index can range from 0 to N where N is the number of characters in the string. If the Index is out of range then result will be 0.

Example 7 : Indexing

// SystemVerilog Strings Indexing
module str; 
  initial begin
    string S1; 
   S1 = "Indexing"; 
  for(int i =0 ;i < 8 ; i++) 
    $display("%s ",S1[i]); 
  end 
endmodule 

Simulation Result :
I
n
d
e
x
i
n
g

Previous : SystemVerilog Constants
Next : Net Type