From 5109511259b82e025840b06a6efc136edfe00e33 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Sat, 25 May 2019 10:02:31 +0200 Subject: [PATCH] soc/interconnect/axi: add round/robin arbitration between writes/reads --- litex/soc/interconnect/axi.py | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/litex/soc/interconnect/axi.py b/litex/soc/interconnect/axi.py index 98ae2aabc..8c25d8d76 100644 --- a/litex/soc/interconnect/axi.py +++ b/litex/soc/interconnect/axi.py @@ -167,16 +167,30 @@ class AXI2AXILite(Module): _data = Signal(axi.data_width) _cmd_done = Signal() + _last_ar_aw_n = Signal() - # FIXME: add anti-starvation self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", NextValue(_cmd_done, 0), - If(axi.ar.valid, + If(axi.ar.valid & axi.aw.valid, + # If last access was a read, do a write + If(_last_ar_aw_n, + axi.aw.connect(ax_burst), + NextValue(_last_ar_aw_n, 0), + NextState("WRITE") + # If last access was a write, do a read + ).Else( + axi.ar.connect(ax_burst), + NextValue(_last_ar_aw_n, 1), + NextState("READ"), + ) + ).Elif(axi.ar.valid, axi.ar.connect(ax_burst), - NextState("READ") + NextValue(_last_ar_aw_n, 1), + NextState("READ"), ).Elif(axi.aw.valid, axi.aw.connect(ax_burst), + NextValue(_last_ar_aw_n, 0), NextState("WRITE") ) ) @@ -248,14 +262,27 @@ class AXILite2Wishbone(Module): _data = Signal(axi_lite.data_width) _r_addr = Signal(axi_lite.address_width) _w_addr = Signal(axi_lite.address_width) + _last_ar_aw_n = Signal() self.comb += _r_addr.eq(axi_lite.ar.addr - base_address) self.comb += _w_addr.eq(axi_lite.aw.addr - base_address) self.submodules.fsm = fsm = FSM(reset_state="IDLE") fsm.act("IDLE", - If(axi_lite.ar.valid, + If(axi_lite.ar.valid & axi_lite.aw.valid, + # If last access was a read, do a write + If(_last_ar_aw_n, + NextValue(_last_ar_aw_n, 0), + NextState("DO-WRITE") + # If last access was a write, do a read + ).Else( + NextValue(_last_ar_aw_n, 1), + NextState("DO-READ") + ) + ).Elif(axi_lite.ar.valid, + NextValue(_last_ar_aw_n, 1), NextState("DO-READ") ).Elif(axi_lite.aw.valid, + NextValue(_last_ar_aw_n, 0), NextState("DO-WRITE") ) )