Added library support for nxp_script
This commit is contained in:
parent
7b5ab586cb
commit
4ea39b4333
@ -1,14 +1,22 @@
|
||||
import typer
|
||||
import os
|
||||
<<<<<<< HEAD
|
||||
from re import split
|
||||
from project_man import findProjectFile, getLibraryInProject, initProjectFile, addLibraryInProject, removeLibraryInProject, getLibrariesPresent
|
||||
=======
|
||||
from project_man import findProjectRoot, getProjectDict, getLibrariesInProject, findProjectFile, getLibraryInProject, getSourceFilesWithLib, initProjectFile, addLibraryInProject, removeLibraryInProject, getLibrariesPresent
|
||||
>>>>>>> 8bf7864 (Added library support for nxp_script)
|
||||
import elab as elaborate
|
||||
import build_env
|
||||
from typing import List, Optional
|
||||
from typing_extensions import Annotated
|
||||
import subprocess
|
||||
|
||||
<<<<<<< HEAD
|
||||
gantry_install_path = "/home/thesis1/repos/gantry/src"
|
||||
=======
|
||||
gantry_install_path = "/home/thesis2/gantry/src"
|
||||
>>>>>>> 8bf7864 (Added library support for nxp_script)
|
||||
|
||||
app = typer.Typer()
|
||||
|
||||
@ -145,22 +153,42 @@ def run(
|
||||
@hardware.command(help="Synthesizes the provided top level design using NXPython. Make sure you run this with NXPython.")
|
||||
def synth(
|
||||
topdef: Annotated[str, typer.Argument(help="Top Definition entity to synthesize")] = "",
|
||||
library: Annotated[str, typer.Option("--library", "-l", help="Library to compile todefaults to \"\"")] = ""
|
||||
arch: Annotated[str, typer.Argument(help="Architecture to synthesize within the top definition provided")] = "",
|
||||
library: Annotated[str, typer.Option("--library", "-l", help="Library to compile to")] = "",
|
||||
includes: Annotated[Optional[List[str]], typer.Option("--include", "-i", help="Which libraries to include in compile")] = None,
|
||||
):
|
||||
proc = subprocess.run(["source_and_run.sh", f"{gantry_install_path}/nxp_script.py", "synthDesign", library, topdef])
|
||||
library = autoDetectLibrary(library)
|
||||
print(f"Synthesizing {topdef} with arch {arch} in library {library}.")
|
||||
if includes is not None:
|
||||
print(f"Including libraries: {includes}")
|
||||
else:
|
||||
_, includes = getSourceFilesWithLib() # TODO: Error handling
|
||||
_, proj_root = findProjectRoot()
|
||||
proc = subprocess.run(["source_and_run.sh", # Source NXPython
|
||||
f"{gantry_install_path}/nxp_script.py", # Run script
|
||||
"synthDesign", # Function call
|
||||
library, # Function arguments
|
||||
topdef,
|
||||
proj_root] +
|
||||
includes
|
||||
)
|
||||
|
||||
@hardware.command(help="Places the provided top level design using NXPython. Make sure you run this with NXPython.")
|
||||
def place(
|
||||
topdef: Annotated[str, typer.Argument(help="Top Definition entity to synthesize")] = "",
|
||||
library: Annotated[str, typer.Option("--library", "-l", help="Library to compile to. If current directory contains libraries, it will be automatically detected")] = ""
|
||||
topdef: Annotated[str, typer.Argument(help="Top Definition entity to place")] = "",
|
||||
arch: Annotated[str, typer.Argument(help="Architecture to place within the top definition provided")] = "",
|
||||
library: Annotated[str, typer.Option("--library", "-l", help="Library to compile to. If current directory contains libraries, it will be automatically detected")] = "",
|
||||
includes: Annotated[Optional[List[str]], typer.Option("--include", "-i", help="Which libraries to include in compile")] = None,
|
||||
):
|
||||
proc = subprocess.run(["source_and_run.sh", f"{gantry_install_path}/nxp_script.py", "placeDesign", library, topdef])
|
||||
|
||||
|
||||
@hardware.command(help="Routes the provided top level design using NXPython. Make sure you run this with NXPython.")
|
||||
def route(
|
||||
topdef: Annotated[str, typer.Argument(help="Top Definition entity to synthesize")] = "",
|
||||
library: Annotated[str, typer.Option("--library", "-l", help="Library to compile to. If current directory contains libraries, it will be automatically detected")] = ""
|
||||
topdef: Annotated[str, typer.Argument(help="Top Definition entity to route")] = "",
|
||||
arch: Annotated[str, typer.Argument(help="Architecture to route within the top definition provided")] = "",
|
||||
library: Annotated[str, typer.Option("--library", "-l", help="Library to compile to. If current directory contains libraries, it will be automatically detected")] = "",
|
||||
includes: Annotated[Optional[List[str]], typer.Option("--include", "-i", help="Which libraries to include in compile")] = None,
|
||||
):
|
||||
proc = subprocess.run(["source_and_run.sh", f"{gantry_install_path}/nxp_script.py", "routeDesign", library, topdef])
|
||||
|
||||
|
||||
@ -1,72 +1,79 @@
|
||||
import os
|
||||
import subprocess
|
||||
import build_env
|
||||
import sys
|
||||
import traceback
|
||||
from nxpython import *
|
||||
|
||||
artifact_path = ""
|
||||
|
||||
|
||||
def getNXFormatedIncludes(path, libs) -> "tuple[bool, list[tuple[str, str]]]":
|
||||
printRemark("These libraries exst in the project: " + str(libs))
|
||||
includes = []
|
||||
for lib in libs:
|
||||
listed = list(os.listdir(os.path.join(path, lib)))
|
||||
files = list(filter(lambda x: ".vhdl" in x or ".vhd" in x or ".v\0" in x, listed)) # Find VHDL and Verilog files
|
||||
lib_name = str.split(lib, "/")[-1]
|
||||
includes = includes + list(map(lambda x: (lib_name, os.path.join(lib, x)), files))
|
||||
return (True, includes)
|
||||
|
||||
# Evaluate whether we want the user to provide a selection of files
|
||||
def makeProject(library: str, project_name: str, path):
|
||||
def makeProject(library: str, project_name: str, includes: "list[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")
|
||||
# Createproject enters the implicitly created directory
|
||||
printRemark(f"Creating project \'{project_name}\'\n")
|
||||
printRemark(f"Setting topcell name to {project_name} in library {library}")
|
||||
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")
|
||||
for lib, file in includes:
|
||||
printRemark(f"Adding file {os.path.join(path, file)} from lib {lib}")
|
||||
getProject().addFile(lib, os.path.join(path, file))
|
||||
printRemark("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):
|
||||
def synthDesign(library: str, project_name: str, includes: "list[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)
|
||||
printRemark("No existing project found, creating new project\n")
|
||||
makeProject(library, project_name, includes, path)
|
||||
getProject().loadNative(os.path.join(artifact_path, project_name + ".nym"))
|
||||
printRemark("Starting synthesis\n")
|
||||
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):
|
||||
def placeDesign(library: str, project_name: str, includes: "list[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)
|
||||
printRemark("No existing synthesis found, entering synthesis stage\n")
|
||||
synthDesign(library, project_name, includes, path)
|
||||
getProject().load(os.path.join(artifact_path, project_name + "-synth.nym"))
|
||||
printRemark("Starting place\n")
|
||||
getProject().progress("Place", 5)
|
||||
getProject().save(os.path.join(artifact_path, project_name + "-place.nym"))
|
||||
|
||||
def routeDesign(library: str, project_name: str, path):
|
||||
def routeDesign(library: str, project_name: str, includes: "list[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)
|
||||
printRemark("No existing place found, entering place stage\n")
|
||||
placeDesign(library, project_name, includes, path)
|
||||
getProject().load(os.path.join(artifact_path, project_name + "-place.nym"))
|
||||
printRemark("Starting route\n")
|
||||
getProject().progress("Route", 3)
|
||||
getProject().save(os.path.join(artifact_path, project_name + "-route.nym"))
|
||||
|
||||
@ -76,6 +83,11 @@ if __name__ == "__main__":
|
||||
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)
|
||||
nx_includes = []
|
||||
for i in range(5, len(sys.argv[5:]), 2):
|
||||
nx_includes.append((sys.argv[i], sys.argv[i + 1]))
|
||||
printRemark("\nNX_INCLUDES ARE: " + str(nx_includes) + "\n")
|
||||
# <Function Name>(Library, Topdef, Includes, Working_dir)
|
||||
globals()[sys.argv[1]](sys.argv[2], sys.argv[3], nx_includes, path)
|
||||
getProject().createAnalyzer()
|
||||
getProject().getAnalyzer().launch(conditions="worstcase", maximumSlack=0, searchPathsLimit=10, synthesisMode=False)
|
||||
|
||||
@ -127,6 +127,7 @@ def getLibraryInProject(lib: str, cwd=os.getcwd()) -> "tuple[bool, dict[str, Any
|
||||
libs[lib]["path"] = os.path.relpath(absPath, cwd)
|
||||
return (True, libs)
|
||||
return (False, {})
|
||||
|
||||
def getLibrariesInProject(cwd=os.getcwd()) -> "tuple[bool, dict[str, Any]]":
|
||||
(exists, projectDict) = getProjectDict()
|
||||
if not exists:
|
||||
@ -152,6 +153,28 @@ def getLibrariesPresent(cwd=os.getcwd()) -> "tuple[bool, dict[str, Any]]":
|
||||
libsInCwd[lib] = libs[lib]
|
||||
return (True, libsInCwd)
|
||||
|
||||
# TODO: Make this function recursively look in folders in the library directory
|
||||
# Returns a list in the format [<lib>, <file_path>, <lib>, <file_path>...]
|
||||
# This is used for sending the files to NXPython
|
||||
def getSourceFilesWithLib() -> "tuple[bool, list[str]]":
|
||||
exists, proj_dict = getProjectDict()
|
||||
if not exists:
|
||||
return (False, [])
|
||||
if "libraries" not in proj_dict.keys():
|
||||
## Successful read, no libs found -> empty return
|
||||
return (True, [])
|
||||
_, proj_root = findProjectRoot()
|
||||
result = []
|
||||
cwd = os.getcwd()
|
||||
for lib in proj_dict["libraries"].keys():
|
||||
listed = list(os.listdir(os.path.join(proj_root, lib)))
|
||||
files = list(filter(lambda x: ".vhdl" in x or ".vhd" in x or ".v\0" in x, listed)) # Find VHDL and Verilog files
|
||||
for file in files:
|
||||
result.append(lib)
|
||||
rel_file_path = os.path.relpath(os.path.join(proj_root, lib, file), cwd)
|
||||
result.append(rel_file_path)
|
||||
return (True, result)
|
||||
|
||||
def createProjectFileTemplate(projectName: str) -> str:
|
||||
return f"""
|
||||
title = "{projectName}"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user