From 800e4d580b833f1307bf447987a1bc3acf2515a4 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sat, 20 Feb 2021 14:30:07 +0000 Subject: [PATCH] add Wishbone-wrapped SPBlock_512W64B8W --- src/soc/bus/SPBlock512W64B8W.py | 80 +++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/soc/bus/SPBlock512W64B8W.py diff --git a/src/soc/bus/SPBlock512W64B8W.py b/src/soc/bus/SPBlock512W64B8W.py new file mode 100644 index 00000000..aa7fe20a --- /dev/null +++ b/src/soc/bus/SPBlock512W64B8W.py @@ -0,0 +1,80 @@ +from nmigen import Elaboratable, Cat, Module, Signal, ClockSignal, Instance +from nmigen.utils import log2_int + +from nmigen_soc.wishbone.bus import Interface +from nmigen.cli import rtlil + +__all__ = ["SPBlock512W64B8W"] + + +class SPBlock512W64B8W(Elaboratable): + """SRAM module carrying a volatile 4k memory block (implemented with + Instance SPBlock512W64B8W). 512 rows, 64-bit, QTY 8 write-enable lines + """ + + def __init__(self, bus=None, features=None): + if features is None: + features = frozenset() + if bus is None: + bus = Interface(addr_width=9, # 512 lines of + data_width=64, # 64 bit + granularity=8, # at 8-bit granularity + features=features, + alignment=0, + name=None) + self.bus = bus + self.granularity = bus.granularity + + n_wrport = 8 + n_bussel = self.bus.sel.width + assert n_wrport == n_bussel, "bus enable count %d " \ + "must match memory wen count %d" % (n_wrport, n_bussel) + + assert len(self.bus.dat_r) == 64, "bus width must be 64" + + def elaborate(self, platform): + m = Module() + + # 4k SRAM instance + a = Signal(9) + we = Signal() + q = Signal(64) # output + d = Signal(64) # input + + sram = Instance("SPBlock_512W64B8W", i_a=a, o_q=q, i_d=d, + i_we=we, i_clk=ClockSignal()) + m.submodules += sram + + wb_active = Signal() + m.d.comb += wb_active.eq(self.bus.cyc & self.bus.stb) + with m.If(wb_active): + # address + m.d.comb += a.eq(self.bus.adr) + + # read + m.d.comb += self.bus.dat_r.eq(q) + + # write + m.d.comb += d.eq(self.bus.dat_w) + with m.If(self.bus.we): + m.d.comb += we.eq(self.bus.sel) + + # generate ack (no "pipeline" mode here) + m.d.sync += self.bus.ack.eq(0) + with m.If(self.bus.cyc & self.bus.stb): + m.d.sync += self.bus.ack.eq(1) + + return m + + +def create_ilang(dut, ports, test_name): + vl = rtlil.convert(dut, name=test_name, ports=ports) + with open("%s.il" % test_name, "w") as f: + f.write(vl) + +if __name__ == "__main__": + alu = SPBlock512W64B8W() + create_ilang(alu, [alu.bus.cyc, alu.bus.stb, alu.bus.ack, + alu.bus.dat_r, alu.bus.dat_w, alu.bus.adr, + alu.bus.we, alu.bus.sel], "SPBlock512W64B8W") + -- 2.30.2