diff --git a/tools/verible-scripts/Makefile b/tools/verible-scripts/Makefile new file mode 100644 index 00000000000..b1899a81741 --- /dev/null +++ b/tools/verible-scripts/Makefile @@ -0,0 +1,15 @@ +all: venv env + +# Check for RV_ROOT +ifeq (,$(wildcard ${RV_ROOT}/configs/veer.config)) +$(error env var RV_ROOT does not point to a valid dir! Exiting!) +endif + +venv: + @echo "# Build virtual environment in venv/bin/python" + python3 -m venv venv + +env: + @echo "# Activate venv in a new shell" + @env bash --init-file "$(PWD)/venv/bin/activate" + diff --git a/tools/verible-scripts/README.md b/tools/verible-scripts/README.md new file mode 100644 index 00000000000..5e6dd13f34b --- /dev/null +++ b/tools/verible-scripts/README.md @@ -0,0 +1,39 @@ +# Verible scripts + +Two scripts which simplify usage of [Verible linting and formatting tools](https://github.com/chipsalliance/verible/tree/master/verilog/tools) are provided: +* `verible.py` - finds all files with Verilog/SystemVerilog extensions and executes linter or formatter on them +* `stats_lint.py` - processes logs from the lint stage and creates a report. The report contains statistics of found linting errors, syntax errors and execution commands. + +# Usage + +`Makefile` and BASH script `run.sh` facilitate usage of the Python scripts and are a recommended way of launching them. + +Makefile target `venv` creates a virtual environment with all required Python packages: + +```bash +make venv +``` + +Makefile target `env` launches new shell, where the virtual environment is activated + +```bash +make env +``` + +Export `RV_ROOT` environment variable. Set its value to root of the VeeR-EL2 Core project. + +```bash +export RV_ROOT= +``` + +Run BASH script which calls the `verible.py` script and the `stats_lint.py` script. Logs are captured in `exec_lint.log` and `exec_format.log`. Linting report is saved in `lint.rpt`. + +```bash +bash run.sh +``` + +## Optional commands + +By default, Verible scripts are configured to apply fixes in-place, so `verible.py` script can be used with flag `--restore_git` to git restore all Verilog/SystemVerilog files. + +If you want to only print a list of Verilog/SystemVerilog files in the project, run `verible.py` script with the flag `--only_discover`. diff --git a/tools/verible-scripts/run.sh b/tools/verible-scripts/run.sh new file mode 100755 index 00000000000..6510eba7257 --- /dev/null +++ b/tools/verible-scripts/run.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +echo "[LINT] See exec_lint.log" +python verible.py --tool=lint &> exec_lint.log + +echo "[FORMAT] See exec_format.log" +python verible.py --tool=format &> exec_format.log + +echo "[LINT STATS] See lint.rpt" +python stats_lint.py &> lint.rpt + diff --git a/tools/verible-scripts/stats_lint.py b/tools/verible-scripts/stats_lint.py new file mode 100644 index 00000000000..448c0c4cf22 --- /dev/null +++ b/tools/verible-scripts/stats_lint.py @@ -0,0 +1,41 @@ +from collections import Counter + +error_codes = [] +run_cmds = [] +syntax_errors = [] + +f = open("exec_lint.log", "r") +lines = f.readlines() +for line in lines: + if line in ["", "\n"]: + continue + # Remove [RUN CMD] lines + if line.startswith("[RUN CMD]"): + run_cmds.append(line.strip()) + continue + + # Remove syntax errors + if "syntax error" in line: + syntax_errors.append(line.strip()) + continue + + # Error type is hidden in 2 last square brackets + line = line.split("[") + error_code = "[" + line[-2].strip() + " [" + line[-1].strip() + error_codes.append(error_code) + +dd = dict(Counter(error_codes)) +total = 0 +print("=" * 20 + " Error statistics " + "=" * 20) +for k in dd.keys(): + print(k, dd[k]) + total += dd[k] +print(f"Total = {total}") + +print("=" * 20 + " Syntax errors " + "=" * 20) +for syntax_error in syntax_errors: + print(syntax_error) + +print("=" * 20 + " Used run cmds " + "=" * 20) +for run_cmd in run_cmds: + print(run_cmd) diff --git a/tools/verible-scripts/verible.py b/tools/verible-scripts/verible.py new file mode 100644 index 00000000000..a6ef53dd1ec --- /dev/null +++ b/tools/verible-scripts/verible.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python + +import argparse +import os + + +def main(): + """ + Parse arguments + """ + parser = argparse.ArgumentParser(description="VeeR Coding Standard") + parser.add_argument( + "--only_discover", + action="store_true", + help="Lists all found {.v|.sv|...} files ", + ) + parser.add_argument("--tool", default="lint", help="Select: {format|lint}") + parser.add_argument( + "--restore_git", action="store_true", help="Restore only {.v|.sv|...} files" + ) + parser.add_argument("--linter", default="verible-verilog-lint", help="Tool") + args = parser.parse_args() + + """ + Check if RV_ROOT exists + """ + RV_ROOT = os.getenv("RV_ROOT") + if not RV_ROOT: + raise ValueError("RV_ROOT must be set") + """ + Discover all {v,sv,...} files + """ + paths = [] + file_extensions = [".v", ".vh", ".sv", ".svi", ".svh"] + for root, dirs, files in os.walk(RV_ROOT): + for file in files: + for extension in file_extensions: + if file.endswith(extension): + paths.append(os.path.join(root, file)) + + if args.only_discover: + for path in paths: + print(path) + print("Exiting early; only-discover") + return + + """ + Restore git + """ + if args.restore_git: + for file in paths: + git_cmd = "git restore " + file + print(f"[GIT RESTORE] {git_cmd}") + os.system(git_cmd) + print("Exiting early; git restore") + return + + """ + Run selected verible tool on all files + - Lint https://github.com/chipsalliance/verible/tree/master/verilog/tools/lint + - Format https://github.com/chipsalliance/verible/tree/master/verilog/formatting + """ + if args.tool == "lint": + verible_tool = "verible-verilog-lint " + verible_tool_opts = " --waiver_files=" + RV_ROOT + "/violations.waiver " + verible_tool_opts += " --rules=line-length=length:100 " + verible_tool_opts += " --autofix=inplace " + if args.tool == "format": + verible_tool = "verible-verilog-format " + verible_tool_opts = " --inplace" + + for file in paths: + tool_cmd = verible_tool + verible_tool_opts + " " + file + print(f"[RUN CMD] {tool_cmd}") + os.system(tool_cmd) + + +if __name__ == "__main__": + main()