【问题标题】:Verilog Ports in Generate Loop生成循环中的 Verilog 端口
【发布时间】:2016-02-14 02:41:16
【问题描述】:

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

【问题讨论】:

  • 您可以使用矢量化端口 (input [COUNT-1:0] bar) 编写您的模块,然后编写一个代码生成器(例如,直接在您的 TCL 脚本中)为一个简单的包装器模块创建 verilog 文件,该包装器模块提供以下类型Qsys 中需要的接口。不理想,但可能仍然比手动操作有所改进。
  • 我没有得到,你到底想要做什么。您能否分享一下您如何使用/实例化该模块的代码片段?
  • @KaranShah 我认为这个例子很清楚。在 Qsys(图形系统构建器)中,对于上面的示例,我将有四个接口,它们将连接到其他东西。 Qsys 不能将向量的位 0 分配给一个接口,只能分配整个接口。这意味着我不必执行input [3:0] bar,而必须执行input bar_0, input bar_1, ...。然后我必须在模块内部执行wire[3:0] bar; assign bar = {bar_3,bar_2,bar_1,bar_0} 之类的操作,以便能够将bar_* 端口用作向量。
  • @CliffordVienna 这听起来是个好主意,我会研究一下。
  • @TomCarpenter:我已经发布了一个答案。相信对你有帮助

标签: verilog quartus qsys


【解决方案1】:

我想,在你的情况下,可以用来解决你的问题。因此,在任何地方,在您的代码中,您都可以使用 bar 作为向量,尽管它不是。

定义一个这样的宏:

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

您可以使用 now bar 作为矢量,如下所示:

`bar(0)
`deadbeef(0)

【讨论】:

  • 我考虑过这种方法,但可惜它只适用于 SystemVerilog(不是世界末日),但更关键的是,它不适用于 generate for 循环。例如. `deadbeef(idx) 将扩展为deafbeef_idx 而不是genvar idx 的值。不过谢谢你的建议。我仍然需要写出所有代码来将接口端口合并到一个数组中。
  • 在这种情况下,您可以使用 2 个宏来处理相同的变量。 `deadbeef(x) 和`deadbeef_gen(x)。要使用其他语言,您始终可以按照 verilog 语言编译此代码,然后将详细代码与其他语言合并。
猜你喜欢
  • 2018-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多