使用包含参数的SystemVerilog结构作为模块的输入/输出端口

时间:2019-04-10 22:56:27

标签: struct parameters verilog system-verilog

我的结构包含随模块而变化的参数。我想使用此结构将输入/输出传递给这些模块。我正在使用它进行设计,因此它必须是可综合的,而且不幸的是,我的工具链不支持接口。

例如:

`ifdef MY_STRUCTS
`define MY_STRUCTS
typedef struct packed {
  logic [PARAMETER_VAL-1:0] field1;
  logic [PARAMETER1_VAL-1:0] field2;
} myStruct_t;
`endif

module top #(
  parameter PARAMETER_VAL = 8;
  parameter PARAMETER1_VAL = 16;
) (
  input myStruct_t in_packet,
  output myStruct_t out_packet,
);

不幸的是,这似乎是鸡或蛋的问题。无法编译结构定义,因为它依赖于模块参数来定义它。但是,无法声明输入/输出声明,因为它依赖于结构知道要声明的内容。

有人对此有解决方案吗?肯定会喜欢的建议。

2 个答案:

答案 0 :(得分:1)

可能还可以使用参数化的界面。

免责声明:以下代码可与synopsys一起使用,但在eda操场上因节奏而失败。我认为Cadence违反了此处的标准(他们可能已在最新版本中对其进行了修复)。

无论如何,这是示例

interface top_if #(int PARAMETER_VAL = 8, PARAMETER1_VAL = 16) ();

   typedef struct packed {
      logic [PARAMETER_VAL-1:0] field1;
      logic [PARAMETER1_VAL-1:0] field2;
   } myStruct_t;

   myStruct_t in_packet, out_packet;

   modport in (input in_packet);
   modport out (output out_packet);

endinterface

module caller();
   top_if #(8,16) top_if();
   always_comb top_if.in_packet = '{11, 22};

   top top(top_if.in, top_if.out);

   logic [top_if.PARAMETER1_VAL-1:0] field2;
   always_comb field2 = top_if.out_packet.field2;
   always @* begin
      $display("out.field2=%0d", field2);
   end
endmodule


module top(
           top_if in,
           top_if out
           );
   logic [in.PARAMETER_VAL-1:0] field1;

   always_comb field1 = in.in_packet.field1;
   always_comb out.out_packet = '{field1, field1+55};

   always @* begin
      $display("input.field1=%d", field1);
   end

endmodule

答案 1 :(得分:0)

两个选项:

而不是传递参数值列表,而是传递具有所需字段宽度的单个struct typedef。无论如何,您可能都想在上层结构中使用该结构。

module upper;
typedef struct packed {
  logic [7:0] field1;
  logic [16:0] field2;
} myStruct_t;
my_Struct in, out;
lower #(.T(my_Struct_t) ins1 (in, out);
...
endmodule
module lower #(type T) (
    input myStruct_t in_packet,
    output myStruct_t out_packet,
);
...
endmodule

在较低级别的模块中创建结构类型,但将端口保留为打包数组。这是可行的,因为该结构也被打包。

module top #(
  parameter PARAMETER_VAL = 8;
  parameter PARAMETER1_VAL = 16;
) (
  input logic [PARAMETER_VAL+PARAMETER_VAL1-1:0] in,
  output logic [PARAMETER_VAL+PARAMETER_VAL1-1:0] myStruct_t out,
);

typedef struct packed {
  logic [PARAMETER_VAL-1:0] field1;
  logic [PARAMETER1_VAL-1:0] field2;
} myStruct_t;
 myStruct_t in_packet, out_packet;
assign in_packet = in;
assign out = out_packet;