I build a uvm testbench using RAL to understand the concept of the abstraction layer, but when i run the simulation i have a UVM_FATAL at my sequencer.
UVM_FATAL @ 10: uvm_test_top.m_env.m_agent.m_seqr [m_seqr] send_request failed to cast sequence item
I try to understand the error and i think is a failing cast operation between the sequence_item and the uvm_reg_bus_op, but i can’t fix the error. Some of the code is below and the link to Github containing all code is UVM-APB_RAL
class reg2apb_adapter extends uvm_reg_adapter;
`uvm_object_utils (reg2apb_adapter)
function new (string name = "reg2apb_adapter");
super.new (name);
endfunction
virtual function uvm_sequence_item reg2bus (const ref uvm_reg_bus_op rw);
apb_tr tr = apb_tr::type_id::create ("tr");
tr.write = (rw.kind == UVM_WRITE) ? 1: 0;
tr.addr = rw.addr;
tr.data = rw.data;
`uvm_info ("adapter", $sformatf ("reg2bus addr=0x%0h data=0x%0h kind=%s", tr.addr, tr.data, rw.kind.name), UVM_DEBUG)
return tr;
endfunction
virtual function void bus2reg (uvm_sequence_item bus_item, ref uvm_reg_bus_op rw);
apb_tr tr;
if (! $cast (tr, bus_item)) begin
`uvm_fatal ("reg2apb_adapter", "Failed to cast bus_item to tr")
end
rw.kind = tr.write ? UVM_WRITE : UVM_READ;
rw.addr = tr.addr;
rw.data = tr.data;
`uvm_info ("adapter", $sformatf("bus2reg : addr=0x%0h data=0x%0h kind=%s status=%s", rw.addr, rw.data, rw.kind.name(), rw.status.name()), UVM_DEBUG)
endfunction
endclass
class traffic_env extends uvm_env;
`uvm_component_utils (traffic_env)
ral_block_traffic_cfg m_ral_model; // Register Model
uvm_reg_predictor #(apb_tr) m_apb2reg_predictor; // Map APB tx to register in model
apb_agent m_agent; // Agent to drive/monitor transactions
traffic_scoreboard m_scoreboard; // Scoreboard
function new (string name = "traffic_env", uvm_component parent);
super.new (name, parent);
endfunction
virtual function void build_phase (uvm_phase phase);
super.build_phase (phase);
m_agent = apb_agent::type_id::create ("m_agent", this);
m_ral_model = ral_block_traffic_cfg::type_id::create ("m_ral_model", this);
m_ral_model.build();
m_apb2reg_predictor = uvm_reg_predictor #(apb_tr)::type_id::create("m_apb2reg_predictor", this);
m_scoreboard = traffic_scoreboard::type_id::create("jb_fc_sub", this );
uvm_config_db #(ral_block_traffic_cfg)::set (null, "uvm_test_top", "m_ral_model", m_ral_model);
uvm_reg::include_coverage ("*", UVM_CVR_ALL);
endfunction
virtual function void connect_phase (uvm_phase phase);
super.connect_phase (phase);
m_agent.ag_ap.connect(m_scoreboard.apb_export);
m_ral_model.reg_map.set_auto_predict(0);
m_ral_model.reg_map.set_sequencer(m_agent.m_seqr, m_agent.reg2apb);
m_apb2reg_predictor.map = m_ral_model.reg_map;
m_apb2reg_predictor.adapter = m_agent.reg2apb;
m_agent.ag_ap.connect(m_apb2reg_predictor.bus_in);
m_scoreboard.m_ral_model = m_ral_model;
endfunction
endclass
class my_sequence extends uvm_reg_sequence();
`uvm_object_utils (my_sequence)
function new (string name = "my_sequence");
super.new (name);
endfunction
virtual task body ();
ral_block_traffic_cfg m_ral_model;
uvm_reg_data_t rdata;
uvm_status_e status;
int reg_idx = 1;
$cast(m_ral_model, model);
write_reg(m_ral_model.ctrl, status, 32'd3);
write_reg(m_ral_model.timer[0], status, 32'b00000010000000000000100000000001);
write_reg(m_ral_model.timer[1], status, 32'd0);
read_reg(m_ral_model.timer[1], status, rdata );
endtask
endclass
class apb_agent extends uvm_agent;
`uvm_component_utils (apb_agent)
uvm_analysis_port #(apb_tr) ag_ap;
apb_driver m_drvr;
apb_monitor m_mon;
reg2apb_adapter reg2apb;
uvm_sequencer #(apb_tr) m_seqr;
function new (string name="apb_agent", uvm_component parent);
super.new (name, parent);
ag_ap = new("ag_ap", this);
endfunction
virtual function void build_phase (uvm_phase phase);
super.build_phase (phase);
m_seqr = uvm_sequencer#(apb_tr)::type_id::create ("m_seqr", this);
m_drvr = apb_driver::type_id::create ("m_drvr", this);
m_mon = apb_monitor::type_id::create ("m_mon", this);
reg2apb = reg2apb_adapter::type_id::create("reg2apb", this);
endfunction
virtual function void connect_phase (uvm_phase phase);
super.connect_phase (phase);
m_drvr.seq_item_port.connect(m_seqr.seq_item_export);
m_mon.mon_ap.connect(ag_ap);
endfunction
endclass
class base_test extends uvm_test;
`uvm_component_utils (base_test)
traffic_env m_env;
ral_block_traffic_cfg m_ral_model;
function new (string name = "base_test", uvm_component parent);
super.new (name, parent);
endfunction
virtual function void build_phase (uvm_phase phase);
super.build_phase (phase);
m_env = traffic_env::type_id::create ("m_env", this);
m_ral_model = ral_block_traffic_cfg::type_id::create("jb_reg_block");
m_ral_model.build();
m_env.m_ral_model = m_ral_model;
// factory.set_type_override_by_type(ral_sample1::get_type(), my_sample::get_type());
// factory.print();
endfunction
virtual task reset_phase (uvm_phase phase);
super.reset_phase (phase);
phase.raise_objection (this);
phase.drop_objection (this);
endtask
virtual task main_phase (uvm_phase phase);
phase.raise_objection (this);
phase.drop_objection (this);
endtask
endclass
Thanks.