【问题标题】:Assertion module in an UVM testbenchUVM 测试平台中的断言模块
【发布时间】:2017-02-24 10:45:52
【问题描述】:

我编写了一个包含 3 个代理的 UVM 测试平台,现在正在编写记分板/检查器。我需要为我的 SystemVerilog 断言提供一个检查器模块,但是这个检查器模块需要知道从测试中完成的寄存器配置(并且可以是随机的,在测试的 run_phase 期间决定)。

我无法弄清楚这将如何工作?如果我要为我的断言创建一个检查器模块,并将其在顶层 (tb_top) 绑定到 dut,那么这个检查器模块如何知道我的寄存器配置?

在阅读了一些论文之后,我想我可以将我的 checker 模块编写为一个接口,将它设置在 tb_top 中。但这将允许访问我的 UVC 接口中的变量。接口如何访问 UVC 中的变量?

感谢任何帮助。我觉得我在这里遗漏了一些关键的东西,因为这可能已经做过很多次了。

编辑:请不要告诉我我必须实现某种 API 来设置我的 UVC 中的每个单独的寄存器设置?我只想获取我的 reg_block(或代理中的任何其他配置变量)的句柄

【问题讨论】:

  • 即使你有reg_block 的句柄,你仍然不能在断言中使用它(很可能),因为你不允许在断言中使用类对象.
  • @TudorTimi 是的,问题就在于此,我能想出的唯一解决方案是在我的断言接口(模块)中添加单独的位,然后将其作为虚拟接口传递到我的 UVC 中。然后每次我做一个 write_reg (例如),我也会去设置位 - > vif.my_reg_bit = value。对于大量寄存器,这可能会很快变得乏味。还有其他方法吗?很难相信我是唯一面临这个问题的人。
  • 没错,你的断言不能使用类数据。您可以做的一件事是,您可以根据您的读/写总线事务编写寄存器断言(您将执行一些红/写总线级别事务以更新寄存器内容,并且您可以编写与前面的条件相同的条件你的断言)。
  • @KaranShah 好的,所以你的意思是在我的断言模块中为我的寄存器读/写协议实现一个解码器。知道了!但我想我会从我的 tb_top 写一点
  • 您可能不需要实现解码器,我相信,您可以编写适当的先行序列,具体取决于您的总线事务

标签: system-verilog uvm


【解决方案1】:

您似乎想将信息从tb_top 传递给您的UVC,反之亦然。此信息将由您在tb_top 中的断言使用,并由您的 UVC 共享。我的建议,你可以使用uvm_resource_dbuvm_config_db

我可以想到两种实现这种交流的方法。

第一种方法是set你的tb_top中的配置,然后你的UVC抓住这个句柄。从这里开始,您可以传达您的注册信息或您的断言所需的任何信息。

class my_tb_config extends uvm_object;
  // ...
endclass

module tb_top;
  my_tb_config tcfg;
  initial begin
    tcfg = new("tcfg");
    uvm_config_db#(my_tb_config)::set(uvm_root::get(), "*", "my_tb_config", tcfg);
    end
endmodule

// somewhere in your UVC
class my_uvc extends uvm_component;
  my_tb_config tcfg;
  function void build_phase(uvm_phase phase);
    // now both tb_top and your UVC point to the same config object
    void'(uvm_config_db#(my_tb_config)::get(this,"","my_tb_config", tcfg));
  endfunction
endclass

另一种方法是相反的。将您的 UVC 配置传递给您的 tb_top

class my_other_uvc extends uvm_component;
  my_tb_config tcfg;
  function void build_phase(uvm_phase);
    tcfg = new("tcfg");
    uvm_resource_db#(my_tb_config)::set("*", "my_tb_config", tcfg);
  endfunction
endclass

// somewhere in your tb_top
module tb_top;
  my_tb_config tcfg;
  initial begin
    #1ps; // small delay, making sure resource is submitted
    void'(uvm_resource_db#(my_tb_config)::read_by_name("*","my_tb_config",tcfg);
    // Now both your tb_top and UVC share same object, so you can freely define your whatever communication between them
    end
endmodule

【讨论】:

  • 这对我的问题没有帮助。您的解决方案只是通过 UVC 层次结构传递一个 uvm_object。在您的示例的上下文中,我的问题是在我的断言模块中访问 tcfg 类变量。请注意,断言模块只是一个模块,没有访问 uvm 类的能力。
  • 我明白了。我通常在顶级测试平台中使用这种方式进行动态检查,但从未尝试将其用于断言检查器。如果是这样,那么是的,这对您的问题没有帮助。
【解决方案2】:

我想出了一个办法。首先,我意识到我问了两个不同的问题:

1) 我的检查器模块需要了解在测试中完成的寄存器配置

我在我的设计中使用跨模块引用来访问我的寄存器,这为我提供了在运行阶段由测试设置的最新寄存器配置。

tb.sv

module tb;
  dut my_dut( ... )

  interface my_checker (
    .input_registerA (tb.my_dut.my_sub_module.regA),
    .input_registerB (tb.my_dut.my_sub_module.regB),
    .input_registerC (tb.my_dut.my_other_sub_module.regC),
    ....
  )
endmodule

my_checker.sv

interface my_checker (
  input input_registerA,
  input input_registerB,
  input input_registerC,
  ....
);

  // Here I can write properties/assertions that are register-aware
endinterface

2) 接口如何访问UVC中的变量?

这有点棘手。我想从 uvm_sequence 或 uvm_monitor 等动态更新我的检查器变量。

我阅读了 Verilab 的这篇论文,其中清楚地描述了执行此操作的方法: http://www.verilab.com/files/litterick_sva_encapsulation.pdf

在我的检查器模块中,我创建了一个 uvm_component。通过这个组件,我现在可以访问 uvm_resource_db,通过它我可以与我的 UVM-testbench 交换信息。

要记住的一点是,checker 模块中实例化的 uvm_component 位于顶层(uvm_root)。

【讨论】:

    猜你喜欢
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-27
    • 2015-03-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多