简体   繁体   English

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

[英]Using SystemVerilog structs that contain parameters as input/output ports to a module

My struct contains parameters that vary per module.我的结构包含每个模块不同的参数。 I'd like to use this struct to pass input/outputs to these modules.我想使用这个结构将输入/输出传递给这些模块。 I'm using this for design so it has to be synthesizable and my toolchain doesn't support Interfaces unfortunately.我使用它进行设计,因此它必须是可综合的,而且我的工具链不支持接口。

For example:例如:

`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,
);

Unfortunately, this seems to be a chicken-or-egg problem.不幸的是,这似乎是先有鸡还是先有蛋的问题。 The struct definition can't be compiled because it relies on the module parameters to define it. struct 定义无法编译,因为它依赖于模块参数来定义它。 However, the input/output declarations can't be declared because it relies on the struct to know what to declare.但是,无法声明输入/输出声明,因为它依赖于结构来知道要声明的内容。

Does anyone have a solution to this?有没有人有解决方案? Would definitely appreciate suggestions.肯定会感谢建议。

Potentially you can also use a parameterized interface.潜在地,您还可以使用参数化接口。

Disclaimer: the following code works with synopsys but fails with cadence in eda playground.免责声明:以下代码适用于 Synopsys,但在 eda playground 中因节奏而失败。 I think that Cadence is in violation of the standard here (They might have fixed it in the latest version).我认为 Cadence 在这里违反了标准(他们可能已经在最新版本中修复了它)。

Anyway, here is the example无论如何,这是示例

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

Two options:两种选择:

Instead of passing a list of parameter values, pass a single struct typedef with the field widths you need.不是传递参数值列表,而是传递具有您需要的字段宽度的单个结构 typedef。 You would likely want to use the struct in the upper level anyway.无论如何,您可能希望在上层使用结构体。

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

Create the struct type inside the lower level module, but keep the ports as packed arrays.在较低级别的模块内创建结构类型,但将端口保留为打包数组。 This works because the struct is packed as well.这是有效的,因为结构也被打包。

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] 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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM