use libresoc version of c4m-jtag repo
[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.test.dmi_sim import dmi_sim
10 from soc.debug.dmi2jtag import DMITAP
11
12 from nmigen_soc.wishbone.sram import SRAM
13 from nmigen import Memory, Signal, Module
14
15 from nmigen.back.pysim import Simulator, Delay, Settle, Tick
16 from nmutil.util import wrap
17
18
19 def tms_state_set(dut, bits):
20 for bit in bits:
21 yield dut.bus.tck.eq(1)
22 yield dut.bus.tms.eq(bit)
23 yield
24 yield dut.bus.tck.eq(0)
25 yield
26 yield dut.bus.tms.eq(0)
27
28
29 def tms_data_getset(dut, tms, d_len, d_in=0):
30 res = 0
31 yield dut.bus.tms.eq(tms)
32 for i in range(d_len):
33 tdi = 1 if (d_in & (1<<i)) else 0
34 yield dut.bus.tck.eq(1)
35 res |= (1<<i) if (yield dut.bus.tdo) else 0
36 yield
37 yield dut.bus.tdi.eq(tdi)
38 yield dut.bus.tck.eq(0)
39 yield
40 yield dut.bus.tms.eq(0)
41
42 return res
43
44
45 def jtag_set_reset(dut):
46 yield from tms_state_set(dut, [1, 1, 1, 1, 1])
47
48 def jtag_set_shift_dr(dut):
49 yield from tms_state_set(dut, [1, 0, 0])
50
51 def jtag_set_shift_ir(dut):
52 yield from tms_state_set(dut, [1, 1, 0])
53
54 def jtag_set_run(dut):
55 yield from tms_state_set(dut, [0])
56
57 def jtag_set_idle(dut):
58 yield from tms_state_set(dut, [1, 1, 0])
59
60
61 def jtag_read_write_reg(dut, addr, d_len, d_in=0):
62 yield from jtag_set_run(dut)
63 yield from jtag_set_shift_ir(dut)
64 yield from tms_data_getset(dut, 0, dut._ir_width, addr)
65 yield from jtag_set_idle(dut)
66
67 yield from jtag_set_shift_dr(dut)
68 result = yield from tms_data_getset(dut, 0, d_len, d_in)
69 yield from jtag_set_idle(dut)
70 return result
71
72
73 # JTAG-ircodes for accessing DMI
74 DMI_ADDR = 5
75 DMI_READ = 6
76 DMI_WRRD = 7
77
78 # JTAG-ircodes for accessing Wishbone
79 WB_ADDR = 8
80 WB_READ = 9
81 WB_WRRD = 10
82
83
84 def jtag_sim(dut):
85
86 ####### JTAGy stuff (IDCODE) ######
87
88 # read idcode
89 yield from jtag_set_reset(dut)
90 idcode = yield from jtag_read_write_reg(dut, 0b1, 32)
91 print ("idcode", hex(idcode))
92 assert idcode == 0x18ff
93
94 ####### JTAG to DMI ######
95
96 # write DMI address
97 yield from jtag_read_write_reg(dut, DMI_ADDR, 8, DBGCore.CTRL)
98
99 # read DMI CTRL register
100 status = yield from jtag_read_write_reg(dut, DMI_READ, 64)
101 print ("dmi ctrl status", hex(status))
102 assert status == 4
103
104 # write DMI address
105 yield from jtag_read_write_reg(dut, DMI_ADDR, 8, 0)
106
107 # write DMI CTRL register
108 status = yield from jtag_read_write_reg(dut, DMI_WRRD, 64, 0b101)
109 print ("dmi ctrl status", hex(status))
110 assert status == 4 # returned old value (nice! cool feature!)
111
112 # write DMI address
113 yield from jtag_read_write_reg(dut, DMI_ADDR, 8, DBGCore.CTRL)
114
115 # read DMI CTRL register
116 status = yield from jtag_read_write_reg(dut, DMI_READ, 64)
117 print ("dmi ctrl status", hex(status))
118 assert status == 5
119
120 # write DMI MSR address
121 yield from jtag_read_write_reg(dut, DMI_ADDR, 8, DBGCore.MSR)
122
123 # read DMI MSR register
124 msr = yield from jtag_read_write_reg(dut, DMI_READ, 64)
125 print ("dmi msr", hex(msr))
126 assert msr == 0xdeadbeef
127
128 ####### JTAG to Wishbone ######
129
130 # write Wishbone address
131 yield from jtag_read_write_reg(dut, WB_ADDR, 16, 0x18)
132
133 # write/read wishbone data
134 data = yield from jtag_read_write_reg(dut, WB_WRRD, 16, 0xfeef)
135 print ("wb write", hex(data))
136
137 # write Wishbone address
138 yield from jtag_read_write_reg(dut, WB_ADDR, 16, 0x18)
139
140 # write/read wishbone data
141 data = yield from jtag_read_write_reg(dut, WB_READ, 16, 0)
142 print ("wb read", hex(data))
143
144 ####### done - tell dmi_sim to stop (otherwise it won't) ########
145
146 dut.stop = True
147
148
149 if __name__ == '__main__':
150 dut = DMITAP(ir_width=4)
151 dut.stop = False
152 iotypes = (IOType.In, IOType.Out, IOType.TriOut, IOType.InTriOut)
153 ios = [dut.add_io(iotype=iotype) for iotype in iotypes]
154 dut.sr = dut.add_shiftreg(ircode=4, length=3) # test loopback register
155
156 # create and connect wishbone SRAM (a quick way to do WB test)
157 dut.wb = dut.add_wishbone(ircodes=[WB_ADDR, WB_READ, WB_WRRD],
158 features={'err'},
159 address_width=16, data_width=16)
160 memory = Memory(width=16, depth=16)
161 sram = SRAM(memory=memory, bus=dut.wb)
162
163 # create DMI2JTAG (goes through to dmi_sim())
164 dut.dmi = dut.add_dmi(ircodes=[DMI_ADDR, DMI_READ, DMI_WRRD])
165
166 m = Module()
167 m.submodules.ast = dut
168 m.submodules.sram = sram
169 m.d.comb += dut.sr.i.eq(dut.sr.o) # loopback
170
171 sim = Simulator(m)
172 sim.add_clock(1e-6, domain="sync") # standard clock
173
174 sim.add_sync_process(wrap(jtag_sim(dut))) # actual jtag tester
175 sim.add_sync_process(wrap(dmi_sim(dut))) # handles (pretends to be) DMI
176
177 with sim.write_vcd("dmi2jtag_test.vcd"):
178 sim.run()