我正在使用用于绑定参数化模块的接口数组。
我的问题是我不能直接将几个简单的接口连接成一个接口数组。
这是我使用的界面的简化版本:
interface channel ();
wire req;
wire ack;
modport in (input req output ack);
modport out(input ack output req);
endinterface
我想做的是:
Channel array[2]();
Channel elem0();
Channel elem1();
"assign" array = '{elem0,elem1};
我找到了一种解决方法,使用一个独立分配每条线的模块:
module passthrough (Channel.in from, Channel.out to );
assign to.req = from.req;
assign from.ack = to.ack;
endmodule
使用它,我必须将每个成员元素“投射”到每个数组成员中。使用前面的示例:
passthrough pass0( .from(elem0), .to(array[0]));
passthrough pass1( .from(elem1), .to(array[1]));
我不喜欢它,因为使用参数化模块的主要想法是让我的 RTL 更清晰、更短且可维护。
我很自然地将这个passthrough
模块的实例化放在一个宏中,但我仍然不满意。
然后我偶然发现了嵌入在界面中的任务。虽然我对 (S)Verilog 中的任务不太熟悉,所以我认为我的想法不会奏效。然而,这是我尝试过的:
interface channel ();
reg req;
reg ack;
modport in (input req output ack);
modport out(input ack output req);
task wrap_from (Channel.in I);
always@* begin
req = I.req;
I.ack = ack;
end
endtask
endinterface
这种方法的优点是每次我需要连接 2 个通道时都不需要创建一个模块。代码行也会更短。
不幸的是,我的编译器(ncsim)在其自己的声明中无法识别channel
为接口(我想它需要endinterface
关键字才能在命名空间中考虑它)。
如果有人有比我更清洁的解决方案来解决这个问题,我将不胜感激。
最后一件事,一切都需要可合成。