由于无法避免的原因(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 循环并连接循环变量来命名。