3 based on Staf Verhaegen (Chips4Makers) wishbone TAP
6 from nmigen
import (Module
, Signal
, Elaboratable
, Const
)
7 from c4m
.nmigen
.jtag
.tap
import TAP
, IOType
8 from soc
.debug
.dmi
import DMIInterface
, DBGCore
9 from soc
.debug
.test
.dmi_sim
import dmi_sim
10 from soc
.debug
.dmi2jtag
import DMITAP
12 from soc
.bus
.sram
import SRAM
13 from nmigen
import Memory
, Signal
, Module
15 from nmigen
.back
.pysim
import Simulator
, Delay
, Settle
, Tick
16 from nmutil
.util
import wrap
19 def tms_state_set(dut
, bits
):
21 yield dut
.bus
.tck
.eq(1)
22 yield dut
.bus
.tms
.eq(bit
)
24 yield dut
.bus
.tck
.eq(0)
26 yield dut
.bus
.tms
.eq(0)
29 def tms_data_getset(dut
, tms
, d_len
, d_in
=0):
31 yield dut
.bus
.tms
.eq(tms
)
32 for i
in range(d_len
):
33 tdi
= 1 if (d_in
& (1<<i
)) else 0
34 yield dut
.bus
.tck
.eq(1)
35 res |
= (1<<i
) if (yield dut
.bus
.tdo
) else 0
37 yield dut
.bus
.tdi
.eq(tdi
)
38 yield dut
.bus
.tck
.eq(0)
40 yield dut
.bus
.tms
.eq(0)
45 def jtag_set_reset(dut
):
46 yield from tms_state_set(dut
, [1, 1, 1, 1, 1])
48 def jtag_set_shift_dr(dut
):
49 yield from tms_state_set(dut
, [1, 0, 0])
51 def jtag_set_shift_ir(dut
):
52 yield from tms_state_set(dut
, [1, 1, 0])
54 def jtag_set_run(dut
):
55 yield from tms_state_set(dut
, [0])
57 def jtag_set_idle(dut
):
58 yield from tms_state_set(dut
, [1, 1, 0])
61 def jtag_read_write_reg(dut
, addr
, d_len
, d_in
=0):
62 yield from jtag_set_run(dut
)
63 yield from jtag_set_shift_ir(dut
)
64 yield from tms_data_getset(dut
, 0, dut
._ir
_width
, addr
)
65 yield from jtag_set_idle(dut
)
67 yield from jtag_set_shift_dr(dut
)
68 result
= yield from tms_data_getset(dut
, 0, d_len
, d_in
)
69 yield from jtag_set_idle(dut
)
73 # JTAG-ircodes for accessing DMI
78 # JTAG-ircodes for accessing Wishbone
86 ####### JTAGy stuff (IDCODE) ######
89 yield from jtag_set_reset(dut
)
90 idcode
= yield from jtag_read_write_reg(dut
, 0b1, 32)
91 print ("idcode", hex(idcode
))
92 assert idcode
== 0x18ff
94 ####### JTAG to DMI ######
97 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, DBGCore
.CTRL
)
99 # read DMI CTRL register
100 status
= yield from jtag_read_write_reg(dut
, DMI_READ
, 64)
101 print ("dmi ctrl status", hex(status
))
105 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, 0)
107 # write DMI CTRL register
108 status
= yield from jtag_read_write_reg(dut
, DMI_WRRD
, 64, 0b101)
109 print ("dmi ctrl status", hex(status
))
110 assert status
== 4 # returned old value (nice! cool feature!)
113 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, DBGCore
.CTRL
)
115 # read DMI CTRL register
116 status
= yield from jtag_read_write_reg(dut
, DMI_READ
, 64)
117 print ("dmi ctrl status", hex(status
))
120 # write DMI MSR address
121 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, DBGCore
.MSR
)
123 # read DMI MSR register
124 msr
= yield from jtag_read_write_reg(dut
, DMI_READ
, 64)
125 print ("dmi msr", hex(msr
))
126 assert msr
== 0xdeadbeef
128 ####### JTAG to Wishbone ######
130 # write Wishbone address
131 yield from jtag_read_write_reg(dut
, WB_ADDR
, 16, 0x18)
133 # write/read wishbone data
134 data
= yield from jtag_read_write_reg(dut
, WB_WRRD
, 16, 0xfeef)
135 print ("wb write", hex(data
))
137 # write Wishbone address
138 yield from jtag_read_write_reg(dut
, WB_ADDR
, 16, 0x18)
140 # write/read wishbone data
141 data
= yield from jtag_read_write_reg(dut
, WB_READ
, 16, 0)
142 print ("wb read", hex(data
))
144 ####### done - tell dmi_sim to stop (otherwise it won't) ########
149 if __name__
== '__main__':
150 dut
= DMITAP(ir_width
=4)
152 iotypes
= (IOType
.In
, IOType
.Out
, IOType
.TriOut
, IOType
.InTriOut
)
153 ios
= [dut
.add_io(iotype
=iotype
) for iotype
in iotypes
]
154 dut
.sr
= dut
.add_shiftreg(ircode
=4, length
=3) # test loopback register
156 # create and connect wishbone SRAM (a quick way to do WB test)
157 dut
.wb
= dut
.add_wishbone(ircodes
=[WB_ADDR
, WB_READ
, WB_WRRD
],
159 address_width
=16, data_width
=16)
160 memory
= Memory(width
=16, depth
=16)
161 sram
= SRAM(memory
=memory
, bus
=dut
.wb
)
163 # create DMI2JTAG (goes through to dmi_sim())
164 dut
.dmi
= dut
.add_dmi(ircodes
=[DMI_ADDR
, DMI_READ
, DMI_WRRD
])
167 m
.submodules
.ast
= dut
168 m
.submodules
.sram
= sram
169 m
.d
.comb
+= dut
.sr
.i
.eq(dut
.sr
.o
) # loopback
172 sim
.add_clock(1e-6, domain
="sync") # standard clock
174 sim
.add_sync_process(wrap(jtag_sim(dut
))) # actual jtag tester
175 sim
.add_sync_process(wrap(dmi_sim(dut
))) # handles (pretends to be) DMI
177 with sim
.write_vcd("dmi2jtag_test.vcd"):