From 82068267dba100b246a8c3db67a87ac1869ab46b Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Wed, 30 Jul 2014 11:35:21 +0200 Subject: [PATCH] mibuild: move programmer to mibuild and create programmer directly in platforms --- mibuild/platforms/de0nano.py | 4 ++ mibuild/platforms/m1.py | 4 ++ mibuild/platforms/mixxeo.py | 4 ++ mibuild/platforms/papilio_pro.py | 4 ++ mibuild/programmer.py | 75 ++++++++++++++++++++++++++++++++ 5 files changed, 91 insertions(+) create mode 100644 mibuild/programmer.py diff --git a/mibuild/platforms/de0nano.py b/mibuild/platforms/de0nano.py index 0fd93726..47ea4da7 100644 --- a/mibuild/platforms/de0nano.py +++ b/mibuild/platforms/de0nano.py @@ -4,6 +4,7 @@ from mibuild.generic_platform import * from mibuild.crg import SimpleCRG from mibuild.altera_quartus import AlteraQuartusPlatform +from mibuild.programmer import USBBlaster _io = [ ("clk50", 0, Pins("R8"), IOStandard("3.3-V LVTTL")), @@ -95,6 +96,9 @@ class Platform(AlteraQuartusPlatform): AlteraQuartusPlatform.__init__(self, "EP4CE22F17C6", _io, lambda p: SimpleCRG(p, "clk50", None)) + def create_programmer(self): + return USBBlaster() + def do_finalize(self, fragment): try: self.add_period_constraint(self.lookup_request("clk50"), 20) diff --git a/mibuild/platforms/m1.py b/mibuild/platforms/m1.py index fa4e4bee..59dafe8e 100644 --- a/mibuild/platforms/m1.py +++ b/mibuild/platforms/m1.py @@ -1,6 +1,7 @@ from mibuild.generic_platform import * from mibuild.crg import SimpleCRG from mibuild.xilinx_ise import XilinxISEPlatform +from mibuild.programmer import UrJTAG _io = [ ("user_led", 0, Pins("B16"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")), @@ -122,6 +123,9 @@ class Platform(XilinxISEPlatform): XilinxISEPlatform.__init__(self, "xc6slx45-fgg484-2", _io, lambda p: SimpleCRG(p, "clk50", None)) + def create_programmer(self): + return UrJTAG("fjmem-m1.bit") + def do_finalize(self, fragment): try: self.add_period_constraint(self.lookup_request("clk50"), 20) diff --git a/mibuild/platforms/mixxeo.py b/mibuild/platforms/mixxeo.py index 01f898d2..d7800c59 100644 --- a/mibuild/platforms/mixxeo.py +++ b/mibuild/platforms/mixxeo.py @@ -1,6 +1,7 @@ from mibuild.generic_platform import * from mibuild.crg import SimpleCRG from mibuild.xilinx_ise import XilinxISEPlatform +from mibuild.programmer import UrJTAG _io = [ ("user_led", 0, Pins("V5"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")), @@ -159,6 +160,9 @@ class Platform(XilinxISEPlatform): lambda p: SimpleCRG(p, "clk50", None)) self.add_platform_command("CONFIG VCCAUX=\"3.3\";\n") + def create_programmer(self): + return UrJTAG("fjmem-mixxeo.bit") + def do_finalize(self, fragment): try: self.add_period_constraint(self.lookup_request("clk50"), 20) diff --git a/mibuild/platforms/papilio_pro.py b/mibuild/platforms/papilio_pro.py index 957d7cfe..4e29ba5d 100644 --- a/mibuild/platforms/papilio_pro.py +++ b/mibuild/platforms/papilio_pro.py @@ -1,6 +1,7 @@ from mibuild.generic_platform import * from mibuild.crg import SimpleCRG from mibuild.xilinx_ise import XilinxISEPlatform +from mibuild.programmer import XC3SProg _io = [ ("user_led", 0, Pins("P112"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")), @@ -53,6 +54,9 @@ class Platform(XilinxISEPlatform): XilinxISEPlatform.__init__(self, "xc6slx9-tqg144-2", _io, lambda p: SimpleCRG(p, "clk32", None), _connectors) + def create_programmer(self): + return XC3SProg("papilio", "bscan_spi_lx9_papilio.bit") + def do_finalize(self, fragment): try: self.add_period_constraint(self.lookup_request("clk32"), 31.25) diff --git a/mibuild/programmer.py b/mibuild/programmer.py new file mode 100644 index 00000000..0de79888 --- /dev/null +++ b/mibuild/programmer.py @@ -0,0 +1,75 @@ +import subprocess +import os + +class Programmer: + def __init__(self, flash_proxy_basename=None): + self.flash_proxy_basename = flash_proxy_basename + self.flash_proxy_dirs = ["~/.mlabs", "/usr/local/share/mlabs", "/usr/share/mlabs"] + + def set_flash_proxy_dir(self, flash_proxy_dir): + if flash_proxy_dir is not None: + self.flash_proxy_dirs = [flash_proxy_dir] + + def find_flash_proxy(self): + for d in self.flash_proxy_dirs: + fulldir = os.path.abspath(os.path.expanduser(d)) + fullname = os.path.join(fulldir, self.flash_proxy_basename) + if os.path.exists(fullname): + return fullname + raise OSError("Failed to find flash proxy bitstream") + +def _run_urjtag(cmds): + with subprocess.Popen("jtag", stdin=subprocess.PIPE) as process: + process.stdin.write(cmds.encode("ASCII")) + process.communicate() + +class UrJTAG(Programmer): + needs_bitreverse = True + needs_flash_proxy = True + + def load_bitstream(self, bitstream_file): + cmds = """cable milkymist +detect +pld load {bitstream} +quit +""".format(bitstream=bitstream_file) + _run_urjtag(cmds) + + def flash(self, address, data_file): + flash_proxy = self.find_flash_proxy() + cmds = """cable milkymist +detect +pld load "{flash_proxy}" +initbus fjmem opcode=000010 +frequency 6000000 +detectflash 0 +endian big +flashmem "{address}" "{data_file}" noverify +""".format(flash_proxy=flash_proxy, address=address, data_file=data_file) + _run_urjtag(cmds) + +class XC3SProg(Programmer): + needs_bitreverse = False + needs_flash_proxy = True + + def __init__(self, cable, flash_proxy_basename=None): + Programmer.__init__(flash_proxy_basename) + self.cable = cable + + def load_bitstream(self, bitstream_file): + subprocess.call(["xc3sprog", "-v", "-c", self.cable, bitstream_file]) + + def flash(self, address, data_file): + flash_proxy = self.find_flash_proxy() + subprocess.call(["xc3sprog", "-v", "-c", self.cable, "-I"+flash_proxy, "{}:w:0x{:x}:BIN".format(data_file, address)]) + +class USBBlaster(Programmer): + needs_bitreverse = False + needs_flash_proxy = False + + def load_bitstream(self, bitstream_file, port=0): + usb_port = "[USB-"+str(port)+"]" + subprocess.call(["quartus_pgm", "-m", "jtag", "-c", "USB-Blaster"+usb_port, "-o", "p;"+bitstream_file]) + + def flash(self, address, data_file): + raise NotImplementedError -- 2.30.2