Allow the formal engine to perform a same-cycle result in the ALU
[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 soc.bus.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 == 6
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()