Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

build: efinix: add function to add ip #2078

Merged
merged 1 commit into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -285,6 +287,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
Loading