build/anlogic: use GenericToolchain

This commit is contained in:
Gwenhael Goavec-Merou 2022-06-26 09:05:58 +02:00
parent b75a6ba636
commit 8446c5b342
1 changed files with 169 additions and 209 deletions

View File

@ -14,15 +14,35 @@ from shutil import which
from migen.fhdl.structure import _Fragment from migen.fhdl.structure import _Fragment
from litex.build.generic_platform import * from litex.build.generic_platform import *
from litex.build.generic_toolchain import GenericToolchain
from litex.build import tools from litex.build import tools
# Constraints (.adc and .sdc) ---------------------------------------------------------------------- # TangDinastyToolchain -----------------------------------------------------------------------------------
def _build_adc(named_sc, named_pc):
class TangDinastyToolchain(GenericToolchain):
attr_translate = {}
def __init__(self):
super().__init__()
self._architecture = ""
self._family = ""
self._package = ""
def finalize(self):
self._architecture, self._family, self._package = self.parse_device()
def build(self, platform, fragment, **kwargs):
return self._build(platform, fragment, **kwargs)
# Constraints (.adc ) --------------------------------------------------------------------------
def build_io_constraints(self):
adc = [] adc = []
flat_sc = [] flat_sc = []
for name, pins, other, resource in named_sc: for name, pins, other, resource in self.named_sc:
if len(pins) > 1: if len(pins) > 1:
for i, p in enumerate(pins): for i, p in enumerate(pins):
flat_sc.append((f"{name}[{i}]", p, other)) flat_sc.append((f"{name}[{i}]", p, other))
@ -37,22 +57,24 @@ def _build_adc(named_sc, named_pc):
line += f"}}" line += f"}}"
adc.append(line) adc.append(line)
if named_pc: if self.named_pc:
adc.extend(named_pc) adc.extend(self.named_pc)
with open("top.adc", "w") as f: tools.write_to_file("top.adc", "\n".join(adc))
f.write("\n".join(adc)) return ("top.adc", "ADC")
def _build_sdc(clocks, vns): # Timing Constraints (in sdc file) -------------------------------------------------------------
def build_timing_constraints(self, vns):
sdc = [] sdc = []
for clk, period in sorted(clocks.items(), key=lambda x: x[0].duid): for clk, period in sorted(self.clocks.items(), key=lambda x: x[0].duid):
sdc.append(f"create_clock -name {vns.get_name(clk)} -period {str(period)} [get_ports {{{vns.get_name(clk)}}}]") sdc.append(f"create_clock -name {vns.get_name(clk)} -period {str(period)} [get_ports {{{vns.get_name(clk)}}}]")
with open("top.sdc", "w") as f: tools.write_to_file("top.sdc", "\n".join(sdc))
f.write("\n".join(sdc)) return ("top.sdc", "SDC")
# Script ------------------------------------------------------------------------------------------- # Project (.ai) --------------------------------------------------------------------------------
def _build_al(name, family, device, files): def build_project(self):
xml = [] xml = []
date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") date = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
@ -63,16 +85,16 @@ def _build_al(name, family, device, files):
xml.append(f" <Project_Created_Time>{date}</Project_Created_Time>") xml.append(f" <Project_Created_Time>{date}</Project_Created_Time>")
xml.append(f" <TD_Version>5.0.28716</TD_Version>") xml.append(f" <TD_Version>5.0.28716</TD_Version>")
xml.append(f" <UCode>00000000</UCode>") xml.append(f" <UCode>00000000</UCode>")
xml.append(f" <Name>{name}</Name>") xml.append(f" <Name>{self._build_name}</Name>")
xml.append(f" <HardWare>") xml.append(f" <HardWare>")
xml.append(f" <Family>{family}</Family>") xml.append(f" <Family>{self._family}</Family>")
xml.append(f" <Device>{device}</Device>") xml.append(f" <Device>{self.platform.device}</Device>")
xml.append(f" </HardWare>") xml.append(f" </HardWare>")
xml.append(f" <Source_Files>") xml.append(f" <Source_Files>")
xml.append(f" <Verilog>") xml.append(f" <Verilog>")
# Add Sources. # Add Sources.
for f, typ, lib in files: for f, typ, lib in self.platform.sources:
xml.append(f" <File Path=\"{f}\">") xml.append(f" <File Path=\"{f}\">")
xml.append(f" <FileInfo>") xml.append(f" <FileInfo>")
xml.append(f" <Attr Name=\"UsedInSyn\" Val=\"true\"/>") xml.append(f" <Attr Name=\"UsedInSyn\" Val=\"true\"/>")
@ -113,7 +135,7 @@ def _build_al(name, family, device, files):
xml.append(f" </FileSets>") xml.append(f" </FileSets>")
xml.append(f" <TOP_MODULE>") xml.append(f" <TOP_MODULE>")
xml.append(f" <LABEL></LABEL>") xml.append(f" <LABEL></LABEL>")
xml.append(f" <MODULE>{name}</MODULE>") xml.append(f" <MODULE>{self._build_name}</MODULE>")
xml.append(f" <CREATEINDEX>auto</CREATEINDEX>") xml.append(f" <CREATEINDEX>auto</CREATEINDEX>")
xml.append(f" </TOP_MODULE>") xml.append(f" </TOP_MODULE>")
xml.append(f" <Property>") xml.append(f" <Property>")
@ -130,20 +152,21 @@ def _build_al(name, family, device, files):
xml.append(f"</Project>") xml.append(f"</Project>")
# Generate .al. # Generate .al.
with open(name + ".al", "w") as f: tools.write_to_file(self._build_name + ".al", "\n".join(xml))
f.write("\n".join(xml))
def _build_tcl(name, architecture, package): # Script ---------------------------------------------------------------------------------------
def build_script(self):
tcl = [] tcl = []
# Set Device. # Set Device.
tcl.append(f"import_device {architecture}.db -package {package}") tcl.append(f"import_device {self._architecture}.db -package {self._package}")
# Add project. # Add project.
tcl.append(f"open_project {name}.al") tcl.append(f"open_project {self._build_name}.al")
# Elaborate. # Elaborate.
tcl.append(f"elaborate -top {name}") tcl.append(f"elaborate -top {self._build_name}")
# Add IOs Constraints. # Add IOs Constraints.
tcl.append("read_adc top.adc") tcl.append("read_adc top.adc")
@ -158,16 +181,24 @@ def _build_tcl(name, architecture, package):
tcl.append("legalize_phy_inst") tcl.append("legalize_phy_inst")
tcl.append("place") tcl.append("place")
tcl.append("route") tcl.append("route")
tcl.append(f"bitgen -bit \"{name}.bit\" -version 0X00 -g ucode:000000000000000000000000") tcl.append(f"bitgen -bit \"{self._build_name}.bit\" -version 0X00 -g ucode:000000000000000000000000")
# Generate .tcl. # Generate .tcl.
with open("run.tcl", "w") as f: tools.write_to_file("run.tcl", "\n".join(tcl))
f.write("\n".join(tcl))
return "run.tcl"
# TangDinastyToolchain ----------------------------------------------------------------------------------- def run_script(self, script):
if which("td") is None:
msg = "Unable to find Tang Dinasty toolchain, please:\n"
msg += "- Add Tang Dinasty toolchain to your $PATH."
raise OSError(msg)
def parse_device(device): if subprocess.call(["td", script]) != 0:
raise OSError("Error occured during Tang Dinasty's script execution.")
def parse_device(self):
device = self.platform.device
devices = { devices = {
"EG4S20BG256" :[ "eagle_s20", "EG4", "BG256" ], "EG4S20BG256" :[ "eagle_s20", "EG4", "BG256" ],
@ -179,77 +210,6 @@ def parse_device(device):
(architecture, family, package) = devices[device] (architecture, family, package) = devices[device]
return (architecture, family, package) return (architecture, family, package)
class TangDinastyToolchain:
attr_translate = {}
def __init__(self):
self.clocks = dict()
def build(self, platform, fragment,
build_dir = "build",
build_name = "top",
run = True,
**kwargs):
# Create build directory.
cwd = os.getcwd()
os.makedirs(build_dir, exist_ok=True)
os.chdir(build_dir)
# Finalize design.
if not isinstance(fragment, _Fragment):
fragment = fragment.get_fragment()
platform.finalize(fragment)
# Generate verilog.
v_output = platform.get_verilog(fragment, name=build_name, **kwargs)
named_sc, named_pc = platform.resolve_signals(v_output.ns)
v_file = build_name + ".v"
v_output.write(v_file)
platform.add_source(v_file)
# Generate constraints file.
# IOs (.adc).
_build_adc(
named_sc = named_sc,
named_pc = named_pc
)
# Timings (.sdc).
_build_sdc(
clocks = self.clocks,
vns = v_output.ns
)
architecture, family, package = parse_device(platform.device)
# Generate project file (.al).
al = _build_al(
name = build_name,
family = family,
device = platform.device,
files = platform.sources)
# Generate build script (.tcl).
script = _build_tcl(
name = build_name,
architecture = architecture,
package = package)
# Run.
if run:
if which("td") is None:
msg = "Unable to find Tang Dinasty toolchain, please:\n"
msg += "- Add Tang Dinasty toolchain to your $PATH."
raise OSError(msg)
if subprocess.call(["td", "run.tcl"]) != 0:
raise OSError("Error occured during Tang Dinasty's script execution.")
os.chdir(cwd)
return v_output.ns
def add_period_constraint(self, platform, clk, period): def add_period_constraint(self, platform, clk, period):
clk.attr.add("keep") clk.attr.add("keep")
period = math.floor(period*1e3)/1e3 # round to lowest picosecond period = math.floor(period*1e3)/1e3 # round to lowest picosecond