Skip to content

Commit

Permalink
Implement script to evaluate lint and format compliance
Browse files Browse the repository at this point in the history
The script enables:
 - Running verible-verilog-{lint|format} on all verilog files in Cores-VeeR-EL2
 - Git restoring changed files
 - Saves outputs in .log files
 - Saves error statistics in lint.rpt file
  • Loading branch information
mczyz-antmicro committed Oct 11, 2023
1 parent 9338f04 commit 1cfecaf
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 0 deletions.
15 changes: 15 additions & 0 deletions tools/verible-scripts/Makefile
Original file line number Diff line number Diff line change
@@ -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"

39 changes: 39 additions & 0 deletions tools/verible-scripts/README.md
Original file line number Diff line number Diff line change
@@ -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=<path_to_root_of_project>
```

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`.
11 changes: 11 additions & 0 deletions tools/verible-scripts/run.sh
Original file line number Diff line number Diff line change
@@ -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

41 changes: 41 additions & 0 deletions tools/verible-scripts/stats_lint.py
Original file line number Diff line number Diff line change
@@ -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)
79 changes: 79 additions & 0 deletions tools/verible-scripts/verible.py
Original file line number Diff line number Diff line change
@@ -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()

0 comments on commit 1cfecaf

Please sign in to comment.