System verilog 在ANSI样式模块端口列表中使用参数化聚合数据类型

System verilog 在ANSI样式模块端口列表中使用参数化聚合数据类型,system-verilog,System Verilog,下面的代码 module test #(A = 1, B = 2) (output t_my sig); typedef struct { logic [A-1:0] fA; logic [B-1:0] fB; } t_my; initial $display("hello\n"); endmodule 返回VCS错误 Error-[SV-UIOT] Undefined interface or type test.vs, 1 t_my, "sig"

下面的代码

module test #(A = 1, B = 2) (output t_my sig);
   typedef struct {
      logic [A-1:0] fA;
      logic [B-1:0] fB;
   } t_my;
   initial $display("hello\n");
endmodule
返回VCS错误

Error-[SV-UIOT] Undefined interface or type
test.vs, 1
t_my, "sig"
  The definition for the forward-referenced interface 't_my' is missing or 
  't_my' is the name of an undefined user type.
  Check to see if the interface definition file/work library is missing or the
  definition of the user type is missing.
如果我改为

typedef struct {
   logic [A-1:0] fA;
   logic [B-1:0] fB;
}t_my;

module test #(A = 1, B = 2) (output t_my sig);
   initial $display("hello\n");
endmodule
然后我得到

Error-[IND] Identifier not declared
test.vs, 2
  Identifier 'A' has not been declared yet. If this error is not expected, 
  please check if you have set `default_nettype to none.


Error-[IND] Identifier not declared
test.vs, 3
  Identifier 'B' has not been declared yet. If this error is not expected, 
  please check if you have set `default_nettype to none.
有没有一种方法可以使用ANSI样式的模块端口列表实现我想要的功能?请注意,我可以在没有ANSI样式端口列表的情况下完成此操作,如下所示:

module test #(A = 1, B = 2) (sig); 
   typedef struct packed { 
       logic [A-1:0] fA; 
       logic [B-1:0] fB; } t_my; 

       output t_my sig; 
       initial $display("hello\n"); 
endmodule

module top; 
  logic topsig [2:0]; 
  test test1 (.sig ({>>{topsig}}) );
endmodule

当端口列表中有用户定义的聚合类型时,需要将该类型放置在可兼容的位置以建立连接,即模块测试,以及模块上方将建立到该端口的连接的模块。有两种方法可以实现这一点:

使用type参数从较高级别向下传递数据类型

module test#(type T) (input T sig);
   parameter A = $bits(sig.fA);
   parameter B = $bits(sig.fB);

   initial #1 $display(A,, B);
endmodule
module top;
   typedef struct {
      logic [3:0] fA;
      logic [4:0] fB;
   } my_t;

   my_t s;

   test #(my_t) t2(s);

endmodule 
显示

#           3           4
或者,您可以将该类型放入公共包中。但是,要使结构参数化,需要将类型包装到类中。参见1800-2012 LRM的第6.25节(这应该是可合成的)


感谢您的回复-第二个选项很有趣,我已经记下了,以备将来使用。但我不同意模块“top”和“test”都需要知道“t”的定义这一基本前提。我知道这一点,因为下面的代码编译和模拟得很好。。。。。。。模块测试#(A=1,B=2)(sig);typedef结构压缩{logic[A-1:0]fA;logic[B-1:0]fB;}t\u my;输出我的信号;初始$display(“hello\n”);endmodule------------模块顶部;逻辑topsig[2:0];测试test1(.sig({>>{topsig}}));endmoduleA压缩结构是另一种情况。所有完整类型均已打包,无需进行类型检查。Verilog规则适用,位将被截断或填充以进行连接或分配。
package p;
class T#(int A,B);
   typedef struct {
      logic [A-1:0] fA;
      logic [B-1:0] fB;
   } my_t;
endclass
endpackage : p

module test#(int A=1, B=2) (input p::T#(A,B)::my_t sig);
   initial #1 $displayb(sig.fA,, sig.fB);
endmodule

module top;
   import p::T;

   T#(2,3)::my_t s = '{'1, '1}; 
   test #(2,3) t(s);

endmodule