首页 > 解决方案 > 您可以转发声明一个用作端口类型的类型,还是可以将接口用作外部端口?

问题描述

我正在尝试在 SystemVerilog 中设计一些硬件,但遇到了一个我找不到答案的问题。情况是我有一个顶级模块(跟踪器),它需要有一个特定类型的输出端口。此类型是在参数化接口内指定的类型定义结构,因为此类型定义需要在顶级模块的某些子模块之间共享。我希望能够拥有接口中指定类型的输出端口,并能够将该类型传递给各种子模块以用于其他目的。

至关重要的是,我还试图将这个硬件作为 Vivado 中的一个自定义 IP(这是一个更大项目的一部分),所以我的目标是一个顶级模块,其中有一些我可以定义的参数,其余的该模块的完全封装。我意识到这最终将涉及在所有内容之上放置一个 Verilog 包装器,但目前我只专注于让它在模拟中正确运行。

我遇到的问题是,由于必须实例化接口,因此您不能将其用作顶级端口,因为您将在哪里实例化接口?但是,因为我所做的只是在接口内引用 typedef,所以我可以以某种方式转发声明这些,以便我可以将类型称为端口类型并将其传递给其他子模块?

所以基本上有人对我如何实现这一点有任何想法吗?如果我完全不正确地解决这个问题,请随时告诉我,dave59在这里提供了将 typedef 捆绑到接口中的想法(https://verificationacademy.com/forums/systemverilog/parameterized-struct-systemverilog-设计),我花了一天时间试图解决这个问题,但一无所获。非常感谢任何帮助以及我将很乐意提供的任何进一步说明。

这是当前每个代码的代码。为了清楚起见,它们都在同一个文件中声明。

接口定义

interface trace_if #(
parameter TDATA_WIDTH = 32, 
parameter INSTR_ADDR_WIDTH = 32, 
parameter INSTR_DATA_WIDTH = 32,
parameter DATA_ADDR_WIDTH = 32);

... (IF_DATA etc. defined here)

typedef struct packed {
    bit [INSTR_DATA_WIDTH-1:0] instruction;
    bit [INSTR_ADDR_WIDTH-1:0] addr;
    bit pass_through;
    IF_data if_data;
    ID_data id_data;
    EX_data ex_data;
    WB_data wb_data;
 } trace_format;

 trace_format trace_output;

endinterface

顶级模块

module tracer
#(
parameter INSTR_ADDR_WIDTH = 32,
parameter INSTR_DATA_WIDTH = 32,
parameter DATA_ADDR_WIDTH = 32,
parameter TDATA_WIDTH = 32,
parameter TRACE_BUFFER_SIZE = 64
)
(   
... other ports declared
trace_if.trace_output trace_data_o
);
// Instantiating the interfaces for communication between submodules

logic if_data_valid;
trace_if #(TDATA_WIDTH, INSTR_ADDR_WIDTH, INSTR_DATA_WIDTH, DATA_ADDR_WIDTH) if_data_o();
logic id_data_ready;
trace_if #(TDATA_WIDTH, INSTR_ADDR_WIDTH, INSTR_DATA_WIDTH, DATA_ADDR_WIDTH) id_data_o();
logic ex_data_ready;
trace_if #(TDATA_WIDTH, INSTR_ADDR_WIDTH, INSTR_DATA_WIDTH, DATA_ADDR_WIDTH) ex_data_o();
logic wb_data_ready;

// Instantiating the submodules

if_tracker if_tr (.*);
id_tracker #(INSTR_DATA_WIDTH, DATA_ADDR_WIDTH, TRACE_BUFFER_SIZE) id_tr(.if_data_i(if_data_o), .*);
ex_tracker #(DATA_ADDR_WIDTH, 256, TRACE_BUFFER_SIZE) ex_tr(.id_data_i(id_data_o), .wb_previous_end_i(previous_end_o), .*);
wb_tracker #(TRACE_BUFFER_SIZE) wb_tr(.ex_data_i(ex_data_o), .wb_data_o(trace_data_o), .*);

... other module related stuff

endmodule

标签: system-verilogvivado

解决方案


如果您发布MCVE ,这些事情会更容易。我想你要问的是:

interface i #(parameter p = 1);

  typedef struct packed {
    bit [p-1:0] b;
  } s_t;

  s_t s;

endinterface

module m #(parameter p = 1) ( /* how can I have a port of type s_t ? */ );

  i i0 ();

endmodule

如果是这样,我认为您需要将其放入struct一个包裹中:

package pkg;

  localparam l = 1;

  typedef struct packed {
    bit [l-1:0] b;
  } s_t;

endpackage

interface i #(parameter p = pkg::l);

  pkg::s_t s;

endinterface

module m #(parameter p = pkg::l) ( pkg::s_t s );

  i i0 ();

endmodule

https://www.edaplayground.com/x/4zQ_


推荐阅读