Added library support for nxp_script
This commit is contained in:
parent
7b5ab586cb
commit
4ea39b4333
@ -1,14 +1,22 @@
|
|||||||
import typer
|
import typer
|
||||||
import os
|
import os
|
||||||
|
<<<<<<< HEAD
|
||||||
from re import split
|
from re import split
|
||||||
from project_man import findProjectFile, getLibraryInProject, initProjectFile, addLibraryInProject, removeLibraryInProject, getLibrariesPresent
|
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 elab as elaborate
|
||||||
import build_env
|
import build_env
|
||||||
from typing import List, Optional
|
from typing import List, Optional
|
||||||
from typing_extensions import Annotated
|
from typing_extensions import Annotated
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
gantry_install_path = "/home/thesis1/repos/gantry/src"
|
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()
|
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.")
|
@hardware.command(help="Synthesizes the provided top level design using NXPython. Make sure you run this with NXPython.")
|
||||||
def synth(
|
def synth(
|
||||||
topdef: Annotated[str, typer.Argument(help="Top Definition entity to synthesize")] = "",
|
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.")
|
@hardware.command(help="Places the provided top level design using NXPython. Make sure you run this with NXPython.")
|
||||||
def place(
|
def place(
|
||||||
topdef: Annotated[str, typer.Argument(help="Top Definition entity to synthesize")] = "",
|
topdef: Annotated[str, typer.Argument(help="Top Definition entity to place")] = "",
|
||||||
library: Annotated[str, typer.Option("--library", "-l", help="Library to compile to. If current directory contains libraries, it will be automatically detected")] = ""
|
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])
|
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.")
|
@hardware.command(help="Routes the provided top level design using NXPython. Make sure you run this with NXPython.")
|
||||||
def route(
|
def route(
|
||||||
topdef: Annotated[str, typer.Argument(help="Top Definition entity to synthesize")] = "",
|
topdef: Annotated[str, typer.Argument(help="Top Definition entity to route")] = "",
|
||||||
library: Annotated[str, typer.Option("--library", "-l", help="Library to compile to. If current directory contains libraries, it will be automatically detected")] = ""
|
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])
|
proc = subprocess.run(["source_and_run.sh", f"{gantry_install_path}/nxp_script.py", "routeDesign", library, topdef])
|
||||||
|
|
||||||
|
|||||||
@ -1,72 +1,79 @@
|
|||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import build_env
|
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
from nxpython import *
|
from nxpython import *
|
||||||
|
|
||||||
artifact_path = ""
|
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
|
# 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
|
# Create an Impulse project and add all VHDL files to it
|
||||||
print(path)
|
# Createproject enters the implicitly created directory
|
||||||
#Createproject enters the implicitly created directory
|
printRemark(f"Creating project \'{project_name}\'\n")
|
||||||
print(f"Creating project \'{project_name}\'\n")
|
printRemark(f"Setting topcell name to {project_name} in library {library}")
|
||||||
getProject().setTopCellName(library, project_name)
|
getProject().setTopCellName(library, project_name)
|
||||||
getProject().setVariantName("NG-MEDIUM", "LGA-625")
|
getProject().setVariantName("NG-MEDIUM", "LGA-625")
|
||||||
getProject().addParameters({})
|
getProject().addParameters({})
|
||||||
print(path)
|
for lib, file in includes:
|
||||||
listed = list(os.listdir(path))
|
printRemark(f"Adding file {os.path.join(path, file)} from lib {lib}")
|
||||||
files = list(filter(lambda x: ".vhdl" in x or ".vhd" in x or ".v\0" in x, listed)) # Find VHDL and Verilog files
|
getProject().addFile(lib, os.path.join(path, file))
|
||||||
files = list(map(lambda x: os.path.join(path, x), files))
|
printRemark("Saving project")
|
||||||
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"))
|
getProject().save(os.path.join(artifact_path, project_name + ".nym"))
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
# Do we want the user to specify how far they want to progress wach step? What does the number mean?
|
# 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`
|
# Synthesize the design of the project of the provided `project_name`
|
||||||
print("Starting synthesis\n")
|
|
||||||
try:
|
try:
|
||||||
nymFile = os.path.join(artifact_path, project_name + ".nym")
|
nymFile = os.path.join(artifact_path, project_name + ".nym")
|
||||||
os.lstat(nymFile)
|
os.lstat(nymFile)
|
||||||
getProject().loadNative(nymFile)
|
getProject().loadNative(nymFile)
|
||||||
except:
|
except:
|
||||||
print("No existing project found, creating new project\n")
|
printRemark("No existing project found, creating new project\n")
|
||||||
makeProject(library, project_name, path)
|
makeProject(library, project_name, includes, path)
|
||||||
getProject().loadNative(os.path.join(artifact_path, project_name + ".nym"))
|
getProject().loadNative(os.path.join(artifact_path, project_name + ".nym"))
|
||||||
|
printRemark("Starting synthesis\n")
|
||||||
getProject().progress("Synthesize", 3)
|
getProject().progress("Synthesize", 3)
|
||||||
getProject().save(os.path.join(artifact_path, project_name + "-synth.nym"))
|
getProject().save(os.path.join(artifact_path, project_name + "-synth.nym"))
|
||||||
return 0
|
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.
|
# Place the given design. Will use a previously synthesized project if available, otherwise one will be created.
|
||||||
print("Starting place\n")
|
|
||||||
try:
|
try:
|
||||||
nymFile = os.path.join(artifact_path, project_name + "-synth.nym")
|
nymFile = os.path.join(artifact_path, project_name + "-synth.nym")
|
||||||
os.lstat(nymFile)
|
os.lstat(nymFile)
|
||||||
getProject().load(nymFile)
|
getProject().load(nymFile)
|
||||||
except:
|
except:
|
||||||
print("No existing synthesis found, entering synthesis stage\n")
|
printRemark("No existing synthesis found, entering synthesis stage\n")
|
||||||
synthDesign(library, project_name, path)
|
synthDesign(library, project_name, includes, path)
|
||||||
getProject().load(os.path.join(artifact_path, project_name + "-synth.nym"))
|
getProject().load(os.path.join(artifact_path, project_name + "-synth.nym"))
|
||||||
|
printRemark("Starting place\n")
|
||||||
getProject().progress("Place", 5)
|
getProject().progress("Place", 5)
|
||||||
getProject().save(os.path.join(artifact_path, project_name + "-place.nym"))
|
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.
|
# Route the given design. Will use a previously placed project if available, otherwise one will be created.
|
||||||
print("Starting route\n")
|
|
||||||
try:
|
try:
|
||||||
nymFile = os.path.join(artifact_path, project_name + "-place.nym")
|
nymFile = os.path.join(artifact_path, project_name + "-place.nym")
|
||||||
os.lstat(nymFile)
|
os.lstat(nymFile)
|
||||||
getProject().load(nymFile)
|
getProject().load(nymFile)
|
||||||
except:
|
except:
|
||||||
print("No existing place found, entering place stage\n")
|
printRemark("No existing place found, entering place stage\n")
|
||||||
placeDesign(library, project_name, path)
|
placeDesign(library, project_name, includes, path)
|
||||||
getProject().load(os.path.join(artifact_path, project_name + "-place.nym"))
|
getProject().load(os.path.join(artifact_path, project_name + "-place.nym"))
|
||||||
|
printRemark("Starting route\n")
|
||||||
getProject().progress("Route", 3)
|
getProject().progress("Route", 3)
|
||||||
getProject().save(os.path.join(artifact_path, project_name + "-route.nym"))
|
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")
|
artifact_path = os.path.join(path, "syn")
|
||||||
print(f"Calling {sys.argv[1]}() with arguments {sys.argv[2]}, {sys.argv[3]}")
|
print(f"Calling {sys.argv[1]}() with arguments {sys.argv[2]}, {sys.argv[3]}")
|
||||||
createProject(artifact_path)
|
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().createAnalyzer()
|
||||||
getProject().getAnalyzer().launch(conditions="worstcase", maximumSlack=0, searchPathsLimit=10, synthesisMode=False)
|
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)
|
libs[lib]["path"] = os.path.relpath(absPath, cwd)
|
||||||
return (True, libs)
|
return (True, libs)
|
||||||
return (False, {})
|
return (False, {})
|
||||||
|
|
||||||
def getLibrariesInProject(cwd=os.getcwd()) -> "tuple[bool, dict[str, Any]]":
|
def getLibrariesInProject(cwd=os.getcwd()) -> "tuple[bool, dict[str, Any]]":
|
||||||
(exists, projectDict) = getProjectDict()
|
(exists, projectDict) = getProjectDict()
|
||||||
if not exists:
|
if not exists:
|
||||||
@ -152,6 +153,28 @@ def getLibrariesPresent(cwd=os.getcwd()) -> "tuple[bool, dict[str, Any]]":
|
|||||||
libsInCwd[lib] = libs[lib]
|
libsInCwd[lib] = libs[lib]
|
||||||
return (True, libsInCwd)
|
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:
|
def createProjectFileTemplate(projectName: str) -> str:
|
||||||
return f"""
|
return f"""
|
||||||
title = "{projectName}"
|
title = "{projectName}"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user