diff --git a/litedram/frontend/fifo.py b/litedram/frontend/fifo.py index 3d29dd8..d9dc921 100644 --- a/litedram/frontend/fifo.py +++ b/litedram/frontend/fifo.py @@ -77,7 +77,7 @@ class _LiteDRAMFIFOCtrl(Module): # LiteDRAMFIFOWriter ------------------------------------------------------------------------------- class _LiteDRAMFIFOWriter(Module): - def __init__(self, data_width, port, ctrl, fifo_depth=32): + def __init__(self, data_width, port, ctrl, fifo_depth=16): self.sink = sink = stream.Endpoint([("data", data_width)]) # # # @@ -98,7 +98,7 @@ class _LiteDRAMFIFOWriter(Module): # LiteDRAMFIFOReader ------------------------------------------------------------------------------- class _LiteDRAMFIFOReader(Module): - def __init__(self, data_width, port, ctrl, fifo_depth=32): + def __init__(self, data_width, port, ctrl, fifo_depth=16): self.source = source = stream.Endpoint([("data", data_width)]) # # # @@ -118,8 +118,8 @@ class _LiteDRAMFIFOReader(Module): class _LiteDRAMFIFO(Module): """LiteDRAM frontend that allows to use DRAM as a FIFO""" def __init__(self, data_width, base, depth, write_port, read_port, - writer_fifo_depth = 32, - reader_fifo_depth = 32): + writer_fifo_depth = 16, + reader_fifo_depth = 16): assert isinstance(write_port, LiteDRAMNativePort) assert isinstance(read_port, LiteDRAMNativePort) self.sink = stream.Endpoint([("data", data_width)]) @@ -213,8 +213,8 @@ class LiteDRAMFIFO(Module): level is below threshold, the modules switches back to Bypass mode. """ def __init__(self, data_width, base, depth, write_port, read_port, with_bypass=False, - writer_fifo_depth = 32, - reader_fifo_depth = 32): + pre_fifo_depth = 16, + post_fifo_depth = 16): assert isinstance(write_port, LiteDRAMNativePort) assert isinstance(read_port, LiteDRAMNativePort) self.sink = stream.Endpoint([("data", data_width)]) @@ -230,8 +230,8 @@ class LiteDRAMFIFO(Module): data_width_ratio = port_data_width//data_width if not with_bypass: assert data_width_ratio == 1 - pre_fifo_depth = 2*data_width_ratio # FIXME: Adjust. - post_fifo_depth = 2*data_width_ratio # FIXME: Adjust. + pre_fifo_depth = max( pre_fifo_depth, 2*data_width_ratio) + post_fifo_depth = max(post_fifo_depth, 2*data_width_ratio) # Submodules. # ----------- @@ -243,13 +243,11 @@ class LiteDRAMFIFO(Module): # DRAM-FIFO. self.submodules.dram_fifo = dram_fifo = _LiteDRAMFIFO( - data_width = port_data_width, - base = base, - depth = depth, - write_port = write_port, - read_port = read_port, - writer_fifo_depth = writer_fifo_depth, - reader_fifo_depth = reader_fifo_depth, + data_width = port_data_width, + base = base, + depth = depth, + write_port = write_port, + read_port = read_port, ) # Post-Converter. @@ -260,20 +258,24 @@ class LiteDRAMFIFO(Module): # Data-Flow. # ---------- - bypass = Signal() - store = Signal() - count = Signal(8) + dram_bypass = Signal() + dram_store = Signal() + dram_store_threshold = Signal() self.comb += [ # Sink --> Pre-FIFO. self.sink.connect(pre_fifo.sink), + # DRAM Threshold. We can only enable path to DRAAM when we have enough data for a full + # DRAM word. + dram_store_threshold.eq(pre_fifo.level > data_width_ratio), + # Bypass / DRAM. - If(with_bypass & bypass, + If(with_bypass & dram_bypass, # Pre-FIFO --> Post-FIFO. pre_fifo.source.connect(post_fifo.sink), ).Else( # Pre-FIFO --> Pre-Converter. - If(store | (not with_bypass), + If(dram_store | (not with_bypass), pre_fifo.source.connect(pre_converter.sink), ), # Post-Converter --> Post-FIFO. @@ -293,43 +295,36 @@ class LiteDRAMFIFO(Module): # FSM. # ---- if with_bypass: - can_store = Signal() - self.comb += can_store.eq(pre_fifo.level > data_width_ratio) self.submodules.fsm = fsm = FSM(reset_state="BYPASS") fsm.act("BYPASS", - bypass.eq(1), + dram_bypass.eq(1), # Switch to DRAM mode when enough data to store a DRAM word. - If(can_store, - NextValue(store, 1), - NextValue(count, 0), + If(dram_store_threshold, + NextValue(dram_store, 1), NextState("DRAM") ) ) - data_inc = Signal() - data_dec = Signal() - data_cnt = Signal(int(math.log2(depth + writer_fifo_depth + reader_fifo_depth) + 1)) - self.sync += data_cnt.eq(data_cnt + data_inc - data_dec) + dram_cnt_inc = Signal() + dram_cnt_dec = Signal() + dram_cnt = Signal(int(math.log2(depth + pre_fifo_depth + post_fifo_depth) + 1)) + self.sync += dram_cnt.eq(dram_cnt + dram_cnt_inc - dram_cnt_dec) fsm.act("DRAM", # Increment DRAM Data Count on Pre-Converter's Sink cycle. - data_inc.eq(pre_converter.sink.valid & pre_converter.sink.ready), + dram_cnt_inc.eq(pre_converter.sink.valid & pre_converter.sink.ready), # Decrement DRAM Data Count on Post-Converter's Source cycle. - data_dec.eq(post_converter.source.valid & post_converter.source.ready), + dram_cnt_dec.eq(post_converter.source.valid & post_converter.source.ready), - # Update store. - If(data_inc, - NextValue(count, count + 1), - If(count == (data_width_ratio - 1), - NextValue(count, 0), - NextValue(store, can_store), - ) + # Update DRAM store.. + If(pre_converter.source.valid, + NextValue(dram_store, dram_store_threshold), ), # Maintain DRAM Data Count. - NextValue(data_cnt, data_cnt + data_inc - data_dec), + NextValue(dram_cnt, dram_cnt + dram_cnt_inc - dram_cnt_dec), # Switch back to Bypass mode when DRAM Data count - If((can_store == 0) & (data_cnt == 0), + If((dram_store_threshold == 0) & (dram_cnt == 0), NextState("BYPASS") ) )