我有一个包含n x n子模块网格的模块,其中每个子模块都连接到网格中的4个邻居。每个子模块大致如下所示:
| up_in
V
____________
left_in | | right_out
---------> | submodule | --------->
|___________|
|
| down_out
V
顶部/底部行和最左/最右列中的子模块的接线方式必须与其余子模块不同,因为它们位于边缘。像下面这样的代码可以正常工作,但是很冗长,并且重复很多:
for (genvar row = 0; row < SIZE; row++) begin
for (genvar col = 0; col < SIZE; col++) begin
if (col == 0) begin
if (row == 0) begin
submodule sub(.left_in(special), .up_in(special), .right_out(normal), .down_out(normal))
end else if (row < SIZE - 1) begin
submodule sub(.left_in(special), .up_in(normal), .right_out(normal), .down_out(normal))
end else begin
submodule sub(.left_in(special), .up_in(normal), .right_out(normal), .down_out(special))
end
end else if (col < SIZE - 1) begin
if (row == 0) begin
submodule sub(.left_in(normal), .up_in(special), .right_out(normal), .down_out(normal))
end else if (row < SIZE - 1) begin
submodule sub(.left_in(normal), .up_in(normal), .right_out(normal), .down_out(normal))
end else begin
submodule sub(.left_in(normal), .up_in(normal), .right_out(normal), .down_out(special))
end
end else begin
if (row == 0) begin
submodule sub(.left_in(normal), .up_in(special), .right_out(special), .down_out(normal))
end else if (row < SIZE - 1) begin
submodule sub(.left_in(normal), .up_in(normal), .right_out(special), .down_out(normal))
end else begin
submodule sub(.left_in(normal), .up_in(normal), .right_out(special), .down_out(special))
end
end
end
end
该子模块实际上具有4个以上的端口,因此修改端口的速度很慢且容易出错。我希望能够执行以下操作:
for (genvar row = 0; row < SIZE; row++) begin
for (genvar col = 0; col < SIZE; col++) begin
submodule sub(
.left_in(col == 0 ? special : normal),
.up_in(row == 0 ? special : normal),
.right_out(col == SIZE - 1 ? special : normal),
.down_out(row == SIZE - 1 ? special : normal)
);
end
end
但是这似乎不起作用,因为我不认为在制定时就对三元进行评估-我认为它们实际上已经变成了在设计中持久存在的多路复用器。我使用的三进制错误吗?是否有一些简洁的方法来生成此n x n子模块网格?
答案 0 :(得分:1)
您可以通过首先创建用于通用连接的阵列来简化。阵列必须足够大以容纳所有连接,包括输入和输出。
// vector row col
wire [WIDTH-1:0] leftright [SIZE] [SIZE+1];
wire [WIDTH-1:0] updown [SIZE+1][SIZE];
for( genvar row=0; row<SIZE; row=row+1) begin : r
for( genvar col=0; col<SIZE; col=col+1) begin : c
submodule #(WIDTH) sub(
.left_in(leftright[row][col]),
.up_in(updown[row][col]),
.right_out(leftright[row][col+1]),
.down_out(updown[row+1][col])
);
end
end
现在您有了一个链接子模块的数组,您可以根据需要将输入和输出映射到该数组。例如:
for( genvar i=0; i<SIZE; i++ ) begin : io_mapping
// inputs
assign leftright[i][0] = toplevel_left_in[i*WIDTH +: WIDTH];
assign updown[0][i] = toplevel_up_in[ i*WIDTH +: WIDTH];
// outputs
assign toplevel_right_out[i*WIDTH +: WIDTH] = leftright[i][SIZE];
assign toplevel_down_out[ i*WIDTH +: WIDTH] = updown[SIZE][i];
end
注意:Verilog不支持3维以上的数组; SystemVerilog可以。要使用Verilog,请更改:
// vector row col
wire [WIDTH-1:0] leftright [SIZE] [SIZE+1];
wire [WIDTH-1:0] updown [SIZE+1][SIZE];
// ...
.left_in(leftright[row][col]),
.up_in(updown[row][col]),
.right_out(leftright[row][col+1]),
.down_out(updown[row+1][col])
// ...
收件人:
// vector row col
wire [WIDTH-1:0] leftright [0:( SIZE *(SIZE+1)) -1];
wire [WIDTH-1:0] updown [0:((SIZE+1)*SIZE ) -1];
// ...
.left_in( leftright[ row*(SIZE+1) + col]),
.up_in( updown[ row*SIZE + col]),
.right_out(leftright[ row*(SIZE+1) + col+1]),
.down_out( updown[ (row+1)*SIZE + col])
// ...