System verilog 在UVM中连接监视器和记分板

System verilog 在UVM中连接监视器和记分板,system-verilog,uvm,System Verilog,Uvm,我正在构建UVM测试台来验证一个简单的设计。我知道记分牌通常在经纪人的外面。我希望我的记分板在代理内,因为我在系统中只有一个代理。现在,在我的代理中,我正在尝试连接监视器和记分板。我想知道是否有一种不使用fifo的连接方式 下面是我的代码片段 class my_monitor extends uvm_monitor; `uvm_component_utils(my_monitor) uvm_analysis_port #(input_seq_item) ap_port; input_

我正在构建UVM测试台来验证一个简单的设计。我知道记分牌通常在经纪人的外面。我希望我的记分板在代理内,因为我在系统中只有一个代理。现在,在我的代理中,我正在尝试连接监视器和记分板。我想知道是否有一种不使用fifo的连接方式

下面是我的代码片段

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
我得到以下错误

# 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] 
有人能帮我吗


提前感谢

问题是您将记分板分析导出挂起,但它需要连接到imp端口。如果您熟悉SystemC,imp端口没有直接等效端口。导入基本上是TLM分析连接的终止点。然后imp端口将调用转发给实例化它的组件


将您的代码更改为
uvm\u analysis\u imp#(…)
,并声明一个
write(input\u seq\u item ite)
函数,以便调用该函数,所有操作都应该正常。

问题是您将记分板分析导出挂起,但它需要连接到imp端口。如果您熟悉SystemC,imp端口没有直接等效端口。导入基本上是TLM分析连接的终止点。然后imp端口将调用转发给实例化它的组件


将您的代码更改为
uvm\u analysis\u imp#(…)
,并声明一个
write(input seq item ite)
函数,让它调用,一切都应该正常。

如果您不想声明write()函数,那么使用FIFO是最好的选择。 这很简单。以下是您编辑的代码

 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

我认为这将解决您的问题。

如果您不想声明write()函数,那么使用FIFO是最好的选择。 这很简单。以下是您编辑的代码

 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

我认为这将解决您的问题。

检查:您是否使用构造函数创建分析端口

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

还可以尝试使用订阅服务器类默认分析\u导出

检查:您是否使用构造函数创建分析端口

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

还可以尝试使用订阅服务器类默认分析\u导出

通常,当您使用导出时,发送给它的数据/事务必须传递给导入(这标志着管道的结束)。因此,除非您希望将正在接收的记分板数据发送到其他块,否则您可以在代码中使用
uvm\u analysis\u imp(…)

这样做时,您将记分板作为目标,监视器作为启动器,因此必须在记分板中实现写函数,并在事务必须通过管道时从监视器调用写函数。

通常,当您使用导出时,发送给它的数据/事务必须传递给导入(这标志着管道的结束)。因此,除非您希望将正在接收的记分板数据发送到其他块,否则您可以在代码中使用
uvm_analysis_imp(…)

这样做时,您将记分板作为目标,监视器作为启动器,因此必须在记分板中实现写入功能,并在事务必须通过管道传输时从监视器调用写入功能。

非常感谢。它成功了。我还有一个疑问。现在我已经在记分板中实现了写入功能,记分板无法控制数据何时到达。我如何检查结果?我是否应该签入写函数本身,以便在监视器将数据写入记分板时,我可以检查还是在运行阶段?如果它应该在运行阶段,我如何知道监视器实际调用了写函数?
write(…)当监视器调用
ap\u port.write(某些项目)
时,将间接调用
(通过方法链接)。
。您应该在记分板的
write(…)中实现任何检查/建模逻辑
函数。非常感谢。它成功了。我还有一个疑问。现在我在记分板中实现了写函数,记分板无法控制数据何时到来。我如何检查结果?我是否应该签入写函数本身,以便在监视器将数据写入记分板时,我可以检查或处于运行阶段?如果它应该处于运行阶段,我如何知道监视器实际调用了write函数?
write(…)
将在监视器调用
ap\u port.write(某些项目)
时间接调用
write(…)
。您应该在记分板的
write(…)
函数中实现任何检查/建模逻辑。