Skip to content

Commit

Permalink
Fix UpConverter write path not working as intended
Browse files Browse the repository at this point in the history
LiteDRAM controler does not check if wdata stream has valid signal set,
it assumes that wdata has valid data when cmd is send.

Signed-off-by: Maciej Dudek <[email protected]>
  • Loading branch information
Maciej Dudek authored and robertszczepanski committed Mar 31, 2022
1 parent d4234b8 commit 52baaa8
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 9 deletions.
35 changes: 27 additions & 8 deletions litedram/frontend/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@ def __init__(self, port_from, port_to, reverse=False,
send_inner_cmd_addr = Signal.like(port_to.cmd.addr)
send_inner_cmd_we = Signal.like(port_to.cmd.we)

send_wdata_latch = Signal(reset=1)
self.cmd_buffer = cmd_buffer = stream.SyncFIFO([ ("cmd_addr", send_cmd_addr.nbits),
("cmd_we", send_cmd_we.nbits)],
cmd_buffer_depth)
Expand All @@ -204,10 +205,10 @@ def __init__(self, port_from, port_to, reverse=False,
)
)
send_fsm.act("SEND",
port_to.cmd.valid.eq(1),
port_to.cmd.valid.eq(~send_inner_cmd_we | (port_to.wdata.valid & send_wdata_latch)),
port_to.cmd.addr.eq(send_inner_cmd_addr),
port_to.cmd.we.eq(send_inner_cmd_we),
If(port_to.cmd.ready,
If(port_to.cmd.ready & port_to.cmd.valid,
If(cmd_buffer.source.valid,
cmd_buffer.source.ready.eq(1),
NextValue(send_inner_cmd_addr, cmd_buffer.source.cmd_addr),
Expand All @@ -218,6 +219,18 @@ def __init__(self, port_from, port_to, reverse=False,
)
)
)

# send_latch keeps track if we have already send write command to valid wdata
self.sync += [
If(port_to.cmd.ready & port_to.cmd.valid & send_inner_cmd_we & ~wdata_finished,
# we have avlid cmd and wdata, but port_to is not ready to recive data, send cmd
# and lock out further write commands until we send our wdata
send_wdata_latch.eq(0),
).Elif(wdata_finished,
# we have send our wdata, unlock send
send_wdata_latch.eq(1),
)
]
# Command flow is quite complicate, nonlinear and it depends on type read/write,
# so here is summary:
# This FSM receives commands from `port_from` and pushes them to `cmd_buffer` queue,
Expand Down Expand Up @@ -290,6 +303,7 @@ def __init__(self, port_from, port_to, reverse=False,
fsm.act("WAIT-FOR-CMD",
If(port_from.cmd.valid,
NextValue(counter, 0),
NextValue(cmd_last, 0),
NextValue(cmd_addr, port_from.cmd.addr[log2_int(ratio):]),
NextValue(cmd_we, port_from.cmd.we),
If(port_from.cmd.we,
Expand Down Expand Up @@ -482,14 +496,12 @@ def __init__(self, port_from, port_to, reverse=False,
]

self.sync += [
If(wdata_fifo.source.valid & wdata_fifo.source.ready,
Case(write_chunk, cases)
),
If(wdata_finished,
write_inner_counter.eq(0),
wdata_buffer.we.eq(0),
).Elif(wdata_fifo.source.valid & wdata_fifo.source.ready,
write_inner_counter.eq(write_inner_counter + 1)
write_inner_counter.eq(write_inner_counter + 1),
Case(write_chunk, cases)
)
]

Expand All @@ -506,10 +518,16 @@ def tx_commit (self, cmd_addr, cmd_we, cmd_last, port_from, counter, ordering):
If(self.send_cmd_busy,
NextState("WAIT-TO-SEND")
).Else(
NextValue(counter, 0),
NextValue(cmd_last, 0),
If(port_from.cmd.valid & port_from.cmd.we,
NextValue(counter, 0),
NextValue(cmd_addr, port_from.cmd.addr[log2_int(self.ratio):]),
NextValue(cmd_we, port_from.cmd.we),
port_from.cmd.ready.eq(1),
NextValue(counter, 1),
NextValue(ordering[:1 * log2_int(self.ratio)],
port_from.cmd.addr[:log2_int(self.ratio)]),
NextValue(cmd_last, port_from.cmd.last),
NextState("FILL")
).Else(
NextState("WAIT-FOR-CMD")
Expand All @@ -533,8 +551,9 @@ def rx_commit (self, cmd_addr, cmd_we, cmd_last, port_from, counter, ordering):
self.send_cmd_we.eq(port_from.cmd.we),
NextValue(cmd_addr, port_from.cmd.addr[log2_int(self.ratio):]),
NextValue(cmd_we, port_from.cmd.we),
NextValue(counter, 0),
NextValue(cmd_last, 0),
If(self.send_cmd_busy,
NextValue(counter, 0),
NextState("WAIT-TO-SEND")
).Else(
port_from.cmd.ready.eq(1),
Expand Down
3 changes: 2 additions & 1 deletion test/test_wishbone.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
from litedram.frontend.wishbone import LiteDRAMWishbone2Native
from litedram.common import LiteDRAMNativePort

from test.common import DRAMMemory, MemoryTestDataMixin
from test.common import *


class TestWishbone(MemoryTestDataMixin, unittest.TestCase):
Expand All @@ -40,6 +40,7 @@ def main_generator(dut):
main_generator(dut),
dut.mem.write_handler(dut.port),
dut.mem.read_handler(dut.port),
timeout_generator(10000)
]
run_simulation(dut, generators, vcd_name='sim.vcd')
self.assertEqual(dut.mem.mem, mem_expected)
Expand Down

0 comments on commit 52baaa8

Please sign in to comment.