SystemVerilog Queue Randomization

Randomize Queue SystemVerilog

In most of the queue use cases, queue is used as buffer or temporary storage. so there wont be much need to randomize queue.

randomize queue size

In below example, queue size will get randomized based on size constraint, and queue elements will get random values

  1. Declare queue with rand
  2. On randomization queue will get random values
class queue_rand;
  rand bit [7:0] qu[$];
  
  constraint size_c  { qu.size() inside {[4:10]}; }
  
  function void display();
    $display("qu size is = %0d",qu.size());
    $display("qu = %p",qu);
  endfunction
endclass

program queue_randomization;
  queue_rand pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end
endprogram 

Simulator Output

qu size is = 7
qu = '{'h88, 'h9b, 'h9a, 'h10, 'h5f, 'hde, 'h84}

Click to execute on   

Introduction

Before moving to SystemVerilog concepts, we will look into what is Verification?  What is verified? Why do we need to verify it? How to Verify?

We need to verify the design to make sure that the design is an accurate representation of the specification without any bugs. Verification is carried out to ensure the correctness of design, to avoid surprises at a later time, to avoid a re-spin of the chip and to enter the market on time with good quality.

In the process of verification, we are going to verify modules, SOC’s (System On Chip) by driving the input to check the design behavior. we should check the behavior of the design by driving correct and an error input, in both cases need to observe the design as it is behaving as expected, if not then there will be a bug.
In verification, we use the Testbench/Verification environment to determine the correctness of the design under test (DUT).

below is the functionality of the Testbench/Verification environment,

  • Generate stimulus
  • Apply stimulus to the DUT
  • Capture the response
  • Check for the correctness
  • Measure progress against the overall verification goals
Asic Verification
Asic Verification

SystemVerilog concepts and methods are explained in the upcoming chapters. The content herein the SystemVerilog tutorial is just for quick reference, for more detailed explanation refer to SystemVerilog LRM.

an added advantage of referring Verification Guide SystemVerilog tutorial is,

  • 100+ easy understanding, compilation error-free example codes.
  • While going through the tutorial no need to copy example code to your simulator, Just One Click for the execution of example codes. All the example codes are saved in the EDA playground.

Thanks to doulos for providing the free access and an option to share the codes on eda (EDA playground).

❮ Previous Next ❯

How to Clear SystemVerilog queue

delete all the entries of queue systemverilog

Calling queue.delete() method will delete the complete queue, which leads to deletion of all the entries of queue.

queue delete method

module qu_delete;
  //queue declaration
  int qu[$];  
  
  initial begin

    qu.push_back(2);
    qu.push_back(13);
    qu.push_back(5);
    qu.push_back(65);
    
    $display("[Before-Delete] Queue size is %0d",qu.size());
    qu.delete();
    $display("[After -Delete] Queue size is %0d",qu.size());    
    
  end
endmodule

Simulator Output

[Before-Delete] Queue size is 4
[After -Delete] Queue size is 0

Click to execute on   

Randomize Unique Elements

Generate Unique Random Values SystemVerilog

In SystemVerilog below is one of the method,

  • to generate unique values to set of variables or
  • unique elements to an array

This can be achieved using Unique constraint.

Unique constraint can be used to generate unique values across the variables, generate unique elements in an array (Fixed Size Array, Dynamic Array, Associative array and Queue) .

In below example the variables (var_1, var_2 and var_3) are constrained using keyword unique, On randomization which leads to generation of unique values to the variables.
Same way to an array (array), random unique elements can be generated by constraining array with unique keyword.

class unique_elements;
  rand bit [3:0] var_1,var_2,var_3;
  rand bit [7:0] array[6];
  
  constraint array_c {unique {array};}
  
  function void display();
    $display("var_1 = %p",var_1);
    $display("var_2 = %p",var_2);
    $display("var_3 = %p",var_3);
    $display("array = %p",array);
  endfunction
endclass

program unique_elements_randomization;
  unique_elements pkt;

  initial begin
    pkt = new();
    pkt.randomize();
    pkt.display();   
  end
endprogram

Simulator Output

var_1 =  8
var_2 = 14
var_3 = 11
array = '{'h81, 'h7b, 'h4, 'h47, 'he1, 'h17}

Click to execute on   

How to display System time in SystemVerilog

module test;
  
  function string get_time();
    int    file_pointer;
    
    //Stores time and date to file sys_time
    void'($system("date +%X--%x > sys_time"));
    //Open the file sys_time with read access
    file_pointer = $fopen("sys_time","r");
    //assin the value from file to variable
    void'($fscanf(file_pointer,"%s",get_time));
    //close the file
    $fclose(file_pointer);
    void'($system("rm sys_time"));
  endfunction
  
  initial begin
    $display("Current System Time is %s",get_time());
  end
endmodule

Simulator Output

Current System Time is 14:39:06--04/25/17

Click to execute on   

How to use UVM try_next_item ?

get_next_item(); 
This method blocks until a REQ sequence_item is available in the sequencer.

    seq_item_port.get_next_item(req);
    req.print();
    drive(req); //drive logic
    seq_item_port.item_done();

try_next_item(); 
This is a non-blocking variant of the get_next_item() method. It will return a null pointer if there is no REQ sequence_item available in the sequencer.

Porting the above code to use try_next_item():

    seq_item_port.try_next_item(req);
    req.print();
    drive(req); //drive logic
    seq_item_port.item_done();

If seq_item is not available on the exection of try_next_item, it returns null; So on execution of req.print(); simulator will give a NULL pointer dereference error.

Best practice to use try_next_item();

    seq_item_port.try_next_item(req);
    if(req != null) begin
      req.print();
      drive(req); //drive logic
      seq_item_port.item_done();
    end   

Example on Using try_next_item();

Below is one of the scenario where i come acroos the real use case of try_next_item();
In this Sequence item consists of multiple pkt’s to be driven,

  class pkt_type;
    rand int pkt_id;
    ...
    ...
  endclass



  class seq_item extends uvm_seq_item;
    ...
    rand pkt_type pkt[];
    ...
    ...
  endclass



Here pkt is dynamic array, it can be 1 to ‘n’ number. On every randomization all the 1 to n pkt’s will get same pkt_id;
As per the design implementation (DUT), the next pkt of same pkt_id can be driven only after getting the completion for previously driven pkt with same pkt_id. and its allowed to drive the pkt with different pkt_id. (Getting the completion for the pkt may take some time, so it is allowed to drive other pkt’s)

Below is one of the way to implement the same,

  while(1) begin
    if(comp_q.size()>0) begin   //comp_q => completions are sampled and corresponding pkt_id is pushed to comp_q
      tmp = comp_q.pop_front();   
      drive_pkt(tmp_pkt[tmp]);  //next pkt with the pkt_id will be driven
      ...
      ...
    end
    else begin
      seq_item_port.try_next_item(req);
      if(req!=null) begin
        drive_pkt(req);
        if(req.pkt.size()>1) tmp_pkt[req.pkt.pkt_id] = req; //req with multiple pkt's are stored for further processing
        seq_item_port.item_done();
      end
    end
    end