add openocd.cfg experiment
[soc.git] / src / soc / debug / test / test_jtag_tap.py
1 """DMI 2 JTAG test
2
3 based on Staf Verhaegen (Chips4Makers) wishbone TAP
4 """
5
6 from nmigen import (Module, Signal, Elaboratable, Const)
7 from c4m.nmigen.jtag.tap import TAP, IOType
8 from soc.debug.dmi import DMIInterface, DBGCore
9 from soc.debug.dmi2jtag import DMITAP
10
11 from nmigen_soc.wishbone.sram import SRAM
12 from nmigen import Memory, Signal, Module
13
14 from nmigen.back.pysim import Simulator, Delay, Settle, Tick
15 from nmutil.util import wrap
16
17
18 def tms_state_set(dut, bits):
19 for bit in bits:
20 yield dut.bus.tck.eq(1)
21 yield dut.bus.tms.eq(bit)
22 yield
23 yield dut.bus.tck.eq(0)
24 yield
25 yield dut.bus.tms.eq(0)
26
27
28 def tms_data_getset(dut, tms, d_len, d_in=0):
29 res = 0
30 yield dut.bus.tms.eq(tms)
31 for i in range(d_len):
32 tdi = 1 if (d_in & (1<<i)) else 0
33 yield dut.bus.tck.eq(1)
34 res |= (1<<i) if (yield dut.bus.tdo) else 0
35 yield
36 yield dut.bus.tdi.eq(tdi)
37 yield dut.bus.tck.eq(0)
38 yield
39 yield dut.bus.tms.eq(0)
40
41 return res
42
43
44 def jtag_set_reset(dut):
45 yield from tms_state_set(dut, [1, 1, 1, 1, 1])
46
47 def jtag_set_shift_dr(dut):
48 yield from tms_state_set(dut, [1, 0, 0])
49
50 def jtag_set_shift_ir(dut):
51 yield from tms_state_set(dut, [1, 1, 0])
52
53 def jtag_set_run(dut):
54 yield from tms_state_set(dut, [0])
55
56 def jtag_set_idle(dut):
57 yield from tms_state_set(dut, [1, 1, 0])
58
59
60 def jtag_read_write_reg(dut, addr, d_len, d_in=0):
61 yield from jtag_set_run(dut)
62 yield from jtag_set_shift_ir(dut)
63 yield from tms_data_getset(dut, 0, dut._ir_width, addr)
64 yield from jtag_set_idle(dut)
65
66 yield from jtag_set_shift_dr(dut)
67 result = yield from tms_data_getset(dut, 0, d_len, d_in)
68 yield from jtag_set_idle(dut)
69 return result
70
71
72 stop = False
73
74 def dmi_sim(dut):
75 global stop
76
77 ctrl_reg = 0b100 # terminated
78
79 dmi = dut.dmi
80 while not stop:
81 # wait for req
82 req = yield dmi.req_i
83 if req == 0:
84 yield
85 continue
86
87 # check read/write and address
88 wen = yield dmi.we_i
89 addr = yield dmi.addr_i
90 print (" dmi wen, addr", wen, addr)
91 if addr == DBGCore.CTRL and wen == 0:
92 print (" read ctrl reg", ctrl_reg)
93 yield dmi.dout.eq(ctrl_reg)
94 yield dmi.ack_o.eq(1)
95 yield
96 yield dmi.ack_o.eq(0)
97 elif addr == DBGCore.CTRL and wen == 1:
98 ctrl_reg = (yield dmi.din)
99 print (" write ctrl reg", ctrl_reg)
100 yield dmi.ack_o.eq(1)
101 yield
102 yield dmi.ack_o.eq(0)
103 elif addr == DBGCore.MSR and wen == 0:
104 print (" read msr reg")
105 yield dmi.dout.eq(0xdeadbeef) # test MSR value
106 yield dmi.ack_o.eq(1)
107 yield
108 yield dmi.ack_o.eq(0)
109 else:
110 # do nothing but just ack it
111 yield dmi.ack_o.eq(1)
112 yield
113 yield dmi.ack_o.eq(0)
114
115 # JTAG-ircodes for accessing DMI
116 DMI_ADDR = 5
117 DMI_READ = 6
118 DMI_WRRD = 7
119
120 # JTAG-ircodes for accessing Wishbone
121 WB_ADDR = 8
122 WB_READ = 9
123 WB_WRRD = 10
124
125
126 def jtag_sim(dut):
127
128 ####### JTAGy stuff (IDCODE) ######
129
130 # read idcode
131 yield from jtag_set_reset(dut)
132 idcode = yield from jtag_read_write_reg(dut, 0b1, 32)
133 print ("idcode", hex(idcode))
134 assert idcode == 0x18ff
135
136 ####### JTAG to DMI ######
137
138 # write DMI address
139 yield from jtag_read_write_reg(dut, DMI_ADDR, 8, DBGCore.CTRL)
140
141 # read DMI CTRL register
142 status = yield from jtag_read_write_reg(dut, DMI_READ, 64)
143 print ("dmi ctrl status", hex(status))
144 assert status == 4
145
146 # write DMI address
147 yield from jtag_read_write_reg(dut, DMI_ADDR, 8, 0)
148
149 # write DMI CTRL register
150 status = yield from jtag_read_write_reg(dut, DMI_WRRD, 64, 0b101)
151 print ("dmi ctrl status", hex(status))
152 assert status == 4 # returned old value (nice! cool feature!)
153
154 # write DMI address
155 yield from jtag_read_write_reg(dut, DMI_ADDR, 8, DBGCore.CTRL)
156
157 # read DMI CTRL register
158 status = yield from jtag_read_write_reg(dut, DMI_READ, 64)
159 print ("dmi ctrl status", hex(status))
160 assert status == 5
161
162 # write DMI MSR address
163 yield from jtag_read_write_reg(dut, DMI_ADDR, 8, DBGCore.MSR)
164
165 # read DMI MSR register
166 msr = yield from jtag_read_write_reg(dut, DMI_READ, 64)
167 print ("dmi msr", hex(msr))
168 assert msr == 0xdeadbeef
169
170 ####### JTAG to Wishbone ######
171
172 # write Wishbone address
173 yield from jtag_read_write_reg(dut, WB_ADDR, 16, 0x18)
174
175 # write/read wishbone data
176 data = yield from jtag_read_write_reg(dut, WB_WRRD, 16, 0xfeef)
177 print ("wb write", hex(data))
178
179 # write Wishbone address
180 yield from jtag_read_write_reg(dut, WB_ADDR, 16, 0x18)
181
182 # write/read wishbone data
183 data = yield from jtag_read_write_reg(dut, WB_READ, 16, 0)
184 print ("wb read", hex(data))
185
186 ####### done - tell dmi_sim to stop (otherwise it won't) ########
187
188 global stop
189 stop = True
190
191
192 if __name__ == '__main__':
193 dut = DMITAP(ir_width=4)
194 iotypes = (IOType.In, IOType.Out, IOType.TriOut, IOType.InTriOut)
195 ios = [dut.add_io(iotype=iotype) for iotype in iotypes]
196 dut.sr = dut.add_shiftreg(ircode=4, length=3) # test loopback register
197
198 # create and connect wishbone SRAM (a quick way to do WB test)
199 dut.wb = dut.add_wishbone(ircodes=[WB_ADDR, WB_READ, WB_WRRD],
200 address_width=16, data_width=16)
201 memory = Memory(width=16, depth=16)
202 sram = SRAM(memory=memory, bus=dut.wb)
203
204 # create DMI2JTAG (goes through to dmi_sim())
205 dut.dmi = dut.add_dmi(ircodes=[DMI_ADDR, DMI_READ, DMI_WRRD])
206
207 m = Module()
208 m.submodules.ast = dut
209 m.submodules.sram = sram
210 m.d.comb += dut.sr.i.eq(dut.sr.o) # loopback
211
212 sim = Simulator(m)
213 sim.add_clock(1e-6, domain="sync") # standard clock
214
215 sim.add_sync_process(wrap(jtag_sim(dut))) # actual jtag tester
216 sim.add_sync_process(wrap(dmi_sim(dut))) # handles (pretends to be) DMI
217
218 with sim.write_vcd("dmi2jtag_test.vcd"):
219 sim.run()