summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2026-07-22 20:56:59 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2026-07-22 20:56:59 +0300
commitbc5941a1fcfd0a607a6aef51f7659c3f233b65dc (patch)
tree89fb6166a698b7a1f2a71276432218ad1a364994 /src
parent0c9c1538996c4e5120a9d409edd6b1cd5c07d22f (diff)
downloadttarv32-master.tar.gz
ttarv32-master.zip
simplift arbHEADmaster
+ Had a higher fMax and smaller area compared to previous attempt, at least when synthesized with OpenROAD
Diffstat (limited to 'src')
-rw-r--r--src/arb.sv99
1 files changed, 21 insertions, 78 deletions
diff --git a/src/arb.sv b/src/arb.sv
index 15d89b3..6dbd6a6 100644
--- a/src/arb.sv
+++ b/src/arb.sv
@@ -1,99 +1,42 @@
-module first_set #(
- parameter WIDTH = 32
-)(
- input reg[WIDTH-1 :0] cand,
- output reg[WIDTH-1 :0] selected
-);
-
-/* base case */
-if (WIDTH == 1) begin :base
- assign selected = cand;
-end
-
-/* recursive case */
-else begin :recursive
- localparam SLICE_WIDTH = WIDTH / 2;
- logic[SLICE_WIDTH-1:0] left, right;
- logic pref_left, pref_right;
- logic empty_left, empty_right;
-
- first_set #(
- .WIDTH(SLICE_WIDTH)
- ) first_set_left (
- .cand(cand[SLICE_WIDTH +: SLICE_WIDTH]),
- .selected (left)
- );
-
- first_set #(
- .WIDTH(SLICE_WIDTH)
- ) first_set_right (
- .cand(cand[0 +: SLICE_WIDTH]),
- .selected (right)
- );
-
- assign selected = right != '0
- ? {{SLICE_WIDTH{1'b0}}, right}
- : {left, {SLICE_WIDTH{1'b0}}}
- ;
-end
-
-always_comb begin
- assert ($onehot0(selected));
-end
-
-`ifdef NOSUCHDEF
-/* assertions that verilator don't support, apparently */
-assert property (WIDTH >= 1)
-else $error("input width too narrow");
-
-assert property (1 << $clog2(WIDTH) == WIDTH)
-else $error("width not pow2");
-
-`endif
-
-endmodule // arb_recursive
-
module arb #(
parameter WIDTH = 32
)(
input clk,
input rstx,
- input [WIDTH-1:0] cand,
+ input [WIDTH-1:0] valid,
output[WIDTH-1:0] selected
);
-localparam W2 = 1 << $clog2(WIDTH);
-localparam DEPTH = W2 == 1 ? 1 : $clog2(W2);
+logic found0, found1;
+logic [WIDTH-1:0] mask, next_mask0, next_mask1, cand0, cand1;
-logic[W2-1:0] w2_cand, w2_selected, mask, next_mask, rot_selected;
+always_comb begin
+ found0 = 0;
+ found1 = 0;
+ for (int i = 0; i < WIDTH; ++i) begin
+ cand0[i] = !found0 & valid[i] & mask[i];
+ cand1[i] = !found1 & valid[i];
-/* if there are candidates within the mask of 'above preferred index', use them,
- * otherwise invert the mask and use candidates 'below' preferred index. */
-assign w2_cand = ((cand & mask) == '0) ? cand & ~mask : cand & mask;
+ next_mask0[i] = found0;
+ next_mask1[i] = found1;
-first_set #(
- .WIDTH(W2)
-) first_set_i (
- .cand (w2_cand),
- .selected(w2_selected)
-);
+ if (valid[i] & mask[i])
+ found0 = 1;
-assign selected = w2_selected;
-
-assign rot_selected = {
- w2_selected[0 +: W2-1],
- w2_selected[W2-1]
-};
+ if (valid[i])
+ found1 = 1;
+ end
+end
-assign next_mask = ~(rot_selected - 1) | rot_selected;
+assign selected = found0 ? cand0 : cand1;
always_ff @(posedge clk or negedge rstx)
if (!rstx) begin
- mask <= ~0;
+ mask <= '0;
end else begin
- if (selected != 0 && mask != next_mask)
- mask <= next_mask;
+ if (|valid)
+ mask <= found0 ? next_mask0 : next_mask1;
else
mask <= mask;
end