Skip to content

Commit

Permalink
Merge pull request #2078 from VOGL-electronic/efinix_add_ipm
Browse files Browse the repository at this point in the history
build: efinix: add function to add ip
  • Loading branch information
enjoy-digital authored Sep 26, 2024
2 parents b11cc8c + 8a6264c commit a19fbb7
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 0 deletions.
1 change: 1 addition & 0 deletions litex/build/efinix/__init__.py
Original file line number Diff line number Diff line change
@@ -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
11 changes: 11 additions & 0 deletions litex/build/efinix/efinity.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

from litex.build.efinix import common
from litex.build.efinix import InterfaceWriter
from litex.build.efinix import IPMWriter


# Efinity Toolchain --------------------------------------------------------------------------------
Expand All @@ -40,6 +41,7 @@ def __init__(self, efinity_path):
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 = []
Expand Down Expand Up @@ -309,6 +311,15 @@ def build_project(self):
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.")

Expand Down
108 changes: 108 additions & 0 deletions litex/build/efinix/ipmwriter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#
# This file is part of LiteX.
#
# Copyright (c) 2024 Fin Maaß <[email protected]>
# 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

0 comments on commit a19fbb7

Please sign in to comment.