I am working with interfaces array used to bind parametrized modules.
My problem is that I cannot directly concatenate several simple interfaces into an array of interfaces.
Here is a light version of the interface that I use:
interface channel ();
wire req;
wire ack;
modport in (input req output ack);
modport out(input ack output req);
endinterface
What I want to do would be:
Channel array[2]();
Channel elem0();
Channel elem1();
"assign" array = '{elem0,elem1};
I found a workaround using a module that assigns each wire independently:
module passthrough (Channel.in from, Channel.out to );
assign to.req = from.req;
assign from.ack = to.ack;
endmodule
Using it, I have to 'cast' each member element into each array member. Using the previous example:
passthrough pass0( .from(elem0), .to(array[0]));
passthrough pass1( .from(elem1), .to(array[1]));
I do not like it though as the primary idea about using parametrized modules was to make my RTL clearer, shorter and maintainable.
I naturally put the instantiation of this passthroughmodule in a macro but still, I am not satisfied.
I then stumbled on tasks embeded in interfaces. Although I am not quite familiar with tasks in (S)Verilog so I do not think that my idea would work. Here is however what I tried:
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
The advantage of this method would be that I would not need to create a module each time I need to connect 2 channels. The code line would also be shorter.
Unfortunately, my compiler(ncsim) does not recognize channel as an interface inside the its own declaration(I guess it needs the endinterface keyword to consider it in the namespace).
I would be extremely grateful if anyone has a cleaner than solution than me for this problem.
One last thing, everything needs to be synthetisable.