我猜你想要一个模块,它comparator
以一种看起来像你的图表的方式多次实例化模块。您需要一个数组(在我的解决方案中是二维的)是由参数控制的宽度以获得最佳灵活性。在generate
块内部使用for-loops
和if-else
语句来建立连接。我的解决方案使用数组的切片,例如+:
.
这遵循 IEEE 标准 (1800-2009),也应该适用于 IEEE 标准 (1800-2005)。
module comparator_list #(parameter int SIZE=10) (input logic [7:0] in [SIZE-1:0], output logic [7:0] out [SIZE-1:0]);
generate
if (SIZE==1) begin : pass_through
always_comb out = in;
end : pass_through
else if (SIZE==2) begin : simple
comparator c0 ( .max(out[0]), .min(out[1]), .in0(in[0]), .in1(in[1]) );
end : simple
else if (SIZE%2==1) begin : odd_list
logic [7:0] in_buf [SIZE:0];
logic [7:0] out_buf [SIZE:0];
always_comb begin : link_in
foreach(in[idx]) in_buf[idx] = in[idx];
in_buf[SIZE] = 8'h00; // force last entry to 'h0 if unasigned, 'h80 if signed
end : link_in
always_comb begin : link_out
foreach(out[idx]) out[idx] = out_buf[idx];
// Note: out_buf[SIZE] is don't care
end : link_out
comparator_list #(SIZE+1) cl (.in(in_buf), .out(out_buf));
end : odd_list
else begin : even_list
logic [(SIZE/2)*8-1:0] top [SIZE+1];
logic [(SIZE/2)*8-1:0] bot [SIZE+1];
for(genvar idx=0; idx<SIZE/2; idx+=1) begin : map
always_comb {top[0][idx*8+:8],bot[0][idx*8+:8]} = {in[2*idx],in[2*idx+1]};
always_comb {out[2*idx],out[2*idx+1]} = {top[SIZE][idx*8+:8],bot[SIZE][idx*8+:8]};
end : map
for(genvar stage=0; stage<SIZE; stage++) begin : link
if(stage%2==0) begin : even
comparator c0[SIZE/2-1:0] (
.max(top[stage+1][0+:(SIZE/2)*8]), .in0(top[stage][0+:(SIZE/2)*8]),
.min(bot[stage+1][0+:(SIZE/2)*8]), .in1(bot[stage][0+:(SIZE/2)*8]) );
end : even
else begin : odd
assign top[stage+1][7:0] = top[stage][7:0];
comparator c1[SIZE/2-2:0] (
.max(bot[stage+1][0+:(SIZE/2-1)*8]),
.min(top[stage+1][8+:(SIZE/2-1)*8]),
.in0(bot[stage][0+:(SIZE/2-1)*8]),
.in1(top[stage][8+:(SIZE/2-1)*8])
);
assign bot[stage+1][(SIZE/2-1)*8+:8] = bot[stage][(SIZE/2-1)*8+:8];
end : odd
end : link
end : even_list
endgenerate
endmodule : comparator_list