I have sequences (reg_seq_A,reg_seq_B,reg_seq_C,…,reg_seq_Z) extending from a base sequence (req_seq_base) itself extending from uvm_reg_sequence.
reg_seq_base has a reference to my register model which is used in reg_seq_A/B/C/…/Z
What is the best way to set the handle to the register model for all these sequences without need to specify it for each sequence separately?
code snippet:
class my_reg_block extends uvm_reg_block;
//....
endclass
class reg_seq_base extends uvm_reg_sequence;
my_reg_block regs;
//....
endclass
class reg_seq_A extends reg_seq_base;
//....
virtual task body();
regs.reg_x1.write(...
regs.reg_x2.write(...
regs.reg_x3.read(...
endtask
//....
endclass
class reg_seq_B extends reg_seq_base;
//....
virtual task body();
regs.reg_x3.write(...
regs.reg_x1.write(...
regs.reg_x2.read(...
endtask
//....
endclass
//......
class reg_seq_Z extends reg_seq_base;
//....
virtual task body();
regs.reg_x6.read(...
regs.reg_x2.write(...
regs.reg_x6.write(...
endtask
//....
endclass
class top_vseq_base extends mvc_sequence;
reg_seq_A my_seq_a0;
reg_seq_B my_seq_b0;
reg_seq_C my_seq_c0;
//....
reg_seq_Z my_seq_z0;
//....
function new ( string name = "top_vseq_base" );
super.new(name);
my_seq_a0= reg_seq_A::type_id::create("my_seq_a0");
my_seq_b0= reg_seq_B::type_id::create("my_seq_b0");
my_seq_c0= reg_seq_C::type_id::create("my_seq_c0");
//....
my_seq_z0= reg_seq_Z::type_id::create("my_seq_z0");
endfunction
task body();
my_seq_b0.start(null);
repeat (10) my_seq_a0.start(null);
my_seq_z0.start(null);
my_seq_c0.start(null);
endtask
endclass
class top_test_base extends uvm_test;
//....
my_reg_block regs;
//....
extern function void init_vseq(top_vseq_base vseq);
extern function void build_phase(uvm_phase phase);
// to hook up register adapter and sequencer
extern function void connect_phase(uvm_phase phase);
extern task run_phase(uvm_phase phase);
function void top_test_base::init_vseq(top_vseq_base vseq);
vseq.my_reg_itf_sqr = env.my_reg_itf.m_sequencer;
//TODO implement in a generic way
vseq.my_seq_a0.m_config = env_cfg.my_reg_itf_cfg;
vseq.my_seq_b0.m_config = env_cfg.my_reg_itf_cfg;
//...
vseq.my_seq_z0.m_config = env_cfg.my_reg_itf_cfg;
vseq.my_seq_a0.regs = regs;
vseq.my_seq_b0.regs = regs;
//...
vseq.my_seq_z0.regs = regs;
endfunction: init_vseq
function void top_test_base::build_phase(uvm_phase phase);
env_cfg = top_env_config::type_id::create("env_cfg");
env_cfg.initialize();
//REG
my_reg_itf_cfg = my_reg_itf_cfg_t::type_id::create("my_reg_itf_cfg" );
if ( !uvm_config_db #(my_reg_itf_bfm_t)::get(this, "", "my_reg_itf", my_reg_itf_cfg.m_bfm) )
`uvm_error("build_phase", "Unable to get virtual interface my_reg_itf for my_reg_itf_cfg from uvm_config_db")
my_reg_itf_config_policy::configure(my_reg_itf_cfg, env_cfg.reg_map);
env_cfg.my_reg_itf_cfg = my_reg_itf_cfg;
// Once the agent configuration objects are done build the env
env = top_env::type_id::create("env", this);
env.cfg = env_cfg;
// create the register model
regs = my_reg_block::type_id::create("regs");
regs.build();
// make available to sequences
//uvm_resource_db #(my_reg_block)::set("*","regs", regs, this);//not working!
// adapter for register bus
reg2bus = reg2bus_adapter_t::type_id::create("reg2bus");
// BUS register predictor
reg_predictor = bus_reg_predictor_t::type_id::create("reg_predictor", this);
endfunction: build_phase
// Function: connect_phase
//
// provide the register model map with a sequencer and a register bus adaptor
//
function void top_test_base::connect_phase(uvm_phase phase);
// direct connection to bus VIP
regs.map.set_sequencer(env.my_reg_itf_cfg.m_sequencer,reg2bus);
regs.map.set_auto_predict(0);
reg_predictor.map = regs.map;
reg_predictor.adapter = reg2bus;
// Connect the predictor to the bus agent monitor analysis port
env.my_reg_itf.ap["burst_transfer"].connect(reg_predictor.bus_item_export);
endfunction
task top_test_base::run_phase(uvm_phase phase);
top_vseq_base vseq;
//
//....
//....
//The sequence is OK to run
`uvm_info(get_type_name(), {"Running virtual sequence '",sequence_name,"'"}, UVM_LOW)
//
phase.raise_objection(this);
init_vseq(vseq);
vseq.start(null);
phase.drop_objection(this);
endtask: run_phase
endclass