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