3 based on Staf Verhaegen (Chips4Makers) wishbone TAP
7 from nmigen
import (Module
, Signal
, Elaboratable
, Const
)
8 from c4m
.nmigen
.jtag
.tap
import TAP
, IOType
9 from c4m
.nmigen
.jtag
.bus
import Interface
as JTAGInterface
10 from soc
.debug
.dmi
import DMIInterface
, DBGCore
11 from soc
.debug
.test
.dmi_sim
import dmi_sim
12 from soc
.debug
.jtag
import JTAG
13 from soc
.debug
.test
.jtagremote
import JTAGServer
, JTAGClient
15 from nmigen_soc
.wishbone
.sram
import SRAM
16 from nmigen
import Memory
, Signal
, Module
18 from nmigen
.back
.pysim
import Simulator
, Delay
, Settle
, Tick
19 from nmutil
.util
import wrap
20 from soc
.debug
.jtagutils
import (jtag_read_write_reg
,
21 jtag_srv
, jtag_set_reset
,
22 jtag_set_ir
, jtag_set_get_dr
)
26 # in, out, tri-out, tri-inout
27 'test': ['io0-', 'io1+', 'io2>', 'io3*'],
31 # JTAG-ircodes for accessing DMI
36 # JTAG-ircodes for accessing Wishbone
41 # JTAG boundary scan reg addresses
48 def jtag_sim(dut
, srv_dut
):
50 ####### JTAGy stuff (IDCODE) ######
53 yield from jtag_set_reset(dut
)
54 idcode
= yield from jtag_read_write_reg(dut
, 0b1, 32)
55 print ("idcode", hex(idcode
))
56 assert idcode
== 0x18ff
58 ####### JTAG Boundary scan ######
61 print ("scan len", bslen
)
65 yield srv_dut
.ios
[0].pad
.i
.eq(1)
66 yield srv_dut
.ios
[1].core
.o
.eq(0)
67 yield srv_dut
.ios
[2].core
.o
.eq(1)
68 yield srv_dut
.ios
[2].core
.oe
.eq(1)
69 yield srv_dut
.ios
[3].pad
.i
.eq(0)
70 yield srv_dut
.ios
[3].core
.o
.eq(0)
71 yield srv_dut
.ios
[3].core
.oe
.eq(1)
74 bs
= yield from jtag_read_write_reg(dut
, BS_SAMPLE
, bslen
, bs_actual
)
75 print ("bs scan", bin(bs
))
78 print ("io0 pad.i", (yield srv_dut
.ios
[0].pad
.i
))
79 print ("io1 core.o", (yield srv_dut
.ios
[1].core
.o
))
80 print ("io2 core.o", (yield srv_dut
.ios
[2].core
.o
))
81 print ("io2 core.oe", (yield srv_dut
.ios
[2].core
.oe
))
82 print ("io3 core.i", (yield srv_dut
.ios
[3].core
.i
))
83 print ("io3 pad.o", (yield srv_dut
.ios
[3].pad
.o
))
84 print ("io3 pad.oe", (yield srv_dut
.ios
[3].pad
.oe
))
87 ir_actual
= yield from jtag_set_ir(dut
, BS_EXTEST
)
88 print ("ir extest", bin(ir_actual
))
91 print ("io0 pad.i", (yield srv_dut
.ios
[0].pad
.i
))
92 print ("io1 core.o", (yield srv_dut
.ios
[1].core
.o
))
93 print ("io2 core.o", (yield srv_dut
.ios
[2].core
.o
))
94 print ("io2 core.oe", (yield srv_dut
.ios
[2].core
.oe
))
95 print ("io3 core.i", (yield srv_dut
.ios
[3].core
.i
))
96 print ("io3 pad.o", (yield srv_dut
.ios
[3].pad
.o
))
97 print ("io3 pad.oe", (yield srv_dut
.ios
[3].pad
.oe
))
100 bs_actual
= 0b1011001
101 yield srv_dut
.ios
[0].pad
.i
.eq(0)
102 yield srv_dut
.ios
[1].core
.o
.eq(1)
103 yield srv_dut
.ios
[2].core
.o
.eq(0)
104 yield srv_dut
.ios
[2].core
.oe
.eq(0)
105 yield srv_dut
.ios
[3].pad
.i
.eq(1)
106 yield srv_dut
.ios
[3].core
.o
.eq(1)
107 yield srv_dut
.ios
[3].core
.oe
.eq(0)
110 bs
= yield from jtag_set_get_dr(dut
, bslen
, bs_actual
)
111 print ("bs scan", bin(bs
))
114 print ("io0 pad.i", (yield srv_dut
.ios
[0].pad
.i
))
115 print ("io1 core.o", (yield srv_dut
.ios
[1].core
.o
))
116 print ("io2 core.o", (yield srv_dut
.ios
[2].core
.o
))
117 print ("io2 core.oe", (yield srv_dut
.ios
[2].core
.oe
))
118 print ("io3 core.i", (yield srv_dut
.ios
[3].core
.i
))
119 print ("io3 pad.o", (yield srv_dut
.ios
[3].pad
.o
))
120 print ("io3 pad.oe", (yield srv_dut
.ios
[3].pad
.oe
))
123 yield from jtag_set_reset(dut
)
127 print ("io0 pad.i", (yield srv_dut
.ios
[0].pad
.i
))
128 print ("io1 core.o", (yield srv_dut
.ios
[1].core
.o
))
129 print ("io2 core.o", (yield srv_dut
.ios
[2].core
.o
))
130 print ("io2 core.oe", (yield srv_dut
.ios
[2].core
.oe
))
131 print ("io3 core.i", (yield srv_dut
.ios
[3].core
.i
))
132 print ("io3 pad.o", (yield srv_dut
.ios
[3].pad
.o
))
133 print ("io3 pad.oe", (yield srv_dut
.ios
[3].pad
.oe
))
135 ####### JTAG to DMI ######
138 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, DBGCore
.CTRL
)
140 # read DMI CTRL register
141 status
= yield from jtag_read_write_reg(dut
, DMI_READ
, 64)
142 print ("dmi ctrl status", hex(status
))
146 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, 0)
148 # write DMI CTRL register
149 status
= yield from jtag_read_write_reg(dut
, DMI_WRRD
, 64, 0b101)
150 print ("dmi ctrl status", hex(status
))
151 assert status
== 4 # returned old value (nice! cool feature!)
154 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, DBGCore
.CTRL
)
156 # read DMI CTRL register
157 status
= yield from jtag_read_write_reg(dut
, DMI_READ
, 64)
158 print ("dmi ctrl status", hex(status
))
161 # write DMI MSR address
162 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, DBGCore
.MSR
)
164 # read DMI MSR register
165 msr
= yield from jtag_read_write_reg(dut
, DMI_READ
, 64)
166 print ("dmi msr", hex(msr
))
167 assert msr
== 0xdeadbeef
169 ####### JTAG to Wishbone ######
171 # write Wishbone address
172 yield from jtag_read_write_reg(dut
, WB_ADDR
, 64, 0x18)
174 # write/read wishbone data
175 data
= yield from jtag_read_write_reg(dut
, WB_WRRD
, 64, 0xfeef)
176 print ("wb write", hex(data
))
178 # write Wishbone address
179 yield from jtag_read_write_reg(dut
, WB_ADDR
, 64, 0x18)
181 # write/read wishbone data
182 data
= yield from jtag_read_write_reg(dut
, WB_READ
, 64, 0)
183 print ("wb read", hex(data
))
185 ####### done - tell dmi_sim to stop (otherwise it won't) ########
188 print ("jtag sim stopping")
191 if __name__
== '__main__':
192 dut
= JTAG(test_pinset(), wb_data_wid
=64)
195 # rather than the client access the JTAG bus directly
196 # create an alternative that the client sets
199 cdut
.cbus
= JTAGInterface()
201 # set up client-server on port 44843-something
203 if len(sys
.argv
) != 2 or sys
.argv
[1] != 'server':
204 cdut
.c
= JTAGClient()
205 dut
.s
.get_connection()
207 dut
.s
.get_connection(None) # block waiting for connection
209 # take copy of ir_width and scan_len
210 cdut
._ir
_width
= dut
._ir
_width
211 cdut
.scan_len
= dut
.scan_len
213 memory
= Memory(width
=64, depth
=16)
214 sram
= SRAM(memory
=memory
, bus
=dut
.wb
)
217 m
.submodules
.ast
= dut
218 m
.submodules
.sram
= sram
221 sim
.add_clock(1e-6, domain
="sync") # standard clock
223 sim
.add_sync_process(wrap(jtag_srv(dut
))) # jtag server
224 if len(sys
.argv
) != 2 or sys
.argv
[1] != 'server':
225 sim
.add_sync_process(wrap(jtag_sim(cdut
, dut
))) # actual jtag tester
227 print ("running server only as requested, use openocd remote to test")
228 sim
.add_sync_process(wrap(dmi_sim(dut
))) # handles (pretends to be) DMI
230 with sim
.write_vcd("dmi2jtag_test_srv.vcd"):