I want to display transaction which is from the reference model and the monitor in the scoreboard.
But, there’s always one positive edge delay happening in the transaction from the model when it is in the scoreboard.
At the meantime, I can display the transaction of model in the model correctly.
Here’s the simulation result
Simulation period is 10ns
# UVM_INFO testbench.sv(223) @ 26: uvm_test_top.mdl [my_model] new_tr.b=2
# UVM_INFO testbench.sv(153) @ 26: uvm_test_top.out_agt.out_mon [output_monitor] tr.b=2
# UVM_INFO testbench.sv(257) @ 26: uvm_test_top.scr [my_scoreboard] mdl_tr.b=x mon_tr.b=2
# UVM_INFO testbench.sv(153) @ 36: uvm_test_top.out_agt.out_mon [output_monitor] tr.b=3
# UVM_INFO testbench.sv(223) @ 36: uvm_test_top.mdl [my_model] new_tr.b=3
# UVM_INFO testbench.sv(257) @ 36: uvm_test_top.scr [my_scoreboard] mdl_tr.b=2 mon_tr.b=3
As you can see, it has one positive delay between the transaction from the model and the monitor in the scoreboard. But, I can display the transaction in their own class correctly.
Please tell me why, and how to improve, thank you
The following is my code
#################################################output_monitor###########################################
class output_monitor extends uvm_monitor;
`uvm_component_utils(output_monitor)
function new(string name="out_monitor",uvm_component parent=null);
super.new(name,parent);
endfunction
my_transaction tr;
virtual my_if out_mon_if;
uvm_put_port#(my_transaction) out_mon_pp;
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
out_mon_pp=new("out_mon_pp",this);
if(!uvm_config_db#(virtual my_if)::get(this,"","out_mon_if",out_mon_if))begin
`uvm_fatal("output_monitor","Can't get interface!!!")
end
endfunction
virtual task main_phase(uvm_phase phase);
super.main_phase(phase);
phase.raise_objection(this);
while(1)begin
tr=my_transaction::type_id::create("tr");
@(posedge out_mon_if.clk)begin
tr.b<=out_mon_if.b;
out_mon_pp.put(tr);
#1;
`uvm_info("output_monitor",$sformatf("tr.b=%d",tr.b),UVM_MEDIUM)
end
end
phase.drop_objection(this);
endtask
endclass
#################################################my_model#################################################
class my_model extends uvm_component;
`uvm_component_utils(my_model)
function new(string name="my_model",uvm_component parent=null);
super.new(name,parent);
endfunction
uvm_get_port#(my_transaction) mdl_gp;
uvm_put_port#(my_transaction) mdl_pp;
my_transaction tr;
my_transaction new_tr;
virtual my_if mdl_if;
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
if(!uvm_config_db#(virtual my_if)::get(this,"","mdl_if",mdl_if))begin
`uvm_fatal("my_model","Can't get interface!!!")
end
mdl_gp=new("mdl_gp",this);
mdl_pp=new("mdl_pp",this);
endfunction
virtual task main_phase(uvm_phase phase);
super.main_phase(phase);
phase.raise_objection(this);
while(1)begin
tr=my_transaction::type_id::create("tr");
new_tr=my_transaction::type_id::create("new_tr");
mdl_gp.get(tr);
@(posedge mdl_if.clk)begin
new_tr.b<=tr.a+1'b1;
end
mdl_pp.put(new_tr);
#1;
`uvm_info("my_model",$sformatf("new_tr.b=%0d",new_tr.b),UVM_MEDIUM)
end
phase.drop_objection(this);
endtask
endclass
############################################my_scoreboard#################################################
class my_scoreboard extends uvm_scoreboard;
`uvm_component_utils(my_scoreboard)
function new(string name="my_scroeboard",uvm_component parent=null);
super.new(name,parent);
endfunction
uvm_get_port#(my_transaction) mdl_scr_gp;
uvm_get_port#(my_transaction) mon_scr_gp;
my_transaction mdl_tr;
my_transaction mon_tr;
virtual my_if scr_if;
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
mdl_scr_gp=new("mdl_scr_gp",this);
mon_scr_gp=new("mon_scr_gp",this);
if(!uvm_config_db#(virtual my_if)::get(this,"","scr_if",scr_if))begin
`uvm_fatal("my_scoreboard","Can't get interface!!!")
end
endfunction
virtual task main_phase(uvm_phase phase);
my_transaction mdl_tr, mon_tr;
super.main_phase(phase);
mdl_tr=my_transaction::type_id::create("mdl_tr");
mon_tr=my_transaction::type_id::create("mon_tr");
phase.raise_objection(this);
while(1)begin
mdl_scr_gp.get(mdl_tr);
mon_scr_gp.get(mon_tr);
#1;
`uvm_info("my_scoreboard",$sformatf("mdl_tr.b=%0d mon_tr.b=%0d",mdl_tr.b,mon_tr.b),UVM_MEDIUM)
end
phase.drop_objection(this);
endtask
endclass
#################################################my_env###################################################
class my_env extends uvm_env;
`uvm_component_utils(my_env)
function new(string name="my_env",uvm_component parent=null);
super.new(name,parent);
endfunction
input_agent in_agt;
my_sequence seq;
my_model mdl;
my_scoreboard scr;
output_agent out_agt;
uvm_tlm_fifo#(my_transaction) mon_mdl_fifo;
uvm_tlm_fifo#(my_transaction) mon_scr_fifo;
uvm_tlm_fifo#(my_transaction) mdl_scr_fifo;
virtual function void build_phase(uvm_phase phase);
super.build_phase(phase);
in_agt=input_agent::type_id::create("in_agt",this);
mdl=my_model::type_id::create("mdl",this);
scr=my_scoreboard::type_id::create("scr",this);
out_agt=output_agent::type_id::create("out_agt",this);
mon_mdl_fifo=new("mon_mdl_fifo",this);
mon_scr_fifo=new("mon_scr_fifo",this);
mdl_scr_fifo=new("mdl_scr_fifo",this);
endfunction
virtual function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
in_agt.in_mon.in_mon_pp.connect(mon_mdl_fifo.put_export);
mdl.mdl_gp.connect(mon_mdl_fifo.get_export);
mdl.mdl_pp.connect(mon_scr_fifo.put_export);
scr.mdl_scr_gp.connect(mdl_scr_fifo.get_export);
scr.mon_scr_gp.connect(mon_scr_fifo.get_export);
out_agt.out_mon.out_mon_pp.connect(mdl_scr_fifo.put_export);
endfunction
virtual task main_phase(uvm_phase phase);
super.main_phase(phase);
seq=my_sequence::type_id::create("seq");
seq.start(in_agt.sqr);
endtask
endclass