e8d31bae2ff1426619dabb61e3b055ecd9146cd1
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
.dmi2jtag
import DMITAP
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
22 tck
= yield dut
.cbus
.tck
23 tms
= yield dut
.cbus
.tms
24 tdi
= yield dut
.cbus
.tdi
25 dut
.c
.jtagremote_client_send((tck
, tms
, tdi
))
26 #print ("about to client recv")
28 tdo
= dut
.c
.jtagremote_client_recv(timeout
=0)
32 yield dut
.cbus
.tdo
.eq(tdo
)
35 def tms_state_set(dut
, bits
):
37 yield dut
.cbus
.tck
.eq(1)
38 yield dut
.cbus
.tms
.eq(bit
)
39 yield from client_sync(dut
)
41 yield dut
.cbus
.tck
.eq(0)
42 yield from client_sync(dut
)
44 yield from client_sync(dut
)
45 yield dut
.cbus
.tms
.eq(0)
46 yield from client_sync(dut
)
49 def tms_data_getset(dut
, tms
, d_len
, d_in
=0):
51 yield dut
.cbus
.tms
.eq(tms
)
52 for i
in range(d_len
):
53 tdi
= 1 if (d_in
& (1<<i
)) else 0
54 yield dut
.cbus
.tck
.eq(1)
55 yield from client_sync(dut
)
56 res |
= (1<<i
) if (yield dut
.bus
.tdo
) else 0
58 yield from client_sync(dut
)
59 yield dut
.cbus
.tdi
.eq(tdi
)
60 yield dut
.cbus
.tck
.eq(0)
61 yield from client_sync(dut
)
63 yield from client_sync(dut
)
64 yield dut
.cbus
.tms
.eq(0)
65 yield from client_sync(dut
)
70 def jtag_set_reset(dut
):
71 yield from tms_state_set(dut
, [1, 1, 1, 1, 1])
73 def jtag_set_shift_dr(dut
):
74 yield from tms_state_set(dut
, [1, 0, 0])
76 def jtag_set_shift_ir(dut
):
77 yield from tms_state_set(dut
, [1, 1, 0])
79 def jtag_set_run(dut
):
80 yield from tms_state_set(dut
, [0])
82 def jtag_set_idle(dut
):
83 yield from tms_state_set(dut
, [1, 1, 0])
86 def jtag_read_write_reg(dut
, addr
, d_len
, d_in
=0):
87 yield from jtag_set_run(dut
)
88 yield from jtag_set_shift_ir(dut
)
89 yield from tms_data_getset(dut
, 0, dut
._ir
_width
, addr
)
90 yield from jtag_set_idle(dut
)
92 yield from jtag_set_shift_dr(dut
)
93 result
= yield from tms_data_getset(dut
, 0, d_len
, d_in
)
94 yield from jtag_set_idle(dut
)
98 # JTAG-ircodes for accessing DMI
103 # JTAG-ircodes for accessing Wishbone
111 # loop and receive data from client
112 tdo
= yield dut
.bus
.tdo
113 #print ("server tdo data", tdo)
114 data
= dut
.s
.jtagremote_server_recv(tdo
)
115 #print ("server recv data", data)
120 yield dut
.bus
.tck
.eq(tck
)
121 yield dut
.bus
.tms
.eq(tms
)
122 yield dut
.bus
.tdi
.eq(tdi
)
128 ####### JTAGy stuff (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
136 ####### JTAG to DMI ######
139 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, DBGCore
.CTRL
)
141 # read DMI CTRL register
142 status
= yield from jtag_read_write_reg(dut
, DMI_READ
, 64)
143 print ("dmi ctrl status", hex(status
))
147 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, 0)
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!)
155 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, DBGCore
.CTRL
)
157 # read DMI CTRL register
158 status
= yield from jtag_read_write_reg(dut
, DMI_READ
, 64)
159 print ("dmi ctrl status", hex(status
))
162 # write DMI MSR address
163 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, DBGCore
.MSR
)
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
170 ####### JTAG to Wishbone ######
172 # write Wishbone address
173 yield from jtag_read_write_reg(dut
, WB_ADDR
, 16, 0x18)
175 # write/read wishbone data
176 data
= yield from jtag_read_write_reg(dut
, WB_WRRD
, 16, 0xfeef)
177 print ("wb write", hex(data
))
179 # write Wishbone address
180 yield from jtag_read_write_reg(dut
, WB_ADDR
, 16, 0x18)
182 # write/read wishbone data
183 data
= yield from jtag_read_write_reg(dut
, WB_READ
, 16, 0)
184 print ("wb read", hex(data
))
186 ####### done - tell dmi_sim to stop (otherwise it won't) ########
191 if __name__
== '__main__':
192 dut
= DMITAP(ir_width
=4)
195 # set up client-server on port 44843-something
197 if len(sys
.argv
) != 2 and sys
.argv
[1] != 'server':
199 dut
.s
.get_connection()
201 dut
.s
.get_connection(None) # block waiting for connection
203 # rather than the client access the JTAG bus directly
204 # create an alternative that the client sets
205 dut
.cbus
= JTAGInterface()
207 iotypes
= (IOType
.In
, IOType
.Out
, IOType
.TriOut
, IOType
.InTriOut
)
208 ios
= [dut
.add_io(iotype
=iotype
) for iotype
in iotypes
]
209 dut
.sr
= dut
.add_shiftreg(ircode
=4, length
=3) # test loopback register
211 # create and connect wishbone SRAM (a quick way to do WB test)
212 dut
.wb
= dut
.add_wishbone(ircodes
=[WB_ADDR
, WB_READ
, WB_WRRD
],
213 address_width
=16, data_width
=16)
214 memory
= Memory(width
=16, depth
=16)
215 sram
= SRAM(memory
=memory
, bus
=dut
.wb
)
217 # create DMI2JTAG (goes through to dmi_sim())
218 dut
.dmi
= dut
.add_dmi(ircodes
=[DMI_ADDR
, DMI_READ
, DMI_WRRD
])
221 m
.submodules
.ast
= dut
222 m
.submodules
.sram
= sram
223 m
.d
.comb
+= dut
.sr
.i
.eq(dut
.sr
.o
) # loopback
226 sim
.add_clock(1e-6, domain
="sync") # standard clock
228 sim
.add_sync_process(wrap(jtag_srv(dut
))) # jtag server
229 if len(sys
.argv
) != 2 and sys
.argv
[1] != 'server':
230 sim
.add_sync_process(wrap(jtag_sim(dut
))) # actual jtag tester
232 print ("running server only as requested, use openocd remote to test")
233 sim
.add_sync_process(wrap(dmi_sim(dut
))) # handles (pretends to be) DMI
235 with sim
.write_vcd("dmi2jtag_test_srv.vcd"):