From d6f7b4cee6a242d1962766f53a09b48871a188fc Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Mon, 17 Jun 2013 23:36:03 +0200 Subject: [PATCH] lasmi: separate request and data ack to support bankmachine FIFOs (buggy/incomplete) --- migen/actorlib/dma_lasmi.py | 45 +++++++++++++++++-------------------- migen/bus/lasmibus.py | 29 ++++++++++++++++-------- migen/bus/wishbone2lasmi.py | 14 ++++++++---- 3 files changed, 50 insertions(+), 38 deletions(-) diff --git a/migen/actorlib/dma_lasmi.py b/migen/actorlib/dma_lasmi.py index 41ac1f44..691c771f 100644 --- a/migen/actorlib/dma_lasmi.py +++ b/migen/actorlib/dma_lasmi.py @@ -11,8 +11,7 @@ class Reader(Module): ### if fifo_depth is None: - fifo_depth = lasmim.read_latency + 2 - assert(fifo_depth >= lasmim.read_latency) + fifo_depth = lasmim.req_queue_size + lasmim.read_latency + 2 # request issuance request_enable = Signal() @@ -22,8 +21,8 @@ class Reader(Module): lasmim.we.eq(0), lasmim.stb.eq(self.address.stb & request_enable), lasmim.adr.eq(self.address.payload.a), - self.address.ack.eq(lasmim.ack), - request_issued.eq(lasmim.stb & lasmim.ack) + self.address.ack.eq(lasmim.req_ack), + request_issued.eq(lasmim.stb & lasmim.req_ack) ] # FIFO reservation level counter @@ -44,7 +43,7 @@ class Reader(Module): ] # data available - data_available = request_issued + data_available = lasmim.dat_ack for i in range(lasmim.read_latency): new_data_available = Signal() self.sync += new_data_available.eq(data_available) @@ -66,42 +65,38 @@ class Reader(Module): class Writer(Module): - def __init__(self, lasmim): + def __init__(self, lasmim, fifo_depth=None): self.address_data = Sink([("a", lasmim.aw), ("d", lasmim.dw)]) self.busy = Signal() ### + if fifo_depth is None: + fifo_depth = lasmim.req_queue_size + lasmim.read_latency + 2 + + fifo = SyncFIFO(lasmim.dw, fifo_depth) + self.submodules += fifo + self.comb += [ lasmim.we.eq(1), - lasmim.stb.eq(self.address_data.stb), + lasmim.stb.eq(fifo.writable & self.address_data.stb), lasmim.adr.eq(self.address_data.payload.a), - self.address_data.ack.eq(lasmim.ack) - ] - - busy_expr = 0 - data_valid = Signal() - data = Signal(lasmim.dw) - self.comb += [ - data_valid.eq(lasmim.stb & lasmim.ack), - data.eq(self.address_data.payload.d) + self.address_data.ack.eq(fifo.writable & lasmim.req_ack), + fifo.we.eq(self.address_data.stb & lasmim.req_ack), + fifo.din.eq(self.address_data.payload.d) ] + data_valid = lasmim.dat_ack for i in range(lasmim.write_latency): new_data_valid = Signal() - new_data = Signal(lasmim.dw) - self.sync += [ - new_data_valid.eq(data_valid), - new_data.eq(data) - ] - busy_expr = busy_expr | new_data_valid + self.sync += new_data_valid.eq(data_valid), data_valid = new_data_valid - data = new_data self.comb += [ + fifo.re.eq(data_valid), If(data_valid, lasmim.dat_we.eq(2**(lasmim.dw//8)-1), - lasmim.dat_w.eq(data) + lasmim.dat_w.eq(fifo.dout) ), - self.busy.eq(busy_expr) + self.busy.eq(fifo.readable) ] diff --git a/migen/bus/lasmibus.py b/migen/bus/lasmibus.py index be724ac1..949530a5 100644 --- a/migen/bus/lasmibus.py +++ b/migen/bus/lasmibus.py @@ -5,10 +5,11 @@ from migen.genlib.record import * from migen.genlib.misc import optree class Interface(Record): - def __init__(self, aw, dw, nbanks, read_latency, write_latency): + def __init__(self, aw, dw, nbanks, req_queue_size, read_latency, write_latency): self.aw = aw self.dw = dw self.nbanks = nbanks + self.req_queue_size = req_queue_size self.read_latency = read_latency self.write_latency = write_latency @@ -16,7 +17,9 @@ class Interface(Record): ("adr", aw, DIR_M_TO_S), ("we", 1, DIR_M_TO_S), ("stb", 1, DIR_M_TO_S), - ("ack", 1, DIR_S_TO_M) + ("req_ack", 1, DIR_S_TO_M), + ("dat_ack", 1, DIR_S_TO_M), + ("lock", 1, DIR_S_TO_M) ] if nbanks > 1: layout = [("bank"+str(i), bank_layout) for i in range(nbanks)] @@ -43,12 +46,13 @@ class Crossbar(Module): rca_bits = _getattr_all(controllers, "aw") dw = _getattr_all(controllers, "dw") nbanks = _getattr_all(controllers, "nbanks") + req_queue_size = _getattr_all(controllers, "req_queue_size") read_latency = _getattr_all(controllers, "read_latency") write_latency = _getattr_all(controllers, "write_latency") bank_bits = log2_int(nbanks, False) controller_bits = log2_int(ncontrollers, False) - self.masters = [Interface(rca_bits + bank_bits + controller_bits, dw, 1, read_latency, write_latency) + self.masters = [Interface(rca_bits + bank_bits + controller_bits, dw, 1, req_queue_size, read_latency, write_latency) for i in range(nmasters)] ### @@ -60,16 +64,20 @@ class Crossbar(Module): controller_selected = [ca == nc for ca in m_ca] else: controller_selected = [1]*nmasters - master_acks = [0]*nmasters + master_req_acks = [0]*nmasters + master_dat_acks = [0]*nmasters for nb in range(nbanks): bank = getattr(controller, "bank"+str(nb)) # arbitrate - rr = roundrobin.RoundRobin(nmasters, roundrobin.SP_WITHDRAW) + rr = roundrobin.RoundRobin(nmasters, roundrobin.SP_CE) self.submodules += rr bank_selected = [cs & (ba == nb) for cs, ba in zip(controller_selected, m_ba)] bank_requested = [bs & master.stb for bs, master in zip(bank_selected, self.masters)] - self.comb += rr.request.eq(Cat(*bank_requested)), + self.comb += [ + rr.request.eq(Cat(*bank_requested)), + rr.ce.eq(~bank.stb & ~bank.lock) + ] # route requests self.comb += [ @@ -77,10 +85,13 @@ class Crossbar(Module): bank.we.eq(Array(self.masters)[rr.grant].we), bank.stb.eq(Array(bank_requested)[rr.grant]) ] - master_acks = [master_ack | ((rr.grant == nm) & bank.ack) - for nm, master_ack in enumerate(master_acks)] + master_req_acks = [master_req_ack | ((rr.grant == nm) & Array(bank_selected)[rr.grant] & bank.req_ack) + for nm, master_req_ack in enumerate(master_req_acks)] + master_dat_acks = [master_dat_ack | ((rr.grant == nm) & bank.dat_ack) + for nm, master_dat_ack in enumerate(master_dat_acks)] - self.comb += [master.ack.eq(master_ack) for master, master_ack in zip(self.masters, master_acks)] + self.comb += [master.req_ack.eq(master_req_ack) for master, master_req_ack in zip(self.masters, master_req_acks)] + self.comb += [master.dat_ack.eq(master_dat_ack) for master, master_dat_ack in zip(self.masters, master_dat_acks)] # route data writes controller_selected_wl = controller_selected diff --git a/migen/bus/wishbone2lasmi.py b/migen/bus/wishbone2lasmi.py index 2aa48ff1..c9a53866 100644 --- a/migen/bus/wishbone2lasmi.py +++ b/migen/bus/wishbone2lasmi.py @@ -72,8 +72,8 @@ class WB2LASMI(Module): # Control FSM assert(lasmim.write_latency >= 1 and lasmim.read_latency >= 1) fsm = FSM("IDLE", "TEST_HIT", - "EVICT_REQUEST", "EVICT_DATA", - "REFILL_WRTAG", "REFILL_REQUEST", "REFILL_DATA", + "EVICT_REQUEST", "EVICT_WAIT_DATA_ACK", "EVICT_DATA", + "REFILL_WRTAG", "REFILL_REQUEST", "REFILL_WAIT_DATA_ACK", "REFILL_DATA", delayed_enters=[ ("EVICT_DATAD", "EVICT_DATA", lasmim.write_latency-1), ("REFILL_DATAD", "REFILL_DATA", lasmim.read_latency-1) @@ -103,7 +103,10 @@ class WB2LASMI(Module): fsm.act(fsm.EVICT_REQUEST, lasmim.stb.eq(1), lasmim.we.eq(1), - If(lasmim.ack, fsm.next_state(fsm.EVICT_DATAD)) + If(lasmim.req_ack, fsm.next_state(fsm.EVICT_WAIT_DATA_ACK)) + ) + fsm.act(fsm.EVICT_WAIT_DATA_ACK, + If(lasmim.dat_ack, fsm.next_state(fsm.EVICT_DATAD)) ) fsm.act(fsm.EVICT_DATA, write_to_lasmi.eq(1), @@ -117,7 +120,10 @@ class WB2LASMI(Module): ) fsm.act(fsm.REFILL_REQUEST, lasmim.stb.eq(1), - If(lasmim.ack, fsm.next_state(fsm.REFILL_DATAD)) + If(lasmim.req_ack, fsm.next_state(fsm.REFILL_WAIT_DATA_ACK)) + ) + fsm.act(fsm.REFILL_WAIT_DATA_ACK, + If(lasmim.dat_ack, fsm.next_state(fsm.REFILL_DATAD)) ) fsm.act(fsm.REFILL_DATA, write_from_lasmi.eq(1), -- 2.30.2