如果在实施时知道,使用 IEEE 1800-2012 的 SystemVerilog 接口第 3.5 节和第 25 节可以解决此问题。
接口是一组命名的网络,因此如果路径中的所有内容都连接到该接口,则向该接口添加一个额外的网络意味着该接口的所有实例都会获得额外的线路。
向接口添加信号允许低级模块使用该总线立即连接到其他所有模块(顶层),一旦接口通过层次结构连接,无需任何额外的端口工作来连接。
Interfaces vs Structs 之前已经讨论过。
关于接口的 Doulos 教程。
为了获得更完整的答案,我包含了 25.3.3 IEEE 1800 中给出的示例,该示例显示了通过接口连接的模块:
// memMod and cpuMod can use any interface
module memMod (interface a, input logic clk);
...
endmodule
module cpuMod(interface b, input logic clk);
...
endmodule
interface simple_bus; // Define the interface
logic req, gnt;
logic [7:0] addr, data;
logic [1:0] mode;
logic start, rdy;
endinterface: simple_bus
module top;
logic clk = 0;
simple_bus sb_intf(); // Instantiate the interface
// Reference the sb_intf instance of the simple_bus
// interface from the generic interfaces of the
// memMod and cpuMod modules
memMod mem (.a(sb_intf), .clk(clk));
cpuMod cpu (.b(sb_intf), .clk(clk));
endmodule
使用 modports(IEEE 1800 的第 25.5 节),您可以指定接口的主从部分来定义端口方向。
正如蒂姆所提到的,我避免使用它,因为它变得非常难以调试。我曾参与过一个大量使用接口的项目。连接不是一对一的,而是通过层次结构到处传播。想象一下寄存器写入发生在 LBUS 上,使用 WiredOR 总线或三态进行回读。我们当时拥有的工具无法让您看到哪个模块正在驱动总线。因此,如果它从多个驱动器中变为 X,那么它就是一个关于导致它的猜测游戏。
我们不仅为标准协议(如 LBUS)使用接口,还为正在动态更改的新协议使用接口,这意味着未针对协议更改进行修复的模块会损坏总线。使用接口大大加快了实现速度,因为额外的信号可以快速集成。由于无法追踪接口问题的根源,因此调试成本几乎是不可能的。