[RNDFLD] Randomization failed in uvm_do_with action

Hi,

When I runnng my simulation, an UVM_WARNING always reported :

UVM_WARNING …/axi/sv/axi_rd_seq_lib.sv(82) @4082 ns: uvm_test_top.***.axi_rd_req_0_1 [RNDFLD] Randomization failed in uvm_do_with action

May because this warning, no stimulus into the DUT. It wiil be grateful for your help. Thanks a lot!

axi_rd_seq_lib.sv :

class axi_read_seq extends axi_base_rd_seq;
rand int burst_num;
rand bit [1:0] row_addr_sel;
rand bit [1:0] master_awid;

function new(string name = “axi_read_seq”);
super.new(name);
endfunction

task body();
for(int i=0; i< burst_num; i++) begin
`uvm_don_with(req, {req.araddr[20:19] == row_addr_sel;
req.arid[7:6] == master_awid;}) //line 82
end
endtask
endclass

The warning is being generated because there is an error randomizing your req item. To provide Can you post the code related to the sequence_item of req?

Also, you are using a randomized int to control a loop count. Be aware that it could randomize to a negative value. Use an ‘int unsigned’ to ensure a positive value.

In reply to cgales:

Thanks for cgales’s kindly help, my sequence item, axi_rd_seq, virtual sequence code is as follows,


//axi_transfer.sv

class axi_rd_transfer extends uvm_sequence_item;
 
  rand bit[`AXI_ADDR_WIDTH-1 :0] araddr;
  ... ... 
  rand bit[`AXI_ID_WIDTH-1 :0] arid;
  ... ...
`uvm_object_utils_begin(axi_rd_transfer)
  ... ...
  `uvm_field_int(arid, UVM_ALL_ON)
  ... ...
`uvm_object_tuils_end

//constraints as following, here not constraint arid 
 ... ...

endclass

//axi_rd_seq_lib.sv :

class axi_read_seq extends axi_base_rd_seq;
rand int burst_num;
rand bit [1:0] row_addr_sel;
rand bit [1:0] master_arid;

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

task body();
for(int i=0; i< burst_num; i++) begin
`uvm_do_with(req, {req.araddr[20:19] == row_addr_sel;
req.arid[7:6] == master_arid;}) //line 82
end
endtask
endclass

//the following is virtual sequence
class axi_rd_after_wr_vseq extends axi_base_seq;

  ... ...
  axi_read_seq  axi_rd_seq_0_1; 
  ... ...

  `uvm_object_utils(axi_rd_after_wr_vseq)
  function new(string name="axi_rd_after_wr_vseq");
    super.new(name);
  endfunction

  virtual task body()
    ... ...
    axi_rd_seq_0_1 = axi_read_seq::type_id::create("axi_rd_seq_0_1");
    ... ...

    fork
       ... ...
       `uvm_do_on_with(axi_rd_seq_0_1, p_sequencer.axi_read_seqr_0_1, {axi_rd_seq_0_1.burst_num ==`d100;
                                                                       axi_rd_seq_0_1.row_addr_sel == 2'b01;
                                                                       axi_rd_seq_0_1.master_arid == 2'b01;})
       ... ...
    join
  endtask
endclass


In reply to dfx9230:

A failed randomization will normally indicate that there is a constraint solver conflict where the constraints are mutually exclusive. Are there any constraints in your sequence item (axi_rd_transfer)? You have a comment about them but they aren’t shown.

I have found the issue,thanks cgales! In order to cut shut the code,I have omited some code in axi_rd_seq,

//axi_rd_seq_lib.sv :
 
class axi_read_seq extends axi_base_rd_seq;
  rand int burst_num;
  rand bit [1:0] row_addr_sel;
  rand bit [1:0] master_arid;
 
  function new(string name = "axi_read_seq");
    super.new(name);
  endfunction
 
  task body();
    for(int i=0; i< burst_num; i++) begin
      `uvm_do_with(req, {req.araddr == i*8;   //line79
                         req.arlen == 4'h1;
                         req.araddr[20:19] == row_addr_sel; //line81
                         req.arid[7:6] == master_arid;}) //line 82
    end
  endtask
endclass

It may cause constraint solver conflict due to line79 & line81.

By the way, when you run into problems like this with the uvm_do* macros, you might find it easier to debug if you rewrite them directly. So, instead of


`uvm_do_on_with(axi_rd_seq_0_1, p_sequencer.axi_read_seqr_0_1, {axi_rd_seq_0_1.burst_num ==`d100;
                                                                axi_rd_seq_0_1.row_addr_sel == 2'b01;
                                                                axi_rd_seq_0_1.master_arid == 2'b01;})

you could write:


axi_rd_seq_0_1.randomize() with {axi_rd_seq_0_1.burst_num ==`d100;
                                 axi_rd_seq_0_1.row_addr_sel == 2'b01;
                                 axi_rd_seq_0_1.master_arid == 2'b01;};
axi_rd_seq_0_1.start(p_sequencer.axi_read_seqr_0_1);

Since you’re now calling randomize() directly, it gives you added flexibility is you want to randomize specific fields of axi_rd_seq_0_1:

axi_rd_seq_0_1.randomize(burst_num) with {axi_rd_seq_0_1.burst_num in (...);};

Personally, I find it easier to understand what the direct code is doing rather than trying to remember what order things happen in with the macros. Give it a shot.
Good luck,
-Tom

Tt’s a very good way used to debug. Thanks Tom’s kindly help! ^_^