summaryrefslogtreecommitdiff
path: root/tb
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2026-06-22 00:50:26 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2026-06-22 00:53:51 +0300
commit76029b9bc1242a9292905cae6f71e080955ceaf2 (patch)
treebbfa5f78edf0516ec59eb1c8545ee8795a270c40 /tb
parentb1ee83cd1ea325a5d353365ac35790a7c1d47845 (diff)
downloadttarv32-76029b9bc1242a9292905cae6f71e080955ceaf2.tar.gz
ttarv32-76029b9bc1242a9292905cae6f71e080955ceaf2.zip
add simple round-robin arbiter
+ Should check how well it synthesises with OpenROAD or something, Vivado seemed to kind of choke on it and it was way slower/bigger than I was expecting.
Diffstat (limited to 'tb')
-rw-r--r--tb/Makefile7
-rw-r--r--tb/arb_tb.sv78
2 files changed, 84 insertions, 1 deletions
diff --git a/tb/Makefile b/tb/Makefile
index f34cb5e..f67e6af 100644
--- a/tb/Makefile
+++ b/tb/Makefile
@@ -1,4 +1,4 @@
-all: rv2insn sched ttarv32
+all: rv2insn sched arb ttarv32
.PHONY: sched
sched: sched_tb.sv ../src/sched.sv ../src/common.svh
@@ -13,6 +13,11 @@ rv2insn: rv2insn_tb.sv ../src/rv2insn.sv ../src/common.svh
verilator --Mdir rv2insn_objdir --assert --trace --binary -I../src rv2insn_tb.sv
./rv2insn_objdir/Vrv2insn_tb
+.PHONY: arb
+arb: arb_tb.sv ../src/arb.sv
+ verilator --Mdir arb_objdir --assert --trace --binary -I../src arb_tb.sv
+ ./arb_objdir/Varb_tb
+
.PHONY: ttarv32
ttarv32: ttarv32_tb.sv ../src/ttarv32.sv ../src/rv2insn.sv ../src/sched.sv ../src/common.svh
riscv32-unknown-elf-gcc -ffreestanding -nostdlib -march=rv32i -mabi=ilp32 \
diff --git a/tb/arb_tb.sv b/tb/arb_tb.sv
new file mode 100644
index 0000000..909c5b2
--- /dev/null
+++ b/tb/arb_tb.sv
@@ -0,0 +1,78 @@
+module arb_tb;
+
+localparam WIDTH = 32;
+
+reg clk;
+reg rstx;
+logic[WIDTH-1:0] cand;
+logic[WIDTH-1:0] selected;
+
+arb #(
+ .WIDTH(32)
+) arb_i (
+ .clk(clk),
+ .rstx(rstx),
+ .cand(cand),
+ .selected(selected)
+);
+
+initial begin
+ clk = 0;
+ forever begin
+ #5 clk = ~clk;
+ end
+end
+
+initial begin
+ $dumpfile("arb_tb.fst");
+ $dumpvars();
+
+ /* trigger resets */
+ rstx = 0;
+ #10 rstx = 1;
+
+ /* honestly, I'm a bit confused about this, if I try to make this be at
+ * a positive clock edge, the selected == 1 condition disappears because
+ * cand apparently triggers `selected` to be recalculated first, which
+ * then is fed into `mask` which then re-triggers `selected` and causes
+ * it to 'skip' ahead to selected == 2. When looking at the waveforms,
+ * the next @(posedge clk) shows 2 while the assert passes. I guess the
+ * assert is run first in the time step...? */
+ cand = ~0;
+
+ @(posedge clk);
+ assert (selected == 1)
+ else $error("expected 1, got ", selected);
+
+ @(posedge clk);
+ assert (selected == 2)
+ else $error("expected 2, got ", selected);
+
+ /* wait one clock cycle, should move forward by one */
+ @(posedge clk);
+ assert (selected == 4)
+ else $error("expected 4, got ", selected);
+
+ /* skip next index */
+ cand = '0;
+
+ @(posedge clk);
+ assert (selected == 0)
+ else $error("expected 0, got ", selected);
+
+ cand = ~8;
+
+ @(posedge clk);
+ assert (selected == 16)
+ else $error("expected 16, got ", selected);
+
+ /* check that ID wraps around nicely */
+ for (int i = 0; i < 32 - 4; ++i)
+ @(posedge clk);
+
+ assert (selected == 1)
+ else $error("wraparound broken, expected 1, got ", selected);
+
+ $finish;
+end
+endmodule