soc/cores/usb_fifo: cleanup and reduce fifo_depth (provide similar throughput when used as UART).

This commit is contained in:
Florent Kermarrec 2020-06-23 16:51:24 +02:00
parent 52b51e1e98
commit 0780b629a9
1 changed files with 39 additions and 57 deletions

View File

@ -36,20 +36,23 @@ def anti_starvation(module, timeout):
class FT245PHYSynchronous(Module): class FT245PHYSynchronous(Module):
def __init__(self, pads, clk_freq, def __init__(self, pads, clk_freq,
fifo_depth=32, fifo_depth = 8,
read_time=128, read_time = 128,
write_time=128): write_time = 128):
dw = len(pads.data) dw = len(pads.data)
# read fifo (FTDI --> SoC) # read fifo (FTDI --> SoC)
read_fifo = ClockDomainsRenamer({"write": "usb", "read": "sys"})(stream.AsyncFIFO(phy_description(dw), fifo_depth)) read_fifo = stream.AsyncFIFO(phy_description(dw), fifo_depth)
read_buffer = ClockDomainsRenamer("usb")(stream.SyncFIFO(phy_description(dw), 4)) read_fifo = ClockDomainsRenamer({"write": "usb", "read": "sys"})(read_fifo)
read_buffer = stream.SyncFIFO(phy_description(dw), 4)
read_buffer = ClockDomainsRenamer("usb")(read_buffer)
self.comb += read_buffer.source.connect(read_fifo.sink) self.comb += read_buffer.source.connect(read_fifo.sink)
self.submodules += read_fifo, read_buffer
# write fifo (SoC --> FTDI) # write fifo (SoC --> FTDI)
write_fifo = ClockDomainsRenamer({"write": "sys", "read": "usb"})(stream.AsyncFIFO(phy_description(dw), fifo_depth)) write_fifo = stream.AsyncFIFO(phy_description(dw), fifo_depth)
write_fifo = ClockDomainsRenamer({"write": "sys", "read": "usb"})(write_fifo)
self.submodules += read_fifo, read_buffer, write_fifo self.submodules += write_fifo
# sink / source interfaces # sink / source interfaces
self.sink = write_fifo.sink self.sink = write_fifo.sink
@ -119,7 +122,6 @@ class FT245PHYSynchronous(Module):
pads.oe_n.eq(0), pads.oe_n.eq(0),
pads.rd_n.eq(~wants_read), pads.rd_n.eq(~wants_read),
pads.wr_n.eq(1) pads.wr_n.eq(1)
).Elif(fsm.ongoing("WRITE"), ).Elif(fsm.ongoing("WRITE"),
data_oe.eq(1), data_oe.eq(1),
@ -128,7 +130,6 @@ class FT245PHYSynchronous(Module):
pads.wr_n.eq(~wants_write), pads.wr_n.eq(~wants_write),
data_w_accepted.eq(~txe_n) data_w_accepted.eq(~txe_n)
).Else( ).Else(
data_oe.eq(1), data_oe.eq(1),
@ -147,9 +148,9 @@ class FT245PHYSynchronous(Module):
class FT245PHYAsynchronous(Module): class FT245PHYAsynchronous(Module):
def __init__(self, pads, clk_freq, def __init__(self, pads, clk_freq,
fifo_depth=32, fifo_depth = 8,
read_time=128, read_time = 128,
write_time=128): write_time = 128):
dw = len(pads.data) dw = len(pads.data)
self.clk_freq = clk_freq self.clk_freq = clk_freq
@ -234,25 +235,15 @@ class FT245PHYAsynchronous(Module):
MultiReg(data_r_async, data_r) MultiReg(data_r_async, data_r)
] ]
# read actions # read actions
pads.rd_n.reset = 1 pads.rd_n.reset = 1
read_fsm = FSM(reset_state="IDLE") read_fsm = FSM(reset_state="IDLE")
self.submodules += read_fsm self.submodules += read_fsm
read_counter = Signal(8) read_counter = Signal(8)
read_counter_reset = Signal()
read_counter_ce = Signal()
self.sync += \
If(read_counter_reset,
read_counter.eq(0)
).Elif(read_counter_ce,
read_counter.eq(read_counter + 1)
)
read_fsm.act("IDLE", read_fsm.act("IDLE",
read_done.eq(1), read_done.eq(1),
read_counter_reset.eq(1), NextValue(read_counter, 0),
If(fsm.ongoing("READ") & wants_read, If(fsm.ongoing("READ") & wants_read,
If(~commuting, If(~commuting,
NextState("PULSE_RD_N") NextState("PULSE_RD_N")
@ -261,8 +252,8 @@ class FT245PHYAsynchronous(Module):
) )
read_fsm.act("PULSE_RD_N", read_fsm.act("PULSE_RD_N",
pads.rd_n.eq(0), pads.rd_n.eq(0),
read_counter_ce.eq(1), NextValue(read_counter, read_counter + 1),
If(read_counter == max((tRD-1), (tRDDataSetup + tMultiReg -1)), If(read_counter == max(tRD-1, tRDDataSetup + tMultiReg -1),
NextState("ACQUIRE_DATA") NextState("ACQUIRE_DATA")
) )
) )
@ -283,18 +274,9 @@ class FT245PHYAsynchronous(Module):
write_fsm = FSM(reset_state="IDLE") write_fsm = FSM(reset_state="IDLE")
self.submodules += write_fsm self.submodules += write_fsm
write_counter = Signal(8) write_counter = Signal(8)
write_counter_reset = Signal()
write_counter_ce = Signal()
self.sync += \
If(write_counter_reset,
write_counter.eq(0)
).Elif(write_counter_ce,
write_counter.eq(write_counter + 1)
)
write_fsm.act("IDLE", write_fsm.act("IDLE",
write_done.eq(1), write_done.eq(1),
write_counter_reset.eq(1), NextValue(write_counter, 0),
If(fsm.ongoing("WRITE") & wants_write, If(fsm.ongoing("WRITE") & wants_write,
If(~commuting, If(~commuting,
NextState("SET_DATA") NextState("SET_DATA")
@ -304,9 +286,9 @@ class FT245PHYAsynchronous(Module):
write_fsm.act("SET_DATA", write_fsm.act("SET_DATA",
data_oe.eq(1), data_oe.eq(1),
data_w.eq(write_fifo.source.data), data_w.eq(write_fifo.source.data),
write_counter_ce.eq(1), NextValue(write_counter, write_counter + 1),
If(write_counter == (tWRDataSetup-1), If(write_counter == (tWRDataSetup-1),
write_counter_reset.eq(1), NextValue(write_counter, 0),
NextState("PULSE_WR_N") NextState("PULSE_WR_N")
) )
) )
@ -314,7 +296,7 @@ class FT245PHYAsynchronous(Module):
data_oe.eq(1), data_oe.eq(1),
data_w.eq(write_fifo.source.data), data_w.eq(write_fifo.source.data),
pads.wr_n.eq(0), pads.wr_n.eq(0),
write_counter_ce.eq(1), NextValue(write_counter, write_counter + 1),
If(write_counter == (tWR-1), If(write_counter == (tWR-1),
NextState("WAIT_TXE_N") NextState("WAIT_TXE_N")
) )
@ -327,7 +309,7 @@ class FT245PHYAsynchronous(Module):
) )
def ns(self, t, margin=True): def ns(self, t, margin=True):
clk_period_ns = 1000000000/self.clk_freq clk_period_ns = 1e9/self.clk_freq
if margin: if margin:
t += clk_period_ns/2 t += clk_period_ns/2
return math.ceil(t/clk_period_ns) return math.ceil(t/clk_period_ns)
@ -336,7 +318,7 @@ class FT245PHYAsynchronous(Module):
def FT245PHY(pads, *args, **kwargs): def FT245PHY(pads, *args, **kwargs):
# autodetect PHY # autodetect PHY
if hasattr(pads, "oe_n"): if hasattr(pads, "clkout"):
return FT245PHYSynchronous(pads, *args, **kwargs) return FT245PHYSynchronous(pads, *args, **kwargs)
else: else:
return FT245PHYAsynchronous(pads, *args, **kwargs) return FT245PHYAsynchronous(pads, *args, **kwargs)