2
0
mirror of https://github.com/m-labs/artiq.git synced 2024-12-26 11:48:27 +08:00

bit2bin, fetch_bin -> flash_tools

This commit is contained in:
occheung 2024-10-24 12:40:25 +08:00
parent f2c13a5041
commit de349e4c39
5 changed files with 118 additions and 134 deletions

View File

@ -12,8 +12,7 @@ from artiq import __version__ as artiq_version
from artiq.master.databases import DeviceDB
from artiq.coredevice.comm_kernel import CommKernel
from artiq.coredevice.comm_mgmt import CommMgmt
from artiq.frontend.bit2bin import bit2bin
from artiq.frontend.fetch_bin import fetch_bin
from artiq.frontend.flash_tools import bit2bin, fetch_bin
def get_argparser():

View File

@ -14,8 +14,7 @@ from sipyco import common_args
from artiq import __version__ as artiq_version
from artiq.remoting import SSHClient, LocalClient
from artiq.frontend.bit2bin import bit2bin
from artiq.frontend.fetch_bin import fetch_bin
from artiq.frontend.flash_tools import artifact_path, bit2bin, fetch_bin
def get_argparser():
@ -305,10 +304,10 @@ def main():
for action in args.action:
if action == "gateware":
gateware_bin = fetch_bin(binary_dir, "gateware", args.srcbuild)
gateware_bin = fetch_bin(binary_dir, ["gateware"], args.srcbuild)
programmer.write_binary(*config["gateware"], gateware_bin)
elif action == "bootloader":
bootloader_bin = fetch_bin(binary_dir, "bootloader", args.srcbuild)
bootloader_bin = fetch_bin(binary_dir, ["bootloader"], args.srcbuild)
programmer.write_binary(*config["bootloader"], bootloader_bin)
elif action == "storage":
storage_img = args.storage

View File

@ -1,69 +0,0 @@
#!/usr/bin/env python3
# Copyright 2014-2017 Robert Jordens <jordens@gmail.com>
# after
# https://github.com/mfischer/fpgadev-zynq/blob/master/top/python/bit_to_zynq_bin.py
import struct
def flip32(data):
sl = struct.Struct("<I")
sb = struct.Struct(">I")
b = memoryview(data)
d = bytearray(len(data))
for offset in range(0, len(data), sl.size):
sb.pack_into(d, offset, *sl.unpack_from(b, offset))
return d
def bit2bin(bit, bin, flip=False):
l, = struct.unpack(">H", bit.read(2))
if l != 9:
raise ValueError("Missing <0009> header, not a bit file")
_ = bit.read(l) # unknown data
l, = struct.unpack(">H", bit.read(2))
if l != 1:
raise ValueError("Missing <0001> header, not a bit file")
while True:
key = bit.read(1).decode()
if not key:
break
if key in "abcd":
d = bit.read(*struct.unpack(">H", bit.read(2)))
assert d.endswith(b"\x00")
d = d[:-1].decode()
name = {
"a": "Design",
"b": "Part name",
"c": "Date",
"d": "Time"
}[key]
print("{}: {}".format(name, d))
elif key == "e":
l, = struct.unpack(">I", bit.read(4))
print("Bitstream payload length: {:#x}".format(l))
d = bit.read(l)
if flip:
d = flip32(d)
bin.write(d)
else:
d = bit.read(*struct.unpack(">H", bit.read(2)))
print("Unexpected key: {}: {}".format(key, d))
if __name__ == "__main__":
import argparse
parser = argparse.ArgumentParser(
description="Convert FPGA bit files to raw bin format "
"suitable for flashing")
parser.add_argument("-f", "--flip", dest="flip", action="store_true",
default=False, help="Flip 32-bit endianess (needed for Zynq)")
parser.add_argument("bitfile", metavar="BITFILE",
help="Input bit file name")
parser.add_argument("binfile", metavar="BINFILE",
help="Output bin file name")
args = parser.parse_args()
with open(args.bitfile, "rb") as f, open(args.binfile, "wb") as g:
bit2bin(f, g, args.flip)

View File

