aa7fe20a24c2b610befed6f34687057a9f134e43
[soc.git] / src / soc / bus / SPBlock512W64B8W.py
1 from nmigen import Elaboratable, Cat, Module, Signal, ClockSignal, Instance
2 from nmigen.utils import log2_int
3
4 from nmigen_soc.wishbone.bus import Interface
5 from nmigen.cli import rtlil
6
7 __all__ = ["SPBlock512W64B8W"]
8
9
10 class SPBlock512W64B8W(Elaboratable):
11 """SRAM module carrying a volatile 4k memory block (implemented with
12 Instance SPBlock512W64B8W). 512 rows, 64-bit, QTY 8 write-enable lines
13 """
14
15 def __init__(self, bus=None, features=None):
16 if features is None:
17 features = frozenset()
18 if bus is None:
19 bus = Interface(addr_width=9, # 512 lines of
20 data_width=64, # 64 bit
21 granularity=8, # at 8-bit granularity
22 features=features,
23 alignment=0,
24 name=None)
25 self.bus = bus
26 self.granularity = bus.granularity
27
28 n_wrport = 8
29 n_bussel = self.bus.sel.width
30 assert n_wrport == n_bussel, "bus enable count %d " \
31 "must match memory wen count %d" % (n_wrport, n_bussel)
32
33 assert len(self.bus.dat_r) == 64, "bus width must be 64"
34
35 def elaborate(self, platform):
36 m = Module()
37
38 # 4k SRAM instance
39 a = Signal(9)
40 we = Signal()
41 q = Signal(64) # output
42 d = Signal(64) # input
43
44 sram = Instance("SPBlock_512W64B8W", i_a=a, o_q=q, i_d=d,
45 i_we=we, i_clk=ClockSignal())
46 m.submodules += sram
47
48 wb_active = Signal()
49 m.d.comb += wb_active.eq(self.bus.cyc & self.bus.stb)
50 with m.If(wb_active):
51 # address
52 m.d.comb += a.eq(self.bus.adr)
53
54 # read
55 m.d.comb += self.bus.dat_r.eq(q)
56
57 # write
58 m.d.comb += d.eq(self.bus.dat_w)
59 with m.If(self.bus.we):
60 m.d.comb += we.eq(self.bus.sel)
61
62 # generate ack (no "pipeline" mode here)
63 m.d.sync += self.bus.ack.eq(0)
64 with m.If(self.bus.cyc & self.bus.stb):
65 m.d.sync += self.bus.ack.eq(1)
66
67 return m
68
69
70 def create_ilang(dut, ports, test_name):
71 vl = rtlil.convert(dut, name=test_name, ports=ports)
72 with open("%s.il" % test_name, "w") as f:
73 f.write(vl)
74
75 if __name__ == "__main__":
76 alu = SPBlock512W64B8W()
77 create_ilang(alu, [alu.bus.cyc, alu.bus.stb, alu.bus.ack,
78 alu.bus.dat_r, alu.bus.dat_w, alu.bus.adr,
79 alu.bus.we, alu.bus.sel], "SPBlock512W64B8W")
80