如何在 Cocotb 中指定记分板的比较功能?

How do I specify the compare function of the scoreboard in Cocotb?

我想扩展 Endian Swapper example of Cocotb, so that, it also checks the contents of the packages outputted by the device under test (DUT). In the provided example code,生成预期输出的 model 函数将 未修改的 输入事务附加到预期输出列表。该列表作为记分牌的参数提供。

为了理解记分板的工作原理以及为什么 model 函数没有附加 字节交换 事务,我在 DUT 中引入了一个设计错误。在 endian_swapper.vhdl

的以下代码块中
if (byteswapping = '0') then
    stream_out_data      <= stream_in_data;
else
    stream_out_data      <= byteswap(stream_in_data);
end if;

我只是将第一行中的 if 条件反转为:(byteswapping /= '0').

重新运行 testbench 后,本以为测试失败了,结果还是通过了:

#  62345.03ns INFO     cocotb.regression                         regression.py:209  in handle_result                   Test Passed: wavedrom_test
#  62345.03ns INFO     cocotb.regression                         regression.py:170  in tear_down                       Passed 33 tests (0 skipped)
#  62345.03ns INFO     cocotb.regression                         regression.py:176  in tear_down                       Shutting down...

似乎在创建 scoreboard:

时缺少比较函数
self.scoreboard = Scoreboard(dut)
self.scoreboard.add_interface(self.stream_out, self.expected_output)

add_interface的调用中应该有第三个参数,但是这个参数没有记录。

那么,我该如何指定这个比较函数,以便同时检查包内容?

我正在使用 QuestaSim 进行仿真并使用 make SIM=questa 执行测试平台。我还清理了运行之间的构建目录。

如果我在使用 Icarus 时应用以下差异,测试将按预期失败:

diff --git a/examples/endian_swapper/hdl/endian_swapper.sv b/examples/endian_swapper/hdl/endian_swapper.sv
index 810d3b7..a85db0d 100644
--- a/examples/endian_swapper/hdl/endian_swapper.sv
+++ b/examples/endian_swapper/hdl/endian_swapper.sv
@@ -119,7 +119,7 @@ always @(posedge clk or negedge reset_n) begin
             stream_out_startofpacket <= stream_in_startofpacket;
             stream_out_endofpacket   <= stream_in_endofpacket;

-            if (!byteswapping)
+            if (byteswapping)
                 stream_out_data      <= stream_in_data;
             else 
                 stream_out_data      <= byteswap(stream_in_data);

我无法访问 Questa,但我会看看在 VHDL 模拟器上会发生什么。我的直觉是在进行更改后仔细检查 运行 make clean 并检查 Questa 是否未以某种方式缓存构建的 RTL 库。

你是正确的,记分板的 add_interface 方法有一些未记录的关键字参数:

  • compare_fn 可以是任何可调用函数
  • reorder_depth 是一个整数,允许重新排序 t运行sactions

如果您提供 compare_fn 它将在被监视器接收时使用 t运行saction 调用,但是这是一个非常原始的机制。它不可扩展,仅出于历史原因(因此未记录)。

更好的方法是子class记分板class并根据以下原型定义自定义compare方法:

def compare(self, got, exp, log, strict_type=True):
    """
    Common function for comparing two transactions.
    Can be re-implemented by a subclass.
    """

其中 gotexp 是接收到的和预期的 t运行saction,log 是对监视器 logger 实例的引用(提供更有意义的消息)。

Endian Swapper 示例的顶层以 SystemVerilog 代码和 VHDL 代码的形式提供。如果编译选项未指定,则默认使用 verilog 代码。

如果我运行:

make SIM=questa TOPLEVEL_LANG=vhdl

正如 Quick Start Guide 中给出的那样,一切都按预期进行。在这种情况下不需要指定比较函数。