systemverilog使用参数指定import namespace

时间:2015-10-23 22:40:46

标签: parameters namespaces package system-verilog

我有一个systemverilog模块,它引用包含各种typedef和函数的生成头文件。这是可综合的代码。该模块之前工作正常,因为头文件是使用预处理器包含的。

现在我的架构发生了变化,我需要实例化该模块的多个案例,并为每个实例指定不同的头文件。由于预处理器定义变量的全局性,我不相信预处理器方法将再次起作用。我不能为一个模块实例包含一个头文件,并为另一个实例包含另一个头文件。正确的吗?

所以我正在尝试使用包。我想做的事情如下:

onCreate

请注意此代码的两个问题,两个问题都与我无法指定与参数一起使用的命名空间有关。我怀疑我的问题是参数更改不一定需要重新编译,我试图影响的更改肯定需要重新编译。哪个适用于我的申请;我不需要在不重新编译代码的情况下进行这些更改。

我可以在SO上找到关于这个问题的最接近的讨论,至少在这里:

Handling parameterization in SystemVerilog packages

但最好的答案是使用预处理器魔法,我认为这种魔法在我的情况下无效。我真的很感激对这个问题的任何见解。感谢。

1 个答案:

答案 0 :(得分:1)

你要做的事情的问题是import语句是它出现的开始/结束范围的本地。你需要在每个分支中声明test_struct变量,不幸的是处理函数的唯一方法是写一个包装器。

package pack1;
  parameter from_pack = 1;
  typedef struct packed
  {
    logic [7:0]  test1;
    logic        test2;
  } test_t;
  function automatic void hello();
    $display("in pack1");
  endfunction
endpackage

package pack2;
  parameter from_pack = 2;
  typedef struct packed
  {
    logic [7:0]  test1;
    logic        test2;
    logic [18:0] test3;
  } test_t;
  function automatic void hello();
    $display("in pack2");
  endfunction
endpackage

module top();
  parameter PACKAGE_INST = 1;

   case (PACKAGE_INST)
     1: begin : genscope
    pack1::test_t test_struct;
    function void hello;
       pack1::hello();
    endfunction
     end
     default: begin :genscope
    pack2::test_t test_struct;
    function void hello;
       pack2::hello();
    endfunction
     end
   endcase

   initial begin
      $display("PACKAGE_INST = %d", PACKAGE_INST);
      $display("%p",genscope.test_struct); 
      genscope.hello();
   end

endmodule

另一种完全不同的方法是使用接口而不是包。通过将模块连接到不同的接口实例,可以选择连接到模块的类型和功能。

interface intf1;
  parameter from_intf = 1;
  typedef struct packed
  {
    logic [7:0]  test1;
    logic        test2;
  } test_t;
  function automatic void hello();
    $display("in intf1");
  endfunction
endinterface

interface intf2;
  parameter from_intf = 2;
  typedef struct packed
  {
    logic [7:0]  test1;
    logic        test2;
    logic [18:0] test3;
  } test_t;
  function automatic void hello();
    $display("in intf2");
  endfunction
endinterface

module DUT(interface itf);

   typedef itf.test_t test_t; // LRM requires this so typename does not
                              // appear as a hierarchical reference
   test_t test_struct;

   initial begin
      $display("%m from_intf = %d", itf.from_intf);
      $display("%p",test_struct); 
      itf.hello();
   end

endmodule

module top2;


   intf1 i1();
   intf2 i2();

   DUT d1(i1);
   DUT d2(i2);

endmodule