1 """JTAG Wishbone firmware upload program
3 to test, run "python3 debug/test/test_jtag_tap_srv.py server"
8 from nmigen
import (Module
, Signal
, Elaboratable
, Const
)
9 from c4m
.nmigen
.jtag
.tap
import TAP
, IOType
10 from c4m
.nmigen
.jtag
.bus
import Interface
as JTAGInterface
11 from soc
.debug
.dmi
import DMIInterface
, DBGCore
, DBGStat
, DBGCtrl
12 from soc
.debug
.test
.dmi_sim
import dmi_sim
13 from soc
.debug
.jtag
import JTAG
14 from soc
.debug
.test
.jtagremote
import JTAGServer
, JTAGClient
16 from nmigen_soc
.wishbone
.sram
import SRAM
17 from nmigen
import Memory
, Signal
, Module
19 from nmigen
.back
.pysim
import Simulator
, Delay
, Settle
, Tick
20 from nmutil
.util
import wrap
21 from soc
.debug
.jtagutils
import (jtag_read_write_reg
,
22 jtag_srv
, jtag_set_reset
,
23 jtag_set_ir
, jtag_set_get_dr
)
27 # in, out, tri-out, tri-inout
28 'test': ['io0-', 'io1+', 'io2>', 'io3*'],
32 # JTAG-ircodes for accessing DMI
37 # JTAG-ircodes for accessing Wishbone
43 def read_dmi_addr(dut
, dmi_addr
):
45 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, dmi_addr
)
48 return (yield from jtag_read_write_reg(dut
, DMI_READ
, 64))
50 def writeread_dmi_addr(dut
, dmi_addr
, data
):
52 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, dmi_addr
)
54 # write and read DMI register
55 return (yield from jtag_read_write_reg(dut
, DMI_WRRD
, 64, data
))
58 def jtag_sim(dut
, firmware
):
59 """uploads firmware with the following commands:
60 * read IDcode (to check)
61 * set "stopped" and reset
62 * repeat until confirmed "stopped"
63 * upload data over wishbone
64 * read data back and check it
65 * issue cache flush command
66 * issue "start" command
69 ####### JTAGy stuff (IDCODE) ######
72 yield from jtag_set_reset(dut
)
73 idcode
= yield from jtag_read_write_reg(dut
, 0b1, 32)
74 print ("idcode", hex(idcode
))
75 assert idcode
== 0x18ff
77 ####### JTAG to DMI Setup (stop, reset) ######
79 yield from read_dmi_addr(dut
, DBGCore
.CTRL
)
81 status
= yield from read_dmi_addr(dut
, DBGCore
.CTRL
)
82 print ("dmi ctrl status", bin(status
))
84 # write DMI CTRL register - STOP and RESET
85 status
= yield from writeread_dmi_addr(dut
, DBGCore
.CTRL
, 0b011)
86 print ("dmi ctrl status", hex(status
))
87 assert status
== 4 # returned old value (nice! cool feature!)
89 # read STAT and wait for "STOPPED"
91 status
= yield from read_dmi_addr(dut
, DBGCore
.STAT
)
92 print ("dmi ctrl status", bin(status
))
93 if (status
& (1<<DBGStat
.STOPPED
)) or (status
& (1<<DBGStat
.TERM
)):
96 ####### JTAG to Wishbone ######
98 # write Wishbone address
99 yield from jtag_read_write_reg(dut
, WB_ADDR
, 64, 0)
101 # write/read wishbone data
103 data
= yield from jtag_read_write_reg(dut
, WB_WRRD
, 64, val
)
104 print ("wb write", hex(data
))
106 # write Wishbone address
107 yield from jtag_read_write_reg(dut
, WB_ADDR
, 64, 0)
109 # confirm data written
111 data
= yield from jtag_read_write_reg(dut
, WB_READ
, 64, 0)
112 print ("wb read", hex(data
))
114 ####### JTAG to DMI Setup (IC-Reset, start) ######
116 # write DMI CTRL register - ICRESET
117 status
= yield from writeread_dmi_addr(dut
, DBGCore
.CTRL
,
119 print ("dmi ctrl status", hex(status
))
121 # write DMI CTRL register - START
122 status
= yield from writeread_dmi_addr(dut
, DBGCore
.CTRL
,
124 print ("dmi ctrl status", hex(status
))
126 # read STAT just for info
128 status
= yield from read_dmi_addr(dut
, DBGCore
.STAT
)
129 print ("dmi stat status", bin(status
))
131 ####### done - tell dmi_sim to stop (otherwise it won't) ########
133 print ("jtag sim stopping")
136 if __name__
== '__main__':
137 # rather than the client access the JTAG bus directly
138 # create an alternative that the client sets
141 cdut
.cbus
= JTAGInterface()
143 # set up client-server on port 44843-something
144 cdut
.c
= JTAGClient()
146 # take copy of ir_width and scan_len
151 m
.d
.sync
+= flag
.eq(~flag
) # get us a "sync" domain
154 sim
.add_clock(1e-6, domain
="sync") # standard clock
156 data
= [0x01, 0x02] # list of 64-bit words
157 sim
.add_sync_process(wrap(jtag_sim(cdut
, data
)))
159 with sim
.write_vcd("jtag_firmware_upload.vcd"):