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 soc
.bus
.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
)
24 from openpower
.simulator
.program
import Program
28 # in, out, tri-out, tri-inout
29 'test': ['io0-', 'io1+', 'io2>', 'io3*'],
33 b
= '{:0{width}b}'.format(n
, width
=width
)
34 return int(b
[::-1], 2)
37 # JTAG-ircodes for accessing DMI
42 # JTAG-ircodes for accessing Wishbone
48 def read_dmi_addr(dut
, dmi_addr
):
50 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, dmi_addr
)
53 return (yield from jtag_read_write_reg(dut
, DMI_READ
, 64))
55 def writeread_dmi_addr(dut
, dmi_addr
, data
):
57 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, dmi_addr
)
59 # write and read DMI register
60 return (yield from jtag_read_write_reg(dut
, DMI_WRRD
, 64, data
))
63 def jtag_sim(dut
, firmware
):
64 """uploads firmware with the following commands:
65 * read IDcode (to check)
66 * set "stopped" and reset
67 * repeat until confirmed "stopped"
68 * upload data over wishbone
69 * read data back and check it
70 * issue cache flush command
71 * issue "start" command
74 ####### JTAGy stuff (IDCODE) ######
77 yield from jtag_set_reset(dut
)
78 idcode
= yield from jtag_read_write_reg(dut
, 0b1, 32)
79 print ("idcode", hex(idcode
))
80 assert idcode
== 0x18ff
82 ####### JTAG to DMI Setup (stop, reset) ######
84 yield from read_dmi_addr(dut
, DBGCore
.CTRL
)
86 status
= yield from read_dmi_addr(dut
, DBGCore
.CTRL
)
87 print ("dmi ctrl status", bin(status
))
89 # write DMI CTRL register - STOP and RESET
90 status
= yield from writeread_dmi_addr(dut
, DBGCore
.CTRL
,
93 print ("dmi ctrl status", hex(status
))
94 assert status
== 0 # returned old value (nice! cool feature!)
96 # read STAT and wait for "STOPPED"
98 status
= yield from read_dmi_addr(dut
, DBGCore
.STAT
)
99 print ("dmi ctrl status", bin(status
))
100 if (status
& (1<<DBGStat
.STOPPED
)) or (status
& (1<<DBGStat
.TERM
)):
103 ####### JTAG to Wishbone - hard-coded 30-bit addr, 32-bit data ######
105 # write Wishbone address
106 yield from jtag_read_write_reg(dut
, WB_ADDR
, 30, 0)
108 # write/read wishbone data
110 data
= yield from jtag_read_write_reg(dut
, WB_WRRD
, 32, val
)
111 print ("wb write", hex(val
), hex(data
))
113 # write Wishbone address
114 yield from jtag_read_write_reg(dut
, WB_ADDR
, 30, 0)
116 # confirm data written
118 data
= yield from jtag_read_write_reg(dut
, WB_READ
, 32, val
)
119 print ("wb read", hex(val
), hex(data
))
121 ####### JTAG to DMI Setup (IC-Reset, start) ######
123 # write DMI CTRL register - ICRESET
124 status
= yield from writeread_dmi_addr(dut
, DBGCore
.CTRL
,
126 print ("dmi ctrl status", hex(status
))
128 # write DMI CTRL register - START
129 status
= yield from writeread_dmi_addr(dut
, DBGCore
.CTRL
,
131 print ("dmi ctrl status", hex(status
))
133 # read STAT just for info
135 status
= yield from read_dmi_addr(dut
, DBGCore
.STAT
)
136 print ("dmi stat status", bin(status
))
138 ####### done - tell dmi_sim to stop (otherwise it won't) ########
140 print ("jtag sim stopping")
143 if __name__
== '__main__':
144 # rather than the client access the JTAG bus directly
145 # create an alternative that the client sets
148 cdut
.cbus
= JTAGInterface()
150 # set up client-server on port 44843-something
151 cdut
.c
= JTAGClient()
153 # take copy of ir_width and scan_len
158 m
.d
.sync
+= flag
.eq(~flag
) # get us a "sync" domain
161 sim
.add_clock(1e-6, domain
="sync") # standard clock
178 lst
= ["addi 9, 0, 0x10", # i = 16
179 "addi 9,9,-1", # i = i - 1
180 "cmpi 2,1,9,12", # compare 9 to value 12, store in CR2
181 "bc 4,10,-16", # branch if CR2 "test was != 12"
186 with
Program(lst
, False) as p
:
187 data
= list(p
.generate_instructions())
188 for instruction
in data
:
189 print (hex(instruction
))
191 sim
.add_sync_process(wrap(jtag_sim(cdut
, data
)))
193 with sim
.write_vcd("jtag_firmware_upload.vcd"):