summaryrefslogtreecommitdiff
path: root/tb/router_tb.sv
diff options
context:
space:
mode:
authorKimplul <kimi.h.kuparinen@gmail.com>2026-09-27 22:30:41 +0300
committerKimplul <kimi.h.kuparinen@gmail.com>2026-09-27 22:30:41 +0300
commitf4afcfa58eb90d14abd55d79640ecda13b23dc21 (patch)
treec0f63b35502d74cbdf3d2bc881675859a235596d /tb/router_tb.sv
parentbc5941a1fcfd0a607a6aef51f7659c3f233b65dc (diff)
downloadttarv32-master.tar.gz
ttarv32-master.zip
implement circular routerHEADmaster
+ Not great latency, but has a fairly high fmax and low resource usage on my FPGA, so go with this for now. Likely better suited for data path, unsure what I'll do for the control path.
Diffstat (limited to 'tb/router_tb.sv')
-rw-r--r--tb/router_tb.sv153
1 files changed, 153 insertions, 0 deletions
diff --git a/tb/router_tb.sv b/tb/router_tb.sv
new file mode 100644
index 0000000..ba83568
--- /dev/null
+++ b/tb/router_tb.sv
@@ -0,0 +1,153 @@
+`include "common.svh"
+
+module router_tb;
+
+logic clk, rstx;
+
+typedef struct packed {
+ logic [7:0] node;
+ logic [7:0] dev;
+} ds_t;
+
+typedef struct packed {
+ ds_t src;
+ ds_t dst;
+} addr_t;
+
+typedef struct packed {
+ int unsigned i;
+} data_t;
+
+localparam N = 1;
+localparam M = 2;
+
+logic [N+2-1:0] valid_o[M], ready_i[M];
+logic [N+2-1:0] valid_i[M], ready_o[M];
+addr_t[N+2-1:0] addr_o[M], addr_i[M];
+data_t[N+2-1:0] data_o[M], data_i[M];
+
+for (genvar i = 0; i < M; ++i) begin :gen_router
+ router #(
+ .N(N),
+ .I(i),
+
+ .data_t(data_t),
+ .addr_t(addr_t)
+ ) router (
+ .clk_i(clk),
+ .rstx_i(rstx),
+
+
+ .valid_i(valid_i[i]),
+ .ready_o(ready_o[i]),
+ .addr_i (addr_i [i]),
+ .data_i (data_i [i]),
+
+ .valid_o(valid_o[i]),
+ .ready_i(ready_i[i]),
+ .addr_o (addr_o [i]),
+ .data_o (data_o [i])
+ );
+end
+
+/* easy to get confused, but here's what we're testing:
+ *
+ * dev0 dev1
+ * | ^
+ * v |
+ * P2 P2
+ * +-------+ +-------+
+ * P1 | node0 | P0 -> P1 | node1 | P0
+ * +-------+ +-------+
+ *
+ * dev0 sends a packet to node0, 1 -> valid_i[0][2]
+ * node0 sends the packet to node1, valid_o[0][0] -> valid_i[1][1]
+ * node1 sends the packet to dev1 , valid_o[1][2]
+ */
+
+/* node0 -> node1 */
+assign valid_i[1][1] = valid_o[0][0];
+assign data_i [1][1] = data_o [0][0];
+assign addr_i [1][1] = addr_o [0][0];
+assign ready_i[1][1] = ready_o[0][0];
+
+/* node1 -> node0 */
+assign valid_i[0][0] = valid_o[1][1];
+assign data_i [0][0] = data_o [1][1];
+assign addr_i [0][0] = addr_o [1][1];
+assign ready_i[0][0] = ready_o[1][1];
+
+
+initial begin :test
+ logic found = 0;
+
+ $dumpfile("router_tb.vcd");
+ $dumpvars();
+
+ for (int i = 0; i < M; ++i)
+ for (int j = 0; j < N + 2; ++j) begin :init
+ valid_i[i][j] = '0;
+ ready_i[i][j] = '0;
+
+ addr_i [i][j] = '{
+ src: '{
+ node: 0,
+ dev: 0
+ },
+
+ dst: '{
+ node: 0,
+ dev: 0
+ }
+ };
+ data_i [i][j] = '{i: 0};
+ end
+
+ clk = 0;
+ rstx = 0;
+
+ #1
+
+ rstx = 1;
+
+ /* send value 3 from first dev to second */
+ valid_i[0][2] = 1'b1;
+ data_i [0][2] = '{i: 3};
+ addr_i [0][2] = '{
+ src: '{
+ node: 0,
+ dev: 0
+ },
+
+ dst: '{
+ node: 1,
+ dev: 0
+ }
+ };
+
+ /* mark receiver as ready */
+ ready_i[1][2] = 1'b1;
+
+ #1 clk = 1;
+ #1 clk = 0;
+
+ valid_i[0][2] = 1'b0;
+
+ for (int i = 0; i < 10; ++i) begin
+ if (valid_o[1][2]) begin
+ found = 1;
+ break;
+ end
+
+ #1 clk = ~clk;
+ end
+
+ assert (found)
+ else $error("took too long to produce output");
+
+ assert (data_o[1][2] == 3)
+ else $error("got wrong result");
+
+ #10 $finish;
+end
+endmodule