Check for supported tool versions

Define supported tool versions in tool_requirements.py, and check them
in a fusesoc run. If an unsupported tool version is found, fusesoc
outputs an error like this:

```
$ fusesoc --cores-root . run --target=lint lowrisc:ibex:ibex_core
INFO: Preparing lowrisc:ibex:check_tool_requirements:0.1
INFO: Preparing lowrisc:prim:assert:0.1
INFO: Preparing lowrisc:ibex:sim_shared:0
INFO: Preparing lowrisc:ibex:ibex_core:0.1
INFO: Setting up project

INFO: Running pre_build script check_tool_requirements
ERROR: verilator is too old: found version 4.010, need at least 4.028
ERROR: Tool requirements not fulfilled. Please update the tools and retry.
ERROR: Failed to build lowrisc:ibex:ibex_core:0.1 : pre_build script 'check_tool_requirements' exited with error code 1
```

The only version checked at this point is Verilator, which is set
somewhat arbitrarily to the version used by me (and I know it works). CI
uses a slightly newer version. As we are about to merge changes soon
which require a newer Verilator version, there's not much point in
finding the oldest supported version right now.
This commit is contained in:
Philipp Wagner 2020-02-11 22:56:00 +00:00 committed by Philipp Wagner
parent db62f5b0c2
commit 3a078865c8
4 changed files with 110 additions and 1 deletions

View file

@ -0,0 +1,31 @@
CAPI=2:
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
name: "lowrisc:ibex:check_tool_requirements:0.1"
description: "Check tool requirements"
filesets:
files_check_tool_requirements:
files:
- ./util/check_tool_requirements.py : { copyto: util/check_tool_requirements.py }
- ./tool_requirements.py : { copyto: tool_requirements.py }
scripts:
check_tool_requirements:
cmd:
- python3
- util/check_tool_requirements.py
# TODO: Use this syntax once https://github.com/olofk/fusesoc/issues/353 is
# fixed. Remove the filesets from the default target, and also remove the
# copyto.
#filesets:
# - files_check_tool_requirements
targets:
default:
filesets:
- files_check_tool_requirements
hooks:
pre_build:
- tool_verilator ? (check_tool_requirements)

View file

@ -4,6 +4,7 @@ CAPI=2:
# SPDX-License-Identifier: Apache-2.0
name: "lowrisc:ibex:ibex_core:0.1"
description: "CPU core with 2 stage pipeline implementing the RV32IMC_Zicsr ISA"
filesets:
files_rtl:
depend:
@ -40,6 +41,10 @@ filesets:
files:
- lint/verilator_waiver.vlt: {file_type: vlt}
files_check_tool_requirements:
depend:
- lowrisc:ibex:check_tool_requirements
parameters:
RVFI:
datatype: bool
@ -73,12 +78,13 @@ targets:
default:
filesets:
- files_rtl
- files_check_tool_requirements
lint:
filesets:
- tool_verilator ? (files_lint_verilator)
- files_rtl
- files_lint
- files_check_tool_requirements
parameters:
- SYNTHESIS=true
- RVFI=true

9
tool_requirements.py Normal file
View file

@ -0,0 +1,9 @@
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
# Version requirements for various tools. Checked by tooling (e.g. fusesoc),
# and inserted into the Sphinx-generated documentation.
__TOOL_REQUIREMENTS__ = {
'verilator': '4.010',
}

63
util/check_tool_requirements.py Executable file
View file

@ -0,0 +1,63 @@
#!/usr/bin/python3
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
from distutils.version import StrictVersion
import logging as log
import os
import subprocess
import sys
# Display INFO log messages and up.
log.basicConfig(level=log.INFO, format="%(levelname)s: %(message)s")
# Populate __TOOL_REQUIREMENTS__
topsrcdir = os.path.join(os.path.dirname(__file__), '..')
exec(open(os.path.join(topsrcdir, 'tool_requirements.py')).read())
def get_verilator_version():
try:
# Note: "verilator" needs to be called through a shell and with all
# arguments in a string, as it doesn't have a shebang, but instead
# relies on perl magic to parse command line arguments.
version_str = subprocess.run('verilator --version', shell=True,
check=True, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True)
return version_str.stdout.split(' ')[1].strip()
except subprocess.CalledProcessError as e:
log.error("Unable to call Verilator to check version: " + str(e))
log.error(e.stdout)
return None
def check_version(tool_name, required_version, actual_version):
if required_version is None or actual_version is None:
return False
if StrictVersion(actual_version) < StrictVersion(required_version):
log.error("%s is too old: found version %s, need at least %s",
tool_name, actual_version, required_version)
return False
else:
log.info("Found sufficiently recent version of %s (found %s, need %s)",
tool_name, actual_version, required_version)
return True
def main():
any_failed = False
if not check_version('verilator', __TOOL_REQUIREMENTS__['verilator'],
get_verilator_version()):
any_failed = True
if any_failed:
log.error("Tool requirements not fulfilled. "
"Please update the tools and retry.")
return 1
return 0
if __name__ == "__main__":
sys.exit(main())