build: efinix: add function to add ip

add function to add efinix IP.

Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
This commit is contained in:
Fin Maaß 2024-09-24 11:59:28 +02:00
parent 9bacbe130b
commit 8a6264c4f6
No known key found for this signature in database
3 changed files with 120 additions and 0 deletions

View File

@ -1,4 +1,5 @@
from litex.build.efinix.programmer import EfinixProgrammer from litex.build.efinix.programmer import EfinixProgrammer
from litex.build.efinix.dbparser import EfinixDbParser from litex.build.efinix.dbparser import EfinixDbParser
from litex.build.efinix.ifacewriter import InterfaceWriter, InterfaceWriterBlock, InterfaceWriterXMLBlock from litex.build.efinix.ifacewriter import InterfaceWriter, InterfaceWriterBlock, InterfaceWriterXMLBlock
from litex.build.efinix.ipmwriter import IPMWriter, IPMWriterBlock, IPMWriterXMLBlock
from litex.build.efinix.platform import EfinixPlatform from litex.build.efinix.platform import EfinixPlatform

View File

@ -27,6 +27,7 @@ from litex.build.generic_toolchain import GenericToolchain
from litex.build.efinix import common from litex.build.efinix import common
from litex.build.efinix import InterfaceWriter from litex.build.efinix import InterfaceWriter
from litex.build.efinix import IPMWriter
# Efinity Toolchain -------------------------------------------------------------------------------- # Efinity Toolchain --------------------------------------------------------------------------------
@ -40,6 +41,7 @@ class EfinityToolchain(GenericToolchain):
self.efinity_path = efinity_path self.efinity_path = efinity_path
os.environ["EFXPT_HOME"] = self.efinity_path + "/pt" os.environ["EFXPT_HOME"] = self.efinity_path + "/pt"
self.ifacewriter = InterfaceWriter(efinity_path) self.ifacewriter = InterfaceWriter(efinity_path)
self.ipmwriter = IPMWriter(efinity_path)
self.excluded_ios = [] self.excluded_ios = []
self.additional_sdc_commands = [] self.additional_sdc_commands = []
self.additional_iface_commands = [] self.additional_iface_commands = []
@ -285,6 +287,15 @@ class EfinityToolchain(GenericToolchain):
xml_str = xml_str.toprettyxml(indent=" ") xml_str = xml_str.toprettyxml(indent=" ")
tools.write_to_file("{}.xml".format(self._build_name), xml_str) tools.write_to_file("{}.xml".format(self._build_name), xml_str)
if len(self.ipmwriter.blocks) > 0:
ipm_header = self.ipmwriter.header(self._build_name, self.platform.device, self.platform.family)
ipm = self.ipmwriter.generate(self.platform.device)
tools.write_to_file("ipm.py", ipm_header + ipm )
if tools.subprocess_call_filtered([self.efinity_path + "/bin/python3", "ipm.py"], common.colors) != 0:
raise OSError("Error occurred during Efinity ip script execution.")
if tools.subprocess_call_filtered([self.efinity_path + "/bin/python3", "iface.py"], common.colors) != 0: if tools.subprocess_call_filtered([self.efinity_path + "/bin/python3", "iface.py"], common.colors) != 0:
raise OSError("Error occurred during Efinity peri script execution.") raise OSError("Error occurred during Efinity peri script execution.")

View File

@ -0,0 +1,108 @@
#
# This file is part of LiteX.
#
# Copyright (c) 2024 Fin Maaß <f.maass@vogl-electronic.com>
# SPDX-License-Identifier: BSD-2-Clause
from migen import *
from litex.build import tools
# Interface Writer Block ---------------------------------------------------------------------------
class IPMWriterBlock(dict):
def generate(self):
raise NotImplementedError # Must be overloaded
class IPMWriterXMLBlock(dict):
def generate(self):
raise NotImplementedError # Must be overloaded
# Interface Writer --------------------------------------------------------------------------------
class IPMWriter:
def __init__(self, efinity_path):
self.efinity_path = efinity_path
self.blocks = []
self.filename = ""
self.platform = None
def set_build_params(self, platform, build_name):
self.filename = build_name
self.platform = platform
def header(self, build_name, partnumber, family):
header = "# Autogenerated by LiteX / git: " + tools.get_litex_git_revision()
header += """
import os
import sys
import pprint
from pathlib import Path
home = "{0}"
os.environ["EFXIPM_HOME"] = home + "/ipm"
sys.path.append(home + "/ipm/bin")
sys.path.append(home + "/lib/python3.11/site-packages")
from ipm_api_service.design import IPMDesignAPI
from ipm_api_service.projectxml import ProjectXML
from common.logger import Logger
Logger.setup_logger(log_path_str=Path(".").absolute())
is_verbose = {1}
project_xml_path = Path(".").absolute()/"{2}.xml"
design = IPMDesignAPI(device_name="{3}", family_name="{4}", is_verbose=is_verbose)
projectxml = ProjectXML(project_xml_path=project_xml_path, is_verbose=is_verbose)
# pprint.pprint(design.get_ip_list())
"""
return header.format(self.efinity_path, "True", build_name, partnumber, family)
def get_block(self, name):
for b in self.blocks:
if b["name"] == name:
return b
return None
def generate_ip_block(self, block, verbose=True):
name = block["name"]
cmd = "# ---------- IP {} ---------\n".format(name)
cmd += f'design.create_ip(module_name="{name}",vendor="{block["vendor"]}",library="{block["library"]}",name="{block["ip_name"]}")\n'
if "configs" in block:
cmd += '# Configs\n'
cmd += f'{name}_configs = {{\n'
for p, v in block["configs"].items():
cmd += f' "{p}":"{v}",\n'
cmd += f'}}\n\n'
cmd += f'design.config_ip(module_name="{name}", configs = {name}_configs)\n'
cmd += f'success, validated_param_result, param_template_list = design.validate_ip(module_name="{name}")\n\n'
cmd += f'if success:\n'
cmd += f' result = design.generate_ip(module_name="{name}")\n'
cmd += f' if not projectxml.is_ip_exists(module_name="{name}"):\n'
cmd += f' projectxml.add_ip(module_name="{name}")\n'
cmd += f' projectxml.save()\n'
cmd += "# ---------- END IP {} ---------\n\n".format(name)
return cmd
def generate(self, partnumber):
output = ""
for block in self.blocks:
if isinstance(block, IPMWriterBlock):
output += block.generate()
else:
if block["type"] == "IP":
output += self.generate_ip_block(block)
return output