The transaction from the reference model has one positive edge delay to be disaplyed in the scoreboard

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


In reply to kawa:

That is a lot of code to look at and still not enough for anyone to reproduce your issue. A couple of things I see that could be a problem.

Do not use nonblocking assignments ‘<=’ to assign to members of transactions

Get rid of all your #1 delays.

Do net create() transaction object in places where you will be calling get(), It is unnecessary and they will just be overwritten.

In my_model::main_phase, you have

 mdl_gp.get(tr);
      @(posedge mdl_if.clk)begin

Since you did not show enough code, I do not know what is doing the put(). The @posedge clk might be unnecessary.

Use the run_phase instead of the main_phase.