@ -1,59 +0,0 @@
import atexit
import os
import tempfile
from artiq.frontend.bit2bin import bit2bin
def fetch_bin(binary_dir, component, srcbuild=False):
def artifact_path(this_binary_dir, *path_filename):
if srcbuild:
# source tree - use path elements to locate file
return os.path.join(this_binary_dir, *path_filename)
else:
# flat tree - all files in the same directory, discard path elements
*_, filename = path_filename
return os.path.join(this_binary_dir, filename)
def convert_gateware(bit_filename):
bin_handle, bin_filename = tempfile.mkstemp(
prefix="artiq_", suffix="_" + os.path.basename(bit_filename))
with open(bit_filename, "rb") as bit_file, open(bin_handle, "wb") as bin_file:
bit2bin(bit_file, bin_file)
atexit.register(lambda: os.unlink(bin_filename))
return bin_filename
if type(component) == list:
bins = []
for option in component:
try:
bins.append(fetch_bin(binary_dir, option, srcbuild))
except FileNotFoundError:
pass
if bins is None:
raise FileNotFoundError("multiple components not found: {}".format(
" ".join(component)))
if len(bins) > 1:
raise ValueError("more than one file, "
"please clean up your build directory. "
"Found files: {}".format(
" ".join(bins)))
return bins[0]
path = artifact_path(binary_dir, *{
"gateware": ["gateware", "top.bit"],
"bootloader": ["software", "bootloader", "bootloader.bin"],
"runtime": ["software", "runtime", "runtime.fbi"],
"satman": ["software", "satman", "satman.fbi"],
}[component])
if not os.path.exists(path):
raise FileNotFoundError("{} not found".format(component))
if component == "gateware":
path = convert_gateware(path)
return path

View File

@ -0,0 +1,114 @@
import atexit
import os
import tempfile
def artifact_path(this_binary_dir, *path_filename, srcbuild=False):
if srcbuild:
# source tree - use path elements to locate file
return os.path.join(this_binary_dir, *path_filename)
else:
# flat tree - all files in the same directory, discard path elements
*_, filename = path_filename
return os.path.join(this_binary_dir, filename)
def fetch_bin(binary_dir, components, srcbuild=False):
def convert_gateware(bit_filename):
bin_handle, bin_filename = tempfile.mkstemp(
prefix="artiq_", suffix="_" + os.path.basename(bit_filename))
with open(bit_filename, "rb") as bit_file, open(bin_handle, "wb") as bin_file:
bit2bin(bit_file, bin_file)
atexit.register(lambda: os.unlink(bin_filename))
return bin_filename
if len(components) > 1:
bins = []
for option in components:
try:
bins.append(fetch_bin(binary_dir, [option], srcbuild))
except FileNotFoundError:
pass
if bins is None:
raise FileNotFoundError("multiple components not found: {}".format(
" ".join(components)))
if len(bins) > 1:
raise ValueError("more than one file, "
"please clean up your build directory. "
"Found files: {}".format(
" ".join(bins)))
return bins[0]
else:
component = components[0]
path = artifact_path(binary_dir, *{
"gateware": ["gateware", "top.bit"],
"boot": ["boot.bin"],
"bootloader": ["software", "bootloader", "bootloader.bin"],
"runtime": ["software", "runtime", "runtime.fbi"],
"satman": ["software", "satman", "satman.fbi"],
}[component], srcbuild=srcbuild)
if not os.path.exists(path):
raise FileNotFoundError("{} not found".format(component))
if component == "gateware":
path = convert_gateware(path)
return path
# Copyright 2014-2017 Robert Jordens <jordens@gmail.com>
# after
# https://github.com/mfischer/fpgadev-zynq/blob/master/top/python/bit_to_zynq_bin.py
import struct
def flip32(data):
sl = struct.Struct("<I")
sb = struct.Struct(">I")
b = memoryview(data)
d = bytearray(len(data))
for offset in range(0, len(data), sl.size):
sb.pack_into(d, offset, *sl.unpack_from(b, offset))
return d
def bit2bin(bit, bin, flip=False):
l, = struct.unpack(">H", bit.read(2))
if l != 9:
raise ValueError("Missing <0009> header, not a bit file")
_ = bit.read(l) # unknown data
l, = struct.unpack(">H", bit.read(2))
if l != 1:
raise ValueError("Missing <0001> header, not a bit file")
while True:
key = bit.read(1).decode()
if not key:
break
if key in "abcd":
d = bit.read(*struct.unpack(">H", bit.read(2)))
assert d.endswith(b"\x00")
d = d[:-1].decode()
name = {
"a": "Design",
"b": "Part name",
"c": "Date",
"d": "Time"
}[key]
print("{}: {}".format(name, d))
elif key == "e":
l, = struct.unpack(">I", bit.read(4))
print("Bitstream payload length: {:#x}".format(l))
d = bit.read(l)
if flip:
d = flip32(d)
bin.write(d)
else:
d = bit.read(*struct.unpack(">H", bit.read(2)))
print("Unexpected key: {}: {}".format(key, d))