From: Luke Kenneth Casson Leighton Date: Fri, 9 Oct 2020 13:12:02 +0000 (+0100) Subject: code-cleanup / comments on JTAG IO X-Git-Tag: 24jan2021ls180~5 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=02abc66cf86613e481eeb21d9c1926ef1713e5dd;p=c4m-jtag.git code-cleanup / comments on JTAG IO --- diff --git a/c4m/nmigen/jtag/tap.py b/c4m/nmigen/jtag/tap.py index acd1f45..73541df 100755 --- a/c4m/nmigen/jtag/tap.py +++ b/c4m/nmigen/jtag/tap.py @@ -157,6 +157,13 @@ class IOType(Enum): InTriOut = auto() class IOConn(Record): + lengths = { + IOType.In: 1, + IOType.Out: 1, + IOType.TriOut: 2, + IOType.InTriOut: 3, + } + """TAP subblock representing the interface for an JTAG IO cell. It contains signal to connect to the core and to the pad @@ -298,7 +305,6 @@ class ShiftReg(Record): ] super().__init__(layout, name=name, src_loc_at=src_loc_at+1) - class TAP(Elaboratable): #TODO: Document TAP def __init__(self, *, with_reset=False, ir_width=None, @@ -530,47 +536,39 @@ class TAP(Elaboratable): return ioconn def _elaborate_ios(self, *, m, capture, shift, update, bd2io, bd2core): - connlength = { - IOType.In: 1, - IOType.Out: 1, - IOType.TriOut: 2, - IOType.InTriOut: 3, - } - length = sum(connlength[conn._iotype] for conn in self._ios) + length = sum(IOConn.lengths[conn._iotype] for conn in self._ios) io_sr = Signal(length) io_bd = Signal(length) + # Boundary scan "capture" mode. makes I/O status available via SR with m.If(capture): + iol = [] idx = 0 for conn in self._ios: - if conn._iotype == IOType.In: - m.d.posjtag += io_sr[idx].eq(conn.pad.i) - idx += 1 - elif conn._iotype == IOType.Out: - m.d.posjtag += io_sr[idx].eq(conn.core.o) - idx += 1 - elif conn._iotype == IOType.TriOut: - m.d.posjtag += [ - io_sr[idx].eq(conn.core.o), - io_sr[idx+1].eq(conn.core.oe), - ] - idx += 2 - elif conn._iotype == IOType.InTriOut: - m.d.posjtag += [ - io_sr[idx].eq(conn.pad.i), - io_sr[idx+1].eq(conn.core.o), - io_sr[idx+2].eq(conn.core.oe), - ] - idx += 3 - else: - raise("Internal error") + # in appropriate sequence: In/TriOut has pad.i, + # Out.InTriOut has everything, Out and TriOut have core.o + if conn._iotype in [IOType.In, IOType.InTriOut]: + iol.append(conn.pad.i) + if conn._iotype in [IOType.Out, IOType.InTriOut]: + iol.append(conn.core.o) + if conn._iotype in [IOType.TriOut, IOType.InTriOut]: + iol.append(conn.core.oe) + # length double-check + idx += IOConn.lengths[conn._iotype] # fails if wrong type assert idx == length, "Internal error" + m.d.posjtag += io_sr.eq(Cat(*iol)) # assigns all io_sr in one hit + + # "Shift" mode (sends out captured data on tdo, sets incoming from tdi) with m.Elif(shift): m.d.posjtag += io_sr.eq(Cat(self.bus.tdi, io_sr[:-1])) + + # "Update" mode with m.Elif(update): m.d.negjtag += io_bd.eq(io_sr) + # sets up IO (pad<->core) or in testing mode depending on requested + # mode, via Muxes controlled by bd2core and bd2io idx = 0 for conn in self._ios: if conn._iotype == IOType.In: