lasmi: simplify usage for the user (it's the job of the controller to manage write...
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Sun, 1 Mar 2015 20:22:12 +0000 (21:22 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Sun, 1 Mar 2015 21:04:27 +0000 (22:04 +0100)
misoclib/mem/sdram/bus/lasmibus.py
misoclib/mem/sdram/bus/wishbone2lasmi.py
misoclib/mem/sdram/lasmicon/bankmachine.py

index f1d3e29a98768912031eeacc32c22bb02da55e80..c17455f2af6d85ec0dbd5c521a929f0ade8b4704 100644 (file)
@@ -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
index a2110caf2f7e2f20300338b1105a81300333f114..91abe5c33cb9f8af3f134b8d5b662f95db8c57e6 100644 (file)
@@ -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")
+                               )
                        )
                )
index 23eb6773f34f225b992bb37721d87abbb2b49888..3ee6c08320cc051f7d7e466ea2ba2e0c9e7e223b 100644 (file)
@@ -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),