xilinx_bscan_spi: port to new migen and clean-up
authorRobert Jordens <jordens@gmail.com>
Mon, 21 Dec 2015 20:36:14 +0000 (13:36 -0700)
committerPaul Fertser <fercerpav@gmail.com>
Tue, 4 Oct 2016 11:06:33 +0000 (12:06 +0100)
* port to new migen
* streamline package/part specification
* add pullup (Series3, Series6) and pullnone (Series7) for unused pins
  as xilinx impact/vivado do it.
* specify respective toolchains
* build Series7 with vivado (broader support, faster)
* point to prebuilt bitstreams at https://github.com/jordens/bscan_spi_bitstreams

Change-Id: Ibfef3d78f855b754425f3e6131e2e49fa111e09a
Signed-off-by: Robert Jordens <jordens@gmail.com>
Reviewed-on: http://openocd.zylin.com/3173
Reviewed-by: Andreas Fritiofson <andreas.fritiofson@gmail.com>
Tested-by: jenkins
Reviewed-by: Robert Jördens
Reviewed-by: William D. Jones
Reviewed-by: Tim "mithro" Ansell <mithro@mithis.com>
contrib/loaders/flash/fpga/xilinx_bscan_spi.py

index a107a6ac78716e78d78d15d9096c4555b1f93671..fa4ec2ace6e22d3a69bf859464adfaab15a30811 100755 (executable)
 #  GNU General Public License for more details.
 #
 
