diff --git a/misoclib/mem/sdram/bus/lasmibus.py b/misoclib/mem/sdram/bus/lasmibus.py index f1d3e29a9..c17455f2a 100644 --- a/misoclib/mem/sdram/bus/lasmibus.py +++ b/misoclib/mem/sdram/bus/lasmibus.py @@ -14,12 +14,13 @@ class Interface(Record): self.write_latency = write_latency bank_layout = [ - ("adr", aw, DIR_M_TO_S), - ("we", 1, DIR_M_TO_S), - ("stb", 1, DIR_M_TO_S), - ("req_ack", 1, DIR_S_TO_M), - ("dat_ack", 1, DIR_S_TO_M), - ("lock", 1, DIR_S_TO_M) + ("adr", aw, DIR_M_TO_S), + ("we", 1, DIR_M_TO_S), + ("stb", 1, DIR_M_TO_S), + ("req_ack", 1, DIR_S_TO_M), + ("dat_w_ack", 1, DIR_S_TO_M), + ("dat_r_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)] @@ -77,7 +78,9 @@ class Crossbar(Module): else: controller_selected = [1]*nmasters master_req_acks = [0]*nmasters - master_dat_acks = [0]*nmasters + master_dat_w_acks = [0]*nmasters + master_dat_r_acks = [0]*nmasters + rrs = [roundrobin.RoundRobin(nmasters, roundrobin.SP_CE) for n in range(self._nbanks)] self.submodules += rrs for nb, rr in enumerate(rrs): @@ -109,11 +112,28 @@ class Crossbar(Module): ] master_req_acks = [master_req_ack | ((rr.grant == nm) & bank_selected[nm] & 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)] + master_dat_w_acks = [master_dat_w_ack | ((rr.grant == nm) & bank.dat_w_ack) + for nm, master_dat_w_ack in enumerate(master_dat_w_acks)] + master_dat_r_acks = [master_dat_r_ack | ((rr.grant == nm) & bank.dat_r_ack) + for nm, master_dat_r_ack in enumerate(master_dat_r_acks)] + + for nm, master_dat_w_ack in enumerate(master_dat_w_acks): + for i in range(self._write_latency): + new_master_dat_w_ack = Signal() + self.sync += new_master_dat_w_ack.eq(master_dat_w_ack) + master_dat_w_ack = new_master_dat_w_ack + master_dat_w_acks[nm] = master_dat_w_ack + + for nm, master_dat_r_ack in enumerate(master_dat_r_acks): + for i in range(self._read_latency): + new_master_dat_r_ack = Signal() + self.sync += new_master_dat_r_ack.eq(master_dat_r_ack) + master_dat_r_ack = new_master_dat_r_ack + master_dat_r_acks[nm] = master_dat_r_ack 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)] + self.comb += [master.dat_w_ack.eq(master_dat_w_ack) for master, master_dat_w_ack in zip(self._masters, master_dat_w_acks)] + self.comb += [master.dat_r_ack.eq(master_dat_r_ack) for master, master_dat_r_ack in zip(self._masters, master_dat_r_acks)] # route data writes controller_selected_wl = controller_selected diff --git a/misoclib/mem/sdram/bus/wishbone2lasmi.py b/misoclib/mem/sdram/bus/wishbone2lasmi.py index a2110caf2..91abe5c33 100644 --- a/misoclib/mem/sdram/bus/wishbone2lasmi.py +++ b/misoclib/mem/sdram/bus/wishbone2lasmi.py @@ -105,8 +105,6 @@ class WB2LASMI(Module, AutoCSR): fsm = FSM(reset_state="IDLE") self.submodules += fsm - fsm.delayed_enter("EVICT_DATAD", "EVICT_DATA", lasmim.write_latency-1) - fsm.delayed_enter("REFILL_DATAD", "REFILL_DATA", lasmim.read_latency-1) fsm.act("IDLE", If(self.wishbone.cyc & self.wishbone.stb, NextState("TEST_HIT")) @@ -135,7 +133,7 @@ class WB2LASMI(Module, AutoCSR): If(lasmim.req_ack, NextState("EVICT_WAIT_DATA_ACK")) ) fsm.act("EVICT_WAIT_DATA_ACK", - If(lasmim.dat_ack, NextState("EVICT_DATAD")) + If(lasmim.dat_w_ack, NextState("EVICT_DATA")) ) fsm.act("EVICT_DATA", write_to_lasmi.eq(1), @@ -155,17 +153,16 @@ class WB2LASMI(Module, AutoCSR): ) fsm.act("REFILL_REQUEST", lasmim.stb.eq(1), - If(lasmim.req_ack, NextState("REFILL_WAIT_DATA_ACK")) - ) - fsm.act("REFILL_WAIT_DATA_ACK", - If(lasmim.dat_ack, NextState("REFILL_DATAD")) + If(lasmim.req_ack, NextState("REFILL_DATA")) ) fsm.act("REFILL_DATA", - write_from_lasmi.eq(1), - word_inc.eq(1), - If(word_is_last(word), - NextState("TEST_HIT"), - ).Else( - NextState("REFILL_REQUEST") + If(lasmim.dat_r_ack, + write_from_lasmi.eq(1), + word_inc.eq(1), + If(word_is_last(word), + NextState("TEST_HIT"), + ).Else( + NextState("REFILL_REQUEST") + ) ) ) diff --git a/misoclib/mem/sdram/lasmicon/bankmachine.py b/misoclib/mem/sdram/lasmicon/bankmachine.py index 23eb6773f..3ee6c0832 100644 --- a/misoclib/mem/sdram/lasmicon/bankmachine.py +++ b/misoclib/mem/sdram/lasmicon/bankmachine.py @@ -41,7 +41,7 @@ class BankMachine(Module): self.req_fifo.we.eq(req.stb), req.req_ack.eq(self.req_fifo.writable), - self.req_fifo.re.eq(req.dat_ack), + self.req_fifo.re.eq(req.dat_w_ack | req.dat_r_ack), req.lock.eq(self.req_fifo.readable) ] reqf = self.req_fifo.dout @@ -100,7 +100,8 @@ class BankMachine(Module): If(hit, # NB: write-to-read specification is enforced by multiplexer self.cmd.stb.eq(1), - req.dat_ack.eq(self.cmd.ack), + req.dat_w_ack.eq(self.cmd.ack & reqf.we), + req.dat_r_ack.eq(self.cmd.ack & ~reqf.we), self.cmd.is_read.eq(~reqf.we), self.cmd.is_write.eq(reqf.we), self.cmd.cas_n.eq(0),