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
|
output wire [WIDTH-1:0] output_unencoded
|
||||||
);
|
);
|
||||||
|
|
||||||
// power-of-two width
|
parameter LEVELS = WIDTH > 2 ? $clog2(WIDTH) : 1;
|
||||||
parameter W1 = 2**$clog2(WIDTH);
|
parameter W = 2**LEVELS;
|
||||||
parameter W2 = W1/2;
|
|
||||||
|
// 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
|
generate
|
||||||
if (WIDTH == 1) begin
|
genvar l, n;
|
||||||
// one input
|
|
||||||
assign output_valid = input_unencoded;
|
// process input bits; generate valid bit and encoded bit for each pair
|
||||||
assign output_encoded = 0;
|
for (n = 0; n < W/2; n = n + 1) begin : loop_in
|
||||||
end else if (WIDTH == 2) begin
|
assign stage_valid[0][n] = |input_padded[n*2+1:n*2];
|
||||||
// two inputs - just an OR gate
|
|
||||||
assign output_valid = |input_unencoded;
|
|
||||||
if (LSB_PRIORITY == "LOW") begin
|
if (LSB_PRIORITY == "LOW") begin
|
||||||
assign output_encoded = input_unencoded[1];
|
assign stage_enc[0][n] = input_padded[n*2+1];
|
||||||
end else begin
|
end else begin
|
||||||
assign output_encoded = ~input_unencoded[0];
|
assign stage_enc[0][n] = !input_padded[n*2+0];
|
||||||
end
|
end
|
||||||
end else begin
|
end
|
||||||
// more than two inputs - split into two parts and recurse
|
|
||||||
// also pad input to correct power-of-two width
|
// compress down to single valid bit and encoded bus
|
||||||
wire [$clog2(W2)-1:0] out1, out2;
|
for (l = 1; l < LEVELS; l = l + 1) begin : loop_levels
|
||||||
wire valid1, valid2;
|
for (n = 0; n < W/(2*2**l); n = n + 1) begin : loop_compress
|
||||||
priority_encoder #(
|
assign stage_valid[l][n] = |stage_valid[l-1][n*2+1:n*2];
|
||||||
.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;
|
|
||||||
if (LSB_PRIORITY == "LOW") begin
|
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
|
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
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
// unencoded output
|
assign output_valid = stage_valid[LEVELS-1];
|
||||||
|
assign output_encoded = stage_enc[LEVELS-1];
|
||||||
assign output_unencoded = 1 << output_encoded;
|
assign output_unencoded = 1 << output_encoded;
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
Loading…
x
Reference in New Issue
Block a user