生成循环中的 Verilog 端口



出于无法避免的原因(Qsys的要求(,我有几个Verilog模块,最终有许多端口,如果将它们打包,它们会更容易使用。为了尝试解释我的意思,这里有一个例子:

module foo #(
    COUNT = 4
) (
    //Interface 0
    input  bar_0,
    output deadbeef_0,
    //Interface 1
    input  bar_1,
    output deadbeef_1,
    //Interface 2
    input  bar_2,
    output deadbeef_2,
    //Interface 3
    input  bar_3,
    output deadbeef_3,
);
...
endmodule

现在通常只制作两个矢量化端口(例如 input [COUNT-1:0] bar, (,但是如果信号需要馈送到不同的接口,Qsys 无法应对这种情况 - 您只能选择整个端口,而不仅仅是一个端口的一点。

可以想象,如果在内部您需要在类似generate循环中访问端口,这会非常烦人,如果您的模块具有具有 10 个端口的接口,必须写出 16 次,则尤其成问题!

到目前为止,我一直在做的是手动将映射添加到模块中。再次和示例来解释 - 继续上面的例子,我会在模块的正文中有这样的东西:

wire [COUNT-1:0] bar;
wire [COUNT-1:0] deadbeef;
generate
if (COUNT > 0) begin
    assign bar[0] = bar_0;
    assign deadbeef_0 = deafbeef[0];
end else begin
    assign deadbeef_0 = 1'b0; //Terminate!
end
if (COUNT > 1) begin
    assign bar[1] = bar_1;
    assign deadbeef_1 = deafbeef[1];
end else begin
    assign deadbeef_1 = 1'b0; //Terminate!
end
...
endgenerate
// deadbeef[] and bar[] can now be used as arrays, woop.

在该示例中,即使只为两个信号写出几个接口,也非常乏味!

我内心程序员的每一部分都在尖叫着停止这样做,并且必须有更好的方法。这就引出了我的问题:

有没有简单的方法可以做到这一点?

理想情况下,我会有某种形式的循环为我生成这些映射,从循环变量生成信号名称。但我不确定这在Verilog中是否可行。

另外,为了让事情变得有趣,我一直在为端口使用十六进制,以使写出时更容易,例如:

input bar_0,
input bar_1,
...
input bar_9,
input bar_a,
input bar_b,
...

理想情况下,这个问题的解决方案也可以处理这样的名称,但说实话,如果它简化了事情,我可以轻松地将名称转换为十进制(bar_10(。


如果您想知道,这在 Qsys

中很容易将接口链接到端口,因为 Qsys 使用 TCL 文件进行映射。在 TCL 中,我可以简单地使用 for 循环并连接循环变量来命名。

我想,在您的情况下,可用于解决您的问题。因此,在代码中,您可以在任何地方使用 bar 作为向量,尽管事实并非如此。

定义一个宏,如下所示:

`define bar(n) bar_``n``
`define deadbeef(n) deadbeef_``n``

您可以使用现在的柱线作为矢量,如下所示:

`bar(0)
`deadbeef(0)

最新更新