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