From c42e167f3d47c9edd345659e27f3e46e248c63c7 Mon Sep 17 00:00:00 2001
From: Kia <kia@special-circumstanc.es>
Date: Wed, 3 Jun 2020 18:17:34 -0600
Subject: [PATCH] started work on nmigen gearboxes

---
 gearbox.py | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 99 insertions(+)
 create mode 100644 gearbox.py

diff --git a/gearbox.py b/gearbox.py
new file mode 100644
index 0000000..b809678
--- /dev/null
+++ b/gearbox.py
@@ -0,0 +1,99 @@
+from nmigen import *
+from nmigen.cli import main
+
+
+class ArbitraryGearbox(Elaboratable): # non-registered
+        def __init__(self, i_width, o_width):
+            self.i_width = i_width
+            self.o_width = o_width
+
+
+            self.upstream_data_in =     Signal(self.i_width)
+            self.downstream_data_out =  Signal(self.o_width)
+
+        def elaborate(self, platform):
+            m = Module()
+
+            len_storage = self.i_width + self.o_width
+            storage = Signal(len_storage)
+            write_ptr = Signal(range(len_storage))
+            read_ptr = Signal(range(len_storage))
+
+            # we signal ready to upstream if and only if the skid buffer is empty
+            m.d.comb += self.upstream_ready_out.eq(~skid_buffer_frozen)
+
+
+            # should we capture a value in the skid buffer?
+            # we should if upstream has data for us *and* downstream cannot accept
+
+            # If we want to fill our skid buffer, we need:
+            # 1. valid input data       (upstream_valid_in   == 1)
+            # 2. a buffer that is empty (skid_buffer_frozen  == 0)
+            # 3. stalled downstream     (downstream_ready_in == 0)
+
+            with m.If(self.upstream_valid_in & (~skid_buffer_frozen)  & (~self.downstream_ready_in)):
+                m.d.sync += skid_buffer_frozen.eq(1)
+
+            # if downstream is accepting data again, we will flush our skid buffer
+            with m.If(self.downstream_ready_in == 1):
+                m.d.sync += skid_buffer_frozen.eq(0)
+
+
+            m.d.comb += self.downstream_valid_out.eq(self.upstream_valid_in | skid_buffer_frozen)
+
+
+            # data path
+
+            # always clock data into the skid buffer as long as the buffer isn't frozen
+
+            with m.If(skid_buffer_frozen == 0):
+                m.d.sync += skid_buffer.eq(self.upstream_data_in)
+
+            with m.If(skid_buffer_frozen == 1):
+                m.d.comb += self.downstream_data_out.eq(skid_buffer)
+
+            # NON registered
+            with m.Elif(self.upstream_valid_in == 1):
+                m.d.comb += self.downstream_data_out.eq(self.upstream_data_in)
+
+            return m
+
+
+
+
+class DummyPlug(Elaboratable):
+    def elaborate(self, platform):
+        m = Module()
+        egg = RegisteredSkidBuffer(8)
+        m.submodules += egg
+
+        cntr = Signal(8)
+        intctr = Signal(8)
+        data_in = Signal(8)
+        m.d.sync += intctr.eq(intctr +1)
+        m.d.comb += egg.upstream_data_in.eq(data_in)
+
+        upstream_valid = Signal(1)
+        m.d.comb += egg.upstream_valid_in.eq(upstream_valid)
+        m.d.comb += upstream_valid.eq(1)
+
+        downstream_ready = Signal(1)
+        m.d.comb += egg.downstream_ready_in.eq(downstream_ready)
+        m.d.comb += downstream_ready.eq(1)
+        m.d.comb += data_in.eq(cntr)
+        with m.If((intctr == 4) | (intctr == 5) | (intctr == 6)):
+            m.d.comb += downstream_ready.eq(0)
+#        with m.If((intctr == 4) | (intctr == 5)):
+#            m.d.comb += upstream_valid.eq(0)
+#            m.d.comb += data_in.eq(0)
+
+        with m.If(egg.upstream_ready_out == 1):
+            m.d.sync += cntr.eq(cntr+1)
+
+
+        return m
+
+
+if __name__ == '__main__':
+    baka =DummyPlug()
+    main(baka)
\ No newline at end of file
-- 
GitLab