diff --git a/misoclib/mem/sdram/bus/lasmibus.py b/misoclib/mem/sdram/bus/lasmibus.py index 7578d0ec1..29aa3e983 100644 --- a/misoclib/mem/sdram/bus/lasmibus.py +++ b/misoclib/mem/sdram/bus/lasmibus.py @@ -18,8 +18,7 @@ class Interface(Record): ("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), + ("dat_ack", 1, DIR_S_TO_M), ("lock", 1, DIR_S_TO_M) ] if nbanks > 1: diff --git a/misoclib/mem/sdram/frontend/dma_lasmi.py b/misoclib/mem/sdram/frontend/dma_lasmi.py index c027b2c15..38da442b0 100644 --- a/misoclib/mem/sdram/frontend/dma_lasmi.py +++ b/misoclib/mem/sdram/frontend/dma_lasmi.py @@ -42,13 +42,20 @@ class Reader(Module): request_enable.eq(rsv_level != fifo_depth) ] + # data available + data_available = lasmim.dat_ack + for i in range(lasmim.read_latency): + new_data_available = Signal() + self.sync += new_data_available.eq(data_available) + data_available = new_data_available + # FIFO fifo = SyncFIFO(lasmim.dw, fifo_depth) self.submodules += fifo self.comb += [ fifo.din.eq(lasmim.dat_r), - fifo.we.eq(lasmim.dat_r_ack), + fifo.we.eq(data_available), self.data.stb.eq(fifo.readable), fifo.re.eq(self.data.ack), @@ -79,9 +86,15 @@ class Writer(Module): fifo.din.eq(self.address_data.d) ] + data_valid = lasmim.dat_ack + for i in range(lasmim.write_latency): + new_data_valid = Signal() + self.sync += new_data_valid.eq(data_valid), + data_valid = new_data_valid + self.comb += [ - If(lasmim.dat_w_ack, - fifo.re.eq(1), + fifo.re.eq(data_valid), + If(data_valid, lasmim.dat_we.eq(2**(lasmim.dw//8)-1), lasmim.dat_w.eq(fifo.dout) ), diff --git a/misoclib/mem/sdram/frontend/wishbone2lasmi.py b/misoclib/mem/sdram/frontend/wishbone2lasmi.py index 91abe5c33..a2110caf2 100644 --- a/misoclib/mem/sdram/frontend/wishbone2lasmi.py +++ b/misoclib/mem/sdram/frontend/wishbone2lasmi.py @@ -105,6 +105,8 @@ 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")) @@ -133,7 +135,7 @@ class WB2LASMI(Module, AutoCSR): If(lasmim.req_ack, NextState("EVICT_WAIT_DATA_ACK")) ) fsm.act("EVICT_WAIT_DATA_ACK", - If(lasmim.dat_w_ack, NextState("EVICT_DATA")) + If(lasmim.dat_ack, NextState("EVICT_DATAD")) ) fsm.act("EVICT_DATA", write_to_lasmi.eq(1), @@ -153,16 +155,17 @@ class WB2LASMI(Module, AutoCSR): ) fsm.act("REFILL_REQUEST", lasmim.stb.eq(1), - If(lasmim.req_ack, NextState("REFILL_DATA")) + If(lasmim.req_ack, NextState("REFILL_WAIT_DATA_ACK")) + ) + fsm.act("REFILL_WAIT_DATA_ACK", + If(lasmim.dat_ack, NextState("REFILL_DATAD")) ) fsm.act("REFILL_DATA", - 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") - ) + 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 3ee6c0832..23eb6773f 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_w_ack | req.dat_r_ack), + self.req_fifo.re.eq(req.dat_ack), req.lock.eq(self.req_fifo.readable) ] reqf = self.req_fifo.dout @@ -100,8 +100,7 @@ class BankMachine(Module): If(hit, # NB: write-to-read specification is enforced by multiplexer self.cmd.stb.eq(1), - req.dat_w_ack.eq(self.cmd.ack & reqf.we), - req.dat_r_ack.eq(self.cmd.ack & ~reqf.we), + req.dat_ack.eq(self.cmd.ack), self.cmd.is_read.eq(~reqf.we), self.cmd.is_write.eq(reqf.we), self.cmd.cas_n.eq(0), diff --git a/misoclib/mem/sdram/lasmicon/crossbar.py b/misoclib/mem/sdram/lasmicon/crossbar.py index e4414900e..18ca51e07 100644 --- a/misoclib/mem/sdram/lasmicon/crossbar.py +++ b/misoclib/mem/sdram/lasmicon/crossbar.py @@ -50,9 +50,7 @@ class Crossbar(Module): else: controller_selected = [1]*nmasters master_req_acks = [0]*nmasters - master_dat_w_acks = [0]*nmasters - master_dat_r_acks = [0]*nmasters - + master_dat_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): @@ -84,28 +82,11 @@ 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_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 + 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.req_ack.eq(master_req_ack) for master, master_req_ack in zip(self._masters, master_req_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)] + 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