added support for auto analyzing dependencies (something GHDL really should do by itself, but doesn't for some reason
This commit is contained in:
parent
3a2151e037
commit
319e3e25c0
71
src/elab.py
71
src/elab.py
@ -1,8 +1,66 @@
|
|||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
import build_env
|
import build_env
|
||||||
|
from re import split, sub
|
||||||
from typing import List
|
from typing import List
|
||||||
from project_man import getLibrariesPresent, getLibrariesInProject
|
from project_man import getLibrariesPresent, getLibrariesInProject, getLibraryInProject
|
||||||
|
|
||||||
|
## returns list of dicts containing {lib: ..., file: ...} in correct compile order
|
||||||
|
def getNeededDependencies(topDef: str, arch: str, lib: str, std: str, includes: List[str]):
|
||||||
|
incs = generateIncludesForGHDL(includes)
|
||||||
|
disableWarnings = [
|
||||||
|
"-Wno-library", "-Wno-deprecated-option", "-Wno-unexpected-option",
|
||||||
|
"-Wno-binding", "-Wno-port", "-Wno-pragma", "-Wno-specs", "-Wno-runtime-error",
|
||||||
|
"-Wno-missing-wait", "-Wno-shared", "-Wno-hide", "-Wno-nowrite",
|
||||||
|
"-Wno-logic-loop", "-Wno-pure", "-Wno-analyze-assert", "-Wno-attribute",
|
||||||
|
"-Wno-useless", "-Wno-open-assoc", "-Wno-conformance", "-Wno-unkept-attribute",
|
||||||
|
"-Wno-unhandled-attribute", "-Wno-elaboration"
|
||||||
|
]
|
||||||
|
command = [
|
||||||
|
"ghdl", "--elab-order", "--workdir=work", f"--work={lib}", f"--std={std}"
|
||||||
|
] + incs + disableWarnings + [
|
||||||
|
"--libraries", f"{topDef}", f"{arch}"
|
||||||
|
]
|
||||||
|
res = subprocess.run(command,capture_output=True)
|
||||||
|
if res.returncode != 0:
|
||||||
|
print(res.stdout, res.stderr)
|
||||||
|
res = split("\r\n", res.stdout.decode())
|
||||||
|
res = res[0:-1]
|
||||||
|
res = list(map(lambda x: {"lib": split(" ",x)[0], "file": split(" ", x)[1]}, res))
|
||||||
|
res = list(filter(lambda x: x["lib"] != lib, res))
|
||||||
|
outputDict = {}
|
||||||
|
for x in res:
|
||||||
|
if x["lib"] not in outputDict.keys():
|
||||||
|
outputDict[x["lib"]] = []
|
||||||
|
## For some reason, GHDL doesn't play nice with relative include paths, so
|
||||||
|
## many unnecessary "cd thing/.." occurs in a row. This regex fixes that.
|
||||||
|
fixed = sub(r"\w*/../","", x["file"])
|
||||||
|
outputDict[x["lib"]].append(fixed)
|
||||||
|
|
||||||
|
print(outputDict)
|
||||||
|
return outputDict
|
||||||
|
|
||||||
|
## anylyzes the needed dependecies such that elaboration using libraries is nice :)
|
||||||
|
def analyzeNeededDependencies(topDef: str, arch: str, lib: str, std: str, includes: List[str]):
|
||||||
|
deps = getNeededDependencies(topDef, arch, lib, std, includes)
|
||||||
|
incs = generateIncludesForGHDL(includes)
|
||||||
|
print(incs)
|
||||||
|
[exists, libDict] = getLibrariesInProject()
|
||||||
|
if not exists:
|
||||||
|
print("project doesn't exist")
|
||||||
|
return
|
||||||
|
for currLib in deps.keys():
|
||||||
|
currLibPath = libDict[currLib]["path"]
|
||||||
|
filesNames = list(map(lambda x: split("/",x)[-1],deps[currLib]))
|
||||||
|
vhdlFiles = list(map(lambda x: os.path.join(currLibPath, x),deps[currLib]))
|
||||||
|
if len(vhdlFiles) == 0:
|
||||||
|
continue
|
||||||
|
print(f"Analyzing dependecies in {currLib}: {filesNames}")
|
||||||
|
command = [
|
||||||
|
"ghdl", "-a", f"--workdir={os.path.join(currLibPath, 'work')}", f"--work={currLib}", f"--std={std}"
|
||||||
|
] + incs + vhdlFiles
|
||||||
|
subprocess.run(command)
|
||||||
|
|
||||||
|
|
||||||
def generateIncludesForGHDL(includes: List[str]):
|
def generateIncludesForGHDL(includes: List[str]):
|
||||||
cmd = []
|
cmd = []
|
||||||
@ -20,9 +78,12 @@ def generateIncludesForGHDL(includes: List[str]):
|
|||||||
def elabDesign(topDef: str, arch: str, lib: str, std: str, includes: List[str]):
|
def elabDesign(topDef: str, arch: str, lib: str, std: str, includes: List[str]):
|
||||||
if not build_env.ghdlEnvExists(std, lib):
|
if not build_env.ghdlEnvExists(std, lib):
|
||||||
print("No GHDL environment present. Add all needed files before elaborating")
|
print("No GHDL environment present. Add all needed files before elaborating")
|
||||||
|
analyzeNeededDependencies(topDef, arch, lib, std, includes)
|
||||||
incs = generateIncludesForGHDL(includes)
|
incs = generateIncludesForGHDL(includes)
|
||||||
command = [
|
command = [
|
||||||
"ghdl", "-m", "--workdir=work", f"--work={lib}", f"--std={std}"] + incs + ["-o", f"work/{topDef}-{arch}", f"work.{topDef}", f"{arch}"]
|
"ghdl", "-m", "--workdir=work", f"--work={lib}", f"--std={std}"
|
||||||
|
] + incs + [
|
||||||
|
"-o", f"work/{topDef}-{arch}", f"work.{topDef}", f"{arch}"]
|
||||||
subprocess.run(command)
|
subprocess.run(command)
|
||||||
|
|
||||||
def runDesign(topDef: str, arch: str, lib: str, std: str, includes):
|
def runDesign(topDef: str, arch: str, lib: str, std: str, includes):
|
||||||
@ -32,11 +93,13 @@ def runDesign(topDef: str, arch: str, lib: str, std: str, includes):
|
|||||||
wavePath = os.path.join(os.getcwd(), "wave")
|
wavePath = os.path.join(os.getcwd(), "wave")
|
||||||
incs = generateIncludesForGHDL(includes)
|
incs = generateIncludesForGHDL(includes)
|
||||||
command = [ ## may add -v for verbose
|
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}",
|
"ghdl", "--elab-run", f"--workdir=work", f"--work={lib}", f"--std={std}"
|
||||||
f"--wave=wave/{topDef}-{arch}.ghw" ##, "--read-wave-opt=<See"
|
] + incs + [
|
||||||
|
"-o", f"work/{topDef}-{arch}", f"{topDef}", f"{arch}", f"--wave=wave/{topDef}-{arch}.ghw" ##, "--read-wave-opt=<See"
|
||||||
]
|
]
|
||||||
subprocess.run(command)
|
subprocess.run(command)
|
||||||
command = [
|
command = [
|
||||||
"gtkwave", f"{topDef}-{arch}.ghw", "--rcvar",
|
"gtkwave", f"{topDef}-{arch}.ghw", "--rcvar",
|
||||||
"do_initial_zoom_fit yes"]
|
"do_initial_zoom_fit yes"]
|
||||||
subprocess.run(command, cwd=wavePath)
|
subprocess.run(command, cwd=wavePath)
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user