5fe2c4caa6cedb0a5803d853098aed78394ef48f
[soc.git] / src / soc / debug / firmware_upload.py
1 """JTAG Wishbone firmware upload program
2
3 to test, run "python3 debug/test/test_jtag_tap_srv.py server"
4
5 """
6
7 import sys
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
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
15
16 from nmigen_soc.wishbone.sram import SRAM
17 from nmigen import Memory, Signal, Module
18
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
25 def test_pinset():
26 return {
27 # in, out, tri-out, tri-inout
28 'test': ['io0-', 'io1+', 'io2>', 'io3*'],
29 }
30
31
32 # JTAG-ircodes for accessing DMI
33 DMI_ADDR = 8
34 DMI_READ = 9
35 DMI_WRRD = 10
36
37 # JTAG-ircodes for accessing Wishbone
38 WB_ADDR = 5
39 WB_READ = 6
40 WB_WRRD = 7
41
42 # JTAG boundary scan reg addresses
43 BS_EXTEST = 0
44 BS_INTEST = 0
45 BS_SAMPLE = 2
46 BS_PRELOAD = 2
47
48
49 def jtag_sim(dut, firmware):
50
51 ####### JTAGy stuff (IDCODE) ######
52
53 # read idcode
54 yield from jtag_set_reset(dut)
55 idcode = yield from jtag_read_write_reg(dut, 0b1, 32)
56 print ("idcode", hex(idcode))
57 assert idcode == 0x18ff
58
59 ####### JTAG to DMI ######
60
61 # write DMI address
62 yield from jtag_read_write_reg(dut, DMI_ADDR, 8, DBGCore.CTRL)
63
64 # read DMI CTRL register
65 status = yield from jtag_read_write_reg(dut, DMI_READ, 64)
66 print ("dmi ctrl status", hex(status))
67 assert status == 4
68
69 # write DMI address
70 yield from jtag_read_write_reg(dut, DMI_ADDR, 8, 0)
71
72 # write DMI CTRL register
73 status = yield from jtag_read_write_reg(dut, DMI_WRRD, 64, 0b101)
74 print ("dmi ctrl status", hex(status))
75 assert status == 4 # returned old value (nice! cool feature!)
76
77 # write DMI address
78 yield from jtag_read_write_reg(dut, DMI_ADDR, 8, DBGCore.CTRL)
79
80 # read DMI CTRL register
81 status = yield from jtag_read_write_reg(dut, DMI_READ, 64)
82 print ("dmi ctrl status", hex(status))
83 assert status == 5
84
85 # write DMI MSR address
86 yield from jtag_read_write_reg(dut, DMI_ADDR, 8, DBGCore.MSR)
87
88 # read DMI MSR register
89 msr = yield from jtag_read_write_reg(dut, DMI_READ, 64)
90 print ("dmi msr", hex(msr))
91 assert msr == 0xdeadbeef
92
93 ####### JTAG to Wishbone ######
94
95 # write Wishbone address
96 yield from jtag_read_write_reg(dut, WB_ADDR, 64, 0)
97
98 # write/read wishbone data
99 for val in firmware:
100 data = yield from jtag_read_write_reg(dut, WB_WRRD, 64, val)
101 print ("wb write", hex(data))
102
103 # write Wishbone address
104 yield from jtag_read_write_reg(dut, WB_ADDR, 64, 0)
105
106 # confirm data written
107 for val in firmware:
108 data = yield from jtag_read_write_reg(dut, WB_READ, 64, 0)
109 print ("wb read", hex(data))
110
111 ####### done - tell dmi_sim to stop (otherwise it won't) ########
112
113 print ("jtag sim stopping")
114
115
116 if __name__ == '__main__':
117 # rather than the client access the JTAG bus directly
118 # create an alternative that the client sets
119 class Dummy: pass
120 cdut = Dummy()
121 cdut.cbus = JTAGInterface()
122
123 # set up client-server on port 44843-something
124 cdut.c = JTAGClient()
125
126 # take copy of ir_width and scan_len
127 cdut._ir_width = 4
128
129 flag = Signal()
130 m = Module()
131 m.d.sync += flag.eq(~flag) # get us a "sync" domain
132
133 sim = Simulator(m)
134 sim.add_clock(1e-6, domain="sync") # standard clock
135
136 data = [0x01, 0x02] # list of 64-bit words
137 sim.add_sync_process(wrap(jtag_sim(cdut, data)))
138
139 with sim.write_vcd("jtag_firmware_upload.vcd"):
140 sim.run()