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
.dmi2jtag
import DMITAP
11 from nmigen_soc
.wishbone
.sram
import SRAM
12 from nmigen
import Memory
, Signal
, Module
14 from nmigen
.back
.pysim
import Simulator
, Delay
, Settle
, Tick
15 from nmutil
.util
import wrap
18 def tms_state_set(dut
, bits
):
20 yield dut
.bus
.tck
.eq(1)
21 yield dut
.bus
.tms
.eq(bit
)
23 yield dut
.bus
.tck
.eq(0)
25 yield dut
.bus
.tms
.eq(0)
28 def tms_data_getset(dut
, tms
, d_len
, d_in
=0):
30 yield dut
.bus
.tms
.eq(tms
)
31 for i
in range(d_len
):
32 tdi
= 1 if (d_in
& (1<<i
)) else 0
33 yield dut
.bus
.tck
.eq(1)
34 res |
= (1<<i
) if (yield dut
.bus
.tdo
) else 0
36 yield dut
.bus
.tdi
.eq(tdi
)
37 yield dut
.bus
.tck
.eq(0)
39 yield dut
.bus
.tms
.eq(0)
44 def jtag_set_reset(dut
):
45 yield from tms_state_set(dut
, [1, 1, 1, 1, 1])
47 def jtag_set_shift_dr(dut
):
48 yield from tms_state_set(dut
, [1, 0, 0])
50 def jtag_set_shift_ir(dut
):
51 yield from tms_state_set(dut
, [1, 1, 0])
53 def jtag_set_run(dut
):
54 yield from tms_state_set(dut
, [0])
56 def jtag_set_idle(dut
):
57 yield from tms_state_set(dut
, [1, 1, 0])
60 def jtag_read_write_reg(dut
, addr
, d_len
, d_in
=0):
61 yield from jtag_set_run(dut
)
62 yield from jtag_set_shift_ir(dut
)
63 yield from tms_data_getset(dut
, 0, dut
._ir
_width
, addr
)
64 yield from jtag_set_idle(dut
)
66 yield from jtag_set_shift_dr(dut
)
67 result
= yield from tms_data_getset(dut
, 0, d_len
, d_in
)
68 yield from jtag_set_idle(dut
)
77 ctrl_reg
= 0b100 # terminated
87 # check read/write and address
89 addr
= yield dmi
.addr_i
90 print (" dmi wen, addr", wen
, addr
)
91 if addr
== DBGCore
.CTRL
and wen
== 0:
92 print (" read ctrl reg", ctrl_reg
)
93 yield dmi
.dout
.eq(ctrl_reg
)
97 elif addr
== DBGCore
.CTRL
and wen
== 1:
98 ctrl_reg
= (yield dmi
.din
)
99 print (" write ctrl reg", ctrl_reg
)
100 yield dmi
.ack_o
.eq(1)
102 yield dmi
.ack_o
.eq(0)
103 elif addr
== DBGCore
.MSR
and wen
== 0:
104 print (" read msr reg")
105 yield dmi
.dout
.eq(0xdeadbeef) # test MSR value
106 yield dmi
.ack_o
.eq(1)
108 yield dmi
.ack_o
.eq(0)
110 # do nothing but just ack it
111 yield dmi
.ack_o
.eq(1)
113 yield dmi
.ack_o
.eq(0)
115 # JTAG-ircodes for accessing DMI
120 # JTAG-ircodes for accessing Wishbone
128 ####### JTAGy stuff (IDCODE) ######
131 yield from jtag_set_reset(dut
)
132 idcode
= yield from jtag_read_write_reg(dut
, 0b1, 32)
133 print ("idcode", hex(idcode
))
134 assert idcode
== 0x18ff
136 ####### JTAG to DMI ######
139 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, DBGCore
.CTRL
)
141 # read DMI CTRL register
142 status
= yield from jtag_read_write_reg(dut
, DMI_READ
, 64)
143 print ("dmi ctrl status", hex(status
))
147 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, 0)
149 # write DMI CTRL register
150 status
= yield from jtag_read_write_reg(dut
, DMI_WRRD
, 64, 0b101)
151 print ("dmi ctrl status", hex(status
))
152 assert status
== 4 # returned old value (nice! cool feature!)
155 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, DBGCore
.CTRL
)
157 # read DMI CTRL register
158 status
= yield from jtag_read_write_reg(dut
, DMI_READ
, 64)
159 print ("dmi ctrl status", hex(status
))
162 # write DMI MSR address
163 yield from jtag_read_write_reg(dut
, DMI_ADDR
, 8, DBGCore
.MSR
)
165 # read DMI MSR register
166 msr
= yield from jtag_read_write_reg(dut
, DMI_READ
, 64)
167 print ("dmi msr", hex(msr
))
168 assert msr
== 0xdeadbeef
170 ####### JTAG to Wishbone ######
172 # write Wishbone address
173 yield from jtag_read_write_reg(dut
, WB_ADDR
, 16, 0x18)
175 # write/read wishbone data
176 data
= yield from jtag_read_write_reg(dut
, WB_WRRD
, 16, 0xfeef)
177 print ("wb write", hex(data
))
179 # write Wishbone address
180 yield from jtag_read_write_reg(dut
, WB_ADDR
, 16, 0x18)
182 # write/read wishbone data
183 data
= yield from jtag_read_write_reg(dut
, WB_READ
, 16, 0)
184 print ("wb read", hex(data
))
186 ####### done - tell dmi_sim to stop (otherwise it won't) ########
192 if __name__
== '__main__':
193 dut
= DMITAP(ir_width
=4)
194 iotypes
= (IOType
.In
, IOType
.Out
, IOType
.TriOut
, IOType
.InTriOut
)
195 ios
= [dut
.add_io(iotype
=iotype
) for iotype
in iotypes
]
196 dut
.sr
= dut
.add_shiftreg(ircode
=4, length
=3) # test loopback register
198 # create and connect wishbone SRAM (a quick way to do WB test)
199 dut
.wb
= dut
.add_wishbone(ircodes
=[WB_ADDR
, WB_READ
, WB_WRRD
],
200 address_width
=16, data_width
=16)
201 memory
= Memory(width
=16, depth
=16)
202 sram
= SRAM(memory
=memory
, bus
=dut
.wb
)
204 # create DMI2JTAG (goes through to dmi_sim())
205 dut
.dmi
= dut
.add_dmi(ircodes
=[DMI_ADDR
, DMI_READ
, DMI_WRRD
])
208 m
.submodules
.ast
= dut
209 m
.submodules
.sram
= sram
210 m
.d
.comb
+= dut
.sr
.i
.eq(dut
.sr
.o
) # loopback
213 sim
.add_clock(1e-6, domain
="sync") # standard clock
215 sim
.add_sync_process(wrap(jtag_sim(dut
))) # actual jtag tester
216 sim
.add_sync_process(wrap(dmi_sim(dut
))) # handles (pretends to be) DMI
218 with sim
.write_vcd("dmi2jtag_test.vcd"):