264578be629fc4b55ee4da88e3c29be95f222f3b
[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, name=None):
16 self.enable = Signal(reset=1) # enable signal, defaults to 1
17 if features is None:
18 features = frozenset()
19 if bus is None:
20 bus = Interface(addr_width=9, # 512 lines of
21 data_width=64, # 64 bit
22 granularity=8, # at 8-bit granularity
23 features=features,
24 alignment=0,
25 name=name)
26 self.bus = bus
27 self.granularity = bus.granularity
28
29 n_wrport = 8
30 n_bussel = self.bus.sel.width
31 assert n_wrport == n_bussel, "bus enable count %d " \
32 "must match memory wen count %d" % (n_wrport, n_bussel)
33
34 assert len(self.bus.dat_r) == 64, "bus width must be 64"
35
36 def elaborate(self, platform):
37 m = Module()
38
39 # 4k SRAM instance
40 a = Signal(9)
41 we = Signal()
42 q = Signal(64) # output
43 d = Signal(64) # input
44
45 # create Chips4Makers 4k SRAM cell here, mark it as "black box"
46 # for coriolis2 to pick up
47 sram = Instance("SPBlock_512W64B8W", i_a=a, o_q=q, i_d=d,
48 i_we=we, i_clk=ClockSignal())
49 m.submodules += sram
50 sram.attrs['blackbox'] = 1
51
52 with m.If(self.enable): # in case of layout problems
53 # wishbone is active if cyc and stb set
54 wb_active = Signal()
55 m.d.comb += wb_active.eq(self.bus.cyc & self.bus.stb)
56
57 # generate ack (no "pipeline" mode here)
58 m.d.sync += self.bus.ack.eq(wb_active)
59
60 with m.If(wb_active):
61
62 # address
63 m.d.comb += a.eq(self.bus.adr)
64
65 # read
66 m.d.comb += self.bus.dat_r.eq(q)
67
68 # write
69 m.d.comb += d.eq(self.bus.dat_w)
70 with m.If(self.bus.we):
71 m.d.comb += we.eq(self.bus.sel)
72
73 return m
74
75
76 def create_ilang(dut, ports, test_name):
77 vl = rtlil.convert(dut, name=test_name, ports=ports)
78 with open("%s.il" % test_name, "w") as f:
79 f.write(vl)
80
81 if __name__ == "__main__":
82 alu = SPBlock512W64B8W()
83 create_ilang(alu, [alu.bus.cyc, alu.bus.stb, alu.bus.ack,
84 alu.bus.dat_r, alu.bus.dat_w, alu.bus.adr,
85 alu.bus.we, alu.bus.sel], "SPBlock512W64B8W")
86