summaryrefslogtreecommitdiff
path: root/src/skid_buffer.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 /src/skid_buffer.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 'src/skid_buffer.sv')
-rw-r--r--src/skid_buffer.sv53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/skid_buffer.sv b/src/skid_buffer.sv
new file mode 100644
index 0000000..3ea6d0d
--- /dev/null
+++ b/src/skid_buffer.sv
@@ -0,0 +1,53 @@
+/* adjusted from pulp common_cells/spill_register_flushable.sv */
+
+module skid_buffer #(
+ parameter unsigned W = 2
+)(
+ input clk_i,
+ input rstx_i,
+
+ input valid_i,
+ output ready_o,
+ input [W-1:0] data_i,
+
+ output valid_o,
+ input ready_i,
+ output [W-1:0] data_o
+);
+
+logic a_fill, a_full, a_drain, b_fill, b_full, b_drain;
+logic [W-1:0] a, b;
+
+/* reg a */
+always_ff @(posedge clk_i or negedge rstx_i)
+if (!rstx_i)
+ a <= '0;
+else if (a_fill)
+ a <= data_i;
+
+always_ff @(posedge clk_i or negedge rstx_i)
+if (!rstx_i)
+ a_full <= '0;
+else if (a_fill || a_drain)
+ a_full <= a_fill;
+
+always_ff @(posedge clk_i or negedge rstx_i)
+if (!rstx_i)
+ b <= '0;
+else if (b_fill)
+ b <= a;
+
+/* fill A first, if upstream can't read A in time, place A into B and skid the
+ * input into A until upstream can clean out B */
+assign a_fill = valid_i && ready_o;
+assign a_drain = a_full && !b_full;
+
+assign b_fill = a_drain && !ready_i;
+assign b_drain = b_full && ready_i;
+
+assign ready_o = !a_full || !b_full;
+assign valid_o = a_full || b_full;
+
+assign data_o = b_full ? b : a;
+
+endmodule // skid_buffer