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)]
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):
]
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
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"))
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),
)
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")
+ )
)
)
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
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),