-from migen.fhdl.std import *
-from mibuild.generic_platform import *
-from mibuild.xilinx import XilinxPlatform
-from mibuild.xilinx.vivado import XilinxVivadoToolchain
-from mibuild.xilinx.ise import XilinxISEToolchain
+from migen import *
+from migen.build.generic_platform import *
+from migen.build import xilinx
 
 
 """
 This migen script produces proxy bitstreams to allow programming SPI flashes
-behind FPGAs. JTAG signalling is connected directly to SPI signalling. CS_N is
-asserted when the JTAG IR contains the USER1 instruction and the state is
-SHIFT-DR.
+behind FPGAs.
+
+Bitstream binaries built with this script are available at:
+https://github.com/jordens/bscan_spi_bitstreams
 
-Xilinx bscan cells sample TDO on falling TCK and forward it.
+JTAG signalling is connected directly to SPI signalling. CS_N is
+asserted when the JTAG IR contains the USER1 instruction and the state is
+SHIFT-DR. Xilinx bscan cells sample TDO on falling TCK and forward it.
 MISO requires sampling on rising CLK and leads to one cycle of latency.
 
 https://github.com/m-labs/migen
@@ -35,8 +36,10 @@ https://github.com/m-labs/migen
 
 class Spartan3(Module):
     macro = "BSCAN_SPARTAN3"
+    toolchain = "ise"
 
     def __init__(self, platform):
+        platform.toolchain.bitgen_opt += " -g compress -g UnusedPin:Pullup"
         self.clock_domains.cd_jtag = ClockDomain(reset_less=True)
         spi = platform.request("spiflash")
         shift = Signal()
@@ -58,7 +61,10 @@ class Spartan3A(Spartan3):
 
 
 class Spartan6(Module):
+    toolchain = "ise"
+
     def __init__(self, platform):
+        platform.toolchain.bitgen_opt += " -g compress -g UnusedPin:Pullup"
         self.clock_domains.cd_jtag = ClockDomain(reset_less=True)
         spi = platform.request("spiflash")
         shift = Signal()
@@ -72,7 +78,13 @@ class Spartan6(Module):
 
 
 class Series7(Module):
+    toolchain = "vivado"
+
     def __init__(self, platform):
+        platform.toolchain.bitstream_commands.extend([
+            "set_property BITSTREAM.GENERAL.COMPRESS True [current_design]",
+            "set_property BITSTREAM.CONFIG.UNUSEDPIN Pullnone [current_design]",
+        ])
         self.clock_domains.cd_jtag = ClockDomain(reset_less=True)
         spi = platform.request("spiflash")
         clk = Signal()
@@ -89,184 +101,105 @@ class Series7(Module):
                                   i_USRCCLKTS=0, i_USRDONEO=1, i_USRDONETS=1)
 
 
-class XilinxBscanSpi(XilinxPlatform):
+class XilinxBscanSpi(xilinx.XilinxPlatform):
+    packages = {
+        # (package-speedgrade, id): [cs_n, clk, mosi, miso, *pullups]
+        ("cp132", 1): ["M2", "N12", "N2", "N8"],
+        ("fg320", 1): ["U3", "U16", "T4", "N10"],
+        ("fg320", 2): ["V3", "U16", "T11", "V16"],
+        ("fg484", 1): ["Y4", "AA20", "AB14", "AB20"],
+        ("fgg484", 1): ["Y4", "AA20", "AB14", "AB20"],
+        ("fgg400", 1): ["Y2", "Y19", "W12", "W18"],
+        ("ftg256", 1): ["T2", "R14", "P10", "T14"],
+        ("ft256", 1): ["T2", "R14", "P10", "T14"],
+        ("fg400", 1): ["Y2", "Y19", "W12", "W18"],
+        ("cs484", 1): ["U7", "V17", "V13", "W17"],
+        ("qg144-2", 1): ["P38", "P70", "P64", "P65", "P62", "P61"],
+        ("cpg196-2", 1): ["P2", "N13", "P11", "N11", "N10", "P10"],
+        ("cpg236-1", 1): ["K19", None, "D18", "D19", "G18", "F18"],
+        ("csg484-2", 1): ["AB5", "W17", "AB17", "Y17", "V13", "W13"],
+        ("csg324-2", 1): ["V3", "R15", "T13", "R13", "T14", "V14"],
+        ("csg324-1", 1): ["L13", None, "K17", "K18", "L14", "M14"],
+        ("fbg484-1", 1): ["T19", None, "P22", "R22", "P21", "R21"],
+        ("fbg484-1", 2): ["L16", None, "H18", "H19", "G18", "F19"],
+        ("fbg676-1", 1): ["C23", None, "B24", "A25", "B22", "A22"],
+        ("ffg901-1", 1): ["V26", None, "R30", "T30", "R28", "T28"],
+        ("ffg1156-1", 1): ["V30", None, "AA33", "AA34", "Y33", "Y34"],
+        ("ffg1157-1", 1): ["AL33", None, "AN33", "AN34", "AK34", "AL34"],
+        ("ffg1158-1", 1): ["C24", None, "A23", "A24", "B26", "A26"],
+        ("ffg1926-1", 1): ["AK33", None, "AN34", "AN35", "AJ34", "AK34"],
+        ("fhg1761-1", 1): ["AL36", None, "AM36", "AN36", "AJ36", "AJ37"],
+        ("flg1155-1", 1): ["AL28", None, "AE28", "AF28", "AJ29", "AJ30"],
+        ("flg1932-1", 1): ["V32", None, "T33", "R33", "U31", "T31"],
+        ("flg1926-1", 1): ["AK33", None, "AN34", "AN35", "AJ34", "AK34"],
+    }
+
     pinouts = {
         # bitstreams are named by die, package does not matter, speed grade
         # should not matter.
-        #                    cs_n, clk, mosi, miso, *pullups
-        "xc3s100e": ("cp132",
-            ["M2", "N12", "N2", "N8"],
-            "LVCMOS33", Spartan3),
-        "xc3s1200e": ("fg320",
-            ["U3", "U16", "T4", "N10"],
-            "LVCMOS33", Spartan3),
-        "xc3s1400a": ("fg484",
-            ["Y4", "AA20", "AB14", "AB20"],
-            "LVCMOS33", Spartan3A),
-        "xc3s1400an": ("fgg484",
-            ["Y4", "AA20", "AB14", "AB20"],
-            "LVCMOS33", Spartan3A),
-        "xc3s1600e": ("fg320",
-            ["U3", "U16", "T4", "N10"],
-            "LVCMOS33", Spartan3),
-        "xc3s200a": ("fg320",
-            ["V3", "U16", "T11", "V16"],
-            "LVCMOS33", Spartan3A),
-        "xc3s200an": ("ftg256",
-            ["T2", "R14", "P10", "T14"],
-            "LVCMOS33", Spartan3A),
-        "xc3s250e": ("cp132",
-            ["M2", "N12", "N2", "N8"],
-            "LVCMOS33", Spartan3),
-        "xc3s400a": ("fg320",
-            ["V3", "U16", "T11", "V16"],
-            "LVCMOS33", Spartan3A),
-        "xc3s400an": ("fgg400",
-            ["Y2", "Y19", "W12", "W18"],
-            "LVCMOS33", Spartan3A),
-        "xc3s500e": ("cp132",
-            ["M2", "N12", "N2", "N8"],
-            "LVCMOS33", Spartan3),
-        "xc3s50a": ("ft256",
-            ["T2", "R14", "P10", "T14"],
-            "LVCMOS33", Spartan3A),
-        "xc3s50an": ("ftg256",
-            ["T2", "R14", "P10", "T14"],
-            "LVCMOS33", Spartan3A),
-        "xc3s700a": ("fg400",
-            ["Y2", "Y19", "W12", "W18"],
-            "LVCMOS33", Spartan3A),
-        "xc3s700an": ("fgg484",
-            ["Y4", "AA20", "AB14", "AB20"],
-            "LVCMOS33", Spartan3A),
-        "xc3sd1800a": ("cs484",
-            ["U7", "V17", "V13", "W17"],
-            "LVCMOS33", Spartan3A),
-        "xc3sd3400a": ("cs484",
-            ["U7", "V17", "V13", "W17"],
-            "LVCMOS33", Spartan3A),
-
-        "xc6slx100": ("csg484-2",
-            ["AB5", "W17", "AB17", "Y17", "V13", "W13"],
-            "LVCMOS33", Spartan6),
-        "xc6slx100t": ("csg484-2",
-            ["AB5", "W17", "AB17", "Y17", "V13", "W13"],
-            "LVCMOS33", Spartan6),
-        "xc6slx150": ("csg484-2",
-            ["AB5", "W17", "AB17", "Y17", "V13", "W13"],
-            "LVCMOS33", Spartan6),
-        "xc6slx150t": ("csg484-2",
-            ["AB5", "W17", "AB17", "Y17", "V13", "W13"],
-            "LVCMOS33", Spartan6),
-        "xc6slx16": ("cpg196-2",
-            ["P2", "N13", "P11", "N11", "N10", "P10"],
-            "LVCMOS33", Spartan6),
-        "xc6slx25": ("csg324-2",
-            ["V3", "R15", "T13", "R13", "T14", "V14"],
-            "LVCMOS33", Spartan6),
-        "xc6slx25t": ("csg324-2",
-            ["V3", "R15", "T13", "R13", "T14", "V14"],
-            "LVCMOS33", Spartan6),
-        "xc6slx45": ("csg324-2",
-            ["V3", "R15", "T13", "R13", "T14", "V14"],
-            "LVCMOS33", Spartan6),
-        "xc6slx45t": ("csg324-2",
-            ["V3", "R15", "T13", "R13", "T14", "V14"],
-            "LVCMOS33", Spartan6),
-        "xc6slx4": ("cpg196-2",
-            ["P2", "N13", "P11", "N11", "N10", "P10"],
-            "LVCMOS33", Spartan6),
-        "xc6slx4t": ("qg144-2",
-            ["P38", "P70", "P64", "P65", "P62", "P61"],
-            "LVCMOS33", Spartan6),
-        "xc6slx75": ("csg484-2",
-            ["AB5", "W17", "AB17", "Y17", "V13", "W13"],
-            "LVCMOS33", Spartan6),
-        "xc6slx75t": ("csg484-2",
-            ["AB5", "W17", "AB17", "Y17", "V13", "W13"],
-            "LVCMOS33", Spartan6),
-        "xc6slx9": ("cpg196-2",
-            ["P2", "N13", "P11", "N11", "N10", "P10"],
-            "LVCMOS33", Spartan6),
-        "xc6slx9t": ("qg144-2",
-            ["P38", "P70", "P64", "P65", "P62", "P61"],
-            "LVCMOS33", Spartan6),
-
-        "xc7a100t": ("csg324-1",
-            ["L13", None, "K17", "K18", "L14", "M14"],
-            "LVCMOS25", Series7),
-        "xc7a15t": ("cpg236-1",
-            ["K19", None, "D18", "D19", "G18", "F18"],
-            "LVCMOS25", Series7),
-        "xc7a200t": ("fbg484-1",
-            ["T19", None, "P22", "R22", "P21", "R21"],
-            "LVCMOS25", Series7),
-        "xc7a35t": ("cpg236-1",
-            ["K19", None, "D18", "D19", "G18", "F18"],
-            "LVCMOS25", Series7),
-        "xc7a50t": ("cpg236-1",
-            ["K19", None, "D18", "D19", "G18", "F18"],
-            "LVCMOS25", Series7),
-        "xc7a75t": ("csg324-1",
-            ["L13", None, "K17", "K18", "L14", "M14"],
-            "LVCMOS25", Series7),
-        "xc7k160t": ("fbg484-1",
-            ["L16", None, "H18", "H19", "G18", "F19"],
-            "LVCMOS25", Series7),
-        "xc7k325t": ("fbg676-1",
-            ["C23", None, "B24", "A25", "B22", "A22"],
-            "LVCMOS25", Series7),
-        "xc7k355t": ("ffg901-1",
-            ["V26", None, "R30", "T30", "R28", "T28"],
-            "LVCMOS25", Series7),
-        "xc7k410t": ("fbg676-1",
-            ["C23", None, "B24", "A25", "B22", "A22"],
-            "LVCMOS25", Series7),
-        "xc7k420t": ("ffg1156-1",
-            ["V30", None, "AA33", "AA34", "Y33", "Y34"],
-            "LVCMOS25", Series7),
-        "xc7k480t": ("ffg1156-1",
-            ["V30", None, "AA33", "AA34", "Y33", "Y34"],
-            "LVCMOS25", Series7),
-        "xc7k70t": ("fbg484-1",
-            ["L16", None, "H18", "H19", "G18", "F19"],
-            "LVCMOS25", Series7),
-        "xc7v2000t": ("fhg1761-1",
-            ["AL36", None, "AM36", "AN36", "AJ36", "AJ37"],
-            "LVCMOS18", Series7),
-        "xc7v585t": ("ffg1157-1",
-            ["AL33", None, "AN33", "AN34", "AK34", "AL34"],
-            "LVCMOS18", Series7),
-        "xc7vh580t": ("flg1155-1",
-            ["AL28", None, "AE28", "AF28", "AJ29", "AJ30"],
-            "LVCMOS18", Series7),
-        "xc7vh870t": ("flg1932-1",
-            ["V32", None, "T33", "R33", "U31", "T31"],
-            "LVCMOS18", Series7),
-        "xc7vx1140t": ("flg1926-1",
-            ["AK33", None, "AN34", "AN35", "AJ34", "AK34"],
-            "LVCMOS18", Series7),
-        "xc7vx330t": ("ffg1157-1",
-            ["AL33", None, "AN33", "AN34", "AK34", "AL34"],
-            "LVCMOS18", Series7),
-        "xc7vx415t": ("ffg1157-1",
-            ["AL33", None, "AN33", "AN34", "AK34", "AL34"],
-            "LVCMOS18", Series7),
-        "xc7vx485t": ("ffg1157-1",
-            ["AL33", None, "AN33", "AN34", "AK34", "AL34"],
-            "LVCMOS18", Series7),
-        "xc7vx550t": ("ffg1158-1",
-            ["C24", None, "A23", "A24", "B26", "A26"],
-            "LVCMOS18", Series7),
-        "xc7vx690t": ("ffg1157-1",
-            ["AL33", None, "AN33", "AN34", "AK34", "AL34"],
-            "LVCMOS18", Series7),
-        "xc7vx980t": ("ffg1926-1",
-            ["AK33", None, "AN34", "AN35", "AJ34", "AK34"],
-            "LVCMOS18", Series7),
+        #
+        # chip: (package, id, standard, class)
+        "xc3s100e": ("cp132", 1, "LVCMOS33", Spartan3),
+        "xc3s1200e": ("fg320", 1, "LVCMOS33", Spartan3),
+        "xc3s1400a": ("fg484", 1, "LVCMOS33", Spartan3A),
+        "xc3s1400an": ("fgg484", 1, "LVCMOS33", Spartan3A),
+        "xc3s1600e": ("fg320", 1, "LVCMOS33", Spartan3),
+        "xc3s200a": ("fg320", 2, "LVCMOS33", Spartan3A),
+        "xc3s200an": ("ftg256", 1, "LVCMOS33", Spartan3A),
+        "xc3s250e": ("cp132", 1, "LVCMOS33", Spartan3),
+        "xc3s400a": ("fg320", 2, "LVCMOS33", Spartan3A),
+        "xc3s400an": ("fgg400", 1, "LVCMOS33", Spartan3A),
+        "xc3s500e": ("cp132", 1, "LVCMOS33", Spartan3),
+        "xc3s50a": ("ft256", 1, "LVCMOS33", Spartan3A),
+        "xc3s50an": ("ftg256", 1, "LVCMOS33", Spartan3A),
+        "xc3s700a": ("fg400", 1, "LVCMOS33", Spartan3A),
+        "xc3s700an": ("fgg484", 1, "LVCMOS33", Spartan3A),
+        "xc3sd1800a": ("cs484", 1, "LVCMOS33", Spartan3A),
+        "xc3sd3400a": ("cs484", 1, "LVCMOS33", Spartan3A),
+
+        "xc6slx100": ("csg484-2", 1, "LVCMOS33", Spartan6),
+        "xc6slx100t": ("csg484-2", 1, "LVCMOS33", Spartan6),
+        "xc6slx150": ("csg484-2", 1, "LVCMOS33", Spartan6),
+        "xc6slx150t": ("csg484-2", 1, "LVCMOS33", Spartan6),
+        "xc6slx16": ("cpg196-2", 1, "LVCMOS33", Spartan6),
+        "xc6slx25": ("csg324-2", 1, "LVCMOS33", Spartan6),
+        "xc6slx25t": ("csg324-2", 1, "LVCMOS33", Spartan6),
+        "xc6slx45": ("csg324-2", 1, "LVCMOS33", Spartan6),
+        "xc6slx45t": ("csg324-2", 1, "LVCMOS33", Spartan6),
+        "xc6slx4": ("cpg196-2", 1, "LVCMOS33", Spartan6),
+        "xc6slx4t": ("qg144-2", 1, "LVCMOS33", Spartan6),
+        "xc6slx75": ("csg484-2", 1, "LVCMOS33", Spartan6),
+        "xc6slx75t": ("csg484-2", 1, "LVCMOS33", Spartan6),
+        "xc6slx9": ("cpg196-2", 1, "LVCMOS33", Spartan6),
+        "xc6slx9t": ("qg144-2", 1, "LVCMOS33", Spartan6),
+
+        "xc7a100t": ("csg324-1", 1, "LVCMOS25", Series7),
+        "xc7a15t": ("cpg236-1", 1, "LVCMOS25", Series7),
+        "xc7a200t": ("fbg484-1", 1, "LVCMOS25", Series7),
+        "xc7a35t": ("cpg236-1", 1, "LVCMOS25", Series7),
+        "xc7a50t": ("cpg236-1", 1, "LVCMOS25", Series7),
+        "xc7a75t": ("csg324-1", 1, "LVCMOS25", Series7),
+        "xc7k160t": ("fbg484-1", 2, "LVCMOS25", Series7),
+        "xc7k325t": ("fbg676-1", 1, "LVCMOS25", Series7),
+        "xc7k355t": ("ffg901-1", 1, "LVCMOS25", Series7),
+        "xc7k410t": ("fbg676-1", 1, "LVCMOS25", Series7),
+        "xc7k420t": ("ffg1156-1", 1, "LVCMOS25", Series7),
+        "xc7k480t": ("ffg1156-1", 1, "LVCMOS25", Series7),
+        "xc7k70t": ("fbg484-1", 2, "LVCMOS25", Series7),
+        "xc7v2000t": ("fhg1761-1", 1, "LVCMOS18", Series7),
+        "xc7v585t": ("ffg1157-1", 1, "LVCMOS18", Series7),
+        "xc7vh580t": ("flg1155-1", 1, "LVCMOS18", Series7),
+        "xc7vh870t": ("flg1932-1", 1, "LVCMOS18", Series7),
+        "xc7vx1140t": ("flg1926-1", 1, "LVCMOS18", Series7),
+        "xc7vx330t": ("ffg1157-1", 1, "LVCMOS18", Series7),
+        "xc7vx415t": ("ffg1157-1", 1, "LVCMOS18", Series7),
+        "xc7vx485t": ("ffg1157-1", 1, "LVCMOS18", Series7),
+        "xc7vx550t": ("ffg1158-1", 1, "LVCMOS18", Series7),
+        "xc7vx690t": ("ffg1157-1", 1, "LVCMOS18", Series7),
+        "xc7vx980t": ("ffg1926-1", 1, "LVCMOS18", Series7),
     }
 
-    def __init__(self, device, pins, std):
+    def __init__(self, device, pins, std, toolchain="ise"):
         cs_n, clk, mosi, miso = pins[:4]
         io = ["spiflash", 0,
               Subsignal("cs_n", Pins(cs_n)),
@@ -278,26 +211,21 @@ class XilinxBscanSpi(XilinxPlatform):
             io.append(Subsignal("clk", Pins(clk)))
         for i, p in enumerate(pins[4:]):
             io.append(Subsignal("pullup{}".format(i), Pins(p), Misc("PULLUP")))
-
-        XilinxPlatform.__init__(self, device, [io])
-        if isinstance(self.toolchain, XilinxVivadoToolchain):
-            self.toolchain.bitstream_commands.append(
-                "set_property BITSTREAM.GENERAL.COMPRESS True [current_design]"
-            )
-        elif isinstance(self.toolchain, XilinxISEToolchain):
-            self.toolchain.bitgen_opt += " -g compress"
+        xilinx.XilinxPlatform.__init__(self, device, [io], toolchain=toolchain)
 
     @classmethod
     def make(cls, device, errors=False):
-        pkg, pins, std, Top = cls.pinouts[device]
-        platform = cls("{}-{}".format(device, pkg), pins, std)
+        pkg, id, std, Top = cls.pinouts[device]
+        pins = cls.packages[(pkg, id)]
+        platform = cls("{}-{}".format(device, pkg), pins, std, Top.toolchain)
         top = Top(platform)
         name = "bscan_spi_{}".format(device)
         dir = "build_{}".format(device)
         try:
             platform.build(top, build_name=name, build_dir=dir)
         except Exception as e:
-            print("ERROR: build failed for {}: {}".format(device, e))
+            print(("ERROR: xilinx_bscan_spi build failed "
+                  "for {}: {}").format(device, e))
             if errors:
                 raise