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

Struct 使用包含参数的SystemVerilog结构作为模块的输入/输出端口,struct,parameters,verilog,system-verilog,Struct,Parameters,Verilog,System Verilog,My struct包含每个模块不同的参数。我想使用这个结构将输入/输出传递给这些模块。我在设计中使用它,所以它必须是可合成的,不幸的是,我的工具链不支持接口 例如: `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

My struct包含每个模块不同的参数。我想使用这个结构将输入/输出传递给这些模块。我在设计中使用它,所以它必须是可合成的,不幸的是,我的工具链不支持接口

例如:

`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,
);
不幸的是,这似乎是一个鸡或蛋的问题。无法编译结构定义,因为它依赖于模块参数来定义它。但是,无法声明输入/输出声明,因为它依赖于结构来知道要声明什么

有人能解决这个问题吗?非常感谢您的建议。

有两种选择:

与其传递参数值列表,不如传递一个带有所需字段宽度的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] 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;
两种选择:

与其传递参数值列表,不如传递一个带有所需字段宽度的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] 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;

也可以使用参数化接口

免责声明:以下代码适用于synopsys,但在eda操场中使用cadence时失败。我认为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

也可以使用参数化接口

免责声明:以下代码适用于synopsys,但在eda操场中使用cadence时失败。我认为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

谢谢你。不幸的是,我们的工具链在设计中不支持SV接口。我希望这样做是正确的方法…另外,如果我使用它,我如何访问模块逻辑中接口中定义的结构?你是说作为模块中声明的typedef吗?我不认为你能。嗯,那就有点混乱了。理想情况下,我希望能够使用相同的结构生成并发送到其他模块。以及在两者之间的失败。结构在这方面是完美的,除了参数用法上的折痕……您可以发送整个接口,如示例所示。您可以访问结构和接口参数的字段。谢谢。不幸的是,我们的工具链在设计中不支持SV接口。我希望这样做是正确的方法…另外,如果我使用它,我如何访问模块逻辑中接口中定义的结构?你是说作为模块中声明的typedef吗?我不认为你能。嗯,那就有点混乱了。理想情况下,我希望能够使用相同的结构生成并发送到其他模块。以及在两者之间的失败。结构在这方面是完美的,除了参数用法上的折痕……您可以发送整个接口,如示例所示。您可以访问结构和接口参数的字段。