From ffd02617c02cde6b9862def7c0f55088c116ad73 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Thu, 8 Oct 2020 14:48:42 +0100 Subject: [PATCH] JTAG boundary scan test 1st attempt --- src/soc/debug/jtag.py | 6 +- src/soc/debug/jtagutils.py | 11 ++- src/soc/debug/test/test_jtag_tap_srv.py | 96 +++++++++++++++++++++++-- 3 files changed, 106 insertions(+), 7 deletions(-) diff --git a/src/soc/debug/jtag.py b/src/soc/debug/jtag.py index 2a9507a1..03f69768 100644 --- a/src/soc/debug/jtag.py +++ b/src/soc/debug/jtag.py @@ -13,11 +13,13 @@ from soc.debug.dmi2jtag import DMITAP # 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, } @@ -67,15 +69,17 @@ class JTAG(DMITAP, Pins): # 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") diff --git a/src/soc/debug/jtagutils.py b/src/soc/debug/jtagutils.py index f0b1830d..7f77558f 100644 --- a/src/soc/debug/jtagutils.py +++ b/src/soc/debug/jtagutils.py @@ -71,17 +71,24 @@ def jtag_set_idle(dut): 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: diff --git a/src/soc/debug/test/test_jtag_tap_srv.py b/src/soc/debug/test/test_jtag_tap_srv.py index 597eb0a6..2fdeeefe 100644 --- a/src/soc/debug/test/test_jtag_tap_srv.py +++ b/src/soc/debug/test/test_jtag_tap_srv.py @@ -9,7 +9,7 @@ from c4m.nmigen.jtag.tap import TAP, IOType 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 @@ -18,7 +18,15 @@ from nmigen import Memory, Signal, Module 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 @@ -30,6 +38,12 @@ WB_ADDR = 5 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): @@ -41,6 +55,77 @@ 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 @@ -98,7 +183,7 @@ def jtag_sim(dut, srv_dut): 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 @@ -106,7 +191,6 @@ if __name__ == '__main__': class Dummy: pass cdut = Dummy() cdut.cbus = JTAGInterface() - cdut._ir_width = 4 # set up client-server on port 44843-something dut.s = JTAGServer() @@ -116,6 +200,10 @@ if __name__ == '__main__': 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) -- 2.30.2