Jump to content
Sign in to follow this  
Khushi

monitor output is delayed due to run_phase ordering

Recommended Posts

Hi Guys

I am very new to UVM and trying to play around with a small example(see below). In this example what I am observing that the following sequence(at each posedge)

- first monitor run_phase is executed

- rtl is executed

- driver is executed

due to this, I get the following output

UVM_INFO example.sv(112) @ 10: uvm_test_top.m_env.m_agent.m_monitor [monitor] out = 0x0
in=x
UVM_INFO example.sv(42) @ 10: uvm_test_top.m_env.m_agent.m_data_sequencer@@m_data_sequence.m_data_item [data_item] in = 0xd, out = 0x0
UVM_INFO example.sv(112) @ 30: uvm_test_top.m_env.m_agent.m_monitor [monitor] out = 0x0
in=d
UVM_INFO example.sv(42) @ 30: uvm_test_top.m_env.m_agent.m_data_sequencer@@m_data_sequence.m_data_item [data_item] in = 0xa, out = 0x2
UVM_INFO example.sv(112) @ 50: uvm_test_top.m_env.m_agent.m_monitor [monitor] out = 0x1a
in=a
UVM_INFO example.sv(42) @ 50: uvm_test_top.m_env.m_agent.m_data_sequencer@@m_data_sequence.m_data_item [data_item] in = 0x4, out = 0x6
UVM_INFO example.sv(112) @ 70: uvm_test_top.m_env.m_agent.m_monitor [monitor] out = 0x14
in=4
UVM_INFO example.sv(42) @ 70: uvm_test_top.m_env.m_agent.m_data_sequencer@@m_data_sequence.m_data_item [data_item] in = 0xc, out = 0xc

But I want the following order(at each posedge)

- driver run_phase

- rtl

- monitor run phase

so that monitor display correct output.

How I can achieve this. Or is there some other way to get the correct output.

Here is the complete code

import uvm_pkg::*;
`include "uvm_macros.svh"

module dut(
  input            clk,
  input [3:0]      in,
  output reg [4:0] out
);

  always @ (posedge clk)
    begin
      $display("in=%h",in);  
      out <= 2*in;
    end

endmodule

interface dut_if (input clk);
    logic [3:0] in;
    logic [4:0] out;
endinterface    

module dut_wrapper(dut_if _if);
    dut dut0(.clk   (_if.clk),
             .in    (_if.in),
             .out   (_if.out));
endmodule   

class data_item extends uvm_sequence_item;

   `uvm_object_utils(data_item)
    rand bit  [3:0] in;
    rand bit [4:0] out;

    constraint c_in {in >=0;in<=15;}

    function new (string name = "");
        super.new(name);
    endfunction

    virtual function void display ();
         `uvm_info (get_type_name (), $sformatf ("in = 0x%0h, out = 0x%0h", in,out), UVM_LOW);
    endfunction

endclass

class data_sequence extends uvm_sequence;
    `uvm_object_utils(data_sequence)
    data_item m_data_item;

    function new (string name="data_sequence");
        super.new(name);
    endfunction

    virtual task body();
        m_data_item = data_item::type_id::create("m_data_item");
        repeat (4) begin
            start_item(m_data_item);
            assert(m_data_item.randomize())
            finish_item(m_data_item);
        end
    endtask
endclass

class driver extends uvm_driver#(data_item);
    `uvm_component_utils(driver)

    data_item m_data_item;
    virtual dut_if m_dut_if;
    
    function new(string name,uvm_component parent);
        super.new(name,parent);
    endfunction

    function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        assert(uvm_config_db #(virtual dut_if) :: get (this, "", "m_dut_if", m_dut_if));
    endfunction
    
    task run_phase(uvm_phase phase);
        forever begin
            @(posedge m_dut_if.clk);
            seq_item_port.get_next_item (m_data_item);
            m_dut_if.in = m_data_item.in;
            m_data_item.display();
            seq_item_port.item_done();
        end
    endtask

endclass

class monitor extends uvm_monitor;
    `uvm_component_utils(monitor)
     virtual dut_if m_dut_if;
     uvm_analysis_port #(data_item)  item_collected_port;
     data_item m_data_item;
     function new(string name, uvm_component parent);
        super.new(name, parent);
        item_collected_port = new ("item_collected_port", this);
    endfunction

    virtual function void build_phase (uvm_phase phase);
         super.build_phase (phase);
         assert(uvm_config_db #(virtual dut_if) :: get (this, "", "m_dut_if", m_dut_if));
    endfunction

    task run_phase(uvm_phase phase);
        super.run_phase(phase);
        m_data_item = data_item::type_id::create ("m_data_item", this);
        forever @(posedge m_dut_if.clk) begin
            m_data_item.out = m_dut_if.out;
            `uvm_info (get_type_name (), $sformatf ("out = 0x%0h", m_data_item.out), UVM_LOW);
            //item_collected_port.write (m_data_item);
        end
    endtask
endclass

class agent extends uvm_agent;
    `uvm_component_utils(agent)
    driver m_driver;
    data_sequence m_data_sequence;
    uvm_sequencer#(data_item) m_data_sequencer;
    monitor m_monitor;
    
    function new(string name, uvm_component parent);
      super.new(name, parent);
    endfunction

    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        m_driver = driver::type_id::create("m_driver",this);
        m_data_sequence = data_sequence::type_id::create("m_data_sequence",this);
        m_data_sequencer = uvm_sequencer#(data_item)::type_id::create("m_data_sequencer",this);
        m_monitor = monitor::type_id::create ("m_monitor", this);
    endfunction

    virtual function void connect_phase (uvm_phase phase);
       super.connect_phase (phase);
       m_driver.seq_item_port.connect (m_data_sequencer.seq_item_export);
    endfunction


endclass

class env extends uvm_env;
    `uvm_component_utils(env)
    agent m_agent;
    
    function new(string name, uvm_component parent);
      super.new(name, parent);
    endfunction

    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        m_agent = agent::type_id::create("m_agent",this);
    endfunction

endclass    

class my_test extends uvm_test;
    `uvm_component_utils(my_test)

    env m_env;
    virtual dut_if m_dut_if;

    function new(string name, uvm_component parent);
      super.new(name, parent);
    endfunction

    virtual function void build_phase(uvm_phase phase);
        super.build_phase(phase);
        m_env = env::type_id::create("m_env",this);
        assert(uvm_config_db #(virtual dut_if) :: get (this, "", "dut_if", m_dut_if));
        uvm_config_db #(virtual dut_if) :: set (this, "*", "m_dut_if", m_dut_if);
    endfunction   

    virtual function void end_of_elaboration_phase (uvm_phase phase);
         uvm_top.print_topology ();
    endfunction

   task run_phase(uvm_phase phase);
       phase.raise_objection(this);
       m_env.m_agent.m_data_sequence.start(m_env.m_agent.m_data_sequencer);
       phase.drop_objection(this);
   endtask

  endclass

module top;
    bit clk;
    always #10 clk <= ~clk;

    dut_if m_dut_if(clk);
    dut_wrapper m_dut_wrapper(._if(m_dut_if));


    initial begin
        uvm_config_db #(virtual dut_if)::set (null, "uvm_test_top", "dut_if", m_dut_if);
        run_test("my_test");
    end
endmodule  

 

 

Share this post


Link to post
Share on other sites

based on your defined data_item, your monitor implementation is incorrect.

the monitor shall sample the sample the in signal and than sample the corresponding out signal, give the encapsulation the two value in a data item, send it out.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...