mirror of
https://github.com/corundum/corundum.git
synced 2025-01-16 08:12:53 +08:00
Rewrite priority encoder to remove recusive construction
This commit is contained in:
parent
71bd4a1811
commit
ae10935a93
@ -42,57 +42,43 @@ module priority_encoder #
|
||||
output wire [WIDTH-1:0] output_unencoded
|
||||
);
|
||||
|
||||
// power-of-two width
|
||||
parameter W1 = 2**$clog2(WIDTH);
|
||||
parameter W2 = W1/2;
|
||||
parameter LEVELS = WIDTH > 2 ? $clog2(WIDTH) : 1;
|
||||
parameter W = 2**LEVELS;
|
||||
|
||||
// pad input to even power of two
|
||||
wire [W-1:0] input_padded = {{W-WIDTH{1'b0}}, input_unencoded};
|
||||
|
||||
wire [W/2-1:0] stage_valid[LEVELS-1:0];
|
||||
wire [W/2-1:0] stage_enc[LEVELS-1:0];
|
||||
|
||||
generate
|
||||
if (WIDTH == 1) begin
|
||||
// one input
|
||||
assign output_valid = input_unencoded;
|
||||
assign output_encoded = 0;
|
||||
end else if (WIDTH == 2) begin
|
||||
// two inputs - just an OR gate
|
||||
assign output_valid = |input_unencoded;
|
||||
genvar l, n;
|
||||
|
||||
// process input bits; generate valid bit and encoded bit for each pair
|
||||
for (n = 0; n < W/2; n = n + 1) begin : loop_in
|
||||
assign stage_valid[0][n] = |input_padded[n*2+1:n*2];
|
||||
if (LSB_PRIORITY == "LOW") begin
|
||||
assign output_encoded = input_unencoded[1];
|
||||
assign stage_enc[0][n] = input_padded[n*2+1];
|
||||
end else begin
|
||||
assign output_encoded = ~input_unencoded[0];
|
||||
assign stage_enc[0][n] = !input_padded[n*2+0];
|
||||
end
|
||||
end else begin
|
||||
// more than two inputs - split into two parts and recurse
|
||||
// also pad input to correct power-of-two width
|
||||
wire [$clog2(W2)-1:0] out1, out2;
|
||||
wire valid1, valid2;
|
||||
priority_encoder #(
|
||||
.WIDTH(W2),
|
||||
.LSB_PRIORITY(LSB_PRIORITY)
|
||||
)
|
||||
priority_encoder_inst1 (
|
||||
.input_unencoded(input_unencoded[W2-1:0]),
|
||||
.output_valid(valid1),
|
||||
.output_encoded(out1)
|
||||
);
|
||||
priority_encoder #(
|
||||
.WIDTH(W2),
|
||||
.LSB_PRIORITY(LSB_PRIORITY)
|
||||
)
|
||||
priority_encoder_inst2 (
|
||||
.input_unencoded({{W1-WIDTH{1'b0}}, input_unencoded[WIDTH-1:W2]}),
|
||||
.output_valid(valid2),
|
||||
.output_encoded(out2)
|
||||
);
|
||||
// multiplexer to select part
|
||||
assign output_valid = valid1 | valid2;
|
||||
end
|
||||
|
||||
// compress down to single valid bit and encoded bus
|
||||
for (l = 1; l < LEVELS; l = l + 1) begin : loop_levels
|
||||
for (n = 0; n < W/(2*2**l); n = n + 1) begin : loop_compress
|
||||
assign stage_valid[l][n] = |stage_valid[l-1][n*2+1:n*2];
|
||||
if (LSB_PRIORITY == "LOW") begin
|
||||
assign output_encoded = valid2 ? {1'b1, out2} : {1'b0, out1};
|
||||
assign stage_enc[l][(n+1)*(l+1)-1:n*(l+1)] = stage_valid[l-1][n*2+1] ? {1'b1, stage_enc[l-1][(n*2+2)*l-1:(n*2+1)*l]} : {1'b0, stage_enc[l-1][(n*2+1)*l-1:(n*2+0)*l]};
|
||||
end else begin
|
||||
assign output_encoded = valid1 ? {1'b0, out1} : {1'b1, out2};
|
||||
assign stage_enc[l][(n+1)*(l+1)-1:n*(l+1)] = stage_valid[l-1][n*2+0] ? {1'b0, stage_enc[l-1][(n*2+1)*l-1:(n*2+0)*l]} : {1'b1, stage_enc[l-1][(n*2+2)*l-1:(n*2+1)*l]};
|
||||
end
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// unencoded output
|
||||
assign output_valid = stage_valid[LEVELS-1];
|
||||
assign output_encoded = stage_enc[LEVELS-1];
|
||||
assign output_unencoded = 1 << output_encoded;
|
||||
|
||||
endmodule
|
||||
|
Loading…
x
Reference in New Issue
Block a user