2018-01-22 18:25:10 +08:00
|
|
|
import os
|
|
|
|
import subprocess
|
|
|
|
|
2020-03-12 22:23:08 +08:00
|
|
|
from migen import *
|
|
|
|
from misoc.interconnect.csr import *
|
2018-01-22 18:25:10 +08:00
|
|
|
from misoc.integration.builder import *
|
|
|
|
|
|
|
|
from artiq.gateware.amp import AMPSoC
|
2018-07-15 17:21:17 +08:00
|
|
|
from artiq import __version__ as artiq_version
|
2018-01-22 18:25:10 +08:00
|
|
|
from artiq import __artiq_dir__ as artiq_dir
|
|
|
|
|
|
|
|
|
2018-07-15 17:21:17 +08:00
|
|
|
__all__ = ["add_identifier", "build_artiq_soc"]
|
|
|
|
|
|
|
|
|
|
|
|
def get_identifier_string(soc, suffix="", add_class_name=True):
|
|
|
|
r = artiq_version
|
|
|
|
if suffix or add_class_name:
|
|
|
|
r += ";"
|
|
|
|
if add_class_name:
|
2019-02-12 18:33:52 +08:00
|
|
|
r += getattr(soc, "class_name_override", soc.__class__.__name__.lower())
|
2018-07-15 17:21:17 +08:00
|
|
|
r += suffix
|
|
|
|
return r
|
|
|
|
|
|
|
|
|
2020-03-12 22:23:08 +08:00
|
|
|
class ReprogrammableIdentifier(Module, AutoCSR):
|
|
|
|
def __init__(self, ident):
|
|
|
|
self.address = CSRStorage(8)
|
|
|
|
self.data = CSRStatus(8)
|
|
|
|
|
|
|
|
contents = list(ident.encode())
|
|
|
|
l = len(contents)
|
|
|
|
if l > 255:
|
|
|
|
raise ValueError("Identifier string must be 255 characters or less")
|
|
|
|
contents.insert(0, l)
|
|
|
|
|
2020-03-12 23:09:13 +08:00
|
|
|
for i in range(8):
|
|
|
|
self.specials += Instance("ROM256X1", name="identifier_str"+str(i),
|
|
|
|
i_A0=self.address.storage[0], i_A1=self.address.storage[1],
|
|
|
|
i_A2=self.address.storage[2], i_A3=self.address.storage[3],
|
|
|
|
i_A4=self.address.storage[4], i_A5=self.address.storage[5],
|
|
|
|
i_A6=self.address.storage[6], i_A7=self.address.storage[7],
|
|
|
|
o_O=self.data.status[i],
|
|
|
|
p_INIT=sum(1 << j if c & (1 << i) else 0 for j, c in enumerate(contents)))
|
2020-03-12 22:23:08 +08:00
|
|
|
|
|
|
|
|
2020-08-28 05:56:57 +08:00
|
|
|
def add_identifier(soc, *args, identifier_str=None, **kwargs):
|
2018-07-15 17:21:17 +08:00
|
|
|
if hasattr(soc, "identifier"):
|
|
|
|
raise ValueError
|
2020-09-01 03:44:27 +08:00
|
|
|
software_identifier_str = get_identifier_string(soc, *args, **kwargs)
|
|
|
|
gateware_identifier_str = identifier_str or software_identifier_str
|
2018-07-15 17:21:17 +08:00
|
|
|
|
2020-09-01 03:44:27 +08:00
|
|
|
soc.submodules.identifier = ReprogrammableIdentifier(gateware_identifier_str)
|
|
|
|
soc.config["IDENTIFIER_STR"] = software_identifier_str
|
2018-07-15 17:21:17 +08:00
|
|
|
|
|
|
|
|
2018-01-22 18:25:10 +08:00
|
|
|
def build_artiq_soc(soc, argdict):
|
|
|
|
firmware_dir = os.path.join(artiq_dir, "firmware")
|
|
|
|
builder = Builder(soc, **argdict)
|
|
|
|
builder.software_packages = []
|
|
|
|
builder.add_software_package("bootloader", os.path.join(firmware_dir, "bootloader"))
|
|
|
|
if isinstance(soc, AMPSoC):
|
|
|
|
builder.add_software_package("libm")
|
|
|
|
builder.add_software_package("libprintf")
|
|
|
|
builder.add_software_package("libunwind")
|
|
|
|
builder.add_software_package("ksupport", os.path.join(firmware_dir, "ksupport"))
|
|
|
|
builder.add_software_package("runtime", os.path.join(firmware_dir, "runtime"))
|
|
|
|
else:
|
|
|
|
# Assume DRTIO satellite.
|
|
|
|
builder.add_software_package("satman", os.path.join(firmware_dir, "satman"))
|
|
|
|
try:
|
|
|
|
builder.build()
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
|
|
raise SystemExit("Command {} failed".format(" ".join(e.cmd)))
|