I have query in uvm_sequence randomization. All the sequences are started by using seq.start(sequence_name) method.And, this will automatically randomize whatever present inside the sequence. But, if we explicitly randomize a seq. i.e seq.randomize with {static_constraints}, when we call the start method, i.e., seq.start(sequence_name), will it take static_constraints which are explicitly randomized by seq.randomize method, or it will again randomize it and give different values.
For example, letâs say a write sequence which has write_data and address. And the sequence is a virtual sequence and declared in p_sequencer.
And, it is randomized as below,
wr_seq.randomize with {write_data == 'h03;
address == 'h0004;};
wr_seq.start(p_sequencer);
Now, when the sequence started will take the write_data as 'h03?.
Calling start() for a sequence doesnât randomize the sequence. It only starts the existing sequence in its current state.
Calling randomize() with {} will randomize the sequence per the specified constraints. Calling start() afterwards doesnât change any values.
Donât use p_sequencer. All virtual sequences should have the required sequencer handles assigned prior to starting and run on a ânullâ sequencer.
Thanks for the comment. In the below code, whatever randomized in trans_seq will be passed to write_seq right. But, while executing this code, I observed that, write_seq.write_data and write_seq.address has different data.
Note : Both are started with p_sequencer.
class write_seq extends uvm_sequence #(uvm_sequence_item);
`uvm_object_utils(write_seq)
`uvm_declare_p_sequencer(virtual_sequencer)
rand bit[31:0] write_data;
rand bit[31:0] address;
endclass : write_seq
class trans_seq extends uvm_sequence #(uvm_sequence_item);
`uvm_object_utils(trans_seq)
`uvm_declare_p_sequencer(virtual_sequencer)
function new(string name = "trans_seq");
super.new(name);
endfunction : new
rand bit[31:0] write_data;
rand bit[31:0] address;
write_seq wr_seq;
extern virtual task body();
endclass : trans_seq
task trans_seq::body();
wr_seq = write_seq::type_id::create("wr_seq");
wr_seq.randomize with {write_data == this.write_data;
address == this.address;};
wr_seq.start(p_sequencer);
endtask : body
If you add a little more code, you can create a self-contained example which demonstrates your issue.
Your issue is that you have variables with the same name in both trans_seq and write_seq. Section 18.7 of the LRM explains how to differentiate between a variable that is local to the class calling randomize() and a variable that is local to the class being randomized. You want to use the qualifier âlocal::â and not âthis.â
import uvm_pkg::*;
`include "uvm_macros.svh"
class write_seq extends uvm_sequence #(uvm_sequence_item);
`uvm_object_utils(write_seq)
rand bit[31:0] write_data;
rand bit[31:0] address;
function new(string name="write_seq");
super.new(name);
endfunction
task body();
`uvm_info(get_name(), $sformatf("write_seq has address: %0h and write_data: %0h", address, write_data), UVM_MEDIUM);
endtask
endclass : write_seq
class trans_seq extends uvm_sequence #(uvm_sequence_item);
`uvm_object_utils(trans_seq)
function new(string name = "trans_seq");
super.new(name);
endfunction : new
rand bit[31:0] write_data;
rand bit[31:0] address;
task body();
write_seq write_seq_incorrect_randomization = write_seq::type_id::create("write_seq_incorrect_randomization");
write_seq write_seq_correct_randomization = write_seq::type_id::create("write_seq_correct_randomization");
`uvm_info(get_name(), $sformatf("trans_seq has address: %0h and write_data: %0h", address, write_data), UVM_MEDIUM);
if (!write_seq_incorrect_randomization.randomize with {write_data == this.write_data;
address == this.address;}) begin
`uvm_fatal("RNDERR", "Unable to randomize write_seq_incorrect_randomization");
end
write_seq_incorrect_randomization.start(null);
if (!write_seq_correct_randomization.randomize with {write_data == local::write_data;
address == local::address;}) begin
`uvm_fatal("RNDERR", "Unable to randomize write_seq_correct_randomization");
end
write_seq_correct_randomization.start(null);
endtask : body
endclass : trans_seq
class my_test extends uvm_test;
`uvm_component_utils(my_test);
function new(string name="my_test", uvm_component parent = null);
super.new(name,parent);
endfunction
task run_phase(uvm_phase phase);
trans_seq test_seq = trans_seq::type_id::create("test_seq");
repeat (10) begin
if (!test_seq.randomize()) begin
`uvm_fatal("RNDERR", "Unable to randomize trans_seq");
end
test_seq.start(null);
end
endtask
endclass
module testbench();
initial begin
run_test("my_test");
end
endmodule