connect up boundary scan to inputs/outputs
[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
14
15 class ADD(Elaboratable):
16 def __init__(self, width):
17 self.width = width
18 self.a = Signal(width)
19 self.b = Signal(width)
20 self.f = Signal(width)
21
22 # set up JTAG
23 self.jtag = TAP(ir_width=4)
24 self.jtag.bus.tck.name = 'jtag_tck'
25 self.jtag.bus.tms.name = 'jtag_tms'
26 self.jtag.bus.tdo.name = 'jtag_tdo'
27 self.jtag.bus.tdi.name = 'jtag_tdi'
28
29 # have to create at least one shift register
30 self.sr = self.jtag.add_shiftreg(ircode=4, length=3)
31
32 # add iotypes
33 self.io_a_0 = self.jtag.add_io(name="a_0", iotype=IOType.In)
34 self.io_a_1 = self.jtag.add_io(name="a_1", iotype=IOType.In)
35 self.io_a_2 = self.jtag.add_io(name="a_2", iotype=IOType.In)
36 self.io_a_3 = self.jtag.add_io(name="a_3", iotype=IOType.In)
37 self.io_b_0 = self.jtag.add_io(name="b_0", iotype=IOType.In)
38 self.io_b_1 = self.jtag.add_io(name="b_1", iotype=IOType.In)
39 self.io_b_2 = self.jtag.add_io(name="b_2", iotype=IOType.In)
40 self.io_b_3 = self.jtag.add_io(name="b_3", iotype=IOType.In)
41 self.io_f_0 = self.jtag.add_io(name="f_0", iotype=IOType.Out)
42 self.io_f_1 = self.jtag.add_io(name="f_1", iotype=IOType.Out)
43 self.io_f_2 = self.jtag.add_io(name="f_2", iotype=IOType.Out)
44 self.io_f_3 = self.jtag.add_io(name="f_3", iotype=IOType.Out)
45
46 def elaborate(self, platform):
47 m = Module()
48
49 m.submodules.jtag = jtag = self.jtag
50 m.d.comb += self.sr.i.eq(self.sr.o) # loopback test
51
52 # connect inputs/outputs to pads
53 m.d.comb += self.io_a_0.pad.i.eq(self.a[0])
54 m.d.comb += self.io_a_1.pad.i.eq(self.a[1])
55 m.d.comb += self.io_a_2.pad.i.eq(self.a[2])
56 m.d.comb += self.io_a_3.pad.i.eq(self.a[3])
57 m.d.comb += self.io_b_0.pad.i.eq(self.b[0])
58 m.d.comb += self.io_b_1.pad.i.eq(self.b[1])
59 m.d.comb += self.io_b_2.pad.i.eq(self.b[2])
60 m.d.comb += self.io_b_3.pad.i.eq(self.b[3])
61 m.d.comb += self.f[0].eq(self.io_f_0.pad.o)
62 m.d.comb += self.f[1].eq(self.io_f_1.pad.o)
63 m.d.comb += self.f[2].eq(self.io_f_2.pad.o)
64 m.d.comb += self.f[3].eq(self.io_f_3.pad.o)
65
66 # internal signals (not external pads basically)
67 a = Signal(self.width)
68 b = Signal(self.width)
69 f = Signal(self.width)
70
71 # and now the internal signals to the core
72 m.d.comb += a[0].eq(self.io_a_0.core.i)
73 m.d.comb += a[1].eq(self.io_a_1.core.i)
74 m.d.comb += a[2].eq(self.io_a_2.core.i)
75 m.d.comb += a[3].eq(self.io_a_3.core.i)
76 m.d.comb += b[0].eq(self.io_b_0.core.i)
77 m.d.comb += b[1].eq(self.io_b_1.core.i)
78 m.d.comb += b[2].eq(self.io_b_2.core.i)
79 m.d.comb += b[3].eq(self.io_b_3.core.i)
80 m.d.comb += self.io_f_0.core.o.eq(f[0])
81 m.d.comb += self.io_f_1.core.o.eq(f[1])
82 m.d.comb += self.io_f_2.core.o.eq(f[2])
83 m.d.comb += self.io_f_3.core.o.eq(f[3])
84
85
86 # do a simple "add"
87 m.d.sync += f.eq(a + b)
88
89 return m
90
91
92 def create_verilog(dut, ports, test_name):
93 vl = verilog.convert(dut, name=test_name, ports=ports)
94 with open("%s.v" % test_name, "w") as f:
95 f.write(vl)
96
97 if __name__ == "__main__":
98 alu = DomainRenamer("sys")(ADD(width=4))
99 create_verilog(alu, [alu.a, alu.b, alu.f,
100 alu.jtag.bus.tck,
101 alu.jtag.bus.tms,
102 alu.jtag.bus.tdo,
103 alu.jtag.bus.tdi], "add")