radix: reading first page table entry
[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+"_wb")
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 # has to be added to the actual module rather than the instance
51 # sram.attrs['blackbox'] = 1
52
53 with m.If(self.enable): # in case of layout problems
54 # wishbone is active if cyc and stb set
55 wb_active = Signal()
56 m.d.comb += wb_active.eq(self.bus.cyc & self.bus.stb)
57
58 # generate ack (no "pipeline" mode here)
59 m.d.sync += self.bus.ack.eq(wb_active)
60
61 with m.If(wb_active):
62
63 # address
64 m.d.comb += a.eq(self.bus.adr)
65
66 # read
67 m.d.comb += self.bus.dat_r.eq(q)
68
69 # write
70 m.d.comb += d.eq(self.bus.dat_w)
71 with m.If(self.bus.we):
72 m.d.comb += we.eq(self.bus.sel)
73
74 return m
75
76
77 def create_ilang(dut, ports, test_name):
78 vl = rtlil.convert(dut, name=test_name, ports=ports)
79 with open("%s.il" % test_name, "w") as f:
80 f.write(vl)
81
82 if __name__ == "__main__":
83 alu = SPBlock512W64B8W()
84 create_ilang(alu, [alu.bus.cyc, alu.bus.stb, alu.bus.ack,
85 alu.bus.dat_r, alu.bus.dat_w, alu.bus.adr,
86 alu.bus.we, alu.bus.sel], "SPBlock512W64B8W")
87