Reputation: 75
I have a module (call it child
) that declares its input and outputs as 2-dimensional arrays. I also have a module (parent
) that instantiates child
. The 2D arrays are broken out into individual signals in parent
.
In order to get the inputs and outputs between parent
and child
to be assigne correctly, I have to reverse the concatenation order between the inputs and outputs.
See the following code example to see what I mean more clearly:
module child (
// Inputs and outputs declared as 2D arrays
input [4:0] my_input[8],
output [4:0] my_output[8]
);
// Dummy assignemts just for clarity, values will be printed in parent
assign my_output[0] = 9;
assign my_output[1] = 10;
assign my_output[2] = 11;
assign my_output[3] = 12;
assign my_output[4] = 13;
assign my_output[5] = 14;
assign my_output[6] = 15;
assign my_output[7] = 16;
initial begin
#2;
// Print out to show how inputs are driven by parent
$display("in child, my_input[0]: %0d, expecting 1 (set by parent)", my_input[0]);
$display("in child, my_input[1]: %0d, expecting 2 (set by parent)", my_input[1]);
$display("in child, my_input[2]: %0d, expecting 3 (set by parent)", my_input[2]);
$display("in child, my_input[3]: %0d, expecting 4 (set by parent)", my_input[3]);
$display("in child, my_input[4]: %0d, expecting 5 (set by parent)", my_input[4]);
$display("in child, my_input[5]: %0d, expecting 6 (set by parent)", my_input[5]);
$display("in child, my_input[6]: %0d, expecting 7 (set by parent)", my_input[6]);
$display("in child, my_input[7]: %0d, expecting 8 (set by parent)", my_input[7]);
end
endmodule
module parent ();
logic [4:0] the_input0;
logic [4:0] the_input1;
logic [4:0] the_input2;
logic [4:0] the_input3;
logic [4:0] the_input4;
logic [4:0] the_input5;
logic [4:0] the_input6;
logic [4:0] the_input7;
logic [4:0] the_output0;
logic [4:0] the_output1;
logic [4:0] the_output2;
logic [4:0] the_output3;
logic [4:0] the_output4;
logic [4:0] the_output5;
logic [4:0] the_output6;
logic [4:0] the_output7;
// Dummy assignemts just for clarity, values will be printed in child
assign the_input0 = 1;
assign the_input1 = 2;
assign the_input2 = 3;
assign the_input3 = 4;
assign the_input4 = 5;
assign the_input5 = 6;
assign the_input6 = 7;
assign the_input7 = 8;
initial begin
#1;
// Print out to show how inputs are driven by child
$display("in parent, the_output0: %0d, expect 9 (set by child)", the_output0);
$display("in parent, the_output1: %0d, expect 10 (set by child)", the_output1);
$display("in parent, the_output2: %0d, expect 11 (set by child)", the_output2);
$display("in parent, the_output3: %0d, expect 12 (set by child)", the_output3);
$display("in parent, the_output4: %0d, expect 13 (set by child)", the_output4);
$display("in parent, the_output5: %0d, expect 14 (set by child)", the_output5);
$display("in parent, the_output6: %0d, expect 15 (set by child)", the_output6);
$display("in parent, the_output7: %0d, expect 16 (set by child)", the_output7);
end
// -------------------------
// THIS IS THE IMPORTANT BIT
// -------------------------
// Note that the signals concatenated for my_input are 0 to 7, but the
// output signals are 7 to 0. Why is this??
child child (
.my_input({the_input0, the_input1, the_input2, the_input3, the_input4, the_input5, the_input6, the_input7}),
.my_output({the_output7, the_output6, the_output5, the_output4, the_output3, the_output2, the_output1, the_output0})
);
endmodule
Hopefully that code is pretty self-explanatory. As I mentioned above, the relevant bit is the instantiation of the child
module.
When the code above is run, the displayed output is what I expect (and what I want):
# in parent, the_output0: 9, expect 9 (set by child)
# in parent, the_output1: 10, expect 10 (set by child)
# in parent, the_output2: 11, expect 11 (set by child)
# in parent, the_output3: 12, expect 12 (set by child)
# in parent, the_output4: 13, expect 13 (set by child)
# in parent, the_output5: 14, expect 14 (set by child)
# in parent, the_output6: 15, expect 15 (set by child)
# in parent, the_output7: 16, expect 16 (set by child)
# in child, my_input[0]: 1, expecting 1 (set by parent)
# in child, my_input[1]: 2, expecting 2 (set by parent)
# in child, my_input[2]: 3, expecting 3 (set by parent)
# in child, my_input[3]: 4, expecting 4 (set by parent)
# in child, my_input[4]: 5, expecting 5 (set by parent)
# in child, my_input[5]: 6, expecting 6 (set by parent)
# in child, my_input[6]: 7, expecting 7 (set by parent)
# in child, my_input[7]: 8, expecting 8 (set by parent)
But I am confused why the instantiation requires me to concatenate the signals differently for inputs vs outputs.
This works:
child child (
// 0 to 7
.my_input({the_input0, the_input1, the_input2, the_input3, the_input4, the_input5, the_input6, the_input7}),
// 7 to 0
.my_output({the_output7, the_output6, the_output5, the_output4, the_output3, the_output2, the_output1, the_output0})
);
but this fails:
child child (
// 7 to 0
.my_input({the_input7, the_input6, the_input5, the_input4, the_input3, the_input2, the_input1, the_input0}),
// 7 to 0
.my_output({the_output7, the_output6, the_output5, the_output4, the_output3, the_output2, the_output1, the_output0})
);
and so does this:
child child (
// 0 to 7
.my_input({the_input0, the_input1, the_input2, the_input3, the_input4, the_input5, the_input6, the_input7}),
// 0 to 7
.my_output({the_output0, the_output1, the_output2, the_output3, the_output4, the_output5, the_output6, the_output7})
);
Thanks in advance for any insights.
Upvotes: 1
Views: 1483
Reputation: 7573
Your best bet at cross-compatibility is to avoid using concatenation like this, at least for the output ports. As you've already seen, some tools interpret the connections in one way, some tools in a different way, while some tools forbid this altogether. This is quite common when it comes to SystemVerilog.
While it's more code, this works will probably work in all simulators without issues:
logic [4:0] outputs[8];
child child (
.my_input({the_input0, the_input1, the_input2, the_input3,
the_input4, the_input5, the_input6, the_input7}),
.my_output(outputs)
);
assign the_output0 = outputs[0];
assign the_output1 = outputs[1];
assign the_output2 = outputs[2];
assign the_output3 = outputs[3];
assign the_output4 = outputs[4];
assign the_output5 = outputs[5];
assign the_output6 = outputs[6];
assign the_output7 = outputs[7];
You should probably do the same for inputs, just to be extra safe.
Upvotes: 3