fix dependency problems caused by pypi master
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 14 Jun 2022 14:17:46 +0000 (15:17 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Tue, 14 Jun 2022 14:17:46 +0000 (15:17 +0100)
c4m/cocotb/jtag/c4m_jtag.py
c4m/cocotb/jtag/c4m_jtag_svfcocotb.py
c4m/cocotb/jtag/c4m_jtag_svfgrammar.py
c4m/nmigen/jtag/tap.py
setup.py
test/nmigen/cocotb/controller/generate.py
test/nmigen/gen/controller/.gitignore [new file with mode: 0644]
test/nmigen/gen/controller/generate.py
test/nmigen/gen/controller/top.v [deleted file]

index 2cf99819f77dfa51828a17436a710a901f6fe051..ac97ce3e00d8face513e79846ad7198a326fe4d5 100644 (file)
@@ -2,9 +2,11 @@ import cocotb
 from cocotb.triggers import Timer
 from cocotb.binary import BinaryValue
 
+
 class JTAGException(Exception):
     pass
 
+
 class JTAG_Clock(object):
     """
     Class for the JTAG clock, run cycle by cycle
@@ -28,6 +30,7 @@ class JTAG_Clock(object):
             self.signal <= 0
             yield self.t
 
+
 class JTAG_Master(object):
     """
     Class that will run JTAG commands, shift in and out data
index ff5107740a1364f0395a2e97654ec56e9aba2bbf..9028961caeaaf73158ed5ef0db5332551683f1a2 100755 (executable)
@@ -5,6 +5,7 @@ from cocotb.binary import BinaryValue
 
 from  .c4m_jtag_svfgrammar import *
 
+
 def decodescanspec(node):
     length = int(str(node[2]))
     fstr = "{:0"+str(node[2])+"b}"
index 8bc949df9da2c44c2bd747741395c85e45499f4a..e09c793998f2305f982c2db91ae71efbc2426453 100644 (file)
@@ -3,25 +3,31 @@ from modgrammar import *
 grammar_whitespace_mode = 'explicit'
 grammar_whitespace = WS_NOEOL
 
+
 class SVFEol(Grammar):
     grammar = (OPTIONAL(SPACE), EOL)
     grammar_collapse = True
 
+
 class SemicolonEol(Grammar):
     grammar = (OPTIONAL(SPACE), L(";"), SVFEol)
     grammar_collapse = True
 
+
 class Integer(Grammar):
     grammar = WORD("0-9")
     grammar_collapse = True
 
+
 class Float(Grammar):
     grammar = (Integer, (L("."), OPTIONAL(Integer)), OPTIONAL(L("E"), Integer))
 
+
 class Hexadecimal(Grammar):
     grammar = (L("("), WORD("0-9A-Fa-f"), L(")"))
     grammar_collapse = True
 
+
 class StableState(Grammar):
     grammar = (L("IRPAUSE") | L("DRPAUSE") | L("RESET") | L("IDLE"))
     grammar_collapse = True
@@ -41,26 +47,34 @@ class ScanSpec(Grammar):
 class EmptyLine(Grammar):
     grammar = SVFEol
 
+
 class Comment(Grammar):
     grammar = (L("!"), REST_OF_LINE, SVFEol)
 
+
 class EndDR(Grammar):
     grammar = (L("ENDDR"), SPACE, StableState, SemicolonEol)
 
+
 class EndIR(Grammar):
     grammar = (L("ENDIR"), SPACE, StableState, SemicolonEol)
 
+
 class Frequency(Grammar):
     grammar = (L("FREQUENCY"), OPTIONAL(SPACE, Float, OPTIONAL(SPACE), L("HZ")), OPTIONAL(SPACE), SemicolonEol)
 
+
 class HDR(Grammar):
     grammar = (L("HDR"), ScanSpec, SemicolonEol)
 
+
 class HIR(Grammar):
     grammar = (L("HIR"), ScanSpec, SemicolonEol)
 
+
 #TODO: PIO, PIOMAP
 
+
 class Runtest(Grammar):
     grammar = (
         L("RUNTEST"),
@@ -72,22 +86,28 @@ class Runtest(Grammar):
         SemicolonEol
     )
 
+
 class SDR(Grammar):
     grammar = (L("SDR"), ScanSpec, SemicolonEol)
 
+
 class SIR(Grammar):
     grammar = (L("SIR"), ScanSpec, SemicolonEol)
 
+
 class State(Grammar):
     # TODO: Path to reach state
     grammar = (L("STATE"), SPACE, StableState, SemicolonEol)
 
+
 class TDR(Grammar):
     grammar = (L("TDR"), ScanSpec, SemicolonEol)
 
+
 class TIR(Grammar):
     grammar = (L("TIR"), ScanSpec, SemicolonEol)
 
+
 class Trst(Grammar):
     grammar = (L("TRST"), SPACE, (L("ON") | L("OFF") | L("Z") | L("ABSENT")), SemicolonEol)
 
index fe6e26b7285125d71fde0e5f9c5e033c6881011f..f5bfd8cc676e02f0e9e53b882a41c2cac25e6bf7 100755 (executable)
@@ -1,4 +1,9 @@
+#!/usr/bin/env python3
 #!/bin/env python3
+# Copyright (C) 2019,2020,2021 Staf Verhaegen <staf@fibraservi.eu>
+# Copyright (C) 2021,2022 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+# Funded by NLnet and NGI POINTER under EU Grants 871528 and 957073
+
 import os, textwrap
 from enum import Enum, auto
 
@@ -25,6 +30,7 @@ class _FSM(Elaboratable):
         self.shift = Signal()
         self.update = Signal()
 
+        # JTAG uses both edges of the incoming clock (TCK). set them up here
         self.posjtag = ClockDomain("posjtag", local=True)
         self.negjtag = ClockDomain("negjtag", local=True, clk_edge="neg")
 
@@ -118,6 +124,7 @@ class _FSM(Elaboratable):
 
         return m
 
+
 class _IRBlock(Elaboratable):
     """TAP subblock for handling the IR shift register"""
     def __init__(self, *, ir_width, cmd_idcode,
@@ -150,12 +157,14 @@ class _IRBlock(Elaboratable):
 
         return m
 
+
 class IOType(Enum):
     In = auto()
     Out = auto()
     TriOut = auto()
     InTriOut = auto()
 
+
 class IOConn(Record):
     lengths = {
         IOType.In: 1,
@@ -165,7 +174,7 @@ class IOConn(Record):
     }
 
     """TAP subblock representing the interface for an JTAG IO cell.
-    It contains signal to connect to the core and to the pad
+    It contains signals to connect to the core and to the pad
 
     This object is normally only allocated and returned from ``TAP.add_io``
     It is a Record subclass.
@@ -188,9 +197,11 @@ class IOConn(Record):
             Input to pad with pad output value.
         oe: Signal(1), present only for IOType.TriOut and IOType.InTriOut.
             Input to pad with pad output enable value.
+
+    bank select, pullup and pulldown may also be optionally added
     """
     @staticmethod
-    def layout(iotype):
+    def layout(iotype, banksel=0, pullup=False, pulldown=False):
         sigs = []
         if iotype in (IOType.In, IOType.InTriOut):
             sigs.append(("i", 1))
@@ -198,14 +209,26 @@ class IOConn(Record):
             sigs.append(("o", 1))
         if iotype in (IOType.TriOut, IOType.InTriOut):
             sigs.append(("oe", 1))
+        if banksel > 0:
+            sigs.append(("sel", banksel))
+        if pullup:
+            sigs.append(("pu", 1))
+        if pulldown:
+            sigs.append(("pd", 1))
 
         return Layout((("core", sigs), ("pad", sigs)))
 
-    def __init__(self, *, iotype, name=None, src_loc_at=0):
-        super().__init__(self.__class__.layout(iotype), name=name,
-                         src_loc_at=src_loc_at+1)
+    def __init__(self, *, iotype, name=None, banksel=0,
+                                  pullup=False, pulldown=False,
+                                  src_loc_at=0):
+        layout = self.__class__.layout(iotype, banksel, pullup, pulldown)
+        super().__init__(layout, name=name, src_loc_at=src_loc_at+1)
 
         self._iotype = iotype
+        self._banksel = banksel
+        self._pullup = pullup
+        self._pulldown = pulldown
+
 
 class _IDBypassBlock(Elaboratable):
     """TAP subblock for the ID shift register"""
@@ -305,6 +328,7 @@ 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,
@@ -355,13 +379,13 @@ class TAP(Elaboratable):
         cmd_preload = 2
         cmd_bypass = 2**ir_width - 1 # All ones
 
-        m.submodules._fsm = fsm = _FSM(bus=self.bus)
+        m.submodules.fsm = fsm = _FSM(bus=self.bus)
         m.domains.posjtag = fsm.posjtag
         m.domains.negjtag = fsm.negjtag
 
         # IR block
         select_ir = fsm.isir
-        m.submodules._irblock = irblock = _IRBlock(
+        m.submodules.irblock = irblock = _IRBlock(
             ir_width=ir_width, cmd_idcode=cmd_idcode, tdi=self.bus.tdi,
             capture=(fsm.isir & fsm.capture),
             shift=(fsm.isir & fsm.shift),
@@ -376,7 +400,7 @@ class TAP(Elaboratable):
         m.d.comb += select_id.eq(fsm.isdr &
                                  ((ir == cmd_idcode) | (ir == cmd_bypass)))
         m.d.comb += id_bypass.eq(ir == cmd_bypass)
-        m.submodules._idblock = idblock = _IDBypassBlock(
+        m.submodules.idblock = idblock = _IDBypassBlock(
             manufacturer_id=self._manufacturer_id,
             part_number=self._part_number,
             version=self._version, tdi=self.bus.tdi,
@@ -416,9 +440,8 @@ class TAP(Elaboratable):
             m.d.comb += tdo.eq(irblock.tdo)
         with m.Elif(select_id):
             m.d.comb += tdo.eq(idblock.tdo)
-        if io_tdo is not None:
-            with m.Elif(select_io):
-                m.d.comb += tdo.eq(io_tdo)
+        with m.Elif(select_io):
+            m.d.comb += tdo.eq(io_tdo)
 
         # shiftregs block
         self._elaborate_shiftregs(
@@ -524,7 +547,9 @@ class TAP(Elaboratable):
                     dmi.we_i.eq(ds.ongoing("WRRD")),
                 ]
 
-    def add_io(self, *, iotype, name=None, src_loc_at=0):
+    def add_io(self, *, iotype, name=None, banksel=0,
+                                pullup=False, pulldown=False,
+                                src_loc_at=0):
         """Add a io cell to the boundary scan chain
 
         Parameters:
@@ -536,14 +561,32 @@ class TAP(Elaboratable):
         if name is None:
             name = "ioconn" + str(len(self._ios))
 
-        ioconn = IOConn(iotype=iotype, name=name, src_loc_at=src_loc_at+1)
+        ioconn = IOConn(iotype=iotype, banksel=banksel,
+                        pullup=pullup, pulldown=pulldown,
+                        name=name, src_loc_at=src_loc_at+1)
         self._ios.append(ioconn)
         return ioconn
 
     def _elaborate_ios(self, *, m, capture, shift, update, bd2io, bd2core):
-        length = sum(IOConn.lengths[conn._iotype] for conn in self._ios)
+        # note: the starting points where each IOConn is placed into
+        # the Shift Register depends *specifically* on the type (parameters)
+        # of each IOConn, and therefore on all IOConn(s) that came before it
+        # [prior calls to add_io].  this function consistently follows
+        # the exact same pattern in the exact same sequence every time,
+        # to compute consistent offsets. developers must do the same:
+        # note that each length depends on *all* parameters:
+        # IOtype, banksel, pullup *and* pulldown.
+
+        # pre-compute the length of the IO shift registers needed.
+        length = 0
+        for conn in self._ios:
+            length += IOConn.lengths[conn._iotype] + conn._banksel
+            if conn._pullup:
+                length += 1
+            if conn._pulldown:
+                length += 1
         if length == 0:
-            return None
+            return self.bus.tdi
 
         io_sr = Signal(length)
         io_bd = Signal(length)
@@ -561,9 +604,19 @@ class TAP(Elaboratable):
                     iol.append(conn.core.o)
                 if conn._iotype in [IOType.TriOut, IOType.InTriOut]:
                     iol.append(conn.core.oe)
-                # length double-check
+                # now also banksel, pullup and pulldown from core are added
+                if conn._banksel != 0:
+                    iol.append(conn.core.sel)
+                    idx += conn._banksel
+                if conn._pullup:
+                    iol.append(conn.core.pu)
+                    idx += 1
+                if conn._pulldown:
+                    iol.append(conn.core.pd)
+                    idx += 1
+                # help with length double-check
                 idx += IOConn.lengths[conn._iotype] # fails if wrong type
-            assert idx == length, "Internal error"
+            assert idx == length, "Internal error, length mismatch"
             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)
@@ -576,8 +629,13 @@ class TAP(Elaboratable):
 
         # sets up IO (pad<->core) or in testing mode depending on requested
         # mode, via Muxes controlled by bd2core and bd2io
+        # for each IOConn, the number of bits needed from io_bd will vary
+        # and is computed on-the-fly, here. it is up to the developer to
+        # keep track of where each IO pad configuration starts and ends
+        # in the Shift Register (TODO: provide a dictionary of starting points)
         idx = 0
         for conn in self._ios:
+            # mux the I/O/OE depending on IOType
             if conn._iotype == IOType.In:
                 m.d.comb += conn.core.i.eq(Mux(bd2core, io_bd[idx], conn.pad.i))
                 idx += 1
@@ -599,8 +657,22 @@ class TAP(Elaboratable):
                 idx += 3
             else:
                 raise("Internal error")
+            # optional mux of banksel, pullup and pulldown.  note that idx
+            # advances each time, so that io_bd[idx] comes from the right point
+            comb = m.d.comb
+            if conn._banksel != 0:
+                s, e = (idx, idx+conn._banksel) # banksel can be multi-bit
+                comb += conn.pad.sel.eq(Mux(bd2io, io_bd[s:e], conn.core.sel))
+                idx = e
+            if conn._pullup:
+                comb += conn.pad.pu.eq(Mux(bd2io, io_bd[idx], conn.core.pu))
+                idx += 1
+            if conn._pulldown:
+                comb += conn.pad.pd.eq(Mux(bd2io, io_bd[idx], conn.core.pd))
+                idx += 1
         assert idx == length, "Internal error"
 
+        # return the last bit of the shift register, for output on tdo
         return io_sr[-1]
 
     def add_shiftreg(self, *, ircode, length, domain="sync", name=None,
@@ -657,6 +729,9 @@ class TAP(Elaboratable):
             # clockdomain latch update in `domain` clockdomain and see when
             # it has falling edge.
             # At that edge put isir in sr.oe for one `domain` clockdomain
+            # Using this custom sync <> JTAG domain synchronization avoids
+            # the use of more generic but also higher latency CDC solutions
+            # like FFSynchronizer.
             update_core = Signal(name=sr.name+"_update_core")
             update_core_prev = Signal(name=sr.name+"_update_core_prev")
             m.d[domain] += [
@@ -678,7 +753,6 @@ class TAP(Elaboratable):
             # tdo = reg[0], tdo_en = shift
             tdos.append((reg[0], sr_shift))
 
-
         # Assign the right tdo to the bus tdo
         for i, (tdo, tdo_en) in enumerate(tdos):
             if i == 0:
@@ -695,7 +769,6 @@ class TAP(Elaboratable):
             # Always connect tdo_jtag to
             m.d.comb += self.bus.tdo.eq(tdo_jtag)
 
-
     def add_wishbone(self, *, ircodes, address_width, data_width,
                      granularity=None, domain="sync", features=None,
                      name=None, src_loc_at=0):
@@ -772,7 +845,10 @@ class TAP(Elaboratable):
                 with m.State("READACK"):
                     with m.If(wb.ack):
                         # Store read data in sr_data.i
-                        # and keep it there til next read
+                        # and keep it there til next read.
+                        # This is enough to synchronize between sync and JTAG
+                        # clock domain and no higher latency solutions like
+                        # FFSynchronizer is needed.
                         m.d[domain] += sr_data.i.eq(wb.dat_r)
                         m.next = "IDLE"
                 with m.State("WRITEREAD"):
@@ -786,8 +862,17 @@ class TAP(Elaboratable):
                         m.d[domain] += wb.adr.eq(wb.adr + 1)
                         m.next = "READ"
 
-                m.d.comb += [
-                    wb.cyc.eq(~fsm.ongoing("IDLE")),
-                    wb.stb.eq(fsm.ongoing("READ") | fsm.ongoing("WRITEREAD")),
-                    wb.we.eq(fsm.ongoing("WRITEREAD")),
-                ]
+                if hasattr(wb, "stall"):
+                    m.d.comb += wb.stb.eq(fsm.ongoing("READ") |
+                                          fsm.ongoing("WRITEREAD"))
+                    m.d.comb += wb.we.eq(fsm.ongoing("WRITEREAD"))
+                else:
+                    # non-stall is single-cycle (litex), must assert stb
+                    # until ack is sent
+                    m.d.comb += wb.stb.eq(fsm.ongoing("READ") |
+                                          fsm.ongoing("WRITEREAD") |
+                                          fsm.ongoing("READACK") |
+                                          fsm.ongoing("WRITEREADACK"))
+                    m.d.comb += wb.we.eq(fsm.ongoing("WRITEREAD") |
+                                         fsm.ongoing("WRITEREADACK"))
+                m.d.comb += wb.cyc.eq(~fsm.ongoing("IDLE"))
index 78796093ccbb27dc22fc37d657141efd174fa05e..5ad599503e623457c7ab6a0f5727b938ae57b379 100644 (file)
--- a/setup.py
+++ b/setup.py
@@ -25,7 +25,10 @@ setup(
     setup_requires=["setuptools_scm"],
 
     # removing cocotb, causing unnecessary dependency and install problems
-    install_requires=["setuptools", "nmigen", "modgrammar"],
+    install_requires=["setuptools",
+        "nmigen>=0.0,<=0.5",
+        "nmigen-soc",
+        "modgrammar"],
 
     # unit tests require cocotb: main operation does not
     tests_require=['cocotb'],
index 16d980321c76f994f3ee4ebc80c69e923abd54a3..2b34aa1d62c629b840de230d05956faed5b91ace 100755 (executable)
@@ -1,4 +1,4 @@
-#!/bin/env python3
+#!/usr/bin/env python3
 import os
 
 from nmigen import *
diff --git a/test/nmigen/gen/controller/.gitignore b/test/nmigen/gen/controller/.gitignore
new file mode 100644 (file)
index 0000000..79327da
--- /dev/null
@@ -0,0 +1,2 @@
+/top.v
+
index de8d6a944482a102bb9a57c5408c3724647fc871..e66a22770b3c120700e2345669ef3881545128cc 100755 (executable)
@@ -1,10 +1,11 @@
-#!/bin/env python3
+#!/usr/bin/env python3
 from nmigen import *
 from nmigen.back.verilog import convert
 from nmigen.build import Platform
 
 from c4m.nmigen.jtag import TAP
 
+
 class DummyPlatform(Platform):
     resources = []
     connectors = []
@@ -13,7 +14,8 @@ class DummyPlatform(Platform):
     def toolchain_prepare(self, fragment, name, **kwargs):
         raise NotImplementedError
 
-tap = TAP(2)
+
+tap = TAP(ir_width=2)
 f = open("top.v", "w")
 f.write(convert(tap, platform=DummyPlatform()))
 f.close()
diff --git a/test/nmigen/gen/controller/top.v b/test/nmigen/gen/controller/top.v
deleted file mode 100644 (file)
index 91f7871..0000000
+++ /dev/null
@@ -1,382 +0,0 @@
-/* Generated by Yosys 0.9+932 (git sha1 ff8529a, gcc 4.8.5 -fPIC -Os) */
-
-(* generator = "nMigen" *)
-(* \nmigen.hierarchy  = "top._fsm" *)
-module _fsm(tap_fsm_isdr, jtag_clk, tap_bus__tck, tap_bus__tms, tap_fsm_capture, tap_fsm_shift, tap_fsm_update, jtag_rst, tap_fsm_isir);
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:359" *)
-  output jtag_clk;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:359" *)
-  output jtag_rst;
-  (* src = "./generate.py:16" *)
-  input tap_bus__tck;
-  (* src = "./generate.py:16" *)
-  input tap_bus__tms;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:25" *)
-  output tap_fsm_capture;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:24" *)
-  output tap_fsm_isdr;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:23" *)
-  output tap_fsm_isir;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:26" *)
-  output tap_fsm_shift;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:27" *)
-  output tap_fsm_update;
-  c4m_jtag_tap_fsm inst (
-    .capture(tap_fsm_capture),
-    .isdr(tap_fsm_isdr),
-    .isir(tap_fsm_isir),
-    .reset(jtag_rst),
-    .shift(tap_fsm_shift),
-    .tck(tap_bus__tck),
-    .tms(tap_bus__tms),
-    .trst_n(1'h1),
-    .update(tap_fsm_update)
-  );
-  assign jtag_clk = tap_bus__tck;
-endmodule
-
-(* generator = "nMigen" *)
-(* \nmigen.hierarchy  = "top._idblock" *)
-module _idblock(ir, tap_id_tdo, jtag_clk, tap_fsm_capture, tap_fsm_shift, tap_bus__tdi, jtag_rst, tap_fsm_isdr);
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:375" *)
-  wire \$1 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:380" *)
-  wire \$11 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:114" *)
-  wire [31:0] \$13 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:375" *)
-  wire \$3 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:379" *)
-  wire \$5 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:375" *)
-  wire \$7 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:375" *)
-  wire \$9 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:60" *)
-  input [1:0] ir;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:359" *)
-  input jtag_clk;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:359" *)
-  input jtag_rst;
-  (* src = "./generate.py:16" *)
-  input tap_bus__tdi;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:25" *)
-  input tap_fsm_capture;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:24" *)
-  input tap_fsm_isdr;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:26" *)
-  input tap_fsm_shift;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:107" *)
-  reg [31:0] tap_id_sr = 32'd0;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:107" *)
-  reg [31:0] \tap_id_sr$next ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:97" *)
-  output tap_id_tdo;
-  assign \$9  = tap_fsm_isdr & (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:375" *) \$7 ;
-  assign \$11  = \$9  & (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:380" *) tap_fsm_shift;
-  assign \$13  = + (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:114" *) { tap_bus__tdi, tap_id_sr[31:2] };
-  assign \$1  = ir == (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:375" *) 1'h1;
-  assign \$3  = tap_fsm_isdr & (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:375" *) \$1 ;
-  assign \$5  = \$3  & (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:379" *) tap_fsm_capture;
-  assign \$7  = ir == (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:375" *) 1'h1;
-  always @(posedge jtag_clk)
-      tap_id_sr <= \tap_id_sr$next ;
-  always @* begin
-    \tap_id_sr$next  = tap_id_sr;
-    (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:111" *)
-    casez ({ \$11 , \$5  })
-      /* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:111" */
-      2'b?1:
-          \tap_id_sr$next  = 32'd6399;
-      /* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:113" */
-      2'b1?:
-          \tap_id_sr$next  = \$13 ;
-    endcase
-  end
-  assign tap_id_tdo = tap_id_sr[0];
-endmodule
-
-(* generator = "nMigen" *)
-(* \nmigen.hierarchy  = "top._ioblock" *)
-module _ioblock(tap_io_tdo, tap_fsm_capture, tap_fsm_shift, tap_fsm_update, tap_bus__tdi, clk, tap_coreio0__o, tap_coreio1__o, tap_coreio0__oe, tap_coreio1__oe, tap_padio0__i, tap_padio1__i, ir);
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ir.py:538" *)
-  input clk;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:60" *)
-  input [1:0] ir;
-  (* src = "./generate.py:16" *)
-  input tap_bus__tdi;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  wire tap_coreio0__i;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  input tap_coreio0__o;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  input tap_coreio0__oe;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  wire tap_coreio1__i;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  input tap_coreio1__o;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  input tap_coreio1__oe;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:25" *)
-  input tap_fsm_capture;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:26" *)
-  input tap_fsm_shift;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:27" *)
-  input tap_fsm_update;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:194" *)
-  output tap_io_tdo;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  input tap_padio0__i;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  wire tap_padio0__o;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  wire tap_padio0__oe;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  input tap_padio1__i;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  wire tap_padio1__o;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  wire tap_padio1__oe;
-  jtag_ioblock_2_2 inst (
-    .capture(tap_fsm_capture),
-    .core_en({ tap_coreio1__oe, tap_coreio0__oe }),
-    .core_in({ tap_coreio1__i, tap_coreio0__i }),
-    .core_out({ tap_coreio1__o, tap_coreio0__o }),
-    .ir(ir),
-    .pad_en({ tap_padio1__oe, tap_padio0__oe }),
-    .pad_in({ tap_padio1__i, tap_padio0__i }),
-    .pad_out({ tap_padio1__o, tap_padio0__o }),
-    .shift(tap_fsm_shift),
-    .tck(clk),
-    .tdi(tap_bus__tdi),
-    .tdo(tap_io_tdo),
-    .update(tap_fsm_update)
-  );
-endmodule
-
-(* generator = "nMigen" *)
-(* \nmigen.hierarchy  = "top._irblock" *)
-module _irblock(ir, tdo, jtag_clk, tap_fsm_capture, tap_fsm_shift, tap_fsm_update, tap_bus__tdi, jtag_rst, tap_fsm_isir);
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:368" *)
-  wire \$1 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:369" *)
-  wire \$11 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:370" *)
-  wire \$13 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:369" *)
-  wire \$3 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:370" *)
-  wire \$5 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:77" *)
-  wire [1:0] \$7 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:368" *)
-  wire \$9 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:60" *)
-  output [1:0] ir;
-  reg [1:0] ir = 2'h1;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:60" *)
-  reg [1:0] \ir$next ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:359" *)
-  input jtag_clk;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:359" *)
-  input jtag_rst;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:71" *)
-  reg [1:0] shift_ir = 2'h0;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:71" *)
-  reg [1:0] \shift_ir$next ;
-  (* src = "./generate.py:16" *)
-  input tap_bus__tdi;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:25" *)
-  input tap_fsm_capture;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:23" *)
-  input tap_fsm_isir;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:26" *)
-  input tap_fsm_shift;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:27" *)
-  input tap_fsm_update;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:61" *)
-  output tdo;
-  assign \$9  = tap_fsm_isir & (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:368" *) tap_fsm_capture;
-  assign \$11  = tap_fsm_isir & (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:369" *) tap_fsm_shift;
-  assign \$13  = tap_fsm_isir & (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:370" *) tap_fsm_update;
-  assign \$1  = tap_fsm_isir & (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:368" *) tap_fsm_capture;
-  assign \$3  = tap_fsm_isir & (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:369" *) tap_fsm_shift;
-  assign \$5  = tap_fsm_isir & (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:370" *) tap_fsm_update;
-  assign \$7  = + (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:77" *) tap_bus__tdi;
-  always @(posedge jtag_clk)
-      ir <= \ir$next ;
-  always @(posedge jtag_clk)
-      shift_ir <= \shift_ir$next ;
-  always @* begin
-    \shift_ir$next  = shift_ir;
-    (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:74" *)
-    casez ({ \$5 , \$3 , \$1  })
-      /* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:74" */
-      3'b??1:
-          \shift_ir$next  = ir;
-      /* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:76" */
-      3'b?1?:
-          \shift_ir$next  = \$7 ;
-    endcase
-  end
-  always @* begin
-    \ir$next  = ir;
-    (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:74" *)
-    casez ({ \$13 , \$11 , \$9  })
-      /* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:74" */
-      3'b??1:
-          /* empty */;
-      /* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:76" */
-      3'b?1?:
-          /* empty */;
-      /* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:78" */
-      3'b1??:
-          \ir$next  = shift_ir;
-    endcase
-    (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/xfrm.py:528" *)
-    casez (jtag_rst)
-      1'h1:
-          \ir$next  = 2'h1;
-    endcase
-  end
-  assign tdo = ir[0];
-endmodule
-
-(* generator = "nMigen" *)
-(* top =  1  *)
-(* \nmigen.hierarchy  = "top" *)
-module top(tap_bus__tms, tap_bus__tdi, clk, tap_coreio0__o, tap_coreio1__o, tap_coreio0__oe, tap_coreio1__oe, tap_padio0__i, tap_padio1__i, tap_bus__tck);
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:375" *)
-  wire \$1 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:388" *)
-  wire \$11 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:388" *)
-  wire \$13 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:388" *)
-  wire \$15 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:375" *)
-  wire \$3 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:388" *)
-  wire \$5 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:388" *)
-  wire \$7 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:388" *)
-  wire \$9 ;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:359" *)
-  wire _fsm_jtag_clk;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:359" *)
-  wire _fsm_jtag_rst;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:25" *)
-  wire _fsm_tap_fsm_capture;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:24" *)
-  wire _fsm_tap_fsm_isdr;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:23" *)
-  wire _fsm_tap_fsm_isir;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:26" *)
-  wire _fsm_tap_fsm_shift;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:27" *)
-  wire _fsm_tap_fsm_update;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:97" *)
-  wire _idblock_tap_id_tdo;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:194" *)
-  wire _ioblock_tap_io_tdo;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:60" *)
-  wire [1:0] _irblock_ir;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:61" *)
-  wire _irblock_tdo;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ir.py:538" *)
-  input clk;
-  (* src = "./generate.py:16" *)
-  input tap_bus__tck;
-  (* src = "./generate.py:16" *)
-  input tap_bus__tdi;
-  (* src = "./generate.py:16" *)
-  wire tap_bus__tdo;
-  (* src = "./generate.py:16" *)
-  input tap_bus__tms;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  input tap_coreio0__o;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  input tap_coreio0__oe;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  input tap_coreio1__o;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  input tap_coreio1__oe;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  input tap_padio0__i;
-  (* src = "/home/verhaegs/anaconda2/envs/nmigen/lib/python3.7/site-packages/nmigen/hdl/ast.py:1075" *)
-  input tap_padio1__i;
-  (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:397" *)
-  reg tap_tdo;
-  assign \$9  = \$5  | (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:388" *) \$7 ;
-  assign \$11  = _irblock_ir == (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:388" *) 2'h2;
-  assign \$13  = \$9  | (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:388" *) \$11 ;
-  assign \$15  = _fsm_tap_fsm_isdr & (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:388" *) \$13 ;
-  assign \$1  = _irblock_ir == (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:375" *) 1'h1;
-  assign \$3  = _fsm_tap_fsm_isdr & (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:375" *) \$1 ;
-  assign \$5  = _irblock_ir == (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:388" *) 1'h0;
-  assign \$7  = _irblock_ir == (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:388" *) 2'h2;
-  _fsm _fsm (
-    .jtag_clk(_fsm_jtag_clk),
-    .jtag_rst(_fsm_jtag_rst),
-    .tap_bus__tck(tap_bus__tck),
-    .tap_bus__tms(tap_bus__tms),
-    .tap_fsm_capture(_fsm_tap_fsm_capture),
-    .tap_fsm_isdr(_fsm_tap_fsm_isdr),
-    .tap_fsm_isir(_fsm_tap_fsm_isir),
-    .tap_fsm_shift(_fsm_tap_fsm_shift),
-    .tap_fsm_update(_fsm_tap_fsm_update)
-  );
-  _idblock _idblock (
-    .ir(_irblock_ir),
-    .jtag_clk(_fsm_jtag_clk),
-    .jtag_rst(_fsm_jtag_rst),
-    .tap_bus__tdi(tap_bus__tdi),
-    .tap_fsm_capture(_fsm_tap_fsm_capture),
-    .tap_fsm_isdr(_fsm_tap_fsm_isdr),
-    .tap_fsm_shift(_fsm_tap_fsm_shift),
-    .tap_id_tdo(_idblock_tap_id_tdo)
-  );
-  _ioblock _ioblock (
-    .clk(clk),
-    .ir(_irblock_ir),
-    .tap_bus__tdi(tap_bus__tdi),
-    .tap_coreio0__o(tap_coreio0__o),
-    .tap_coreio0__oe(tap_coreio0__oe),
-    .tap_coreio1__o(tap_coreio1__o),
-    .tap_coreio1__oe(tap_coreio1__oe),
-    .tap_fsm_capture(_fsm_tap_fsm_capture),
-    .tap_fsm_shift(_fsm_tap_fsm_shift),
-    .tap_fsm_update(_fsm_tap_fsm_update),
-    .tap_io_tdo(_ioblock_tap_io_tdo),
-    .tap_padio0__i(tap_padio0__i),
-    .tap_padio1__i(tap_padio1__i)
-  );
-  _irblock _irblock (
-    .ir(_irblock_ir),
-    .jtag_clk(_fsm_jtag_clk),
-    .jtag_rst(_fsm_jtag_rst),
-    .tap_bus__tdi(tap_bus__tdi),
-    .tap_fsm_capture(_fsm_tap_fsm_capture),
-    .tap_fsm_isir(_fsm_tap_fsm_isir),
-    .tap_fsm_shift(_fsm_tap_fsm_shift),
-    .tap_fsm_update(_fsm_tap_fsm_update),
-    .tdo(_irblock_tdo)
-  );
-  always @* begin
-    tap_tdo = 1'h0;
-    (* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:398" *)
-    casez ({ \$15 , \$3 , _fsm_tap_fsm_isir })
-      /* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:398" */
-      3'b??1:
-          tap_tdo = _irblock_tdo;
-      /* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:400" */
-      3'b?1?:
-          tap_tdo = _idblock_tap_id_tdo;
-      /* src = "/home/verhaegs/eda/code/c4m_jtag/c4m/nmigen/jtag/tap.py:402" */
-      3'b1??:
-          tap_tdo = _ioblock_tap_io_tdo;
-    endcase
-  end
-  assign tap_bus__tdo = tap_tdo;
-endmodule