diff --git a/gearbox.py b/gearbox.py index 1e679cac5db5143a7c452c7ef9987458c2d7a25d..41f49282bb981ed94ae8e7a61298b89bda9087b0 100755 --- a/gearbox.py +++ b/gearbox.py @@ -3,13 +3,22 @@ from nmigen import * from nmigen.hdl.rec import * from nmigen.cli import main + + +# REMAINING WORK +# +# make a quick-and-dirty testbench that selects a random inwidth, random outwidth, and randomly +# starts/stops the input/output and verifies that the sequence of bits coming out is the same +# as that coming in (can do with PRBS) and that bus interface constraints are not violated + + class IndexDisambiguator(Enum): LAST_OP_UNKNOWN = 0 LAST_OP_WAS_WRITE = 1 LAST_OP_WAS_READ = 2 class GearboxBusLayout(Layout): - def __init__(self, *, in_width, out_width): + def __init__(self, *, in_width, out_width): # the * forces keyword args super().__init__([ # DATA ("data_in", unsigned(in_width)), # FROM SOURCE @@ -30,11 +39,41 @@ class GearboxBus(Record): super().__init__(GearboxBusLayout(in_width=in_width, out_width=out_width)) -class GearboxFlow(Elaboratable): - def __init__(self): + +class GearboxFCLayout(Layout): + def __init__(self, *, len_storage): + super().__init__([ + # DATA + ("read_ptr", unsigned(range(len_storage))), # FROM GEARBOX + ("write_ptr", unsigned(range(len_storage))), # FROM GEARBOX + + # CONTROL + ("write_happens_this_cycle", 1), # TO GEARBOX + ("read_happens_this_cycle", 1), # TO GEARBOX + + ("ready_in", 1), # FROM GEARBOX (FROM DOWNSTREAM) + ("valid_in", 1), # FROM GEARBOX (FROM UPSTREAM) + + + ]) + +class GearboxFCBus(Record): + def __init__(self, *, len_storage): + super().__init__(GearboxFCLayout(len_storage=len_storage)) + + + +class GearboxFlowControl(Elaboratable): + def __init__(self, *, in_width, out_width, len_storage): + self.in_width = in_width + self.out_width = out_width + self.len_storage = len_storage + + self.bus = GearboxBus(len_storage=len_storage) + def elaborate(self, platform): - # The top-level flow control logic works as follows. + # The top-level flow control logic works as follows. # First, we determine which operations are *possible* based on the read/write indices # and the index disambiguator bit: @@ -90,9 +129,6 @@ class GearboxFlow(Elaboratable): - - - class ArbitraryGearbox(Elaboratable): def __init__(self, *, in_width, out_width): self.in_width = in_width