[lint] Preliminary Verilator/AscentLint lint flows for AES
This patch adds preliminary linting support for Verilator and
AscentLint for the AES module (the lint targets and waiver files will
follow in a subsequent commit).
Support for AscentLint is preliminary, since the flow still requires a
proprietary lint policy file, which is not publicly available. However,
this lint policy will be available soon as a built-in lint policy in the
upcoming 2019.A.p3 release of the tool. The lint waivers will all be
publicly available, and the lint makefile supports a summary report option
that filters out the relevant messages from a batch run. Note that lint
report information must be filtered using this summary report script
before publishing openly.
The Verilator lint waivers are only partially populated at the moment, and
hence this linting flow still throws many warnings and messages. Further,
there is no summary report generation for Verilator lint yet.
Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/hw/ip/aes/aes.core b/hw/ip/aes/aes.core
index 1fe8608..f6f9569 100644
--- a/hw/ip/aes/aes.core
+++ b/hw/ip/aes/aes.core
@@ -24,8 +24,47 @@
- rtl/aes.sv
file_type: systemVerilogSource
+ files_verilator_waiver:
+ depend:
+ # common waivers
+ - lowrisc:lint:common
+ - lowrisc:lint:comportable
+ files:
+ - lint/aes.vlt
+ file_type: vlt
+
+ files_ascentlint_waiver:
+ depend:
+ # common waivers
+ - lowrisc:lint:common
+ - lowrisc:lint:comportable
+ files:
+ - lint/aes.waiver
+ file_type: waiver
+
+
+parameters:
+ SYNTHESIS:
+ datatype: bool
+ paramtype: vlogdefine
+
+
targets:
default: &default_target
filesets:
+ - tool_verilator ? (files_verilator_waiver)
+ - tool_ascentlint ? (files_ascentlint_waiver)
- files_rtl
toplevel: aes
+
+ lint:
+ <<: *default_target
+ default_tool: verilator
+ parameters:
+ - SYNTHESIS=true
+ tools:
+ verilator:
+ mode: lint-only
+ verilator_options:
+ - "-Wall"
+
diff --git a/hw/ip/aes/lint/aes.vlt b/hw/ip/aes/lint/aes.vlt
new file mode 100644
index 0000000..2bd771e
--- /dev/null
+++ b/hw/ip/aes/lint/aes.vlt
@@ -0,0 +1,6 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// waiver file for aes
+
diff --git a/hw/ip/aes/lint/aes.waiver b/hw/ip/aes/lint/aes.waiver
new file mode 100644
index 0000000..47b102d
--- /dev/null
+++ b/hw/ip/aes/lint/aes.waiver
@@ -0,0 +1,5 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+#
+# waiver file for aes
diff --git a/hw/lint/.gitignore b/hw/lint/.gitignore
new file mode 100644
index 0000000..d4d090c
--- /dev/null
+++ b/hw/lint/.gitignore
@@ -0,0 +1,3 @@
+build
+reports
+ascentlint.policy
diff --git a/hw/lint/Makefile b/hw/lint/Makefile
new file mode 100644
index 0000000..78208b5
--- /dev/null
+++ b/hw/lint/Makefile
@@ -0,0 +1,103 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+#
+# Makefile with ascentlint and verilator-lint targets for OpenTitan
+#
+# TODO: currently we cannot support parallel builds since some fusesoc cores
+# define filesets with files outside the current folder (e.g. using relative
+# path prefixes such as "../../"). this can cause collisions between parallel
+# builds since they are not nicely contained within the same folder. This should
+# be solved by reworking the fusesoc core files (especially the top-level one).
+
+CORE_ROOT ?= ../../
+REPORT_DIR ?= reports
+
+IPS ?= ip-aes \
+ ip-alert_handler \
+ ip-flash_ctrl \
+ ip-gpio \
+ ip-hmac \
+ ip-i2c \
+ ip-nmi_gen \
+ ip-padctrl \
+ ip-padring \
+ ip-pinmux \
+ ip-rv_core_ibex \
+ ip-rv_dm \
+ ip-rv_plic_example \
+ ip-rv_timer \
+ ip-spi_device \
+ ip-uart \
+ ip-usbdev \
+ ip-usb_fs_nb_pe \
+ ip-usbuart \
+ tlul-socket_1n \
+ tlul-socket_m1 \
+ tlul-adapter_reg \
+ tlul-adapter_sram \
+ tlul-sram2tlul \
+ systems-top_earlgrey
+
+ips_lint = $(addsuffix _lint, $(IPS))
+ips_vlint = $(addsuffix _vlint, $(IPS))
+
+######################
+# ascentlint targets #
+######################
+
+# lint all discovered targets and make a report
+all: lint
+ $(MAKE) report
+
+lint: clean
+ @echo Discovered lint targets:
+ @echo -e "\n $(patsubst %,%\\n,$(strip $(ips_lint)))"
+ $(MAKE) $(ips_lint)
+
+$(ips_lint):
+ rm -rf build
+ mkdir -p ${REPORT_DIR}
+ -fusesoc --cores-root ${CORE_ROOT} run --target=lint --tool=ascentlint lowrisc:$(subst -,:,$(patsubst %_lint,%,$@))
+ cp build/lowrisc_*$(subst -,_,$(patsubst %_lint,%,$@))*/lint-ascentlint/ascentlint.log ${REPORT_DIR}/$(patsubst %_lint,%,$@).log
+ cp build/lowrisc_*$(subst -,_,$(patsubst %_lint,%,$@))*/lint-ascentlint/ascentlint.rpt ${REPORT_DIR}/$(patsubst %_lint,%,$@).rpt
+
+# creates a (filtered) summary report from all available ascentlint logs/rpts
+# note that lint reports have to be filtered using this script before publishing
+# any information from these reports publicly
+report:
+ rm -f ${REPORT_DIR}/lint_summary.rpt
+ ./gen_report.sh | tee ${REPORT_DIR}/lint_summary.rpt
+
+#####################
+# verilator targets #
+#####################
+
+# lint all discovered targets and make a report
+vall: vlint
+ $(MAKE) vreport
+
+vlint: clean
+ @echo Discovered vlint targets:
+ @echo -e "\n $(patsubst %,%\\n,$(strip $(ips_vlint)))"
+ $(MAKE) $(ips_vlint)
+
+$(ips_vlint):
+ rm -rf build
+ mkdir -p ${REPORT_DIR}
+ -fusesoc --cores-root ${CORE_ROOT} run --target=lint lowrisc:$(subst -,:,$(patsubst %_vlint,%,$@))
+# cp build/lowrisc_*$(patsubst %_vlint,%,$@)*/vlint-verilator/verilator-lint.rpt ${REPORT_DIR}/$@.rpt
+
+# TODO: add a verilator summary report function
+# add a summary report option for verilator
+vreport:
+
+##################
+# common targets #
+##################
+
+clean:
+ rm -rf build
+ rm -rf ${REPORT_DIR}/*
+
+.PHONY: all lint $(ips_lint) report vall vlint $(ips_vlint) clean
diff --git a/hw/lint/common.core b/hw/lint/common.core
new file mode 100644
index 0000000..d620dd0
--- /dev/null
+++ b/hw/lint/common.core
@@ -0,0 +1,24 @@
+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:lint:common:0.1"
+description: "Common waivers"
+filesets:
+ files_verilator:
+ files:
+ - common.vlt
+ file_type: vlt
+
+ files_ascentlint:
+ files:
+ - common.waiver: {file_type: waiver}
+ - ascentlint.policy: {file_type: tclSource}
+
+targets:
+ default: &default_target
+ filesets:
+ - tool_verilator ? (files_verilator)
+ - tool_ascentlint ? (files_ascentlint)
+
+
diff --git a/hw/lint/common.vlt b/hw/lint/common.vlt
new file mode 100644
index 0000000..f0d4d73
--- /dev/null
+++ b/hw/lint/common.vlt
@@ -0,0 +1,6 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// common waiver rules for verilator
+
diff --git a/hw/lint/common.waiver b/hw/lint/common.waiver
new file mode 100644
index 0000000..9e694c6
--- /dev/null
+++ b/hw/lint/common.waiver
@@ -0,0 +1,11 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+#
+# common waiver rules for ascentlint
+
+# waiver for unused_* signals for HIER_* rules (note that our policy file has a
+# similar exception list for rule NOT_READ)
+waive -rules {HIER_NET_NOT_READ HIER_BRANCH_NOT_READ} -pattern {unused_*}
+waive -rules {HIER_NET_NOT_READ HIER_BRANCH_NOT_READ} -pattern {gen_*.unused_*}
+
diff --git a/hw/lint/comportable.core b/hw/lint/comportable.core
new file mode 100644
index 0000000..7a25c75
--- /dev/null
+++ b/hw/lint/comportable.core
@@ -0,0 +1,24 @@
+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:lint:comportable:0.1"
+description: "Waiver files for comportable IPs"
+filesets:
+ files_verilator_waiver:
+ files:
+ - comportable.vlt
+ file_type: vlt
+
+ files_ascentlint_waiver:
+ files:
+ - comportable.waiver
+ file_type: waiver
+
+targets:
+ default: &default_target
+ filesets:
+ - tool_verilator ? (files_verilator_waiver)
+ - tool_ascentlint ? (files_ascentlint_waiver)
+
+
diff --git a/hw/lint/comportable.vlt b/hw/lint/comportable.vlt
new file mode 100644
index 0000000..5da936b
--- /dev/null
+++ b/hw/lint/comportable.vlt
@@ -0,0 +1,6 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+//
+// comportable IP waiver rules for verilator
+
diff --git a/hw/lint/comportable.waiver b/hw/lint/comportable.waiver
new file mode 100644
index 0000000..43ebcfc
--- /dev/null
+++ b/hw/lint/comportable.waiver
@@ -0,0 +1,21 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+#
+# comportable IP waiver rules for ascentlint
+
+# auto-generated register files
+
+waive -rules CONST_FF -location {*_reg_top*} -regexp {rsp_opcode.*is driven by constant zeros} \
+ -comment "makes the code more readable"
+waive -rules CONST_OUTPUT -location {*_reg_top*} -regexp {Output 'tl_o.d_(param|size|sink|user)' is driven by constant} \
+ -comment "makes the code more readable"
+waive -rules INPUT_NOT_READ -location {*_reg_top*} -regexp {Input port.*a_(address|param|user).*not read from} \
+ -comment "several TLUL signals are not used by register file"
+waive -rules HIER_NET_NOT_READ -location {*_reg_top*} -regexp {Net 'tl_reg_h2d.a_(address|param|user).* is not read from} \
+ -comment "several TLUL signals are not used by register file"
+waive -rules CASE_SEL_CONST -location {*_reg_top*} \
+ -comment "addr_hit is one hot encoded."
+waive -rules LINE_LENGTH -location {*_reg_top*} -regexp {Line length of .* exceeds .* character limit} \
+ -comment "These files are one-liners in order to comply with our SV style guide."
+
diff --git a/hw/lint/gen_report.sh b/hw/lint/gen_report.sh
new file mode 100755
index 0000000..2bc452c
--- /dev/null
+++ b/hw/lint/gen_report.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+#
+# Ascentlint report summary generation script.
+#
+
+REPORT_DIR=reports
+
+#-------------------------------------------------------------------------
+# print header
+#-------------------------------------------------------------------------
+printf "NUMBER OF LINT ERRORS PER BLOCK:\n\n"
+format="%20s %10s %10s \n"
+printf "${format}" "Block" "Errors" "Warnings"
+echo "-------------------------------------------"
+
+#-------------------------------------------------------------------------
+# run lint and summarize results
+#-------------------------------------------------------------------------
+rm -Rf build
+
+for report in ${REPORT_DIR}/*.rpt ; do
+
+ # summarize results
+ crash=`grep "Exiting with error status" "${report%.*}.log"`
+ if [[ ! -z "$crash" ]]; then
+ error_cnt="CRASH"
+ warni_cnt="CRASH"
+ else
+ error_cnt=`grep "^E " "${report%.*}.rpt" | wc -l`
+ warni_cnt=`grep "^W " "${report%.*}.rpt" | wc -l`
+ fi
+ printf "${format}" `basename "${report%.*}"` $error_cnt $warni_cnt
+done
+
+echo "-------------------------------------------"
+echo "END SUMMARY"
+
+#-------------------------------------------------------------------------
+# generate detailed reports
+#-------------------------------------------------------------------------
+printf "\n\nLIST OF ERRORS (E) AND WARNINGS (W) FOR EACH BLOCK:"
+for report in ${REPORT_DIR}/*.rpt ; do
+
+ printf "\n\n`basename "${report%.*}"`\n"
+
+ # grep for lint crashes and lint errors, and limit line length
+ grep "^ ERR" -A 2 "${report%.*}.log" | cut -c -200
+ grep "^E " "${report%.*}.rpt" | cut -c -200
+ grep "^W " "${report%.*}.rpt" | cut -c -200
+
+done