system-verilog - 您可以转发声明一个用作端口类型的类型,还是可以将接口用作外部端口?
问题描述
我正在尝试在 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
解决方案
如果您发布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
推荐阅读
- bash - 从目标目录内部与外部使用 bash zip
- pandas - 通过带有日期时间时间戳的熊猫数据框进行索引
- c# - join+into 子句如何转换为 GroupJoin
- javascript - 为什么不能在 Node.js 中使用 await?
- travis-ci - Travis 上的 SonarCloud 错误:未授权。请检查属性 sonar.login 和 sonar.password
- icons - PyGtk3 - 创建带有图标的 Gtk.TreeView 列标题?
- vue.js - 如何在 VUE 中创建具有新数据和参数的组件或设置新方法?
- spring-boot - 从 JSP 到 Thymeleaf 的转换
- python - 使用 Python 编写平铺地板的算法
- php - 如何在活动子菜单 wordpress 中删除活动类