# map from pinmux to c4m jtag iotypes
iotypes = {'-': IOType.In,
'+': IOType.Out,
+ '>': IOType.TriOut,
'*': IOType.InTriOut,
}
scanlens = {IOType.In: 1,
IOType.Out: 1,
+ IOType.TriOut: 2,
IOType.InTriOut: 3,
}
# enumerate pin specs and create IOConn Records.
# we store the boundary scan register offset in the IOConn record
self.ios = [] # these are enumerated in external_ports
+ self.scan_len = 0
for fn, pin, iotype, pin_name, scan_idx in list(self):
io = self.add_io(iotype=iotype, name=pin_name)
io._scan_idx = scan_idx # hmm shouldn't really do this
+ self.scan_len += scan_idx # record full length of boundary scan
self.ios.append(io)
# this is redundant. or maybe part of testing, i don't know.
self.sr = self.add_shiftreg(ircode=4, length=3)
- # create and connect wishbone
+ # create and connect wishbone
self.wb = self.add_wishbone(ircodes=[5, 6, 7],
address_width=29, data_width=wb_data_wid,
name="jtag_wb")
yield from tms_state_set(dut, [1, 1, 0])
-def jtag_read_write_reg(dut, addr, d_len, d_in=0):
+def jtag_set_ir(dut, addr):
yield from jtag_set_run(dut)
yield from jtag_set_shift_ir(dut)
- yield from tms_data_getset(dut, 0, dut._ir_width, addr)
+ result = yield from tms_data_getset(dut, 0, dut._ir_width, addr)
yield from jtag_set_idle(dut)
+ return result
+
+def jtag_set_get_dr(dut, d_len, d_in=0):
yield from jtag_set_shift_dr(dut)
result = yield from tms_data_getset(dut, 0, d_len, d_in)
yield from jtag_set_idle(dut)
return result
+def jtag_read_write_reg(dut, addr, d_len, d_in=0):
+ yield from jtag_set_ir(dut, addr)
+ return (yield from jtag_set_get_dr(dut, d_len, d_in))
+
def jtag_srv(dut):
while not dut.stop:
from c4m.nmigen.jtag.bus import Interface as JTAGInterface
from soc.debug.dmi import DMIInterface, DBGCore
from soc.debug.test.dmi_sim import dmi_sim
-from soc.debug.jtag import JTAG, dummy_pinset
+from soc.debug.jtag import JTAG
from soc.debug.test.jtagremote import JTAGServer, JTAGClient
from nmigen_soc.wishbone.sram import SRAM
from nmigen.back.pysim import Simulator, Delay, Settle, Tick
from nmutil.util import wrap
from soc.debug.jtagutils import (jtag_read_write_reg,
- jtag_srv, jtag_set_reset)
+ jtag_srv, jtag_set_reset,
+ jtag_set_ir, jtag_set_get_dr)
+
+def test_pinset():
+ return {
+ # in, out, tri-out, tri-inout
+ 'test': ['io0-', 'io1+', 'io2>', 'io3*'],
+ }
+
# JTAG-ircodes for accessing DMI
DMI_ADDR = 8
WB_READ = 6
WB_WRRD = 7
+# JTAG boundary scan reg addresses
+BS_EXTEST = 0
+BS_INTEST = 0
+BS_SAMPLE = 2
+BS_PRELOAD = 2
+
def jtag_sim(dut, srv_dut):
print ("idcode", hex(idcode))
assert idcode == 0x18ff
+ ####### JTAG Boundary scan ######
+
+ bslen = dut.scan_len
+ print ("scan len", bslen)
+
+ # sample test
+ bs_actual = 0b100110
+ yield srv_dut.ios[0].pad.i.eq(1)
+ yield srv_dut.ios[1].core.o.eq(0)
+ yield srv_dut.ios[2].core.o.eq(1)
+ yield srv_dut.ios[2].core.oe.eq(1)
+ yield srv_dut.ios[3].pad.i.eq(0)
+ yield srv_dut.ios[3].core.o.eq(0)
+ yield srv_dut.ios[3].core.oe.eq(1)
+
+ bs = yield from jtag_read_write_reg(dut, BS_SAMPLE, bslen, bs_actual)
+ print ("bs scan", bin(bs))
+
+ print ("io0 pad.i", (yield srv_dut.ios[0].pad.i))
+ print ("io1 core.o", (yield srv_dut.ios[1].core.o))
+ print ("io2 core.o", (yield srv_dut.ios[2].core.o))
+ print ("io2 core.oe", (yield srv_dut.ios[2].core.oe))
+ print ("io3 core.i", (yield srv_dut.ios[3].core.i))
+ print ("io3 pad.o", (yield srv_dut.ios[3].pad.o))
+ print ("io3 pad.oe", (yield srv_dut.ios[3].pad.oe))
+
+ # extest
+ ir_actual = yield from jtag_set_ir(dut, BS_EXTEST)
+ print ("ir extest", bin(ir_actual))
+
+ print ("io0 pad.i", (yield srv_dut.ios[0].pad.i))
+ print ("io1 core.o", (yield srv_dut.ios[1].core.o))
+ print ("io2 core.o", (yield srv_dut.ios[2].core.o))
+ print ("io2 core.oe", (yield srv_dut.ios[2].core.oe))
+ print ("io3 core.i", (yield srv_dut.ios[3].core.i))
+ print ("io3 pad.o", (yield srv_dut.ios[3].pad.o))
+ print ("io3 pad.oe", (yield srv_dut.ios[3].pad.oe))
+
+ # set pins
+ bs_actual = 0b1011001
+ yield srv_dut.ios[0].pad.i.eq(0)
+ yield srv_dut.ios[1].core.o.eq(1)
+ yield srv_dut.ios[2].core.o.eq(0)
+ yield srv_dut.ios[2].core.oe.eq(0)
+ yield srv_dut.ios[3].pad.i.eq(1)
+ yield srv_dut.ios[3].core.o.eq(1)
+ yield srv_dut.ios[3].core.oe.eq(0)
+
+ bs = yield from jtag_set_get_dr(dut, bslen, bs_actual)
+ print ("bs scan", bin(bs))
+
+ print ("io0 pad.i", (yield srv_dut.ios[0].pad.i))
+ print ("io1 core.o", (yield srv_dut.ios[1].core.o))
+ print ("io2 core.o", (yield srv_dut.ios[2].core.o))
+ print ("io2 core.oe", (yield srv_dut.ios[2].core.oe))
+ print ("io3 core.i", (yield srv_dut.ios[3].core.i))
+ print ("io3 pad.o", (yield srv_dut.ios[3].pad.o))
+ print ("io3 pad.oe", (yield srv_dut.ios[3].pad.oe))
+
+ # reset
+ yield from jtag_set_reset(dut)
+ print ("bs reset")
+
+ print ("io0 pad.i", (yield srv_dut.ios[0].pad.i))
+ print ("io1 core.o", (yield srv_dut.ios[1].core.o))
+ print ("io2 core.o", (yield srv_dut.ios[2].core.o))
+ print ("io2 core.oe", (yield srv_dut.ios[2].core.oe))
+ print ("io3 core.i", (yield srv_dut.ios[3].core.i))
+ print ("io3 pad.o", (yield srv_dut.ios[3].pad.o))
+ print ("io3 pad.oe", (yield srv_dut.ios[3].pad.oe))
+
####### JTAG to DMI ######
# write DMI address
if __name__ == '__main__':
- dut = JTAG(dummy_pinset(), wb_data_wid=64)
+ dut = JTAG(test_pinset(), wb_data_wid=64)
dut.stop = False
# rather than the client access the JTAG bus directly
class Dummy: pass
cdut = Dummy()
cdut.cbus = JTAGInterface()
- cdut._ir_width = 4
# set up client-server on port 44843-something
dut.s = JTAGServer()
else:
dut.s.get_connection(None) # block waiting for connection
+ # take copy of ir_width and scan_len
+ cdut._ir_width = dut._ir_width
+ cdut.scan_len = dut.scan_len
+
memory = Memory(width=64, depth=16)
sram = SRAM(memory=memory, bus=dut.wb)