Connection modules in combination circuit Verilog or SystemVerilog
I want to connect multiple instances of a module up in a grid with column and row connections (like in a diagram). Can I do this with nested generation blocks? I need the code to be scalable because the design is big.
Output 1 of the module is controlled to input 1 of the module to the left of it. The outputs of the 2.3 module are driven to the inputs of the 2.3 module below it.
Edit my question after Morgan's answer: I'm trying to give as input a slice of each array using the following code:
module top(
//Inputs to system:
input out1[0][1:3],
input out2[1:3][0],
input out3[1:3][0]
);
wire out1[0:3][1:3];
wire out2[1:3][0:3];
wire out3[1:3][0:3];
I cannot compile it. What's my error? I tried to figure out myself but couldn't.
source to share
New answer based on edited question. The answer will work through my process, understanding the problem and clarifying, otherwise the generators used will be quite difficult to understand. Skip to the bottom to see the generation syntax.
First, an example of the desired relationship from this diagram.
Basic module:
module m (
input in1,
input in2,
input in3,
output out1,
output out2,
output out3
);
endmodule
Connection example:
//row 1 to drive row 2 (in2/3)
//column 1 to drive column 2 (in1)
//port _ col(x) _ row(y)
wire out1_1_1, out2_1_1, out3_1_1;
wire out1_1_2, out2_1_2, out3_1_2;
wire out1_1_3, out2_1_3, out3_1_3;
wire out1_2_1, out2_2_1, out3_2_1;
wire out1_2_2, out2_2_2, out3_2_2;
wire out1_2_3, out2_2_3, out3_2_3;
wire out1_3_1, out2_3_1, out3_3_1;
wire out1_3_2, out2_3_2, out3_3_2;
wire out1_3_3, out2_3_3, out3_3_3;
//First column
m m_1_1( .in1( ? ), .in2( ? ), .in3( ? ),
.out1(out1_1_1), .out2(out2_1_1), .out3(out3_1_1) );
m m_1_2( .in1( ? ), .in2( out2_1_1), .in3( out3_1_1),
.out1(out1_1_2), .out2(out2_1_2), .out3(out3_1_2) ); //in2/3 driven from 0_0 (Above)
m m_1_3( .in1( ? ), .in2( out2_1_2), .in3( out3_1_2),
.out1(out1_1_3), .out2(out2_1_3), .out3(out3_1_3) ); //in2/3 driven from 0_1 (above)
//Second Vertical column, in1 driven from previous column.
m m_2_1( .in1( out1_1_1), .in2( ? ), .in3( ? ),
.out1(out1_2_1), .out2(out2_2_1), .out3(out3_2_1) );
m m_2_2( .in1( out1_1_2), .in2( out2_2_1), .in3( out3_2_1),
.out1(out1_2_2), .out2(out2_2_2), .out3(out3_2_2) );
m m_2_3( .in1( out1_1_3), .in2( out2_2_2), .in3( out3_2_2),
.out1(out1_2_3), .out2(out2_2_3), .out3(out3_2_3) );
m m_3_1( .in1( out1_2_1), .in2( ? ), .in3( ? ).
.out1(out1_3_1), .out2(out2_3_1), .out3(out3_3_1) );
m m_3_2( .in1( out1_2_2), .in2( out2_3_1), .in3( out3_3_1),
.out1(out1_3_2), .out2(out2_3_2), .out3(out3_3_2) );
m m_3_3( .in1( out1_2_3), .in2( out2_3_2), .in3( out3_3_2),
.out1(out1_3_3), .out2(out2_3_3), .out3(out3_3_3) );
The xy numbers encoded in the wires can become an index to the array that can be used with the generate operators, the main problem to overcome is connecting the primary inputs noted above with ?
Filling in those spaces to match the pattern will result in multiple "0" indices, so I started with 1 for the first example. Then add:
//Inputs to system:
wire out1_0_1, out1_0_2, out1_0_3;
wire out2_1_0, out3_1_0;
wire out2_2_0, out3_2_0;
wire out2_3_0, out3_3_0;
//First column
m m_1_1( .in1( out1_0_1), .in2( out2_1_0), .in3( out3_1_0),
.out1(out1_1_1), .out2(out2_1_1), .out3(out3_1_1) );
m m_1_2( .in1( out1_0_2), .in2( out2_1_1), .in3( out3_1_1),
.out1(out1_1_2), .out2(out2_1_2), .out3(out3_1_2) ); //in2/3 driven from 0_0 (Above)
m m_1_3( .in1( out1_0_3), .in2( out2_1_2), .in3( out3_1_2),
.out1(out1_1_3), .out2(out2_1_3), .out3(out3_1_3) ); //in2/3 driven from 0_1 (above)
//Second Vertical column, in1 driven from previous column.
m m_2_1( .in1( out1_1_1), .in2( out2_2_0), .in3( out3_2_0),
.out1(out1_2_1), .out2(out2_2_1), .out3(out3_2_1) );
m m_2_2( .in1( out1_1_2), .in2( out2_2_1), .in3( out3_2_1),
.out1(out1_2_2), .out2(out2_2_2), .out3(out3_2_2) );
m m_2_3( .in1( out1_1_3), .in2( out2_2_2), .in3( out3_2_2),
.out1(out1_2_3), .out2(out2_2_3), .out3(out3_2_3) );
m m_3_1( .in1( out1_2_1), .in2( out2_3_0), .in3( out3_3_0).
.out1(out1_3_1), .out2(out2_3_1), .out3(out3_3_1) );
m m_3_2( .in1( out1_2_2), .in2( out2_3_1), .in3( out3_3_1),
.out1(out1_3_2), .out2(out2_3_2), .out3(out3_3_2) );
m m_3_3( .in1( out1_2_3), .in2( out2_3_2), .in3( out3_3_2),
.out1(out1_3_3), .out2(out2_3_3), .out3(out3_3_3) );
Now, vecturing the wires for use in generation, we get:
wire out1[0:3][1:3];
wire out2[1:3][0:3];
wire out3[1:3][0:3];
//First column
m m_1_1( .in1( out1[0][1]), .in2( out2[1][0]), .in3( out3[1][0]),
.out1(out1[1][1]), .out2(out2[1][1]), .out3(out3[1][1]) );
m m_1_2( .in1( out1[0][2]), .in2( out2[1][1]), .in3( out3[1][1]),
.out1(out1[1][2]), .out2(out2[1][2]), .out3(out3[1][2]) ); //in2/3 driven from 0_0 (Above)
m m_1_3( .in1( out1[0][3]), .in2( out2[1][2]), .in3( out3[1][2]),
.out1(out1[1][3]), .out2(out2[1][3]), .out3(out3[1][3]) ); //in2/3 driven from 0_1 (above)
//Second Vertical column, in1 driven from previous column.
m m_2_1( .in1( out1[1][1]), .in2( out2[2][0]), .in3( out3[2][0]),
.out1(out1[2][1]), .out2(out2[2][1]), .out3(out3[2][1]) );
m m_2_2( .in1( out1[1][2]), .in2( out2[2][1]), .in3( out3[2][1]),
.out1(out1[2][2]), .out2(out2[2][2]), .out3(out3[2][2]) );
m m_2_3( .in1( out1[1][3]), .in2( out2[2][2]), .in3( out3[2][2]),
.out1(out1[2][3]), .out2(out2[2][3]), .out3(out3[2][3]) );
m m_3_1( .in1( out1[2][1]), .in2( out2[3][0]), .in3( out3[3][0]).
.out1(out1[3][1]), .out2(out2[3][1]), .out3(out3[3][1]) );
m m_3_2( .in1( out1[2][2]), .in2( out2[3][1]), .in3( out3[3][1]),
.out1(out1[3][2]), .out2(out2[3][2]), .out3(out3[3][2]) );
m m_3_3( .in1( out1[2][3]), .in2( out2[3][2]), .in3( out3[3][2]),
.out1(out1[3][3]), .out2(out2[3][3]), .out3(out3[3][3]) );
Now you just need to define the template and equations for the indices.
m m_x_y( .in1( out1[x-1][y]), .in2( out2[x][y-1]), .in3( out3[x][y-1]),
.out1(out1[x ][y]), .out2(out2[x][y ]), .out3(out3[x][y ]) );
TL; DR
After completing this, you will receive the following:
//Inputs to system:
//out1[0][1], out1[0][2], out1[0][3]
//out2[1][0], out3[1][0]
//out2[2][0], out3[2][0]
//out2[3][0], out3[3][0]
parameter WIDTH = 3;
parameter DEPTH = 3;
wire out1[0:WIDTH][1:DEPTH];
wire out2[1:WIDTH][0:DEPTH];
wire out3[1:WIDTH][0:DEPTH];
genvar x;
genvar y;
generate
for(y=1; y<=DEPTH; y++) begin
for (x=1; x<=WIDTH; x++) begin
m m_x_y( .in1( out1[x-1][y]), .in2( out2[x][y-1]), .in3( out3[x][y-1]),
.out1(out1[x ][y]), .out2(out2[x][y ]), .out3(out3[x][y ]) );
end
end
endgenerate
Inputs
Inputs can be connected via assigns:
module xor (
input in1,
input in2,
//...
);
parameter WIDTH = 3;
parameter DEPTH = 3;
wire out1[0:WIDTH][1:DEPTH];
wire out2[1:WIDTH][0:DEPTH];
wire out3[1:WIDTH][0:DEPTH];
assign out1[0][1] = in1;
assign out1[0][2] = in2;
// etc
source to share