Fix EOS-S3 build on F4PGA

This commit is contained in:
Artur Kowalski 2023-10-11 18:42:20 +02:00 committed by Gwenhael Goavec-Merou
parent 329bd36f7f
commit abcc0b8ab6
2 changed files with 53 additions and 39 deletions

View File

@ -11,6 +11,7 @@
import os
import sys
import subprocess
import json
from shutil import which
from migen.fhdl.structure import _Fragment
@ -50,47 +51,57 @@ class F4PGAToolchain(GenericToolchain):
tools.write_to_file(self._build_name + ".pcf", pcf)
return (self._build_name + ".pcf", "PCF")
# Build Makefile -------------------------------------------------------------------------------
# Timing constraints (.sdc) --------------------------------------------------------------------
def build_timing_constraints(self, vns):
sdc = []
for clk, [period, name] in sorted(self.clocks.items(), key=lambda x: x[0].duid):
clk_sig = vns.get_name(clk)
sdc.append("create_clock -period {} {}".format(str(period), clk_sig))
tools.write_to_file(self._build_name + "_in.sdc", "\n".join(sdc))
return (self._build_name + "_in.sdc", "SDC")
# Build flow.json ------------------------------------------------------------------------------
# FIXME: Makefile approach is deprecated and must replaced by the use of f4pga script + a json file.
def build_script(self):
makefile = []
part = {"ql-eos-s3": "PU64"}.get(self.platform.device)
flow = {
"default_part": "EOS3FF512-PDN64",
"values": {
"top": self._build_name
},
"dependencies": {
"sources": [
f"{self._build_name}.v"
],
"synth_log": "synth.log",
"pack_log": "pack.log",
"analysis_log": "analysis.log"
},
"EOS3FF512-PDN64": {
"default_target": "bitstream",
"dependencies": {
"build_dir": self._build_dir,
"pcf": f"{self._build_name}.pcf",
"sdc-in": f"{self._build_name}_in.sdc"
},
"values": {
"part": self.platform.device,
"package": part
}
}
};
# Define Paths.
makefile.append("mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))")
makefile.append("current_dir := $(patsubst %/,%,$(dir $(mkfile_path)))")
# Create Project.
# FIXME: Only use top file for now and ignore .init files.
makefile.append("all: {top}_bit.h {top}.bin build/{top}.bit".format(top=self._build_name))
# build bit file (default)
makefile.append(f"build/{self._build_name}.bit:")
makefile.append("\tql_symbiflow -compile -d {device} -P {part} -v {verilog} -t {top} -p {pcf}".format(
device = self.platform.device,
part = {"ql-eos-s3": "PU64"}.get(self.platform.device),
verilog = f"{self._build_name}.v",
top = self._build_name,
pcf = f"{self._build_name}.pcf"
))
# build header to include in CPU firmware
makefile.append("{top}_bit.h: build/{top}.bit".format(top=self._build_name))
makefile.append(f"\tsymbiflow_write_bitheader $^ $@")
# build binary to write in dedicated FLASH area
makefile.append("{top}.bin: build/{top}.bit".format(top=self._build_name))
makefile.append(f"\tsymbiflow_write_binary $^ $@")
# Generate Makefile.
tools.write_to_file("Makefile", "\n".join(makefile))
return "Makefile"
tools.write_to_file("flow.json", json.dumps(flow))
return "flow.json"
def run_script(self, script):
make_cmd = ["make", "-j1"]
if which("ql_symbiflow") is None:
msg = "Unable to find QuickLogic Symbiflow toolchain, please:\n"
msg += "- Add QuickLogic Symbiflow toolchain to your $PATH."
raise OSError(msg)
make_cmd = ["f4pga", "-vvv", "build", "--flow", "flow.json"]
if subprocess.call(make_cmd) != 0:
raise OSError("Error occured during QuickLogic Symbiflow's script execution.")
make_cmd.append("--target")
for target in ["bitstream_openocd", "bitstream_jlink", "bitstream_bitheader", "bitstream_binary"]:
if subprocess.call(make_cmd + [target]) != 0:
raise OSError(f"Error occured during QuickLogic Symbiflow's script execution for step {target}.")

View File

@ -19,10 +19,13 @@ class QuickLogicPlatform(GenericPlatform):
def __init__(self, *args, toolchain="f4pga", **kwargs):
GenericPlatform.__init__(self, *args, **kwargs)
if toolchain == "symbiflow" or toolchain == "f4pga":
self.toolchain = f4pga.F4PGAToolchain()
if isinstance(toolchain, str):
if toolchain == "symbiflow" or toolchain == "f4pga":
self.toolchain = f4pga.F4PGAToolchain()
else:
raise ValueError(f"Unknown toolchain {toolchain}")
else:
raise ValueError(f"Unknown toolchain {toolchain}")
self.toolchain = toolchain
def get_verilog(self, *args, special_overrides=dict(), **kwargs):
so = dict(common.quicklogic_special_overrides)