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