frontend/fifo: Simplify code and expose pre/post fifo_depth instead of writer/reader_fifo_depth.

This commit is contained in:
Florent Kermarrec 2021-09-24 09:52:24 +02:00
parent 3d3bf623aa
commit b24381ca4a
1 changed files with 36 additions and 41 deletions

View File

@ -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")
)
)