参数化接口和可重用VIP:第三部分

描述

在本系列的第一部分中,介绍了SystemVerilog接口的基本概念,并描述了这些接口的参数化给测试平台代码带来的问题。在第二部分中,描述了使用访问器类来保护VIP代码免受参数化影响的方法,但此解决方案对该接口的VIP访问施加了新的限制。在本系列的最后一篇文章中,介绍了一个过程,该流程允许测试平台使用参数化接口,而不会对VIP访问其提供的接口的方式施加任何限制。

最大占用空间:两全其美

参数化接口引入动态测试平台代码的问题无法使用当今现有的SystemVerilog功能来解决。因此,我们必须设计一种方法来避免将这些参数暴露给VIP代码。本系列的上一篇文章介绍了访问器类来实现这一点。另一种解决方案是定义 VIP 可以与之交互的最大占用空间样式接口,以及包装此最大占用空间接口并从最大占用空间接口连接到所需信号的参数化接口。

最大占位面积样式接口定义了每个信号的最大宽度,并且可以将各个VIP组件配置为利用来自这些信号的位片。这允许具有不同宽度的多个 VIP 实例,并且不需要参数化类来使用参数化接口。以下代码段演示了这些概念。

首先,我们定义最大占用空间样式接口。请注意,此接口未参数化,因为这是 VIP 代码将与之交互的接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Redefinable max footprint
`ifndef MAX_DATA_WIDTH
 `define MAX_DATA_WIDTH 32
`endif
 
interface max_footprint_if;
  logic clk;
  logic[`MAX_DATA_WIDTH-1:0] data_in;
  logic[`MAX_DATA_WIDTH-1:0] data_out;
 
  clocking active_cb @(posedge clk);
    default input #1 output #1;
    input data_in;
    output data_out;
  endclocking
 
  modport active_mp (clocking active_cb);
endinterface
 
typedef virtual max_footprint_if max_footprint_vif;

接下来,定义参数化接口,用于包装最大占用空间接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interface param_if#(int width = 8);
  logic clk;
  logic[width-1:0] data_in;
  logic[width-1:0] data_out;
 
  max_footprint_if internal_if();
 
  assign internal_if.clk = clk;
 
  // Z values driven on unused inputs of the max footprint
  assign internal_if.data_in = {`MAX_DATA_WIDTH'hz, data_in};
 
  // Only selected output values used from the max footprint
  assign data_out = internal_if.data_out[width-1:0];
endinterface

在此之后,实现VIP代码以使用最大占用空间接口而不是参数化接口。下面显示的一个附加类在前面的帖子中没有显示,它是配置类,用于定义每个 VIP 实例的信号宽度。该解决方案造成的另一个复杂问题是,VIP在采样和驱动信号时必须使用位切片技术。这很不幸,但SystemVerilog完全有能力处理这个问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
  //=======================================================================
  class cust_cfg extends uvm_object;
    rand int data_width;
    constraint valid_data_width {
      data_width inside {8, 16, 32};
    }
 
  //=======================================================================
  class cust_driver extends uvm_driver#(cust_data);
    max_footprint_vif vif;
    cust_cfg cfg;
 
    `uvm_component_utils(cust_driver)
 
    function void build_phase(uvm_phase phase);
      if (!uvm_config_db#(max_footprint_vif)::get(this, "", "vif", vif))
        `uvm_fatal("build", "A valid virtual interface was not received.");
      if (!uvm_config_db#(cust_cfg)::get(this, "", "cfg", cfg))
        `uvm_fatal("build", "A valid configuration was not received.");
 
    task consume_from_seq_item_port();
        seq_item_port.get_next_item(req);
        vif.active_cb.prop_out <= ((req.prop <> (`MAX_DATA_WIDTH-cfg.data_width));
        @(vif.active_cb);
 
    task sample_signals();
        bit[31:0] sampled_prop_in = ((vif.active_cb.prop_in <> (`MAX_DATA_WIDTH-cfg.data_width));
VM_LOW);
        @(vif.active_cb);
 
  //=======================================================================
  class cust_agent extends uvm_agent;
    `uvm_component_utils(cust_agent)
 
    max_footprint_vif vif;
    cust_driver driver;
 
    function void build_phase(uvm_phase phase);
      if (!uvm_config_db#(max_footprint_vif)::get(this, "", "vif", vif))
        `uvm_fatal("build", "A valid virtual interface was not received.");
      if (!uvm_config_db#(cust_cfg)::get(this, "", "cfg", cfg))
        `uvm_fatal("build", "A valid configuration was not received.");
 
      uvm_config_db#(max_footprint_vif)::set(this, "driver", "vif", vif);
      uvm_config_db#(cust_cfg)::set(this, "driver", "cfg", cfg);
      driver = cust_driver::type_id::create("driver", this);

最后,给出了测试平台代码。测试用例无需参数化即可访问 VIP,并且实例化接口的顶级模块可以使用参数化接口。还显示了为每个 VIP 实例创建配置对象的附加步骤(这不是额外的步骤,因为早期的解决方案也需要这样做,但为了简洁起见,省略了)。

利用最大占用空间样式接口进行VIP信号访问,无需参数化VIP代码即可创建VIP代码。定义参数化接口允许测试平台利用它们所支持的改进集成功能。使用参数化接口包装最大占用空间接口的策略可实现这两种样式的优势。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//=======================================================================
class cust_test extends uvm_test;
  cust_cfg cfg8;
  cust_cfg cfg16;
  cust_cfg cfg32;
 
  cust_agent agent8;
  cust_agent agent16;
  cust_agent agent32;
 
  virtual function void build_phase(uvm_phase phase);
    cfg8 = new("cfg8");
    cfg8.data_width = 8;
    uvm_config_db#(cust_cfg)::set(this, "agent8", "cfg", cfg8);
    agent8 = cust_agent::type_id::create("agent8", this);
 
    cfg16 = new("cfg16");
    cfg16.data_width = 16;
    uvm_config_db#(cust_cfg)::set(this, "agent16", "cfg", cfg16);
    agent16 = cust_agent::type_id::create("agent16", this);
 
    cfg32 = new("cfg32");
    cfg32.data_width = 32;
    uvm_config_db#(cust_cfg)::set(this, "agent32", "cfg", cfg32);
    agent32 = cust_agent::type_id::create("agent32", this);
  endfunction
endclass
 
//=======================================================================
module test_top;
  param_if#(8) if8();
  param_if#(16) if16();
  param_if#(32) if32();
 
  initial begin
 
    uvm_config_db#(max_footprint_vif)::set(uvm_root::get(), "uvm_test_top.agent8", "vif", if8.internal_if);
    uvm_config_db#(max_footprint_vif)::set(uvm_root::get(), "uvm_test_top.agent16", "vif", if16.internal_if);
    uvm_config_db#(max_footprint_vif)::set(uvm_root::get(), "uvm_test_top.agent32", "vif", if32.internal_if);
 
    run_test("cust_test");
  end
endmodule

利用最大占用空间样式接口进行VIP信号访问,无需参数化VIP代码即可创建VIP代码。定义参数化接口允许测试平台利用它们所支持的改进集成功能。使用参数化接口包装最大占用空间接口的策略可实现这两种样式的优势。

审核编辑:郭婷

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分