diff --git a/litedram/common.py b/litedram/common.py index e5b600e..67a3284 100644 --- a/litedram/common.py +++ b/litedram/common.py @@ -60,6 +60,7 @@ def data_layout(dw, bankbits): return [ ("wdata", dw, DIR_M_TO_S), ("wdata_we", dw//8, DIR_M_TO_S), + ("wbank", bankbits, DIR_S_TO_M), ("rdata", dw, DIR_S_TO_M), ("rbank", bankbits, DIR_S_TO_M) ] @@ -82,14 +83,18 @@ def cmd_description(aw): ("adr", aw) ] -def wdata_description(dw): +def wdata_description(dw, nbanks): return [ ("data", dw), - ("we", dw//8) + ("we", dw//8), + ("bank", nbanks) ] def rdata_description(dw, nbanks): - return [("data", dw), ("bank", nbanks)] + return [ + ("data", dw), + ("bank", nbanks) + ] class LiteDRAMPort: @@ -103,7 +108,7 @@ class LiteDRAMPort: self.lock = Signal() self.cmd = stream.Endpoint(cmd_description(aw)) - self.wdata = stream.Endpoint(wdata_description(dw)) + self.wdata = stream.Endpoint(wdata_description(dw, bankbits)) self.rdata = stream.Endpoint(rdata_description(dw, bankbits)) self.flush = Signal() diff --git a/litedram/frontend/crossbar.py b/litedram/frontend/crossbar.py index ed7fc27..56a263f 100644 --- a/litedram/frontend/crossbar.py +++ b/litedram/frontend/crossbar.py @@ -70,6 +70,7 @@ class LiteDRAMCrossbar(Module): self.submodules += arbiters rbank = Signal(max=self.nbanks) + wbank = Signal(max=self.nbanks) for nb, arbiter in enumerate(arbiters): bank = getattr(controller, "bank"+str(nb)) @@ -84,7 +85,7 @@ class LiteDRAMCrossbar(Module): master_locked.append(locked) # arbitrate - bank_selected = [(ba == nb) & ~locked for ba, locked in zip(m_ba, master_locked)] + bank_selected = [(ba == nb) for ba, locked in zip(m_ba, master_locked)] bank_requested = [bs & master.cmd.valid for bs, master in zip(bank_selected, self.masters)] self.comb += [ arbiter.request.eq(Cat(*bank_requested)), @@ -97,6 +98,12 @@ class LiteDRAMCrossbar(Module): rbank.eq(nb) ) + # Get wdata source bank + self.sync += \ + If((arbiter.grant == nm) & bank.wdata_ready, + wbank.eq(nb) + ) + # route requests self.comb += [ bank.adr.eq(Array(m_rca)[arbiter.grant]), @@ -129,6 +136,11 @@ class LiteDRAMCrossbar(Module): new_master_rbank = Signal(max=self.nbanks) self.sync += new_master_rbank.eq(rbank) rbank = new_master_rbank + # Delay wbank output to match wready + for i in range(self.write_latency-1): + new_master_wbank = Signal(max=self.nbanks) + self.sync += new_master_wbank.eq(wbank) + wbank = new_master_wbank for master, master_ready in zip(self.masters, master_readys): self.comb += master.cmd.ready.eq(master_ready) @@ -154,6 +166,7 @@ class LiteDRAMCrossbar(Module): for master in self.masters: self.comb += master.rdata.data.eq(self.controller.rdata) self.comb += master.rdata.bank.eq(rbank) + self.comb += master.wdata.bank.eq(wbank) def split_master_addresses(self, bank_bits, rca_bits, cba_shift): m_ba = [] # bank address