System verilog 在实例化此模块时,为什么必须反转输入和输出的连接顺序?

System verilog 在实例化此模块时,为什么必须反转输入和输出的连接顺序?,system-verilog,System Verilog,我有一个模块(称之为child),它将输入和输出声明为二维数组。我还有一个模块(parent)实例化child。2D阵列在parent中被分解为单个信号 为了正确分配父级和子级之间的输入和输出,我必须颠倒输入和输出之间的连接顺序 请参阅以下代码示例,以更清楚地了解我的意思: module child ( // Inputs and outputs declared as 2D arrays input [4:0] my_input[8], output [4:0] my

我有一个模块(称之为
child
),它将输入和输出声明为二维数组。我还有一个模块(
parent
)实例化
child
。2D阵列在
parent
中被分解为单个信号

为了正确分配
父级
子级
之间的输入和输出,我必须颠倒输入和输出之间的连接顺序

请参阅以下代码示例,以更清楚地了解我的意思:

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
希望这段代码是非常自解释的。如上所述,相关位是
子模块的实例化

运行上述代码时,显示的输出是我期望的(以及我想要的):

但我很困惑,为什么实例化要求我以不同的方式连接输入和输出的信号

这项工作:

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})
);
但这失败了:

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})
);
这也是:

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})
);

提前感谢您提供的任何见解。

您在交叉兼容性方面的最佳选择是避免使用这样的串联,至少对于输出端口是这样。正如您已经看到的,有些工具以一种方式解释连接,有些工具以另一种方式解释连接,而有些工具完全禁止这样做。这在SystemVerilog中非常常见

虽然代码较多,但这项工作可能在所有模拟器中都能正常工作,不会出现问题:

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];

为了更加安全,您可能也应该对输入执行同样的操作。

您使用的是什么模拟器?它在Riviera Pro上运行正常(与您的不同)。我使用的是Modelsim 10.4e2。你说它工作正常是什么意思?我上面粘贴的代码可以工作,我想知道的是为什么它可以工作。看看EDA操场上的代码。是的,我注册时遇到了问题,但我现在加入了。我发现行为会因模拟器的不同而有所不同。有没有一种方法可以使每个模拟器都以相同的方式工作?是的,经过几次实验后,我发现这是我必须采取的方法。谢谢
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];