1 # generate add.il ilang file with: python3 add.py
4 from nmigen
import Elaboratable
, Signal
, Module
, Const
, DomainRenamer
5 from nmigen
.cli
import verilog
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
12 from c4m
.nmigen
.jtag
.tap
import TAP
, IOType
13 from nmigen_soc
.wishbone
.sram
import SRAM
14 from nmigen
import Memory
17 class ADD(Elaboratable
):
18 def __init__(self
, width
):
20 self
.a
= Signal(width
)
21 self
.b
= Signal(width
)
22 self
.f
= Signal(width
)
24 # set up JTAG - use an irwidth of 4, up to 16 ircodes (1<<4).
25 # change this to add more Wishbone interfaces: see below
26 self
.jtag
= TAP(ir_width
=4)
27 self
.jtag
.bus
.tck
.name
= 'jtag_tck'
28 self
.jtag
.bus
.tms
.name
= 'jtag_tms'
29 self
.jtag
.bus
.tdo
.name
= 'jtag_tdo'
30 self
.jtag
.bus
.tdi
.name
= 'jtag_tdi'
32 # have to create at least one shift register
33 self
.sr
= self
.jtag
.add_shiftreg(ircode
=4, length
=3)
35 # decide how many SRAMs you want to create (and what sizes)
36 # simply edit this before running "make lvx"
37 # try not to go above 3 because you run out of JTAG ircodes that way.
38 # if you really really must, then increase ir_width above, first
40 #self.memsizes.append((32, 32)) # width, depth
41 self
.memsizes
.append((32, 16)) # width, depth
42 self
.memsizes
.append((32, 16)) # width, depth
44 # create and connect wishbone(s). okok, a better solution is to
45 # use a Wishbone Arbiter, and only have one WB bus.
47 ircode
= 5 # start at 5,6,7 then jump 11,12,13 then 14,15,16 etc. etc.
48 for i
, (width
, depth
) in enumerate(self
.memsizes
):
49 ircodes
= [ircode
, ircode
+1, ircode
+2]
51 # next one skips DMI (see below - 8,9,10 already used)
55 wb
= self
.jtag
.add_wishbone(ircodes
=ircodes
, features
={'err'},
56 address_width
=30, data_width
=width
,
57 granularity
=8, # 8-bit wide
58 name
="jtag_wb_%d" % i
)
61 # create DMI2JTAG (goes through to dmi_sim())
62 self
.dmi
= self
.jtag
.add_dmi(ircodes
=[8, 9, 10])
65 self
.io_a_0
= self
.jtag
.add_io(name
="a_0", iotype
=IOType
.In
)
66 self
.io_a_1
= self
.jtag
.add_io(name
="a_1", iotype
=IOType
.In
)
67 self
.io_a_2
= self
.jtag
.add_io(name
="a_2", iotype
=IOType
.In
)
68 self
.io_a_3
= self
.jtag
.add_io(name
="a_3", iotype
=IOType
.In
)
69 self
.io_b_0
= self
.jtag
.add_io(name
="b_0", iotype
=IOType
.In
)
70 self
.io_b_1
= self
.jtag
.add_io(name
="b_1", iotype
=IOType
.In
)
71 self
.io_b_2
= self
.jtag
.add_io(name
="b_2", iotype
=IOType
.In
)
72 self
.io_b_3
= self
.jtag
.add_io(name
="b_3", iotype
=IOType
.In
)
73 self
.io_f_0
= self
.jtag
.add_io(name
="f_0", iotype
=IOType
.Out
)
74 self
.io_f_1
= self
.jtag
.add_io(name
="f_1", iotype
=IOType
.Out
)
75 self
.io_f_2
= self
.jtag
.add_io(name
="f_2", iotype
=IOType
.Out
)
76 self
.io_f_3
= self
.jtag
.add_io(name
="f_3", iotype
=IOType
.Out
)
78 def elaborate(self
, platform
):
81 m
.submodules
.jtag
= jtag
= self
.jtag
82 m
.d
.comb
+= self
.sr
.i
.eq(self
.sr
.o
) # loopback test
84 # connect inputs/outputs to pads
85 m
.d
.comb
+= self
.io_a_0
.pad
.i
.eq(self
.a
[0])
86 m
.d
.comb
+= self
.io_a_1
.pad
.i
.eq(self
.a
[1])
87 m
.d
.comb
+= self
.io_a_2
.pad
.i
.eq(self
.a
[2])
88 m
.d
.comb
+= self
.io_a_3
.pad
.i
.eq(self
.a
[3])
89 m
.d
.comb
+= self
.io_b_0
.pad
.i
.eq(self
.b
[0])
90 m
.d
.comb
+= self
.io_b_1
.pad
.i
.eq(self
.b
[1])
91 m
.d
.comb
+= self
.io_b_2
.pad
.i
.eq(self
.b
[2])
92 m
.d
.comb
+= self
.io_b_3
.pad
.i
.eq(self
.b
[3])
93 m
.d
.comb
+= self
.f
[0].eq(self
.io_f_0
.pad
.o
)
94 m
.d
.comb
+= self
.f
[1].eq(self
.io_f_1
.pad
.o
)
95 m
.d
.comb
+= self
.f
[2].eq(self
.io_f_2
.pad
.o
)
96 m
.d
.comb
+= self
.f
[3].eq(self
.io_f_3
.pad
.o
)
98 # internal signals (not external pads basically)
99 a
= Signal(self
.width
)
100 b
= Signal(self
.width
)
101 f
= Signal(self
.width
)
103 # and now the internal signals to the core
104 m
.d
.comb
+= a
[0].eq(self
.io_a_0
.core
.i
)
105 m
.d
.comb
+= a
[1].eq(self
.io_a_1
.core
.i
)
106 m
.d
.comb
+= a
[2].eq(self
.io_a_2
.core
.i
)
107 m
.d
.comb
+= a
[3].eq(self
.io_a_3
.core
.i
)
108 m
.d
.comb
+= b
[0].eq(self
.io_b_0
.core
.i
)
109 m
.d
.comb
+= b
[1].eq(self
.io_b_1
.core
.i
)
110 m
.d
.comb
+= b
[2].eq(self
.io_b_2
.core
.i
)
111 m
.d
.comb
+= b
[3].eq(self
.io_b_3
.core
.i
)
112 m
.d
.comb
+= self
.io_f_0
.core
.o
.eq(f
[0])
113 m
.d
.comb
+= self
.io_f_1
.core
.o
.eq(f
[1])
114 m
.d
.comb
+= self
.io_f_2
.core
.o
.eq(f
[2])
115 m
.d
.comb
+= self
.io_f_3
.core
.o
.eq(f
[3])
117 # create Memories, each with their own individual JTAG bus
118 for i
, (width
, depth
) in enumerate(self
.memsizes
):
119 memory
= Memory(width
=width
, depth
=depth
)
120 sram
= SRAM(memory
=memory
, granularity
=8)
121 m
.submodules
['sram%d' % i
] = sram
124 m
.d
.comb
+= sram
.bus
.cyc
.eq(wb
.cyc
)
125 m
.d
.comb
+= sram
.bus
.stb
.eq(wb
.stb
)
126 m
.d
.comb
+= sram
.bus
.we
.eq(wb
.we
)
127 m
.d
.comb
+= sram
.bus
.sel
.eq(wb
.sel
)
128 m
.d
.comb
+= sram
.bus
.adr
.eq(wb
.adr
)
129 m
.d
.comb
+= sram
.bus
.dat_w
.eq(wb
.dat_w
)
131 m
.d
.comb
+= wb
.ack
.eq(sram
.bus
.ack
)
132 m
.d
.comb
+= wb
.dat_r
.eq(sram
.bus
.dat_r
)
135 m
.d
.sync
+= f
.eq(a
+ b
)
140 def create_verilog(dut
, ports
, test_name
):
141 vl
= verilog
.convert(dut
, name
=test_name
, ports
=ports
)
142 with
open("%s.v" % test_name
, "w") as f
:
145 if __name__
== "__main__":
146 alu
= DomainRenamer("sys")(ADD(width
=4))
147 create_verilog(alu
, [alu
.a
, alu
.b
, alu
.f
,
151 alu
.jtag
.bus
.tdi
], "add")