From 092ae03bdd075fe79a10c69af026deeed08725f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Erik=20=C3=96rtenberg?= Date: Thu, 13 Mar 2025 15:14:27 +0100 Subject: [PATCH] Added project files to automate library imports --- scripts/README.md | 6 -- scripts/build_env.py | 68 --------------------- scripts/dependecies.md | 4 -- scripts/elab.py | 39 ------------ scripts/gantry.py | 87 --------------------------- scripts/install_gantry.sh | 9 --- scripts/nxp_script.py | 81 ------------------------- scripts/project_man.py | 122 -------------------------------------- scripts/requirements.txt | 14 ----- 9 files changed, 430 deletions(-) delete mode 100644 scripts/README.md delete mode 100644 scripts/build_env.py delete mode 100644 scripts/dependecies.md delete mode 100644 scripts/elab.py delete mode 100644 scripts/gantry.py delete mode 100755 scripts/install_gantry.sh delete mode 100644 scripts/nxp_script.py delete mode 100644 scripts/project_man.py delete mode 100644 scripts/requirements.txt diff --git a/scripts/README.md b/scripts/README.md deleted file mode 100644 index 53a3716..0000000 --- a/scripts/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# Installation -* Run `python -m venv .` -* Run `./bin/pip install -r requirements.txt` - -# Running -* `./bin/python gantry.py --help` documents how it works diff --git a/scripts/build_env.py b/scripts/build_env.py deleted file mode 100644 index d9ff493..0000000 --- a/scripts/build_env.py +++ /dev/null @@ -1,68 +0,0 @@ -import os -from re import split -import subprocess - -def getCfFileId(std: str): - return "08" if std == "08" else "93" ## Weird behaviour from GHDL, but all vhdl versions besides 08 have [...]93.cf - -def ghdlEnvExists(std, lib): - ## Check if work exists - try: - os.lstat("work") - except: - return False - ## Check that work is writable - if not os.access("work", os.W_OK): - print("work is write-protected, please acquire correct permissions") - return False - cfFileExists = False - filesInWork = os.listdir("work") - cfFileId = getCfFileId(std) - for file in filesInWork: - if ".cf" in file and lib in file and cfFileId in file: - cfFileExists = True - if not cfFileExists: - return False - ## Nothing bad, continue - return True - -def createBuildEnv(std: str, lib: str): - if ghdlEnvExists(std=std, lib=lib): - print("Build environment already exists, exiting...") - return -1 - ## Create build env - print("Initializing GHDL project in current directory...") - os.makedirs("work",exist_ok=True) - addAllVHDLFiles(std=std, lib=lib, init=True) - return 0 - -def addAllVHDLFiles(std: str, lib: str, init=False): - ## Ensure everything is ready for adding files - ## (init exception to avoid one if-case in ghdlEnvExists) - if not ghdlEnvExists(std=std, lib=lib) and not init: - return -1 - vhdlFiles = [] - currentlyAdded = [] - cfFileId = getCfFileId(std) - ## Find already present files - if not init: - cfFileName = list(filter(lambda x: ".cf" in x and lib in x and cfFileId in x, os.listdir("work")))[0] - cfFilePath = os.path.join("work",cfFileName) - currentlyAdded = getCurrentlyAddedFiles(cfFilePath) - ## Add files not added - for file in os.listdir(): - if ".vhd" in file and file not in currentlyAdded: - vhdlFiles.append(file) - if len(vhdlFiles) > 0: - print(f"Detected new files. Adding {vhdlFiles}") - command = ["ghdl", "-i", "--workdir=work", f"--work={lib}", f"--std={std}"] + vhdlFiles - subprocess.run(command) - return 0 - -def getCurrentlyAddedFiles(cfFilePath:str): - f = open(cfFilePath,"r") - lines = f.readlines() - f.close() - fileLines = filter(lambda x: "file" in x, lines) - files = map(lambda x: split("\" \"",x)[1], fileLines) - return list(files) diff --git a/scripts/dependecies.md b/scripts/dependecies.md deleted file mode 100644 index 0feb6b1..0000000 --- a/scripts/dependecies.md +++ /dev/null @@ -1,4 +0,0 @@ -* GHDL = 4.1.0 -* Python >= 3.0.0 -* gtkwave >= v3.3.120 - diff --git a/scripts/elab.py b/scripts/elab.py deleted file mode 100644 index 7cf0edc..0000000 --- a/scripts/elab.py +++ /dev/null @@ -1,39 +0,0 @@ -import os -import subprocess -import build_env -from typing import List - - -def generateIncludesForGHDL(includes: List[str]): - cmd = [] - for inc in includes: - cmd.append(f"-P{inc}/work") - return cmd - -def elabDesign(topDef: str, arch: str, lib: str, std: str, includes: List[str]): - ## Add all source files present in pwd - if build_env.addAllVHDLFiles(std, lib) == -1: - print("Adding files failed. GHDL Build environment may be broken...") - return -1 - incs = generateIncludesForGHDL(includes) - command = [ - "ghdl", "-m", "--workdir=work", f"--work={lib}", f"--std={std}"] + incs + ["-o", f"work/{topDef}-{arch}", f"work.{topDef}", f"{arch}"] - subprocess.run(command) - -def runDesign(topDef: str, arch: str, lib: str, std: str, includes): - ## elaborate first, then run - if elabDesign(topDef, arch, lib, std, includes) == -1: - print("Elaboration failed...") - return -1 - os.makedirs("wave",exist_ok=True) - wavePath = "wave" - incs = generateIncludesForGHDL(includes) - command = [ ## may add -v for verbose - "ghdl", "--elab-run", f"--workdir=work", f"--work={lib}", f"--std={std}"] + incs + ["-o", f"work/{topDef}-{arch}", f"{topDef}", f"{arch}", - f"--wave=wave/{topDef}-{arch}.ghw" ##, "--read-wave-opt= "$PWD/gantry" -chmod +x "$PWD/gantry" - diff --git a/scripts/nxp_script.py b/scripts/nxp_script.py deleted file mode 100644 index fc310b7..0000000 --- a/scripts/nxp_script.py +++ /dev/null @@ -1,81 +0,0 @@ -import os -import subprocess -import build_env -import sys -import traceback -from nxpython import * - -artifact_path = "" - -# Evaluate whether we want the user to provide a selection of files -def makeProject(library: str, project_name: str, path): - # Create an Impulse project and add all VHDL files to it - print(path) - #Createproject enters the implicitly created directory - print(f"Creating project \'{project_name}\'\n") - getProject().setTopCellName(library, project_name) - getProject().setVariantName("NG-MEDIUM", "LGA-625") - getProject().addParameters({}) - print(path) - listed = list(os.listdir(path)) - files = list(filter(lambda x: ".vhdl" in x or ".vhd" in x or ".v\0" in x, listed)) # Find VHDL and Verilog files - files = list(map(lambda x: os.path.join(path, x), files)) - print(f"Adding the following files to project: {files}\n") - getProject().addFiles(files) - print("Saving project") - getProject().save(os.path.join(artifact_path, project_name + ".nym")) - return 0 - -# Do we want the user to specify how far they want to progress wach step? What does the number mean? -def synthDesign(library: str, project_name: str, path): - # Synthesize the design of the project of the provided `project_name` - print("Starting synthesis\n") - try: - nymFile = os.path.join(artifact_path, project_name + ".nym") - os.lstat(nymFile) - getProject().loadNative(nymFile) - except: - print("No existing project found, creating new project\n") - makeProject(library, project_name, path) - getProject().loadNative(os.path.join(artifact_path, project_name + ".nym")) - getProject().progress("Synthesize", 3) - getProject().save(os.path.join(artifact_path, project_name + "-synth.nym")) - return 0 - -def placeDesign(library: str, project_name: str, path): - # Place the given design. Will use a previously synthesized project if available, otherwise one will be created. - print("Starting place\n") - try: - nymFile = os.path.join(artifact_path, project_name + "-synth.nym") - os.lstat(nymFile) - getProject().load(nymFile) - except: - print("No existing synthesis found, entering synthesis stage\n") - synthDesign(library, project_name, path) - getProject().load(os.path.join(artifact_path, project_name + "-synth.nym")) - getProject().progress("Place", 5) - getProject().save(os.path.join(artifact_path, project_name + "-place.nym")) - -def routeDesign(library: str, project_name: str, path): - # Route the given design. Will use a previously placed project if available, otherwise one will be created. - print("Starting route\n") - try: - nymFile = os.path.join(artifact_path, project_name + "-place.nym") - os.lstat(nymFile) - getProject().load(nymFile) - except: - print("No existing place found, entering place stage\n") - placeDesign(library, project_name, path) - getProject().load(os.path.join(artifact_path, project_name + "-place.nym")) - getProject().progress("Route", 3) - getProject().save(os.path.join(artifact_path, project_name + "-route.nym")) - - -if __name__ == "__main__": - path = os.getcwd() - artifact_path = os.path.join(path, "syn") - print(f"Calling {sys.argv[1]}() with arguments {sys.argv[2]}, {sys.argv[3]}") - createProject(artifact_path) - globals()[sys.argv[1]](sys.argv[2], sys.argv[3], path) - getProject().createAnalyzer() - getProject().getAnalyzer().launch(conditions="worstcase", maximumSlack=0, searchPathsLimit=10, synthesisMode=False) diff --git a/scripts/project_man.py b/scripts/project_man.py deleted file mode 100644 index 425ad20..0000000 --- a/scripts/project_man.py +++ /dev/null @@ -1,122 +0,0 @@ -import os -from typing import Any -import toml -import datetime - - -def findProjectRoot() -> tuple[bool, str]: - [exists, projectFile] = findProjectFile() - if not exists: - return (False, "") - return (True, "/".join(projectFile.split("/")[0:-1])) - -def findProjectFile() -> tuple[bool, str]: - cwd = os.getcwd().split("/") - for i in range(len(cwd) - 2): - searchPath = "/".join(cwd[0:len(cwd)-i]) - [exists, pathToProjectFile] = projectFileExists(searchPath) - if exists: - return (True, pathToProjectFile) - return (False, "") - -def projectFileExists(path: str) -> tuple[bool, str]: - files = os.listdir(path) - for file in files: - if "gantry.toml" in file: - return (True, os.path.join(path, file)) - return (False,"") - -def initProjectFile(projectName: str) -> tuple[bool, str]: - cwd = os.getcwd() - projectPath = os.path.join(cwd, "gantry.toml") - [exists, existingProjectPath] = projectFileExists(cwd) - if exists: - existingProjectName = existingProjectPath.split("/")[-1] - return (False, f"Project {existingProjectName} already exists, amend it to fit your intention or delete it to create a new project") - try: - with open(projectPath, "w") as f: - parsedTOML = toml.loads(createProjectFileTemplate(projectName)) - toml.dump(parsedTOML, f) - except: - return (False, "Creation of file failed, permissions may be set wrong") - - return (True, projectPath) - -def loadProjectFile() -> tuple[bool, str | dict[str, Any]] : - [exists, path] = findProjectFile() - if not exists: - return (False, "") - try: - with open(path, "r") as f: - toml.load - parsedTOML = toml.load(f) - return (True, parsedTOML) - except: - return (False, "Reading Project file failed, permissions may be set wrong") - -def writeProjectFile(projectDict: dict[str, Any]) -> tuple[bool, str]: - [exists, path] = findProjectFile() - if not exists: - return (False, "") - try: - with open(path, "w") as f: - toml.dump(projectDict, f) - return (True, "") - except: - return (False, "Reading Project file failed, permissions may be set wrong") - -def removeLibraryInProject(lib: str) -> tuple[bool, str]: - [exists, output] = loadProjectFile() - if not exists: - return (False, "Project doesn't exist.") - projectDict = {} - if isinstance(output, dict): - projectDict = output - else: - return (False, "Output wasn't a dictionary") - if "libraries" not in projectDict.keys(): - return (False, "No libraries are declared in this project.") - if lib in projectDict["libraries"].keys(): - projectDict["libraries"].pop(lib) - [wentWell, _] = writeProjectFile(projectDict) - return (wentWell, "") - return (False, "Library with this name is not declared") - - -def addLibraryInProject(lib: str, std: str) -> tuple[bool, str]: - [exists, output] = loadProjectFile() - if not exists: - return (False, "Project doesn't exist.") - projectDict = {} - if isinstance(output, dict): - projectDict = output - else: - return (False, "Output wasn't a dictionary") - if "libraries" not in projectDict.keys(): - projectDict["libraries"] = {} - if lib not in projectDict["libraries"].keys(): - projectDict["libraries"][lib] = {} - projectDict["libraries"][lib]["vhdl-version"] = std - projectDict["libraries"][lib]["path"] = os.path.join(os.getcwd(), lib) - [wentWell, _] = writeProjectFile(projectDict) - return (wentWell, "") - return (False, "Library with this name is already declared") - -def createProjectFileTemplate(projectName: str) -> str: - return f""" -title = "{projectName}" -createdAt = "{datetime.date.today()}" -maintainer = "" -email = "" -version = "0.0.1" -""" - - - -if __name__ == "__main__": - print(initProjectFile("test")) - print(loadProjectFile()) - print(findProjectFile()) - print(findProjectRoot()) - print(addLibraryInProject("ganimede", "93")) - print(removeLibraryInProject("ganimede")) diff --git a/scripts/requirements.txt b/scripts/requirements.txt deleted file mode 100644 index 5f05862..0000000 --- a/scripts/requirements.txt +++ /dev/null @@ -1,14 +0,0 @@ -attrs==21.4.0 -click==8.0.4 -commonmark==0.9.1 -dataclasses==0.8 -importlib-metadata==4.8.3 -markdown-it-py==2.0.1 -mdurl==0.1.0 -Pygments==2.14.0 -rich==12.6.0 -shellingham==1.4.0 -type-extensions==0.1.2 -typer==0.10.0 -typing_extensions==4.1.1 -zipp==3.6.0