From 17527092dbb7b4734fe51092bb0d21a3a034cb2a Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 31 May 2023 08:54:44 +0200 Subject: [PATCH 1/8] frontend/avalon: First review pass to make codestyle more similar to other LiteX/LiteDRAM modules. --- litedram/frontend/avalon.py | 143 ++++++++++++++++++++++-------------- 1 file changed, 86 insertions(+), 57 deletions(-) diff --git a/litedram/frontend/avalon.py b/litedram/frontend/avalon.py index 6878ffe3..83b42291 100644 --- a/litedram/frontend/avalon.py +++ b/litedram/frontend/avalon.py @@ -10,21 +10,25 @@ from migen import * +from litex.gen import * + from litex.soc.interconnect import stream + from litedram.common import LiteDRAMNativePort from litedram.frontend.adapter import LiteDRAMNativePortConverter - # LiteDRAMAvalonMM2Native -------------------------------------------------------------------------- -class LiteDRAMAvalonMM2Native(Module): +class LiteDRAMAvalonMM2Native(LiteXModule): def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000, burst_increment=1): + # Parameters. avalon_data_width = len(avalon.writedata) - port_data_width = 2**int(log2(len(port.wdata.data))) # Round to lowest power 2 - ratio = avalon_data_width/port_data_width - downconvert = ratio > 1 - upconvert = ratio < 1 + port_data_width = 2**int(log2(len(port.wdata.data))) # Round to lowest power 2 + ratio = avalon_data_width/port_data_width + downconvert = ratio > 1 + upconvert = ratio < 1 + # DownConverter (Optional). if avalon_data_width != port_data_width: if avalon_data_width > port_data_width: addr_shift = -log2_int(avalon_data_width//port_data_width) @@ -40,67 +44,78 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 # # # - offset = base_address >> log2_int(port.data_width//8) + # Internal Signals. + offset = (base_address >> log2_int(port.data_width//8)) - burstcounter = Signal(9) - start_burst = Signal() - active_burst = Signal() - address = Signal.like(port.cmd.addr) - byteenable = Signal.like(avalon.byteenable) + burst_count = Signal(9) + burst_start = Signal() + burst_active = Signal() + address = Signal(port.address_width) + byteenable = Signal(avalon_data_width//8) writedata = Signal(avalon_data_width) start_transaction = Signal() + start_condition = Signal() cmd_ready_seen = Signal() - cmd_ready_counter = Signal.like(burstcounter) + cmd_ready_count = Signal(9) - cmd_layout = [("address", len(address))] + # Layouts. + cmd_layout = [("address", len(address))] wdata_layout = [ - ("data", avalon_data_width), - ("byteenable", len(avalon.byteenable)) + ("data", avalon_data_width), + ("byteenable", avalon_data_width//8), ] self.comb += [ - start_burst .eq(2 <= avalon.burstcount), - active_burst.eq(1 <= burstcounter) + burst_start .eq(avalon.burstcount >= 2), + burst_active.eq(burst_count >= 1), ] self.sync += [ If(start_transaction, byteenable.eq(avalon.byteenable), - burstcounter.eq(avalon.burstcount), - address.eq(avalon.address - offset)) + burst_count.eq(avalon.burstcount), + address.eq(avalon.address - offset), + ) ] - start_condition = start_transaction if downconvert else (start_transaction & (start_burst | port.cmd.ready)) - + # FSM. self.submodules.fsm = fsm = FSM(reset_state="START") fsm.act("START", avalon.waitrequest.eq(1), - If (~start_burst, + If(~burst_start, port.cmd.addr.eq(avalon.address - offset), port.cmd.we.eq(avalon.write), port.cmd.valid.eq(avalon.read | avalon.write) ), start_transaction.eq(avalon.read | avalon.write), - + If(downconvert, + start_condition.eq(start_transaction) + ).Else( + start_condition.eq(start_transaction & (burst_start | port.cmd.ready)) + ), If(start_condition, - [] if downconvert else [If (~start_burst, avalon.waitrequest.eq(0))], - If (avalon.write, - If (start_burst, + If(downconvert, + avalon.waitrequest.eq(1) + ).Else( + If(~burst_start, avalon.waitrequest.eq(0)) + ), + If(avalon.write, + If(burst_start, NextState("BURST_WRITE") ).Else( - [ + If(downconvert, port.wdata.data.eq(avalon.writedata), port.wdata.valid.eq(1), port.wdata.we.eq(avalon.byteenable), - ] if downconvert else [], + ), NextValue(writedata, avalon.writedata), port.cmd.last.eq(1), NextState("SINGLE_WRITE") ) ).Elif(avalon.read, - If (start_burst, + If(burst_start, avalon.waitrequest.eq(0), - NextValue(cmd_ready_counter, avalon.burstcount), + NextValue(cmd_ready_count, avalon.burstcount), NextState("BURST_READ") ).Else( port.cmd.last.eq(1), @@ -114,28 +129,36 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 avalon.waitrequest.eq(1), port.rdata.ready.eq(0), - [ + If(downconvert, port.cmd.addr.eq(address), port.cmd.we.eq(1), port.cmd.valid.eq(1), - If(port.cmd.ready, NextValue(cmd_ready_seen, 1)), + If(port.cmd.ready, + NextValue(cmd_ready_seen, 1) + ), If(cmd_ready_seen, port.cmd.valid.eq(0), port.cmd.we.eq(0) ), - ] if downconvert else [], + ), port.wdata.data.eq(writedata), port.wdata.valid.eq(1), port.wdata.we.eq(byteenable), If(port.wdata.ready, - avalon.waitrequest.eq(0 if downconvert else 1), + If(downconvert, + avalon.waitrequest.eq(0) + ), NextValue(writedata, avalon.writedata), port.flush.eq(1), - NextValue(cmd_ready_seen, 0) if downconvert else NextValue(port.cmd.last, 1), + If(downconvert, + NextValue(cmd_ready_seen, 0) + ).Else( + NextValue(port.cmd.last, 1) + ), NextValue(byteenable, 0), NextState("START") ) @@ -145,33 +168,36 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 avalon.waitrequest.eq(1), port.rdata.ready.eq(1), - [ + If(downconvert, port.cmd.addr.eq(address), port.cmd.we.eq(0), port.cmd.valid.eq(1), - If(port.cmd.ready, NextValue(cmd_ready_seen, 1)), + If(port.cmd.ready, + NextValue(cmd_ready_seen, 1) + ), If(cmd_ready_seen, port.cmd.valid.eq(0), port.cmd.we.eq(0) ), - ] if downconvert else [], + ), If(port.rdata.valid, avalon.readdata.eq(port.rdata.data), avalon.readdatavalid.eq(1), - [ + If(downconvert, port.cmd.valid.eq(0), avalon.waitrequest.eq(0), NextValue(cmd_ready_seen, 0), - ] if downconvert else [], + ), + NextState("START") ) ) - self.submodules.cmd_fifo = cmd_fifo = stream.SyncFIFO(cmd_layout, max_burst_length) - self.submodules.wdata_fifo = wdata_fifo = stream.SyncFIFO(wdata_layout, max_burst_length) + self.cmd_fifo = cmd_fifo = stream.SyncFIFO(cmd_layout, max_burst_length) + self.wdata_fifo = wdata_fifo = stream.SyncFIFO(wdata_layout, max_burst_length) fsm.act("BURST_WRITE", # FIFO producer @@ -183,15 +209,15 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 wdata_fifo.sink.payload.byteenable.eq(avalon.byteenable), wdata_fifo.sink.valid.eq(avalon.write & ~avalon.waitrequest), - If (avalon.write & active_burst, - If (cmd_fifo.sink.ready & cmd_fifo.sink.valid, - NextValue(burstcounter, burstcounter - 1), - NextValue(address, address + burst_increment)) + If(avalon.write & burst_active, + If(cmd_fifo.sink.ready & cmd_fifo.sink.valid, + NextValue(burst_count, burst_count - 1), + NextValue(address, address + burst_increment) + ) ).Else( avalon.waitrequest.eq(1), - # wait for the FIFO to be empty - If ((cmd_fifo .level == 0) & - (wdata_fifo.level == 1) & port.wdata.ready, + # Wait for the FIFO to be empty + If((cmd_fifo.level == 0) & (wdata_fifo.level == 1) & port.wdata.ready, NextState("START") ) ), @@ -218,16 +244,19 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 avalon.readdata.eq(port.rdata.data), avalon.readdatavalid.eq(port.rdata.valid), - If (port.cmd.ready, - If (cmd_ready_counter == 1, NextValue(cmd_ready_seen, 1)), - NextValue(cmd_ready_counter, cmd_ready_counter - 1), + If(port.cmd.ready, + If(cmd_ready_count == 1, + NextValue(cmd_ready_seen, 1) + ), + NextValue(cmd_ready_count, cmd_ready_count - 1), NextValue(address, address + burst_increment) ), - If (port.rdata.valid, - If (burstcounter == 1, + If(port.rdata.valid, + If(burst_count == 1, NextValue(cmd_ready_seen, 0), - NextState("START")), - NextValue(burstcounter, burstcounter - 1) + NextState("START") + ), + NextValue(burst_count, burst_count - 1) ) ) From 9950904cb56159bf5c5df1d3fcd4d25ea2e36d8d Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 31 May 2023 09:21:14 +0200 Subject: [PATCH 2/8] frontend/avalon: Simplify start condition. --- litedram/frontend/avalon.py | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/litedram/frontend/avalon.py b/litedram/frontend/avalon.py index 83b42291..8a76e900 100644 --- a/litedram/frontend/avalon.py +++ b/litedram/frontend/avalon.py @@ -53,8 +53,7 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 address = Signal(port.address_width) byteenable = Signal(avalon_data_width//8) writedata = Signal(avalon_data_width) - start_transaction = Signal() - start_condition = Signal() + start = Signal() cmd_ready_seen = Signal() cmd_ready_count = Signal(9) @@ -66,11 +65,11 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 ] self.comb += [ - burst_start .eq(avalon.burstcount >= 2), - burst_active.eq(burst_count >= 1), + burst_start .eq(avalon.burstcount > 1), + burst_active.eq(burst_count > 0), ] self.sync += [ - If(start_transaction, + If(start, byteenable.eq(avalon.byteenable), burst_count.eq(avalon.burstcount), address.eq(avalon.address - offset), @@ -87,17 +86,20 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 port.cmd.valid.eq(avalon.read | avalon.write) ), - start_transaction.eq(avalon.read | avalon.write), - If(downconvert, - start_condition.eq(start_transaction) - ).Else( - start_condition.eq(start_transaction & (burst_start | port.cmd.ready)) + If(avalon.read | avalon.write, + If(downconvert, + start.eq(1) + ).Else( + start.eq(burst_start | port.cmd.ready) + ) ), - If(start_condition, + If(start, If(downconvert, avalon.waitrequest.eq(1) ).Else( - If(~burst_start, avalon.waitrequest.eq(0)) + If(~burst_start, + avalon.waitrequest.eq(0) + ) ), If(avalon.write, If(burst_start, From b0503f1b005c6a7bdd239c7717f16f8f7c505920 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 31 May 2023 10:03:39 +0200 Subject: [PATCH 3/8] frotend/avalon: Another simplifiation pass on start condition. --- litedram/frontend/avalon.py | 106 +++++++++++++++--------------------- 1 file changed, 44 insertions(+), 62 deletions(-) diff --git a/litedram/frontend/avalon.py b/litedram/frontend/avalon.py index 8a76e900..b3874ed0 100644 --- a/litedram/frontend/avalon.py +++ b/litedram/frontend/avalon.py @@ -28,7 +28,7 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 downconvert = ratio > 1 upconvert = ratio < 1 - # DownConverter (Optional). + # Data-Width Converter (Optional). if avalon_data_width != port_data_width: if avalon_data_width > port_data_width: addr_shift = -log2_int(avalon_data_width//port_data_width) @@ -39,23 +39,23 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 address_width = port.address_width + addr_shift, data_width = avalon_data_width ) - self.submodules += LiteDRAMNativePortConverter(new_port, port) + self.converter = LiteDRAMNativePortConverter(new_port, port) port = new_port # # # # Internal Signals. - offset = (base_address >> log2_int(port.data_width//8)) - - burst_count = Signal(9) - burst_start = Signal() - burst_active = Signal() - address = Signal(port.address_width) - byteenable = Signal(avalon_data_width//8) - writedata = Signal(avalon_data_width) - start = Signal() - cmd_ready_seen = Signal() - cmd_ready_count = Signal(9) + burst_count = Signal(9) + burst_start = Signal() + address = Signal(port.address_width) + address_offset = Signal(port.address_width) + byteenable = Signal(avalon_data_width//8) + writedata = Signal(avalon_data_width) + start = Signal() + cmd_ready_seen = Signal() + cmd_ready_count = Signal(9) + + self.comb += address_offset.eq(base_address >> log2_int(port.data_width//8)) # Layouts. cmd_layout = [("address", len(address))] @@ -64,64 +64,46 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 ("byteenable", avalon_data_width//8), ] - self.comb += [ - burst_start .eq(avalon.burstcount > 1), - burst_active.eq(burst_count > 0), - ] self.sync += [ If(start, byteenable.eq(avalon.byteenable), + writedata.eq(avalon.writedata), burst_count.eq(avalon.burstcount), - address.eq(avalon.address - offset), + address.eq(avalon.address - address_offset), ) ] # FSM. - self.submodules.fsm = fsm = FSM(reset_state="START") + self.fsm = fsm = FSM(reset_state="START") fsm.act("START", avalon.waitrequest.eq(1), - If(~burst_start, - port.cmd.addr.eq(avalon.address - offset), + If(avalon.burstcount <= 1, + port.cmd.addr.eq(avalon.address - address_offset), port.cmd.we.eq(avalon.write), port.cmd.valid.eq(avalon.read | avalon.write) ), - If(avalon.read | avalon.write, - If(downconvert, - start.eq(1) - ).Else( - start.eq(burst_start | port.cmd.ready) - ) - ), - If(start, - If(downconvert, - avalon.waitrequest.eq(1) - ).Else( - If(~burst_start, + If((avalon.burstcount > 1) | (downconvert == True) | port.cmd.ready, + start.eq(1), + If((downconvert == False) & (avalon.burstcount <= 1), avalon.waitrequest.eq(0) - ) - ), - If(avalon.write, - If(burst_start, - NextState("BURST_WRITE") - ).Else( - If(downconvert, - port.wdata.data.eq(avalon.writedata), - port.wdata.valid.eq(1), - port.wdata.we.eq(avalon.byteenable), - ), - NextValue(writedata, avalon.writedata), - port.cmd.last.eq(1), - NextState("SINGLE_WRITE") - ) - ).Elif(avalon.read, - If(burst_start, - avalon.waitrequest.eq(0), - NextValue(cmd_ready_count, avalon.burstcount), - NextState("BURST_READ") - ).Else( - port.cmd.last.eq(1), - NextState("SINGLE_READ") + ), + If(avalon.write, + If(avalon.burstcount > 1, + NextState("BURST_WRITE") + ).Else( + port.cmd.last.eq(1), + NextState("SINGLE_WRITE") + ) + ).Elif(avalon.read, + If(avalon.burstcount > 1, + avalon.waitrequest.eq(0), + NextValue(cmd_ready_count, avalon.burstcount), + NextState("BURST_READ") + ).Else( + port.cmd.last.eq(1), + NextState("SINGLE_READ") + ) ) ) ) @@ -131,7 +113,7 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 avalon.waitrequest.eq(1), port.rdata.ready.eq(0), - If(downconvert, + If((downconvert == True), port.cmd.addr.eq(address), port.cmd.we.eq(1), port.cmd.valid.eq(1), @@ -150,13 +132,13 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 port.wdata.we.eq(byteenable), If(port.wdata.ready, - If(downconvert, + If((downconvert == True), avalon.waitrequest.eq(0) ), NextValue(writedata, avalon.writedata), port.flush.eq(1), - If(downconvert, + If((downconvert == True), NextValue(cmd_ready_seen, 0) ).Else( NextValue(port.cmd.last, 1) @@ -170,7 +152,7 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 avalon.waitrequest.eq(1), port.rdata.ready.eq(1), - If(downconvert, + If((downconvert == True), port.cmd.addr.eq(address), port.cmd.we.eq(0), port.cmd.valid.eq(1), @@ -188,7 +170,7 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 avalon.readdata.eq(port.rdata.data), avalon.readdatavalid.eq(1), - If(downconvert, + If((downconvert == True), port.cmd.valid.eq(0), avalon.waitrequest.eq(0), NextValue(cmd_ready_seen, 0), @@ -211,7 +193,7 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 wdata_fifo.sink.payload.byteenable.eq(avalon.byteenable), wdata_fifo.sink.valid.eq(avalon.write & ~avalon.waitrequest), - If(avalon.write & burst_active, + If(avalon.write & (burst_count > 0), If(cmd_fifo.sink.ready & cmd_fifo.sink.valid, NextValue(burst_count, burst_count - 1), NextValue(address, address + burst_increment) From f1f5f637e78068d6ca61bc32ddee8d90dca2fcf8 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 31 May 2023 10:42:21 +0200 Subject: [PATCH 4/8] frontend/avalon: Improve decoupling in START state. --- litedram/frontend/avalon.py | 46 ++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/litedram/frontend/avalon.py b/litedram/frontend/avalon.py index b3874ed0..d4905c71 100644 --- a/litedram/frontend/avalon.py +++ b/litedram/frontend/avalon.py @@ -46,12 +46,11 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 # Internal Signals. burst_count = Signal(9) - burst_start = Signal() address = Signal(port.address_width) address_offset = Signal(port.address_width) byteenable = Signal(avalon_data_width//8) writedata = Signal(avalon_data_width) - start = Signal() + latch = Signal() cmd_ready_seen = Signal() cmd_ready_count = Signal(9) @@ -65,7 +64,7 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 ] self.sync += [ - If(start, + If(latch, byteenable.eq(avalon.byteenable), writedata.eq(avalon.writedata), burst_count.eq(avalon.burstcount), @@ -77,31 +76,30 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 self.fsm = fsm = FSM(reset_state="START") fsm.act("START", avalon.waitrequest.eq(1), - If(avalon.burstcount <= 1, - port.cmd.addr.eq(avalon.address - address_offset), - port.cmd.we.eq(avalon.write), - port.cmd.valid.eq(avalon.read | avalon.write) - ), + # Start of Access. If(avalon.read | avalon.write, - If((avalon.burstcount > 1) | (downconvert == True) | port.cmd.ready, - start.eq(1), - If((downconvert == False) & (avalon.burstcount <= 1), - avalon.waitrequest.eq(0) - ), + latch.eq(1), + # Burst Access. + If(avalon.burstcount > 1, If(avalon.write, - If(avalon.burstcount > 1, - NextState("BURST_WRITE") - ).Else( - port.cmd.last.eq(1), + NextState("BURST_WRITE") + ), + If(avalon.read, + avalon.waitrequest.eq(0), + NextValue(cmd_ready_count, avalon.burstcount), + NextState("BURST_READ") + ) + # Single Access. + ).Else( + port.cmd.addr.eq(avalon.address - address_offset), + port.cmd.we.eq(avalon.write), + port.cmd.valid.eq(1), + port.cmd.last.eq(1), + If((downconvert == True) | port.cmd.ready, + avalon.waitrequest.eq(downconvert == True), + If(port.cmd.we, NextState("SINGLE_WRITE") - ) - ).Elif(avalon.read, - If(avalon.burstcount > 1, - avalon.waitrequest.eq(0), - NextValue(cmd_ready_count, avalon.burstcount), - NextState("BURST_READ") ).Else( - port.cmd.last.eq(1), NextState("SINGLE_READ") ) ) From ff9f75054eef0bc917bf14c234e887e8e66af062 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 31 May 2023 10:52:48 +0200 Subject: [PATCH 5/8] frontend/avalon: Avoid byteenable clear (data) and clear cmd_ready_seen in START. --- litedram/frontend/avalon.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/litedram/frontend/avalon.py b/litedram/frontend/avalon.py index d4905c71..d1a208da 100644 --- a/litedram/frontend/avalon.py +++ b/litedram/frontend/avalon.py @@ -76,6 +76,7 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 self.fsm = fsm = FSM(reset_state="START") fsm.act("START", avalon.waitrequest.eq(1), + NextValue(cmd_ready_seen, 0), # Start of Access. If(avalon.read | avalon.write, latch.eq(1), @@ -136,12 +137,9 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 NextValue(writedata, avalon.writedata), port.flush.eq(1), - If((downconvert == True), - NextValue(cmd_ready_seen, 0) - ).Else( + If((downconvert == False), NextValue(port.cmd.last, 1) ), - NextValue(byteenable, 0), NextState("START") ) ) @@ -171,7 +169,6 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 If((downconvert == True), port.cmd.valid.eq(0), avalon.waitrequest.eq(0), - NextValue(cmd_ready_seen, 0), ), NextState("START") @@ -236,7 +233,6 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 If(port.rdata.valid, If(burst_count == 1, - NextValue(cmd_ready_seen, 0), NextState("START") ), NextValue(burst_count, burst_count - 1) From 5e7ba4ee71c835fc5d4d76d59360d1ea7f268596 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 31 May 2023 11:00:45 +0200 Subject: [PATCH 6/8] frontend/avalon/SINGLE_WRITE: Remove writedata update and port.cmd.last (not useful). --- litedram/frontend/avalon.py | 6 ------ 1 file changed, 6 deletions(-) diff --git a/litedram/frontend/avalon.py b/litedram/frontend/avalon.py index d1a208da..67f0fce5 100644 --- a/litedram/frontend/avalon.py +++ b/litedram/frontend/avalon.py @@ -134,12 +134,6 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 If((downconvert == True), avalon.waitrequest.eq(0) ), - NextValue(writedata, avalon.writedata), - - port.flush.eq(1), - If((downconvert == False), - NextValue(port.cmd.last, 1) - ), NextState("START") ) ) From ed1e569e29d3f6909e0b5f4bbdbcb50c071b3047 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 31 May 2023 16:52:38 +0200 Subject: [PATCH 7/8] frontend/adapter/LiteDRAMNativePortDownConverter: Do early ack of user cmd. To better decouple cmd/data paths in user logic. --- litedram/frontend/adapter.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/litedram/frontend/adapter.py b/litedram/frontend/adapter.py index 5c1461e9..8530279e 100644 --- a/litedram/frontend/adapter.py +++ b/litedram/frontend/adapter.py @@ -81,23 +81,28 @@ def __init__(self, port_from, port_to, reverse=False): ratio = port_from.data_width//port_to.data_width mode = port_from.mode - count = Signal(max=ratio) + + cmd_count = Signal(max=ratio) + cmd_addr = Signal(len(port_from.cmd.addr)) + cmd_we = Signal() self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", - NextValue(count, 0), + port_from.cmd.ready.eq(1), If(port_from.cmd.valid, + NextValue(cmd_count, 0), + NextValue(cmd_addr, port_from.cmd.addr), + NextValue(cmd_we, port_from.cmd.we), NextState("CONVERT") ) ) fsm.act("CONVERT", port_to.cmd.valid.eq(1), - port_to.cmd.we.eq(port_from.cmd.we), - port_to.cmd.addr.eq(port_from.cmd.addr*ratio + count), + port_to.cmd.we.eq(cmd_we), + port_to.cmd.addr.eq(cmd_addr*ratio + cmd_count), If(port_to.cmd.ready, - NextValue(count, count + 1), - If(count == (ratio - 1), - port_from.cmd.ready.eq(1), + NextValue(cmd_count, cmd_count + 1), + If(cmd_count == (ratio - 1), NextState("IDLE") ) ) From d7344c04ad32dd55c352332f0cc188afe22e0e55 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 31 May 2023 16:54:56 +0200 Subject: [PATCH 8/8] frontend/avalon: Remove downconvert specific logic (no longer required with LiteDRAMNativePortConverter improvement). --- litedram/frontend/avalon.py | 40 ++----------------------------------- 1 file changed, 2 insertions(+), 38 deletions(-) diff --git a/litedram/frontend/avalon.py b/litedram/frontend/avalon.py index 67f0fce5..fc3f8865 100644 --- a/litedram/frontend/avalon.py +++ b/litedram/frontend/avalon.py @@ -96,8 +96,8 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 port.cmd.we.eq(avalon.write), port.cmd.valid.eq(1), port.cmd.last.eq(1), - If((downconvert == True) | port.cmd.ready, - avalon.waitrequest.eq(downconvert == True), + If(port.cmd.ready, + avalon.waitrequest.eq(0), If(port.cmd.we, NextState("SINGLE_WRITE") ).Else( @@ -112,28 +112,11 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 avalon.waitrequest.eq(1), port.rdata.ready.eq(0), - If((downconvert == True), - port.cmd.addr.eq(address), - port.cmd.we.eq(1), - port.cmd.valid.eq(1), - - If(port.cmd.ready, - NextValue(cmd_ready_seen, 1) - ), - If(cmd_ready_seen, - port.cmd.valid.eq(0), - port.cmd.we.eq(0) - ), - ), - port.wdata.data.eq(writedata), port.wdata.valid.eq(1), port.wdata.we.eq(byteenable), If(port.wdata.ready, - If((downconvert == True), - avalon.waitrequest.eq(0) - ), NextState("START") ) ) @@ -142,29 +125,10 @@ def __init__(self, avalon, port, *, max_burst_length=16, base_address=0x00000000 avalon.waitrequest.eq(1), port.rdata.ready.eq(1), - If((downconvert == True), - port.cmd.addr.eq(address), - port.cmd.we.eq(0), - port.cmd.valid.eq(1), - - If(port.cmd.ready, - NextValue(cmd_ready_seen, 1) - ), - If(cmd_ready_seen, - port.cmd.valid.eq(0), - port.cmd.we.eq(0) - ), - ), - If(port.rdata.valid, avalon.readdata.eq(port.rdata.data), avalon.readdatavalid.eq(1), - If((downconvert == True), - port.cmd.valid.eq(0), - avalon.waitrequest.eq(0), - ), - NextState("START") ) )