add an SRAM and wishbone to add test (makes it bigger)
[soclayout.git] / experiments10_verilog / add.py
1 # generate add.il ilang file with: python3 add.py
2 #
3
4 from nmigen import Elaboratable, Signal, Module, Const, DomainRenamer
5 from nmigen.cli import verilog
6
7 # to get c4m-jtag
8 # clone with $ git clone gitolite3@git.libre-soc.org:nmigen-soc.git
9 # $ git clone gitolite3@git.libre-soc.org:c4m-jtag.git
10 # for each: $ python3 setup.py develop # optional: --user
11
12 from c4m.nmigen.jtag.tap import TAP, IOType
13 from nmigen_soc.wishbone.sram import SRAM
14 from nmigen import Memory
15
16
17 class ADD(Elaboratable):
18 def __init__(self, width):
19 self.width = width
20 self.a = Signal(width)
21 self.b = Signal(width)
22 self.f = Signal(width)
23
24 # set up JTAG
25 self.jtag = TAP(ir_width=4)
26 self.jtag.bus.tck.name = 'jtag_tck'
27 self.jtag.bus.tms.name = 'jtag_tms'
28 self.jtag.bus.tdo.name = 'jtag_tdo'
29 self.jtag.bus.tdi.name = 'jtag_tdi'
30
31 # have to create at least one shift register
32 self.sr = self.jtag.add_shiftreg(ircode=4, length=3)
33
34 # create and connect wishbone
35 self.wb = self.jtag.add_wishbone(ircodes=[5, 6, 7], features={'err'},
36 address_width=30, data_width=32,
37 granularity=8, # 8-bit wide
38 name="jtag_wb")
39
40 # create DMI2JTAG (goes through to dmi_sim())
41 self.dmi = self.jtag.add_dmi(ircodes=[8, 9, 10])
42
43 # add iotypes
44 self.io_a_0 = self.jtag.add_io(name="a_0", iotype=IOType.In)
45 self.io_a_1 = self.jtag.add_io(name="a_1", iotype=IOType.In)
46 self.io_a_2 = self.jtag.add_io(name="a_2", iotype=IOType.In)
47 self.io_a_3 = self.jtag.add_io(name="a_3", iotype=IOType.In)
48 self.io_b_0 = self.jtag.add_io(name="b_0", iotype=IOType.In)
49 self.io_b_1 = self.jtag.add_io(name="b_1", iotype=IOType.In)
50 self.io_b_2 = self.jtag.add_io(name="b_2", iotype=IOType.In)
51 self.io_b_3 = self.jtag.add_io(name="b_3", iotype=IOType.In)
52 self.io_f_0 = self.jtag.add_io(name="f_0", iotype=IOType.Out)
53 self.io_f_1 = self.jtag.add_io(name="f_1", iotype=IOType.Out)
54 self.io_f_2 = self.jtag.add_io(name="f_2", iotype=IOType.Out)
55 self.io_f_3 = self.jtag.add_io(name="f_3", iotype=IOType.Out)
56
57 def elaborate(self, platform):
58 m = Module()
59
60 m.submodules.jtag = jtag = self.jtag
61 m.d.comb += self.sr.i.eq(self.sr.o) # loopback test
62
63 # connect inputs/outputs to pads
64 m.d.comb += self.io_a_0.pad.i.eq(self.a[0])
65 m.d.comb += self.io_a_1.pad.i.eq(self.a[1])
66 m.d.comb += self.io_a_2.pad.i.eq(self.a[2])
67 m.d.comb += self.io_a_3.pad.i.eq(self.a[3])
68 m.d.comb += self.io_b_0.pad.i.eq(self.b[0])
69 m.d.comb += self.io_b_1.pad.i.eq(self.b[1])
70 m.d.comb += self.io_b_2.pad.i.eq(self.b[2])
71 m.d.comb += self.io_b_3.pad.i.eq(self.b[3])
72 m.d.comb += self.f[0].eq(self.io_f_0.pad.o)
73 m.d.comb += self.f[1].eq(self.io_f_1.pad.o)
74 m.d.comb += self.f[2].eq(self.io_f_2.pad.o)
75 m.d.comb += self.f[3].eq(self.io_f_3.pad.o)
76
77 # internal signals (not external pads basically)
78 a = Signal(self.width)
79 b = Signal(self.width)
80 f = Signal(self.width)
81
82 # and now the internal signals to the core
83 m.d.comb += a[0].eq(self.io_a_0.core.i)
84 m.d.comb += a[1].eq(self.io_a_1.core.i)
85 m.d.comb += a[2].eq(self.io_a_2.core.i)
86 m.d.comb += a[3].eq(self.io_a_3.core.i)
87 m.d.comb += b[0].eq(self.io_b_0.core.i)
88 m.d.comb += b[1].eq(self.io_b_1.core.i)
89 m.d.comb += b[2].eq(self.io_b_2.core.i)
90 m.d.comb += b[3].eq(self.io_b_3.core.i)
91 m.d.comb += self.io_f_0.core.o.eq(f[0])
92 m.d.comb += self.io_f_1.core.o.eq(f[1])
93 m.d.comb += self.io_f_2.core.o.eq(f[2])
94 m.d.comb += self.io_f_3.core.o.eq(f[3])
95
96 # create a Memory
97 memory = Memory(width=32, depth=32)
98 sram = SRAM(memory=memory, granularity=8)
99
100 m.submodules.sram = sram
101
102 m.d.comb += sram.bus.cyc.eq(self.wb.cyc)
103 m.d.comb += sram.bus.stb.eq(self.wb.stb)
104 m.d.comb += sram.bus.we.eq(self.wb.we)
105 m.d.comb += sram.bus.sel.eq(self.wb.sel)
106 m.d.comb += sram.bus.adr.eq(self.wb.adr)
107 m.d.comb += sram.bus.dat_w.eq(self.wb.dat_w)
108
109 m.d.comb += self.wb.ack.eq(sram.bus.ack)
110 m.d.comb += self.wb.dat_r.eq(sram.bus.dat_r)
111
112 # do a simple "add"
113 m.d.sync += f.eq(a + b)
114
115 return m
116
117
118 def create_verilog(dut, ports, test_name):
119 vl = verilog.convert(dut, name=test_name, ports=ports)
120 with open("%s.v" % test_name, "w") as f:
121 f.write(vl)
122
123 if __name__ == "__main__":
124 alu = DomainRenamer("sys")(ADD(width=4))
125 create_verilog(alu, [alu.a, alu.b, alu.f,
126 alu.jtag.bus.tck,
127 alu.jtag.bus.tms,
128 alu.jtag.bus.tdo,
129 alu.jtag.bus.tdi], "add")