How to create the queue array of class from text file

In reply to chr_sue:

Thanks for suggestion.

Could you suggest some pseudo code for the same if possible

In reply to chr_sue:

In reply to rupeshblr:
The solution would look like this:

int fd;
logic [31:0] addr;
logic [31:0] data;
logic [31:0] wmask;
logic [31:0] rmask;
fd = $fopen ("data.txt" , "r");
// $fscanf returns the number of matches, i.e. 4 in your case
while ($fscanf (fd, "%0h %0h %0h %0h", addr, data, wmask, rmask) == 4) begin
// do something
end
$fclose(fd);

But using this file solution is not really smart. There is a solution without using the file.

May i know the solution without using the file ?

is it the same which you have given in the the last post

"But you are wasting your resources in terms of memory space by writing data to queues. This will slowdown your simulation. You should do a on-the-fly checking of your packet data.
You could store your write data in an associative array in the sequence. This allows data to be stored in a non-contigious way. When reading your data you can pass back the read data as a response to your sequence and compare with the data in the assoc. array. "

In reply to rupeshblr:

Could you please show how your sequence (body task) looks like?

In reply to chr_sue:

class svci_master_seq extends svci_base_sequence;

  //Sequence instantiation 
  master_write_cmd_seq	write_seq;
  master_read_cmd_seq	read_seq;
  svci_master_id_pkt	master_id_pkt;
  //int			valid_tag_q[$];
  int		 	j,seq_error_set,valid_tag_q[0:((2**`SVCI_TAG_ID_WIDTH)-1)];

  function new(string name="svci_master_seq");
    super.new(name);
  endfunction

  `uvm_object_utils(svci_master_seq)
  

  virtual task body();
  endtask

  task svci_master_write(bit [31:0] tag='hDEAD,bit [31:0] mid='hDEAD,bit [31:0] addr='hDEAD,
                                 bit [63:0] data='hDEAD,bit [31:0] len='hDEAD,cmd_opc_t opc='hDEAD,
                                 bit [31:0] prty='hDEAD,bit [31:0] delay='hDEAD);

     << Logic >>>
  endtask

  task svci_master_read(bit [31:0] tag='hDEAD,bit [31:0] mid='hDEAD,bit [31:0] addr='hDEAD,bit [31:0] len='hDEAD,cmd_opc_t opc='hDEAD,bit [31:0] prty='hDEAD,bit [31:0] delay='hDEAD);
<<<<logic>>>>>>>>>>>>.     

  endtask

 
endclass : svci_master_seq

class svci_master_reg_seq extends svci_master_seq;

  function new(string name="svci_master_reg_seq");
    super.new(name);
  endfunction

  `uvm_object_utils(svci_master_reg_seq)
  `uvm_declare_p_sequencer(svci_master_sequencer)


  virtual task body();
   reg [63:0] data ;
      for (int i= 0 ; i<= 4; i++)
       begin
         if (i == 0)
         data = 64'hffffffffffffffff;
         else if (i == 1)
         data = 64'hAAAAAAAAAAAAAAAA;
         else if (i == 2)
         data = 64'h5555555555555555;
         else 
         data = 64'h0000000000000000;
  $display ("svci_reg_addr = %h ",`VERSION_ID +`REG_OFFSET );
    svci_master_write(.addr(`VERSION_ID +`REG_OFFSET ), .data(data), .delay('h8), .len('h2), .opc('h2), .mid('h2));
    svci_master_read(.addr(`VERSION_ID +`REG_OFFSET ),  .delay('h8), .len('h2), .opc('h0), .mid('h2));

    $display ("svci_reg_addr = %h ",`IP_FORCE_CG +`REG_OFFSET );
    svci_master_write(.addr(`IP_FORCE_CG +`REG_OFFSET ), .data(data), .delay('h8), .len('h2), .opc('h2), .mid('h2));
    svci_master_read(.addr(`IP_FORCE_CG +`REG_OFFSET ),  .delay('h8), .len('h2), .opc('h0), .mid('h2));

    $display ("svci_reg_addr = %h ",`IP_CG_STATUS +`REG_OFFSET );
    svci_master_write(.addr(`IP_CG_STATUS +`REG_OFFSET ), .data(data), .delay('h8), .len('h2), .opc('h2), .mid('h2));
    svci_master_read(.addr(`IP_CG_STATUS +`REG_OFFSET ),  .delay('h8), .len('h2), .opc('h0), .mid('h2));

  
<<<<<list of all registers>>>>>>>>>>>>>>>

  endtask

endclass : svci_master_reg_seq

In reply to rupeshblr:
What I see is you are writing your registers in a fixed ordder with fixed values, even when running in the i-loop. This results in a low verification quality. You should write and read your registers in random order and writing with random values (if random values are possible).
Are the addresses in series or are there gaps in between?
Nevertheless you can put all your register addresses into an adr queue.
Then you are declaring in the body task an associative array. When wrint to the registers you are passing the write data with the corresponding address into an associative array. The associative array contains then the expected data values. When reading the registers you get the read value from the read task. This is the actual value and you can compare with the entry for the corresponding address from the assoc. array. This is a very simple process and avoids any additional scoreboard.
To write the addresses in random order you are calling on the address queue the shuffle method. For reading the registers you are shuffeling again your address queue reading in another random order.

In reply to chr_sue:
1.Since its SOC level test, I am just checking the walkng 1’s and walking 0’s pattern.
2. Address is in Series Order.

Please provide the pseudo code (template)it will be very helpful. since i am not able to get from above hint.

In reply to rupeshblr:

Please see here. Consider this code as a template.

class my_seq_item extends uvm_sequence_item;
  rand int addr;
  rand logic [63:0]  data;
  rand int   delay;
  rand int   len;
  rand int   opc;
  rand int   mid;

  `uvm_object_utils(my_seq_item)

  function new(string name="my_seq_item");
    super.new(name);
  endfunction

endclass

class svci_master_reg_seq extends svci_master_seq;

int addr_qu[$];                   // address queue
logic [63:0]  expect_mem [int];   // associative array
 
  function new(string name="svci_master_reg_seq");
    super.new(name);
  endfunction
 
  `uvm_object_utils(svci_master_reg_seq)
 // `uvm_declare_p_sequencer(svci_master_sequencer)   // p_sequencer is not a really good idea
 
 
  virtual task body();

     bit [63:0] data;
     my_seq_item item;
     item = my_seq_item::type_id::create("item");

     // fill the addr_queue;
     for (int i = 0; i < no_of_regs; i++)
       addr_queue.push_back(<reg_addresses>);
     addr_queue.shuffle();    // randomize the addresses  

     // Writing all regs
     foreach (addr_queue[i]) begin
       void'(item.randomize() with {addr == addr_queue[i]; delay == 8; len == 2; opc == 2; mid == 2;});
       svci_master_write(.addr(item.addr), .data(item.data), .delay(item.delay), .len(item.len), .opc(item.opc), .mid(item.mid));
       `uvm_info(get_type_name(), $sformatf("writing req addr = %0d with data = %0h ", addr_queue[i], data), UVM_MEDIUM)
       expect_mem[addr_queue[i]] = item.data;
     end   

    // Reading all regs
     addr_queue.shuffle();    // randomize the addresses  
     foreach (addr_queue[i]) begin
       svci_master_read(.addr(addr_queue[i]), .data(data), .delay(`h8), .len(`h2), .opc(`h2), .mid(`h2));
       if (data == expect_mem[addr_queue[i]])
	 `uvm_info(get_type_name(), $sformatf("check passed for addr = %0d", addr_queue[i]), UVM_MEDIUM)  
       else	 
	 `uvm_error(get_type_name(), $sformatf("check failed for addr = %0d", addr_queue[i])
     end	 
 
<<<<<list of all registers>>>>>>>>>>>>>>>
 
  endtask
 
endclass : svci_master_reg_seq

In reply to chr_sue:

Thanks for template.

with above implementation, I have only problem with Expected data {expect_mem[addr_queue[i]] = item.data;}. the read data coming from design is not equal to data which is randomly generated (item.data). Since i am doing for SOC level verification rd_data is depenent on RD_MASK and WR_MASK and RSTVAL which i have explained on the previous comment

Error :
check failed for addr = f0000000, actual rd_data = 000000000003415e , expected rd_data = af427c75f92dde78.

example :

addr F00003d8 w_data FFFFFFFF wr_mask 0000000F rd_mask 0000000F rd_data 000000000000000F

In reply to rkg_:

It is still unclear to me where the masks are coming from. They should be known also for storing the expected values.

In reply to chr_sue:

Designers gives the RDF file (where each registers field and value are defined ).

Example
REG ABC : 0x648 {

FIELD	SEL_POL				S_RO	C_RW	0	init=0x0 
							  
								   % 
FIELD	MASK				S_RO	C_RW	15:3	init=0x0  
FIELD	ADDR				S_RO	C_RW	31:19	init=0x0 

};
For above register WR_MASk AND RD_MASK will be (THis is the input file for us given by designer)
define ABC_REGRSTVAL 0x0UL
define ABC_REGWRMASK 0xFFF8FFF9UL
define ABC_REGRDMASK 0xFFF8FFF9UL

Now if i give WR_DATA (item.data) 0xFFFFFFFF to abc REG then i will get rd_data (from design) (WR_DATA & REGWRMASK )but as per your implemention expected rd_data will be 0xFFFFFFFF (item.data). so it will give mismatch.

I hope now it is clear

In reply to rkg_:

Simply put the masks to the seq_item and constrain them accordingly.

In reply to chr_sue:

virtual task body();
 
     bit [63:0] rd_data;
     bit [63:0] data;
     my_seq_item item;
     int no_of_regs = 4;
     item = my_seq_item::type_id::create("item");
     $display ("Calling get all regs ");
     get_all_regs(); //to do 
     // fill the addr_queue;
     for (int i = 0; i < no_of_regs; i++)
     begin
     addr_queue.push_back(32'hf0000000);
     addr_queue.push_back(32'hf0000064);
     addr_queue.push_back(32'hf0000130);
     addr_queue.push_back(32'hf0000134);
     addr_queue.push_back(32'hF0000138); 
    end 
     $display("addr_queue size = %0d", addr_queue.size);
     $display("\taddr_queue = %p",addr_queue);
   //  addr_queue.shuffle();    // randomize the addresses  
  //   $display("\tshuffle addr_queue = %p",addr_queue); 
     // Writing all regs
     foreach (addr_queue[i]) begin
       void'(item.randomize() with {addr == addr_queue[i]; delay == 8; len == 2; opc == 3; tag ==0; mid == 0;prty == 3; });
     
       $display("value of item_addr = %h", item.addr);
      svci_master_write(.addr(item.addr), .data(data), .delay(item.delay), .len(item.len), .opc(item.opc),.tag(item.tag),.prty(item.prty), .mid(item.mid));
       `uvm_info(get_type_name(), $sformatf("writing req addr = %0h with data = %0h ", item.addr, data), UVM_MEDIUM)
    
    
        exp_pkt = wr_rd_reg_addr_array_q.pop_front();  
       
        expect_mem[addr_queue[i]] = exp_pkt.rdata;
        $display("expect_mem[%0h] = %0h",addr_queue[i],expect_mem[addr_queue[i]]); 
     end   
   
    // Reading all regs
     
     foreach (addr_queue[i]) begin
       svci_master_read(.addr(addr_queue[i]), .rd_data(rd_data), .delay('h8), .len('h2), .opc('h0), .mid('h0),.tag(0),.prty(3));
      
       if (rd_data == expect_mem[addr_queue[i]])
	 `uvm_info(get_type_name(), $sformatf("check passed for addr = %0h ,  rd_data = %h , expected rd_data = %h", addr_queue[i], rd_data,expect_mem[addr_queue[i]]), UVM_MEDIUM)  
       else	 
	 `uvm_error("DATA MISMATCH ERROR", $sformatf("check failed for addr = %0h,  actual rd_data = %h , expected rd_data = %h", addr_queue[i],rd_data,expect_mem[addr_queue[i]] ))
     end

How to make data for master_write task FFFFF, AAAAA, 55555, 000000 for each set of reg_address.

output should be like
ue size = 20
addr_queue = '{'hf0000000, 'hf0000064, 'hf0000130, 'hf0000134, 'hf0000138, 'hf0000000, 'hf0000064, 'hf0000130, 'hf0000134, 'hf0000138, 'hf0000000, 'hf0000064, 'hf0000130, 'hf0000134, 'hf0000138, 'hf0000000, 'hf0000064, 'hf0000130, 'hf0000134, 'hf0000138}
write_data {ffffffff, fffffff,fffffff,ffffff,fffffff, aaaaaaaa,aaaaaaa,aaaaaaa,aaaaaaa,aaaaaaaa,5555555,55555555…so on} should be on sequence

In reply to rkg_:

As I said, where do you get the wr_msk and the read_mask. If you have them in txt-file you can import them into the testbench in a storage element. Having it a txt-file is not a flexible solution.

In reply to chr_sue:

task body();
  bit [31:0] addr[$];
  bit [31:0] data[$];

  addr = '{32h'f0000000, 32'hf0000064, 32'hf0000130, 32'hf0000134, 32'hf0000138};
  data = '{32'hffffffff, 32'haaaaaaaa; 32'h55555555, 32'h00000000};
  for (int i = 0; i <= 5; i++)
    for (int j = 0; j <= 5; j++)
      req.randomize with {addr == addr[j]; data == data [i]};

endtask

In reply to chr_sue:

Hi Chr_sue,

Now same scenario Registers WR/RD i am doing through RAL model. Write Transaction is going well but I am not seeing the read transaction at Interface.

Sequence Code :-

task body;  
    uvm_status_e   status;
    uvm_reg_data_t incoming;
    bit [31:0]     rdata;
   
    if (starting_phase != null)
      starting_phase.raise_objection(this);  
    //Write to the Registers
        m_sfr_aon_reg_model.FW_SPARE0.write(status,32'haaaa_5555);  
    //Read from the registers       
    m_sfr_aon_reg_model.FW_SPARE0.read(status, rdata);
    if (starting_phase != null)
      starting_phase.drop_objection(this);  
    
  endtask

Adapter Code :

 virtual function uvm_sequence_item reg2bus( const ref uvm_reg_bus_op rw );
    svci_cmd_trans_pkt cmd_tx = svci_cmd_trans_pkt::type_id::create("cmd_tx");

    `uvm_info("REG2BUS",$sformatf("Entered reg2bus at time = %0t",$time),UVM_LOW)
 
    cmd_tx.cmd_addr = rw.addr;

    if ( rw.kind == UVM_READ ) begin
    $display ("adapter read");
      cmd_tx.cmd_opc = 'h0;
      //cmd_tx.cmd_len = rd_cmd_len;
      cmd_tx.cmd_len = 'h2;
      `uvm_info("REG2BUS", $sformatf(" read access = %s",  cmd_tx.cmd_opc.name), UVM_LOW)
    end
    else if ( rw.kind == UVM_WRITE ) begin

    $display ("adapter write");
      //cmd_tx.cmd_opc = wr_type ? NON_POSTED_WRITE : POSTED_WRITE ;
      cmd_tx.cmd_opc = NON_POSTED_WRITE ;
      //cmd_tx.cmd_len = wr_cmd_len;
      cmd_tx.cmd_len = 'h2;
      cmd_tx.cmd_mid = 'h0;
      //cmd_tx.cmd_tag = rand_val_tag;
      cmd_tx.cmd_tag = 'h0;
       cmd_tx.cmd_wdata = rw.addr[2]? {rw.data[31:0],32'h0} : {32'h0,rw.data[31:0]};
            //`uvm_info("REG2BUS", $sformatf(" Address = %h, Data = %h, access = %s", cmd_tx.cmd_addr, cmd_tx.cmd_wdata, cmd_tx.cmd_opc.name), UVM_MEDIUM)
        `uvm_info("REG2BUS", $sformatf(" Address = %h, Data = %h, access = %s", cmd_tx.cmd_addr, cmd_tx.cmd_wdata, cmd_tx.cmd_opc.name), UVM_LOW)

    end

    return cmd_tx;
  endfunction: reg2bus

  virtual function void bus2reg( uvm_sequence_item bus_item, ref uvm_reg_bus_op rw );
    svci_cmd_trans_pkt cmd_tx = svci_cmd_trans_pkt::type_id::create("cmd_tx");
    svci_rsp_reg_pkt   rsp_tx = svci_rsp_reg_pkt  ::type_id::create("rsp_tx");
    if($cast( rsp_tx, bus_item))begin
      rw.kind   = ( rsp_tx.rsp_type ==READ ) ? UVM_READ : UVM_WRITE;
      rw.addr   = rsp_tx.rsp_addr;
      rw.data   = rsp_tx.rsp_rdata; 
      rw.status = UVM_IS_OK;
      `uvm_info("BUS2REG", $sformatf(" :: 2 :: Address = %h, Data = %h, access = %s", rsp_tx.rsp_addr,rsp_tx.rsp_rdata, rsp_tx.rsp_opc.name), UVM_LOW)
    end
    
  endfunction: bus2reg

Could you give me any hint how to debug this scenario ?

when i do not use RAL model it work very well (which has been explained in earlier post).

In reply to rkg_:

The first thing any data (read or write data) used together with the RAL has to be of type

uvm_reg_data_t

Dou you see the write data are arriving in the DUT?
I cannot give you a good advice bedause I do not know which access type the corresponding register has. And your protocol implementation to assign the read data from the data bus might be incorrect.
What is your error message? Which kind of data do you see when reading?

In reply to chr_sue:

Yes, I can see the Write data are arriving in the DUT.

How to make sure " m_sfr_aon_reg_model.FW_SPARE0.read(status, rdata);" this issued the read transaction correctly.

I am getting this msg “$display (“adapter read”);” in my log. does it mean read transaction issued correctly ?

Mentioned registers has RW access and my cmd.opc = 0 for read.

I am not getting any error and getting RDATA 0 since i dont see any read request getting generated.

In reply to rkg_:
Now i can see RDATA is coming .

But seeing the below issue.
xmsim: *E,TRNULLID: NULL pointer dereference.
File: /pga/cadence/xcelium/19.09.003/tools/methodology/UVM/CDNS-1.1d/sv/src/reg/uvm_reg_predictor.svh, line = 151, pos = 12
Scope: worklib.uvm_pkg::uvm_reg_predictor#(svci_pkg::svci_rsp_trans_pkt)@10625_2.write
Time: 1035946034 PS + 61

In reply to rkg_:
Now i can see RDATA is coming .

But seeing the below issue.
xmsim: *E,TRNULLID: NULL pointer dereference.
File: /pga/cadence/xcelium/19.09.003/tools/methodology/UVM/CDNS-1.1d/sv/src/reg/uvm_reg_predictor.svh, line = 151, pos = 12
Scope: worklib.uvm_pkg::uvm_reg_predictor#(svci_pkg::svci_rsp_trans_pkt)@10625_2.write
Time: 1035946034 PS + 61

In reply to rkg_:

The adapter is an individual implementation. If it’s wrong it will indicate all things are fine. But you do not see the expected result.
BTW NEVER use a $display in a UVM testbench. Use instead the `uvm_info.
The NULL pointer dereference is an indication an object does not exist. Look if the transaction svci_rsp_trans_pkt has been constructed.