Somewhat missnamed branch build-scripts merge with main #3

Merged
kryddan merged 7 commits from build-scripts into main 2025-02-12 10:30:49 +01:00
9 changed files with 176 additions and 1 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*/wave
*/work

View File

@ -2,7 +2,7 @@
This repository is the public part of the thesis work created by Adam Magnusson and Erik Örtenberg at Chalmers Univerity of Technology. The work contained wihtin this repo details how a network interface will work, mostly built in VHDL. This repository is the public part of the thesis work created by Adam Magnusson and Erik Örtenberg at Chalmers Univerity of Technology. The work contained wihtin this repo details how a network interface will work, mostly built in VHDL.
# Tool instructions # Tool instructions
TBW Read the README.md in `./scripts`
# Build instructions # Build instructions
TBW TBW

7
scripts/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
# Created by venv; see https://docs.python.org/3/library/venv.html
bin
include
lib
lib64
pyvenv.cfg
__pycache__

6
scripts/README.md Normal file
View File

@ -0,0 +1,6 @@
# Installation
* Run `python -m venv .`
* Run `./bin/pip install -r requirements.txt`
# Running
* `./bin/python gantry.py --help` documents how it works

67
scripts/build_env.py Normal file
View File

@ -0,0 +1,67 @@
import os
from re import split
import subprocess
def ghdlEnvExists(relativePath="work"):
## Check if work exists
try:
os.lstat(relativePath)
except:
return False
## Check that work is writable
if not os.access(relativePath, os.W_OK):
print(f"{relativePath} is write-protected, please acquire correct permissions")
return False
cfFileExists = False
filesInWork = os.listdir(relativePath)
for file in filesInWork:
if ".cf" in file:
cfFileExists = True
if not cfFileExists:
return False
## Nothing bad, continue
return True
def createBuildEnv():
if ghdlEnvExists():
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(init=True)
return 0
def addAllVHDLFiles(init=False):
## Ensure everything is ready for adding files
## (init exception to avoid one if-case in ghdlEnvExists)
if not ghdlEnvExists() and not init:
return -1
vhdlFiles = []
currentlyAdded = []
## Find already present files
if not init:
cfFileName = list(filter(lambda x: ".cf" in x, os.listdir("work")))[0]
cfFilePath = os.path.join(os.getcwd(),f"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"] + 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)
if __name__ == "__main__":
getCurrentlyAddedFiles("work/work-obj93.cf")

4
scripts/dependecies.md Normal file
View File

@ -0,0 +1,4 @@
* GHDL = 4.1.0
* Python >= 3.0.0
* gtkwave >= v3.3.120

31
scripts/elab.py Normal file
View File

@ -0,0 +1,31 @@
import os
import subprocess
import build_env
def elabDesign(topDef: str, arch: str, lib: str, std: str):
## Add all source files present in pwd
if build_env.addAllVHDLFiles() == -1:
print("Adding files failed. GHDL Build environment may be broken...")
return -1
command = [
"ghdl", "-m", f"--workdir={lib}", f"--work={lib}", f"--std={std}",
"-o", f"{lib}/{topDef}-{arch}", f"{lib}.{topDef}", f"{arch}"]
subprocess.run(command)
def runDesign(topDef: str, arch: str, lib: str, std: str):
## elaborate first, then run
if elabDesign(topDef, arch, lib, std) == -1:
print("Elaboration failed...")
return -1
os.makedirs("wave",exist_ok=True)
libPath = os.path.join(os.getcwd(), lib)
wavePath = os.path.join(os.getcwd(), "wave")
command = [ ## may add -v for verbose
"ghdl", "-r", f"{topDef}", f"{arch}",
f"--wave={os.path.join(libPath, topDef)}-{arch}.ghw" ##, "--read-wave-opt=<See"
]
subprocess.run(command, cwd=libPath)
command = [
"gtkwave", f"{topDef}-{arch}.ghw", "--rcvar",
"do_initial_zoom_fit yes"]
subprocess.run(command, cwd=wavePath)

48
scripts/gantry.py Normal file
View File

@ -0,0 +1,48 @@
import typer
import elab
import build_env
from typing_extensions import Annotated
app = typer.Typer()
software = typer.Typer()
hardware = typer.Typer()
app.add_typer(software, name="sim", help="GHDL simulator command group")
app.add_typer(hardware, name="syn", help="Synthesis and deployment command group")
@software.command(help="Initializes the GHDL build environment in a library named \"work\". Adds all files ending in \".vhd\" to the project")
def init():
return build_env.createBuildEnv()
def complete_vhdl_ver():
return ["87", "93", "93c", "00", "02", "08"]
@software.command(help="Runs analysis and elaboration on the provided top definition and architecture using GHDL. Automatically adds new files not present in the project")
def elab(
topdef: Annotated[str, typer.Argument(help="Top Definition entity to synthesize")] = "",
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 from")] = "work",
std: Annotated[str, typer.Option(help="Which VHDL standard to use. 87, 93, 93c, 00, 02 or 08", autocompletion=complete_vhdl_ver)] = "93c"
):
print(f"Elaborating {topdef} with arch {arch} in library {library}. VHDL {std}")
return elab.elabDesign(topdef, arch, library, std)
@software.command(help="Simulates elaborated design in GHDL and views waves in gtkwave. Automatically runs `gantry elab` on the same top def and arch.")
def run(
topdef: Annotated[str, typer.Argument(help="Top Definition entity to synthesize")] = "",
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 from")] = "work",
std: Annotated[str, typer.Option(help="Which VHDL standard to use. 87, 93, 93c, 00, 02 or 08", autocompletion=complete_vhdl_ver)] = "93c"
):
print(f"Running (and synthesizing if needed) {topdef} with arch {arch} in library {library}. VHDL {std}")
return elab.runDesign(topdef, arch, library, std)
@hardware.command()
def build():
print("Build!")
if __name__ == "__main__":
app()

10
scripts/requirements.txt Normal file
View File

@ -0,0 +1,10 @@
click==8.1.8
markdown-it-py==3.0.0
mdurl==0.1.2
Pygments==2.19.1
rich==13.9.4
setuptools==75.8.0
shellingham==1.5.4
type-extensions==0.1.2
typer==0.15.1
typing_extensions==4.12.2