如何根据实例化使同一模块使用不同的包

时间:2019-07-19 16:09:19

标签: verilog system-verilog

我有一个System Verilog模块,该模块在设计中被多次实例化。每个实例都需要使用不同的包。实现此目的的最佳方法是什么?

  package A;
   parameter logic [15:0] array [0:15] = '{
   16'd1,
   16'd2,
   .
   .
   16'd16 
   }
  endpackage

  package B;
   parameter logic [15:0] array [0:7] = '{
   16'd1,
   16'd2,
   .
   .
   16'd8 
   }
  endpackage

   module test(

   );

    import packageA::*;

这就是我在模块的一个实例中使用它的方式。但是在第二个实例中,我想使用packageB

我应该使用:

  1. ifdefs?
  2. 是否可以通过软件包名称? 或
  3. 只是将其作为参数传递给模块?即使是二维数组?

什么是最好的方法?

1 个答案:

答案 0 :(得分:0)

System Verilog语法不提供任何方式将软件包作为参数传递给任何对象。可以使用会改变模块定义的宏。尽管有可能,但这是一种不好的做法,通常不建议这样做。最后,我将举一个例子。

处理此问题的唯一方法是对模块进行参数化,并在实例化时传递相应的数组,例如

package A;
parameter bit[3:0] data[4] = '{0,1,2,3};
endpackage

package B;
parameter bit[3:0] data[6] = '{5,4,3,2,1,0};
endpackage

module C#(int WDT = 1, bit [3:0] array [WDT] = '{0}) ();
  initial begin
    for (int i = 0; i < WDT; i++) 
      $display("%m: array[%0d] = %0d", i, array[i]);
  end
endmodule

module D();
  C #($size(A::data), A::data) c1();
  C #($size(B::data), B::data) c2();  
endmodule

还有其他类型的版本,即

package A;
typedef  bit[3:0] Array[4];
parameter Array array = {0,1,2,3};
endpackage

package B;
typedef  bit[3:0] Array[6] ;
parameter Array array = {5,4,3,2,1,0};
endpackage

typedef bit[3:0] DefaultArray[1];
module C#(type  X = DefaultArray, X array = {0}) ();
  initial begin
    for (int i = 0; i < $size(array); i++) 
      $display("%m array[%0d] = %0d", i, array[i]);
  end
endmodule

module D();
  D #(A::Array, A::array)d1();
  D #(B::Array, B::array)d2();
endmodule

对于宏,您可以在宏中定义整个模块。我觉得这很丑

`define PMOD(NAME,PKG) module NAME (); ... import PKG""* ...
 ...
`PMOD(C1, A)
`PMOD(C2, B)

 ...
 C1 c1();
 C2 c2();

一个人也可以使用ifdefs with include。我不会推荐任何基于宏的方法,特别是基于包含的方法。它们会产生可读性,可维护性,代码分析和调试问题。