How to Run SystemC code in EDA playground

How to Run SystemC programs using EDA play ground

Examples are already present for easy understanding  SystemC Examples

For example lets consider SystemC  counter example,

Below steps to Run the program:
1. Make below settings
Ø Testbench + Design C++/SystemC
Ø Libraries Systemc 2.3.1
Ø Tools and Simulators C++
2. Write Testbench code in testbench.cpp
3. Write Source code in design.cpp
4. Run the program
5. You can view the result in log window
6. If you want to view the waveform

Tick Open EPWave after run
*waveform window appears after the run automatically

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