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)
28 def tms_data_getset(dut
, tms
, d_len
, d_in
=0, reverse
=False):
30 # Reverse the for loop to transmit MSB-first
31 bit_range
= range(d_len
-1, -1, -1)
33 bit_range
= range(d_len
)
36 yield dut
.bus
.tms
.eq(tms
)
38 tdi
= 1 if (d_in
& (1<<i
)) else 0
39 yield dut
.bus
.tck
.eq(1)
40 res |
= (1<<i
) if (yield dut
.bus
.tdo
) else 0
42 yield dut
.bus
.tdi
.eq(tdi
)
43 yield dut
.bus
.tck
.eq(0)
45 yield dut
.bus
.tms
.eq(0)
50 def jtag_set_reset(dut
):
51 yield from tms_state_set(dut
, [1, 1, 1, 1, 1])
53 def jtag_set_shift_dr(dut
):
54 yield from tms_state_set(dut
, [1, 0, 0])
56 def jtag_set_shift_ir(dut
):
57 yield from tms_state_set(dut
, [1, 1, 0])
59 def jtag_set_run(dut
):
60 yield from tms_state_set(dut
, [0])
62 def jtag_set_idle(dut
):
63 yield from tms_state_set(dut
, [1, 1, 0])
66 def jtag_read_write_reg(dut
, addr
, d_len
, d_in
=0, reverse
=False):
67 yield from jtag_set_run(dut
)
68 yield from jtag_set_shift_ir(dut
)
69 yield from tms_data_getset(dut
, 0, dut
._ir
_width
, addr
)
70 yield from jtag_set_idle(dut
)
72 yield from jtag_set_shift_dr(dut
)
73 result
= yield from tms_data_getset(dut
, 0, d_len
, d_in
, reverse
)
74 yield from jtag_set_idle(dut
)
78 # JTAG-ircodes for accessing DMI
83 # JTAG-ircodes for accessing Wishbone
91 ####### JTAGy stuff (IDCODE) ######
94 yield from jtag_set_reset(dut
)
95 idcode
= yield from jtag_read_write_reg(dut
, 0b1, 32)
96 print ("idcode", hex(idcode
))
97 assert idcode
== 0x18ff
99 ####### JTAG to DMI ######
102 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, DBGCore
.CTRL
)
104 # read DMI CTRL register
105 status
= yield from jtag_read_write_reg(dut
, DMI_READ
, 64)
106 print ("dmi ctrl status", hex(status
))
110 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, 0)
112 # write DMI CTRL register
113 status
= yield from jtag_read_write_reg(dut
, DMI_WRRD
, 64, 0b101)
114 print ("dmi ctrl status", hex(status
))
115 assert status
== 4 # returned old value (nice! cool feature!)
118 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, DBGCore
.CTRL
)
120 # read DMI CTRL register
121 status
= yield from jtag_read_write_reg(dut
, DMI_READ
, 64)
122 print ("dmi ctrl status", hex(status
))
125 # write DMI MSR address
126 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, DBGCore
.MSR
)
128 # read DMI MSR register
129 msr
= yield from jtag_read_write_reg(dut
, DMI_READ
, 64)
130 print ("dmi msr", hex(msr
))
131 assert msr
== 0xdeadbeef
133 ####### JTAG to Wishbone ######
135 # write Wishbone address
136 yield from jtag_read_write_reg(dut
, WB_ADDR
, 16, 0x18)
138 # write/read wishbone data
139 data
= yield from jtag_read_write_reg(dut
, WB_WRRD
, 16, 0xfeef)
140 print ("wb write", hex(data
))
142 # write Wishbone address
143 yield from jtag_read_write_reg(dut
, WB_ADDR
, 16, 0x18)
145 # write/read wishbone data
146 data
= yield from jtag_read_write_reg(dut
, WB_READ
, 16, 0)
147 print ("wb read", hex(data
))
149 ####### done - tell dmi_sim to stop (otherwise it won't) ########
154 if __name__
== '__main__':
155 dut
= DMITAP(ir_width
=4)
157 iotypes
= (IOType
.In
, IOType
.Out
, IOType
.TriOut
, IOType
.InTriOut
)
158 ios
= [dut
.add_io(iotype
=iotype
) for iotype
in iotypes
]
159 dut
.sr
= dut
.add_shiftreg(ircode
=4, length
=3) # test loopback register
161 # create and connect wishbone SRAM (a quick way to do WB test)
162 dut
.wb
= dut
.add_wishbone(ircodes
=[WB_ADDR
, WB_READ
, WB_WRRD
],
164 address_width
=16, data_width
=16)
165 memory
= Memory(width
=16, depth
=16)
166 sram
= SRAM(memory
=memory
, bus
=dut
.wb
)
168 # create DMI2JTAG (goes through to dmi_sim())
169 dut
.dmi
= dut
.add_dmi(ircodes
=[DMI_ADDR
, DMI_READ
, DMI_WRRD
])
172 m
.submodules
.ast
= dut
173 m
.submodules
.sram
= sram
174 m
.d
.comb
+= dut
.sr
.i
.eq(dut
.sr
.o
) # loopback
177 sim
.add_clock(1e-6, domain
="sync") # standard clock
179 sim
.add_sync_process(wrap(jtag_sim(dut
))) # actual jtag tester
180 sim
.add_sync_process(wrap(dmi_sim(dut
))) # handles (pretends to be) DMI
182 with sim
.write_vcd("dmi2jtag_test.vcd"):