Merge pull request #2078 from VOGL-electronic/efinix_add_ipm

build: efinix: add function to add ip
This commit is contained in:
enjoy-digital 2024-09-26 11:42:34 +02:00 committed by GitHub
commit a19fbb70c4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
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.dbparser import EfinixDbParser
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

View File

@ -27,6 +27,7 @@ from litex.build.generic_toolchain import GenericToolchain
from litex.build.efinix import common
from litex.build.efinix import InterfaceWriter
from litex.build.efinix import IPMWriter
# Efinity Toolchain --------------------------------------------------------------------------------
@ -40,6 +41,7 @@ class EfinityToolchain(GenericToolchain):
self.efinity_path = efinity_path
os.environ["EFXPT_HOME"] = self.efinity_path + "/pt"
self.ifacewriter = InterfaceWriter(efinity_path)
self.ipmwriter = IPMWriter(efinity_path)
self.excluded_ios = []
self.additional_sdc_commands = []
self.additional_iface_commands = []
@ -309,6 +311,15 @@ class EfinityToolchain(GenericToolchain):
xml_str = xml_str.toprettyxml(indent=" ")
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:
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