I’m trying to make an extended uvm_sequence class that auto-encapsulates a uvm_sequence_item so it can be forwarded to a sequencer. My aim is to forward predicted transactions from a scoreboard to a sequencer, thereby performing module emulation.
Here is the wrapper definition along with some proprietary class extensions:
virtual class k_sequence_item extends uvm_sequence_item;
...
endclass
virtual class k_sequencer #(type SEQ=k_sequence_item) extends uvm_sequencer #(SEQ);
`uvm_component_utils(k_sequencer)
...
endclass
virtual class k_sequence_wrapper #(type SEQ=k_sequence_item) extends uvm_sequence #(SEQ);
`uvm_object_utils(k_sequence_wrapper)
SEQ seq;
function new(string name = "k_sequence_wrapper");
super.new(name);
endfunction
virtual function void set_sequence(SEQ seq);
this.seq = seq;
endfunction
virtual task body;
start_item(seq);
finish_item(seq);
endtask
endclass
Here is the comparator definition. Predicted transactions come in on refport.
virtual class k_comparator #(type SEQ=k_sequence_item) extends uvm_component;
`uvm_component_utils(k_comparator)
k_sequencer #(SEQ) sqr;
k_sequence_wrapper #(SEQ) wpr;
uvm_analysis_export #(SEQ) refport;
uvm_tlm_analysis_fifo #(SEQ) expfifo;
/* ... */
function void build_phase(uvm_phase phase);
super.build_phase(phase);
/* ... */
refport = new("refport", this);
expfifo = new("expfifo", this);
/* ... */
endfunction
/* ... */
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
refport.connect(expfifo.analysis_export);
/* ... */
endfunction
/* ... */
task run_phase(uvm_phase phase);
/* ... */
//
// If we have a DUT, compare the observed transaction to the predicted
// one.
//
if (sqr == null) fork
/* ... */
join_none else
//
// If we don't have a DUT, forward the expected transaction to the
// sequencer and use the agent as an emulator.
//
fork
forever begin
expfifo.get(exp_txn);
/* ... */
/* >>> */ wpr = k_sequence_wrapper#(SEQ)::type_id::create("wpr", this);
wpr.set_sequence(exp_txn);
wpr.start(sqr);
end
/* ... */
join_none
/* ... */
endtask
endclass
With that set up, I extend this comparator class:
class transceiver_cmp extends k_comparator #(transceiver_pkt);
`uvm_component_utils(transceiver_cmp)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
endclass
The problem line is k_sequence_wrapper…create. When I try to load this package into Questasim, I get the following error:
** Error: (vsim-3978) ...: Illegal assignment to class base.test_pkg::k_sequence_wrapper #(class base.test_pkg::transceiver_pkt) from class base.test_pkg::k_sequence_wrapper #(class base.test_pkg::k_sequence_item)
Note how the assignee variable wpr has been overridden as expected with the transceiver_pkt type, but the create call still has the type k_sequence_item from the base class. How do I correct this so the variable assignment works?