Regarding weighted distribution in system verilog

Hi,

I am in a process of developing an SV based verification env for a generic fifo where in primary functionalities of the VIP shall be to INSERT , UPDATE& DELETE.
i wanted to apply these commands to the DUT by randomly distributing the weights for qhich i have come up with the below implementation in the input generator class of the SV test bench.

class generator;
  
  //declaring transaction class 
  rand transaction trans,tr;
  
  //repeat count, to specify number of items to generate
  // This section has declaration for declaring the other block
  int  repeat_count;
  int insert_wt;
  int delete_wt;
  int update_wt;
  int initial_insert;
  bit [31:0] price [];
  bit [31:0] OrderId[];
  int totalInsert=-1;
  bit[1:0] Opcodes  ;
  rand int randno=0;
  
  //mailbox, to generate and send the packet to driver
  mailbox gen2driv;
  
  //event
  event ended;
  
  //constructor
  function new(mailbox gen2driv,event ended);
    //getting the mailbox handle from env, in order to share the transaction packet between the generator and driver, the same mailbox is shared between both.
    this.gen2driv = gen2driv;
    this.ended    = ended;
    trans = new();
  endfunction
  
  //main task, generates(create and randomizes) the repeat_count number of transaction packets and puts into mailbox
  task main();
  // set the distribution here
  price= new [repeat_count];
  OrderId= new [repeat_count];
  //Opcodes= new [repeat_count];
	// Opcodes = trans.GenerateOpcode(repeat_count,initial_insert,insert_wt,update_wt,delete_wt);
    trans.setdistribution( insert_wt,update_wt,delete_wt);
    trans.displaydistribution();
	for (int i=0;i<repeat_count;i++)
	 begin
	 
     if( !trans.randomize() )
     $fatal("Gen:: trans randomization failed");      
if (i<initial_insert)
		begin
		trans.cmdcode =0; //insert
		 totalInsert=totalInsert+1;
		 price[totalInsert] = trans.ORDER_BOOK.Price;
		 OrderId[totalInsert]=trans.ORDER_BOOK.OrderID;
          $display("Insert initial iteration =%d, order ID =%d, price =%d ",i,trans.ORDER_BOOK.OrderID,trans.ORDER_BOOK.Price);
		end
       else if (i>=initial_insert)
		begin
		Opcodes=trans.cmdcode;
		if(Opcodes==0)
		 begin
		
		 trans.cmdcode =0; //insert
		 totalInsert=totalInsert+1;
		 price[totalInsert] = trans.ORDER_BOOK.Price;
		 OrderId[totalInsert]=trans.ORDER_BOOK.OrderID;
           $display("This is insert command itertion =%d, OrderId=%d, price=%d, ",i,trans.ORDER_BOOK.OrderID,trans.ORDER_BOOK.Price);
		 end
		if(Opcodes==1)
		 begin
		
           $display("This is delete command orderID=%d, iteration =%d ", OrderId[totalInsert],i);
		 // Delete the last element added //LIFO
		 trans.cmdcode =1; //delete
		 trans.ORDER_BOOK.OrderID=OrderId[totalInsert];
		 totalInsert=totalInsert-1;
		 end
		 	if(Opcodes==2)
		 begin
		 randno = $urandom_range(0,totalInsert);
		 trans.cmdcode =2; //update
		 trans.ORDER_BOOK.OrderID=OrderId[randno];
		 trans.newprice = trans.CalNewPrice(price[randno]);
           $display("This is update command orderID =%d, updated price =%d, itr =%d", OrderId[randno],trans.newprice,i);
		 end
		 end
	 tr = trans.do_copy();
	
     gen2driv.put(tr);
    end
    -> ended; 
  endtask
  endclass

After which i am applying weights to these commands from my test case  as shown below


  	`include "environment.sv"
//
program test(mem_intf intf);
  
    environment env;
	transaction my_tr;
  
  initial begin
    //creating environment
    env = new(intf);
    
    my_tr = new();
    
    //setting the repeat count of generator as 4, means to generate 4 packets
    
    
    env.gen.repeat_count = 40;
	env.gen.initial_insert =10;
	// control the distribution of the insert , delete and update
    env.gen.insert_wt=70;
	env.gen.delete_wt=10;
	env.gen.update_wt=50;
   // env.gen.trans.
    env.gen.trans = my_tr;
    
    //calling run of env, it interns calls generator and driver main tasks.
    env.run();
  end
  endprogram

I wanted to understand if there is a much simpler way to implement this… something like i wanted to apply total 10 commands out of which 5 insert , 3 update and 2 delete. I.e. 50% of inserts 30% of updates and 20% deletes

In reply to ArjunNag:
The following code demonstrates the concepts you need.


import uvm_pkg::*; `include "uvm_macros.svh" 
module top; 
	timeunit 1ns;     timeprecision 100ps;  
	enum { INSERT , UPDATE, DELETE}      tr;
	bit clk, a, b;  
	default clocking @(posedge clk); endclocking
	initial forever #10 clk=!clk;  
  
	initial begin 
		repeat(20) begin 
			@(posedge clk);   
			if (!randomize(tr)  with // 50% of inserts 30% of updates and 20% deletes
					{ tr dist {INSERT:=5, UPDATE:=3, DELETE:=2}; 
					}) `uvm_error("MYERR", "This is a randomize error")
			$display("tr= %s", tr); 
		end 
		$stop; 
	end 
endmodule  
// simulation results 
tr= INSERT
# tr= UPDATE
# tr= DELETE
# tr= UPDATE
# tr= UPDATE
# tr= UPDATE
# tr= INSERT
# tr= UPDATE
# tr= INSERT
# tr= INSERT
# tr= DELETE
# tr= DELETE
# tr= UPDATE
# tr= DELETE
# tr= INSERT
# tr= INSERT
# tr= DELETE
# tr= INSERT
# tr= UPDATE
# tr= UPDATE 

More runs are needed to demonstrate those statistics.
With the following changes, I get

 
import uvm_pkg::*; `include "uvm_macros.svh" 
module top; 
	timeunit 1ns;     timeprecision 100ps;  
	enum { INSERT , UPDATE, DELETE}      tr;
	int c_i, c_u, c_d; // counts 
	bit clk, a, b;  
	default clocking @(posedge clk); endclocking
	initial forever #10 clk=!clk;  
  
	initial begin 
		repeat(10000) begin 
			@(posedge clk);   
			if (!randomize(tr)  with //  5 insert , 3 update and 2 delete. 
					{ tr dist {INSERT:=5, UPDATE:=3, DELETE:=2}; 
					}) `uvm_error("MYERR", "This is a randomize error")
			//$display("tr= %s", tr); 
			if(tr==INSERT) c_i += 1; 
			if(tr==UPDATE) c_u += 1;
			if(tr==DELETE) c_d += 1;
		end 
		$display ("c_i=%d, c_u=%d, c_d=%d", c_i, c_u, c_d);
		$stop; 
	end 
endmodule  
// simulation 
c_i=       5021, c_u=       3013, c_d=       1966
// Very close to 50% insert , 30% update and 20% delete

BTW, way too long and complex questions tend not to be answered … my observations.
Thus, keep your questions short and more generic.

Hope this was useful
Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact Home - My cvcblr