0
votes

I am constructing the UVM testbench to verify a simple design. I have learnt that scoreboard will usually be outside the agent. I want my scoreboard to be inside the agent as I have only one agent in the system. Now, in my agent, I am trying to connect monitor and scoreboard. I want to know if there is a way to connect without using fifo.

Here are my code snippets

class my_monitor extends uvm_monitor;
  `uvm_component_utils(my_monitor)
  uvm_analysis_port #(input_seq_item) ap_port;
  input_seq_item mon_item;
  ....
endclass

class my_scoreboard extends uvm_scoreboard;
  `uvm_component_utils(my_scoreboard)
  uvm_analysis_export #(input_seq_item) ap_port_sb;
  ...
endclass

class agent extends uvm_agent;
  `uvm_component_utils(agent)
  sequencer sqr;
  my_driver drv;
  my_sequence seq;
  my_monitor mon;
  my_scoreboard sb;
  ...
    function void connect_phase(uvm_phase phase);
    super.connect_phase(phase);
    drv.seq_item_port.connect(sqr.seq_item_export);
    mon.ap_port.connect(sb.ap_port_sb);
  endfunction
  ...
endclass

I am getting the following error

# KERNEL: UVM_INFO @ 0: reporter [RNTST] Running test test...
# KERNEL: UVM_ERROR @ 0: uvm_test_top.env.sb.ap_port_sb [Connection Error] connection count of 0 does not meet required minimum of 1
# KERNEL: UVM_FATAL @ 0: reporter [BUILDERR] stopping due to build errors
# KERNEL: UVM_INFO /home/build/vlib1/vlib/uvm-1.2/src/base/uvm_report_server.svh(855) @ 0: reporter [UVM/REPORT/SERVER] 

Can anyone help me with this?

Thanks in advance

4

4 Answers

3
votes

The problem is you left your scoreboard analysis export hanging, but it needs to be connected to an imp port. If you're familiar with SystemC, an imp port doesn't have a direct equivalent. An import basically is a termination point of a TLM analysis connection. The imp port then forwards the calls to the component that instantiates it.

Change your code to uvm_analysis_imp #(...) and declare a write(input_seq_item ite) function for it to call and everything should work.

1
votes

Check: Are you using constructor to create analysis ports?

//For monitor
function new(..);
..
monitor_ap = new("monitor_ap", this);
endfunction

Also try with Subscriber class default analysis_export!

0
votes

If you don't want to declare write() function than Using FIFO is the best option. It is very easy.Following is your edited code..

 class my_monitor extends uvm_monitor;
`uvm_component_utils(my_monitor)
 uvm_analysis_port #(input_seq_item) ap_port;
 input_seq_item mon_item;
 ....
 endclass

class my_scoreboard extends uvm_scoreboard;
 `uvm_component_utils(my_scoreboard)
  uvm_analysis_export #(input_seq_item) ap_port_sb;
  ...
endclass

class agent extends uvm_agent;
 `uvm_component_utils(agent)
 sequencer sqr;
 my_driver drv;
 my_sequence seq;
 my_monitor mon;
 my_scoreboard sb;
 uvm_tlm_analysis_fifo fifo;
 ...
   function void connect_phase(uvm_phase phase);
     super.connect_phase(phase);
     drv.seq_item_port.connect(fifo.analysis_export);
     mon.ap_port.connect(fifo.analysis_export);
   endfunction
...
endclass

I think this will solve your Problem..

0
votes

Generally when you use an export, then the data/transaction that is sent to it must be passed on to an import (which marks the end of the pipeline). Hence unless you want to send data from scoreboard that you are receiving to some other blocks, you can use uvm_analysis_imp #(...) in your code. On doing so, you are making the scoreboard as a Target, and monitor as the Initiator, hence a write function has to be implemented in the Scoreboard, and called upon from the monitor whenever the transaction has to be pipelined.