Merge from master for release.
This commit is contained in:
commit
d915745073
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
exclude_paths:
|
||||
- ".github/**"
|
||||
- "ci/build_verilator.sh"
|
||||
- "include/vltstd/**"
|
||||
- "nodist/fastcov.py"
|
||||
- ".github/**" #
|
||||
- "ci/build_verilator.sh" #
|
||||
- "include/vltstd/**" #
|
||||
- "nodist/fastcov.py" #
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
---
|
||||
# DESCRIPTION: codecov.io config
|
||||
#
|
||||
# Copyright 2020-2025 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
####################
|
||||
# Validate:
|
||||
# curl --data-binary @.codecov.yml https://codecov.io/validate
|
||||
#
|
||||
coverage:
|
||||
precision: 2
|
||||
range: 75...100
|
||||
round: down
|
||||
status:
|
||||
project: false
|
||||
patch: false
|
||||
comment: false
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
---
|
||||
name: Bug report
|
||||
about: Use this to report that something isn't working as expected, and it isn't "Unsupported." (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.rst)
|
||||
title: ''
|
||||
labels: new
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Thanks for taking the time to report this.
|
||||
|
||||
Can you attach an example that shows the issue? (Must be openly licensed, completely self-contained and self-checking so can directly run what you provide. Ideally use test_regress format, see https://veripool.org/guide/latest/contributing.html?highlight=test_regress#reporting-bugs
|
||||
|
||||
What 'verilator' command line do we use to run your example?
|
||||
|
||||
What 'verilator --version' are you using? Did you try it with the git master version?
|
||||
|
||||
What OS and distribution are you using?
|
||||
|
||||
May we assist you in trying to fix this in Verilator yourself?
|
||||
|
||||
(Please avoid attaching screenshots that show text - you can convert images to text using e.g. https://ocr.space)
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
---
|
||||
name: Feature Request
|
||||
about: Use this to request something should be supported, or a new feature added. (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.rst)
|
||||
title: ''
|
||||
labels: new
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Thanks for taking the time to report this.
|
||||
|
||||
What would you like added/supported?
|
||||
|
||||
What 'verilator --version' are you using? Did you try it with the git master version?
|
||||
|
||||
Can you attach an example that runs on other simulators? (Must be openly licensed, completely self-contained and self-checking so can directly run what you provide. Ideally use test_regress format, see https://veripool.org/guide/latest/contributing.html?highlight=test_regress#reporting-bugs
|
||||
|
||||
May we assist you in trying to fix this in Verilator yourself?
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
---
|
||||
name: Bug or feature
|
||||
about: Use this to report that something isn't working as expected, or is a desired feature. (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.rst)
|
||||
title: ''
|
||||
labels: new
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
Thanks for taking the time to report this.
|
||||
|
||||
Can you please attach an example that shows the issue or missing feature? (Must be openly licensed, completely self-contained so can directly run what you provide. Ideally use test_regress format, see https://veripool.org/guide/latest/contributing.html?highlight=test_regress#reporting-bugs)
|
||||
|
||||
What output from that test indicates it is wrong, and what is the correct or expected output? (Or, please make test self-checking if possible.)
|
||||
|
||||
What 'verilator' command line do we use to run your example?
|
||||
|
||||
What 'verilator --version' are you using? Did you try it with the git master version? Did you try it with other simulators?
|
||||
|
||||
What OS and distribution are you using?
|
||||
|
||||
May we assist you in trying to fix this in Verilator yourself?
|
||||
|
||||
(Please avoid attaching screenshots that show text - you can convert images to text using e.g. https://ocr.space)
|
||||
|
|
@ -9,4 +9,4 @@ assignees: ''
|
|||
|
||||
How may we help - what is your question?
|
||||
|
||||
(If reporting a bug or requesting a feature please use one of the other issue templates.)
|
||||
(If reporting a bug or requesting a feature please hit BACK on your browser and use a different issue templates.)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
# See https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
|
|
@ -3,10 +3,12 @@
|
|||
# This name is key to badges in README.rst, so we use the name build
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
name: build
|
||||
name: build-test
|
||||
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'dependabot/**' # Avoid duplicates: only run the PR, not the push
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
|
|
@ -17,72 +19,158 @@ permissions:
|
|||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
working-directory: repo
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.actor }}-${{ github.event_name == 'pull_request' && github.ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
# At most 1 job per branch. Auto cancel on pull requests and on all forks
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' || github.repository != 'verilator/verilator' }}
|
||||
|
||||
jobs:
|
||||
|
||||
build-2404-gcc:
|
||||
name: Build
|
||||
name: Build | ${{ matrix.os }} | ${{ matrix.cc }}${{ matrix.asan && ' | asan' || '' }}
|
||||
uses: ./.github/workflows/reusable-build.yml
|
||||
with:
|
||||
sha: ${{ github.sha }}
|
||||
os: ${{ matrix.os }}
|
||||
os-name: linux
|
||||
cc: ${{ matrix.cc }}
|
||||
dev-asan: ${{ matrix.asan }}
|
||||
dev-gcov: 0
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- {os: ubuntu-24.04, cc: gcc}
|
||||
- {os: ubuntu-24.04, cc: gcc, asan: 0}
|
||||
|
||||
build-2404-clang:
|
||||
name: Build
|
||||
name: Build | ${{ matrix.os }} | ${{ matrix.cc }}${{ matrix.asan && ' | asan' || '' }}
|
||||
uses: ./.github/workflows/reusable-build.yml
|
||||
with:
|
||||
sha: ${{ github.sha }}
|
||||
os: ${{ matrix.os }}
|
||||
os-name: linux
|
||||
cc: ${{ matrix.cc }}
|
||||
dev-asan: ${{ matrix.asan }}
|
||||
dev-gcov: 0
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- {os: ubuntu-24.04, cc: clang}
|
||||
- {os: ubuntu-24.04, cc: clang, asan: 1}
|
||||
|
||||
build-2204-gcc:
|
||||
name: Build
|
||||
name: Build | ${{ matrix.os }} | ${{ matrix.cc }}${{ matrix.asan && ' | asan' || '' }}
|
||||
uses: ./.github/workflows/reusable-build.yml
|
||||
with:
|
||||
sha: ${{ github.sha }}
|
||||
os: ${{ matrix.os }}
|
||||
os-name: linux
|
||||
cc: ${{ matrix.cc }}
|
||||
dev-asan: ${{ matrix.asan }}
|
||||
dev-gcov: 0
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- {os: ubuntu-22.04, cc: gcc}
|
||||
- {os: ubuntu-22.04, cc: gcc, asan: 0}
|
||||
|
||||
build-2204-clang:
|
||||
name: Build
|
||||
name: Build | ${{ matrix.os }} | ${{ matrix.cc }}${{ matrix.asan && ' | asan' || '' }}
|
||||
uses: ./.github/workflows/reusable-build.yml
|
||||
with:
|
||||
sha: ${{ github.sha }}
|
||||
os: ${{ matrix.os }}
|
||||
os-name: linux
|
||||
cc: ${{ matrix.cc }}
|
||||
dev-asan: ${{ matrix.asan }}
|
||||
dev-gcov: 0
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- {os: ubuntu-22.04, cc: clang}
|
||||
- {os: ubuntu-22.04, cc: clang, asan: 0}
|
||||
|
||||
build-osx-gcc:
|
||||
name: Build | ${{ matrix.os }} | ${{ matrix.cc }}${{ matrix.asan && ' | asan' || '' }}
|
||||
uses: ./.github/workflows/reusable-build.yml
|
||||
with:
|
||||
sha: ${{ github.sha }}
|
||||
os: ${{ matrix.os }}
|
||||
os-name: osx
|
||||
cc: ${{ matrix.cc }}
|
||||
dev-asan: ${{ matrix.asan }}
|
||||
dev-gcov: 0
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- {os: macos-15, cc: gcc, asan: 0}
|
||||
|
||||
build-osx-clang:
|
||||
name: Build | ${{ matrix.os }} | ${{ matrix.cc }}${{ matrix.asan && ' | asan' || '' }}
|
||||
uses: ./.github/workflows/reusable-build.yml
|
||||
with:
|
||||
sha: ${{ github.sha }}
|
||||
os: ${{ matrix.os }}
|
||||
os-name: osx
|
||||
cc: ${{ matrix.cc }}
|
||||
dev-asan: ${{ matrix.asan }}
|
||||
dev-gcov: 0
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- {os: macos-15, cc: clang, asan: 0}
|
||||
|
||||
build-windows:
|
||||
name: Build | ${{ matrix.os }} | ${{ matrix.cc }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- {os: windows-2025, cc: msvc}
|
||||
env:
|
||||
CI_OS_NAME: win
|
||||
CCACHE_COMPRESS: 1
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_LIMIT_MULTIPLE: 0.95
|
||||
steps:
|
||||
- uses: actions/checkout@v5
|
||||
with:
|
||||
path: repo
|
||||
- name: Cache $CCACHE_DIR
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: msbuild-msvc-cmake
|
||||
- name: compile
|
||||
env:
|
||||
WIN_FLEX_BISON: ${{ github.workspace }}/.ccache
|
||||
run: ./ci/ci-win-compile.ps1
|
||||
- name: test build
|
||||
run: ./ci/ci-win-test.ps1
|
||||
- name: Zip up repository
|
||||
run: Compress-Archive -LiteralPath install -DestinationPath verilator.zip
|
||||
- name: Upload zip archive
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
path: ${{ github.workspace }}/repo/verilator.zip
|
||||
name: verilator-win.zip
|
||||
|
||||
test-2404-gcc:
|
||||
name: Test | ${{ matrix.os }} | ${{ matrix.cc }}
|
||||
name: Test | ${{ matrix.os }} | ${{ matrix.cc }} | ${{ matrix.reloc && 'reloc | ' || '' }} ${{ matrix.suite }}
|
||||
needs: build-2404-gcc
|
||||
uses: ./.github/workflows/reusable-test.yml
|
||||
with:
|
||||
archive: ${{ needs.build-2404-gcc.outputs.archive }}
|
||||
os: ${{ matrix.os }}
|
||||
cc: ${{ matrix.cc }}
|
||||
reloc: ${{ matrix.reloc }}
|
||||
suite: ${{ matrix.suite }}
|
||||
dev-gcov: 0
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
|
@ -97,14 +185,16 @@ jobs:
|
|||
- {os: ubuntu-24.04, cc: gcc, reloc: 0, suite: vltmt-2}
|
||||
|
||||
test-2404-clang:
|
||||
name: Test | ${{ matrix.os }} | ${{ matrix.cc }}
|
||||
name: Test | ${{ matrix.os }} | ${{ matrix.cc }} | ${{ matrix.reloc && 'reloc | ' || '' }} ${{ matrix.suite }}
|
||||
needs: build-2404-clang
|
||||
uses: ./.github/workflows/reusable-test.yml
|
||||
with:
|
||||
archive: ${{ needs.build-2404-clang.outputs.archive }}
|
||||
os: ${{ matrix.os }}
|
||||
cc: ${{ matrix.cc }}
|
||||
reloc: ${{ matrix.reloc }}
|
||||
suite: ${{ matrix.suite }}
|
||||
dev-gcov: 0
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
|
@ -119,14 +209,16 @@ jobs:
|
|||
- {os: ubuntu-24.04, cc: clang, reloc: 0, suite: vltmt-2}
|
||||
|
||||
test-2204-gcc:
|
||||
name: Test | ${{ matrix.os }} | ${{ matrix.cc }}
|
||||
name: Test | ${{ matrix.os }} | ${{ matrix.cc }} | ${{ matrix.reloc && 'reloc | ' || '' }} ${{ matrix.suite }}
|
||||
needs: build-2204-gcc
|
||||
uses: ./.github/workflows/reusable-test.yml
|
||||
with:
|
||||
archive: ${{ needs.build-2204-gcc.outputs.archive }}
|
||||
os: ${{ matrix.os }}
|
||||
cc: ${{ matrix.cc }}
|
||||
reloc: ${{ matrix.reloc }}
|
||||
suite: ${{ matrix.suite }}
|
||||
dev-gcov: 0
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
|
@ -141,14 +233,16 @@ jobs:
|
|||
- {os: ubuntu-22.04, cc: gcc, reloc: 0, suite: vltmt-2}
|
||||
|
||||
test-2204-clang:
|
||||
name: Test | ${{ matrix.os }} | ${{ matrix.cc }}
|
||||
name: Test | ${{ matrix.os }} | ${{ matrix.cc }} | ${{ matrix.reloc && 'reloc | ' || '' }} ${{ matrix.suite }}
|
||||
needs: build-2204-clang
|
||||
uses: ./.github/workflows/reusable-test.yml
|
||||
with:
|
||||
archive: ${{ needs.build-2204-clang.outputs.archive }}
|
||||
os: ${{ matrix.os }}
|
||||
cc: ${{ matrix.cc }}
|
||||
reloc: ${{ matrix.reloc }}
|
||||
suite: ${{ matrix.suite }}
|
||||
dev-gcov: 0
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
|
@ -163,34 +257,30 @@ jobs:
|
|||
- {os: ubuntu-22.04, cc: clang, reloc: 1, suite: vltmt-2}
|
||||
|
||||
lint-py:
|
||||
runs-on: ubuntu-22.04
|
||||
name: Lint Python
|
||||
env:
|
||||
CI_OS_NAME: linux
|
||||
CI_COMMIT: ${{ github.sha }}
|
||||
CI_BUILD_STAGE_NAME: build
|
||||
CI_RUNS_ON: ubuntu-22.04
|
||||
CCACHE_COMPRESS: 1
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_LIMIT_MULTIPLE: 0.95
|
||||
strategy:
|
||||
fail-fast: false
|
||||
uses: ./.github/workflows/reusable-lint-py.yml
|
||||
|
||||
passed:
|
||||
name: Test suite passed
|
||||
if: always()
|
||||
needs:
|
||||
- build-2404-gcc
|
||||
- build-2404-clang
|
||||
- build-2204-gcc
|
||||
- build-2204-clang
|
||||
- build-osx-gcc
|
||||
- build-osx-clang
|
||||
- build-windows
|
||||
- test-2404-gcc
|
||||
- test-2404-clang
|
||||
- test-2204-gcc
|
||||
- test-2204-clang
|
||||
- lint-py
|
||||
|
||||
runs-on: ubuntu-24.04
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
- name: Decide whether the needed jobs succeeded or failed
|
||||
uses: re-actors/alls-green@release/v1
|
||||
with:
|
||||
path: repo
|
||||
|
||||
- name: Install packages for build
|
||||
run: ./ci/ci-install.bash
|
||||
|
||||
# We use specific version numbers, otherwise a Python package
|
||||
# update may add a warning and break our build
|
||||
- name: Install packages for lint
|
||||
run: sudo pip3 install pylint==3.0.2 ruff==0.1.3 clang sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe ruff
|
||||
|
||||
- name: Configure
|
||||
run: autoconf && ./configure --enable-longtests --enable-ccwarn
|
||||
|
||||
- name: Lint
|
||||
run: make -k lint-py
|
||||
jobs: ${{ toJSON(needs) }}
|
||||
|
|
@ -5,6 +5,8 @@
|
|||
name: Contributor Agreement
|
||||
on:
|
||||
push:
|
||||
branches-ignore:
|
||||
- 'dependabot/**' # Avoid duplicates: only run the PR, not the push
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
permissions:
|
||||
|
|
@ -14,5 +16,5 @@ jobs:
|
|||
name: "'docs/CONTRIBUTORS' was signed"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v5
|
||||
- run: test_regress/t/t_dist_contributors.py
|
||||
|
|
|
|||
|
|
@ -2,96 +2,212 @@
|
|||
# DESCRIPTION: Github actions config
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
name: coverage
|
||||
name: Code coverage
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: '0 0 * * 0' # weekly
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened, labeled, unlabeled]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
env:
|
||||
CI_OS_NAME: linux
|
||||
CI_COMMIT: ${{ github.sha }}
|
||||
COVERAGE: 1
|
||||
VERILATOR_ARCHIVE: verilator-coverage-${{ github.sha }}.tar.gz
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
working-directory: repo
|
||||
|
||||
concurrency:
|
||||
# At most 1 job per branch. Auto cancel all but scheduled jobs
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name != 'schedule' }}
|
||||
|
||||
jobs:
|
||||
|
||||
Build:
|
||||
build:
|
||||
name: Build
|
||||
# Only run scheduled jobs if explicitly enabled for that repo (e.g.: not on forks)
|
||||
if: ${{ github.event_name != 'schedule' || vars.ENABLE_SCHEDULED_JOBS == 'true' }}
|
||||
runs-on: ubuntu-24.04
|
||||
env:
|
||||
CI_BUILD_STAGE_NAME: build
|
||||
CI_RUNS_ON: ubuntu-24.04
|
||||
steps:
|
||||
# Only run pull request jobs if labelled as needing an coverage run
|
||||
# Always run workflow dispatch jobs
|
||||
if: |
|
||||
(github.event_name == 'schedule'
|
||||
&& vars.ENABLE_SCHEDULED_JOBS == 'true') ||
|
||||
(github.event_name == 'pull_request'
|
||||
&& contains(github.event.pull_request.labels.*.name, 'pr: dev-coverage')) ||
|
||||
(github.event_name == 'workflow_dispatch')
|
||||
uses: ./.github/workflows/reusable-build.yml
|
||||
with:
|
||||
# For pull requests, build the head of the pull request branch, not the
|
||||
# merge commit, otherwise patch coverage would include the changes
|
||||
# between the root of the pull request and the target branch
|
||||
sha: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.sha || github.sha }}
|
||||
os: ubuntu-24.04
|
||||
os-name: linux
|
||||
cc: gcc
|
||||
dev-asan: 0
|
||||
dev-gcov: 1
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: repo
|
||||
|
||||
- name: Install packages for build
|
||||
run: ./ci/ci-install.bash
|
||||
|
||||
- name: Build
|
||||
run: ./ci/ci-script.bash
|
||||
|
||||
- name: Tar up repository
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: tar --posix -c -z -f ${{ env.VERILATOR_ARCHIVE }} repo
|
||||
|
||||
- name: Upload tar archive
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/${{ env.VERILATOR_ARCHIVE }}
|
||||
name: ${{ env.VERILATOR_ARCHIVE }}
|
||||
|
||||
Test:
|
||||
needs: Build
|
||||
test:
|
||||
name: Test | ${{ matrix.test }}${{ matrix.num }}
|
||||
needs: build
|
||||
uses: ./.github/workflows/reusable-test.yml
|
||||
with:
|
||||
archive: ${{ needs.build.outputs.archive }}
|
||||
os: ubuntu-24.04
|
||||
cc: gcc
|
||||
reloc: 0
|
||||
suite: ${{ matrix.test }}${{ matrix.num }}
|
||||
dev-gcov: 1
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
test: [vlt-, vltmt-]
|
||||
test: [coverage-vlt-, coverage-vltmt-]
|
||||
num: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
include:
|
||||
- {test: dist, num: ''}
|
||||
runs-on: ubuntu-24.04
|
||||
name: test-${{ matrix.test }}${{ matrix.num }}
|
||||
env:
|
||||
CI_BUILD_STAGE_NAME: test
|
||||
CI_RUNS_ON: ubuntu-24.04
|
||||
steps:
|
||||
- {test: coverage-dist, num: ''}
|
||||
|
||||
- name: Download tar archive
|
||||
uses: actions/download-artifact@v4
|
||||
publish-codecov:
|
||||
name: Publish results to codecov.io
|
||||
needs: test
|
||||
if: ${{ contains(needs.*.result, 'success') && !cancelled() }}
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Download code coverage data
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: ${{ env.VERILATOR_ARCHIVE }}
|
||||
pattern: code-coverage-*
|
||||
path: obj_coverage
|
||||
merge-multiple: true
|
||||
|
||||
- name: List files
|
||||
id: list-files
|
||||
run: |
|
||||
ls -lsha obj_coverage
|
||||
find obj_coverage -type f | paste -sd, | sed "s/^/files=/" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload to codecov.io
|
||||
uses: codecov/codecov-action@v5
|
||||
with:
|
||||
disable_file_fixes: true
|
||||
disable_search: true
|
||||
fail_ci_if_error: true
|
||||
files: ${{ steps.list-files.outputs.files }}
|
||||
plugins: noop
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
verbose: true
|
||||
|
||||
prepare-report:
|
||||
name: Prepare HTML report
|
||||
needs: [build, test]
|
||||
if: ${{ contains(needs.*.result, 'success') && !cancelled() }}
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
echo 'set man-db/auto-update false' | sudo debconf-communicate >/dev/null
|
||||
sudo dpkg-reconfigure man-db
|
||||
sudo apt install lcov
|
||||
|
||||
- name: Download repository archive
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: ${{ needs.build.outputs.archive }}
|
||||
path: ${{ github.workspace }}
|
||||
|
||||
- name: Unpack tar archive
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: tar -x -z -f ${{ env.VERILATOR_ARCHIVE }}
|
||||
|
||||
- name: Install test dependencies
|
||||
run: ./ci/ci-install.bash
|
||||
|
||||
- name: Test
|
||||
env:
|
||||
TESTS: coverage-${{ matrix.test }}${{ matrix.num }}
|
||||
run: ./ci/ci-script.bash
|
||||
|
||||
- name: Upload coverage data to Codecov
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
- name: Unpack repository archive
|
||||
run: |
|
||||
find . -name '*.gcno' -exec rm {} \;
|
||||
./ci/codecov -v upload-process -Z --sha ${{ github.sha }} -f nodist/obj_dir/coverage/app_total.info
|
||||
tar -x -z -f ${{ needs.build.outputs.archive }}
|
||||
ls -lsha
|
||||
|
||||
- name: Download code coverage data
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
pattern: code-coverage-*
|
||||
path: repo/obj_coverage
|
||||
merge-multiple: true
|
||||
|
||||
- name: Create report
|
||||
working-directory: repo
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
ls -lsha obj_coverage
|
||||
# Combine reports from test jobs
|
||||
nodist/fastcov.py -C obj_coverage/verilator-*.info --lcov -o obj_coverage/verilator.info
|
||||
# For a PR, report patch coverage against the merge-base between the head of the PR and the target branch
|
||||
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
|
||||
COVERAGE_BASE=$(git rev-parse --short $(git merge-base ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}))
|
||||
make coverage-report COVERAGE_BASE=${COVERAGE_BASE} |& tee ${{ github.workspace }}/make-coverage-report.log
|
||||
else
|
||||
make coverage-report
|
||||
fi
|
||||
# Remove data files
|
||||
rm -f obj_coverage/verilator*.info
|
||||
# Some extra work for PRs only
|
||||
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
|
||||
# Save PR number in report
|
||||
echo ${{ github.event.number }} > obj_coverage/pr-number.txt
|
||||
# Generate notification comment content
|
||||
mkdir -p notification
|
||||
echo ${{ github.event.number }} > notification/pr-number.txt
|
||||
NUM=$(gh run view ${{ github.run_id }} --json number --jq ".number")
|
||||
URL=$(gh run view ${{ github.run_id }} --json url --jq ".url")
|
||||
echo "Patch coverage from PR workflow [#$NUM]($URL) (code coverage of lines changed relative to ${COVERAGE_BASE}):" > notification/body.txt
|
||||
if [[ ! -f obj_coverage/empty-patch ]]; then
|
||||
echo "<pre>" >> notification/body.txt
|
||||
grep -E "(lines|branches)\.*:" ${{ github.workspace }}/make-coverage-report.log | sed "s/\.*:/:/" >> notification/body.txt || true
|
||||
echo "</pre>" >> notification/body.txt
|
||||
echo "Report: [${{ github.run_id }}](https://${{ github.repository_owner }}.github.io/verilator/coverage-reports/${{ github.run_id }}/index.html)" >> notification/body.txt
|
||||
else
|
||||
echo "Patch contains no code changes" >> notification/body.txt
|
||||
fi
|
||||
cat notification/body.txt
|
||||
fi
|
||||
|
||||
- name: Upload report
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
path: repo/obj_coverage
|
||||
name: coverage-report
|
||||
|
||||
- name: Upload notification
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
path: repo/notification
|
||||
name: coverage-pr-notification
|
||||
|
||||
# Create GitHub issue for failed scheduled jobs
|
||||
# This should always be the last job (we want an issue if anything breaks)
|
||||
create-issue:
|
||||
name: Create issue on failure
|
||||
needs: [publish-codecov, prepare-report]
|
||||
if: ${{ github.event_name == 'schedule' && github.repository == 'verilator/verilator' && github.run_attempt == 1 && failure() && !cancelled() }}
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
# Creating issues requires elevated privilege
|
||||
- name: Generate access token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@v2.1.4
|
||||
with:
|
||||
app-id: ${{ vars.VERILATOR_CI_ID }}
|
||||
private-key: ${{ secrets.VERILATOR_CI_KEY }}
|
||||
owner: verilator
|
||||
repositories: verilator
|
||||
permission-issues: write
|
||||
- name: Create issue
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||
run: |-
|
||||
echo "This issue was created automatically by the GitHub Actions CI due to the failure of a scheduled Code coverage run." >> body.txt
|
||||
echo "" >> body.txt
|
||||
echo "Workflow status: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> body.txt
|
||||
gh issue --repo ${{ github.repository }} create \
|
||||
--title "Code coverage run #${{ github.run_number }} Failed" \
|
||||
--body-file body.txt \
|
||||
--label new \
|
||||
--assignee gezalore,wsnyder
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ jobs:
|
|||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
|
||||
- name: Extract context variables
|
||||
run: |
|
||||
|
|
@ -54,7 +54,7 @@ jobs:
|
|||
|
||||
- name: Docker meta
|
||||
id: docker_meta
|
||||
uses: docker/metadata-action@v4
|
||||
uses: docker/metadata-action@v5
|
||||
with:
|
||||
images: |
|
||||
${{ vars.DOCKER_HUB_NAMESPACE }}/${{ env.image_name }}
|
||||
|
|
@ -64,21 +64,21 @@ jobs:
|
|||
type=raw,value=latest,enable=${{ inputs.add_latest_tag == true }}
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v2
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v2
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
buildkitd-flags: --debug
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v2
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_HUB_USER }}
|
||||
password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}
|
||||
|
||||
- name: Build and Push to Docker
|
||||
uses: docker/build-push-action@v4
|
||||
uses: docker/build-push-action@v6
|
||||
if: startsWith(github.ref, 'refs/tags/v') || github.event_name == 'workflow_dispatch'
|
||||
with:
|
||||
context: ${{ env.build_context }}
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@
|
|||
name: format
|
||||
on:
|
||||
push:
|
||||
pull_request_target:
|
||||
workflow_dispatch:
|
||||
branches-ignore:
|
||||
- 'dependabot/**' # Avoid duplicates: only run the PR, not the push
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
format:
|
||||
runs-on: ubuntu-24.04
|
||||
|
|
@ -19,7 +21,7 @@ jobs:
|
|||
CI_COMMIT: ${{ github.sha }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Install packages for build
|
||||
|
|
@ -38,7 +40,7 @@ jobs:
|
|||
make -j 2 format CLANGFORMAT=clang-format-18 &&
|
||||
git status
|
||||
- name: Push
|
||||
run: |
|
||||
run: |-
|
||||
if [ -n "$(git status --porcelain)" ]; then
|
||||
git commit . -m "Apply 'make format'" &&
|
||||
git push origin
|
||||
|
|
|
|||
|
|
@ -1,52 +0,0 @@
|
|||
---
|
||||
# DESCRIPTION: Github actions config
|
||||
# This name is key to badges in README.rst, so we use the name build
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
#
|
||||
name: msbuild
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
workflow_dispatch:
|
||||
schedule:
|
||||
- cron: 0 0 * * 0 # weekly
|
||||
permissions:
|
||||
contents: read
|
||||
env:
|
||||
CI_OS_NAME: win
|
||||
CI_COMMIT: ${{ github.sha }}
|
||||
CCACHE_COMPRESS: 1
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_LIMIT_MULTIPLE: 0.95
|
||||
defaults:
|
||||
run:
|
||||
working-directory: repo
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.actor }}-${{ github.event_name == 'pull_request' && github.ref || github.run_id }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
windows:
|
||||
name: run on windows
|
||||
runs-on: windows-2025
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: repo
|
||||
- name: Cache $CCACHE_DIR
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: msbuild-msvc-cmake
|
||||
- name: compile
|
||||
env:
|
||||
WIN_FLEX_BISON: ${{ github.workspace }}/.ccache
|
||||
run: ./ci/ci-win-compile.ps1
|
||||
- name: test build
|
||||
run: ./ci/ci-win-test.ps1
|
||||
- name: Zip up repository
|
||||
run: Compress-Archive -LiteralPath install -DestinationPath verilator.zip
|
||||
- name: Upload zip archive
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/repo/verilator.zip
|
||||
name: verilator-win.zip
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
---
|
||||
# DESCRIPTION: Github actions config
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
name: Pages
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
paths:
|
||||
- "ci/**"
|
||||
- ".github/workflows"
|
||||
workflow_dispatch:
|
||||
workflow_run:
|
||||
workflows: ["Code coverage"]
|
||||
types: [completed]
|
||||
|
||||
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
|
||||
permissions:
|
||||
contents: read
|
||||
pages: write
|
||||
id-token: write
|
||||
|
||||
# Allow only one concurrent deployment, skipping runs queued between the run
|
||||
# in-progress and latest queued. However, do NOT cancel in-progress runs as we
|
||||
# want to allow these deployments to complete.
|
||||
concurrency:
|
||||
group: "pages"
|
||||
cancel-in-progress: false
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build content
|
||||
runs-on: ubuntu-24.04
|
||||
outputs:
|
||||
coverage-pr-run-ids: ${{ steps.build.outputs.coverage-pr-run-ids }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
- name: Build pages
|
||||
id: build
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
run: |
|
||||
bash -x ./ci/ci-pages.bash
|
||||
ls -lsha
|
||||
tree -L 3 pages
|
||||
- name: Upload pages artifact
|
||||
uses: actions/upload-pages-artifact@v4
|
||||
with:
|
||||
path: pages
|
||||
|
||||
deploy:
|
||||
name: Deploy
|
||||
needs: build
|
||||
runs-on: ubuntu-24.04
|
||||
environment:
|
||||
name: github-pages
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
steps:
|
||||
- name: Deploy to GitHub Pages
|
||||
uses: actions/deploy-pages@v4
|
||||
|
||||
notify:
|
||||
name: Notify
|
||||
needs: [build, deploy]
|
||||
runs-on: ubuntu-24.04
|
||||
if: ${{ github.repository == 'verilator/verilator' }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
# Use the Verilator CI app to post the comment
|
||||
- name: Generate access token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@v2.1.4
|
||||
with:
|
||||
app-id: ${{ vars.VERILATOR_CI_ID }}
|
||||
private-key: ${{ secrets.VERILATOR_CI_KEY }}
|
||||
permission-actions: write
|
||||
permission-pull-requests: write
|
||||
- name: Comment on PR
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||
COVERAGE_PR_RUN_IDS: ${{ needs.build.outputs.coverage-pr-run-ids }}
|
||||
run: bash -x ./ci/ci-pages-notify.bash
|
||||
|
|
@ -7,16 +7,32 @@ name: reusable-build
|
|||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
sha:
|
||||
description: "Commit SHA to build"
|
||||
required: true
|
||||
type: string
|
||||
os: # e.g. ubuntu-24.04
|
||||
required: true
|
||||
type: string
|
||||
cc: # gcc or clang
|
||||
cc: # 'clang' or 'gcc'
|
||||
required: true
|
||||
type: string
|
||||
os-name: # 'linux' or 'osx'
|
||||
required: true
|
||||
type: string
|
||||
dev-asan:
|
||||
required: true
|
||||
type: number
|
||||
dev-gcov:
|
||||
required: true
|
||||
type: number
|
||||
outputs:
|
||||
archive:
|
||||
description: "Name of the built repository archive artifact"
|
||||
value: ${{ jobs.build.outputs.archive }}
|
||||
|
||||
env:
|
||||
CI_OS_NAME: linux
|
||||
CI_COMMIT: ${{ github.sha }}
|
||||
CI_OS_NAME: ${{ inputs.os-name }}
|
||||
CCACHE_COMPRESS: 1
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_LIMIT_MULTIPLE: 0.95
|
||||
|
|
@ -31,22 +47,25 @@ defaults:
|
|||
jobs:
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ${{ inputs.os }}
|
||||
name: Sub-build | ${{ inputs.os }} | ${{ inputs.cc }}
|
||||
outputs:
|
||||
archive: ${{ steps.create-archive.outputs.archive }}
|
||||
env:
|
||||
CI_BUILD_STAGE_NAME: build
|
||||
CI_DEV_ASAN: ${{ inputs.dev-asan }}
|
||||
CI_DEV_GCOV: ${{ inputs.dev-gcov }}
|
||||
CI_RUNS_ON: ${{ inputs.os }}
|
||||
CC: ${{ inputs.cc }}
|
||||
CXX: ${{ inputs.cc == 'clang' && 'clang++' || 'g++' }}
|
||||
CACHE_BASE_KEY: build-${{ inputs.os }}-${{ inputs.cc }}
|
||||
CCACHE_MAXSIZE: 1000M # Per build matrix entry (* 5 = 5000M in total)
|
||||
VERILATOR_ARCHIVE: verilator-${{ github.sha }}-${{ inputs.os }}-${{ inputs.cc }}.tar.gz
|
||||
steps:
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
path: repo
|
||||
ref: ${{ inputs.sha }}
|
||||
fetch-depth: ${{ inputs.dev-gcov && '0' || '1' }} # Coverage flow needs full history
|
||||
|
||||
- name: Cache $CCACHE_DIR
|
||||
uses: actions/cache@v4
|
||||
|
|
@ -54,7 +73,7 @@ jobs:
|
|||
CACHE_KEY: ${{ env.CACHE_BASE_KEY }}-ccache
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ env.CACHE_KEY }}-${{ github.sha }}
|
||||
key: ${{ env.CACHE_KEY }}-${{ inputs.sha }}
|
||||
restore-keys: |
|
||||
${{ env.CACHE_KEY }}-
|
||||
|
||||
|
|
@ -64,12 +83,17 @@ jobs:
|
|||
- name: Build
|
||||
run: ./ci/ci-script.bash
|
||||
|
||||
- name: Tar up repository
|
||||
- name: Create repository archive
|
||||
id: create-archive
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: tar --posix -c -z -f ${{ env.VERILATOR_ARCHIVE }} repo
|
||||
run: |
|
||||
# Name of the archive must be unique based on the build parameters
|
||||
ARCHIVE=verilator-${{ inputs.sha }}-${{ inputs.os }}-${{ inputs.cc }}-${{ inputs.dev-asan }}-${{ inputs.dev-gcov }}.tar.gz
|
||||
tar --posix -c -z -f $ARCHIVE repo
|
||||
echo "archive=$ARCHIVE" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload tar archive
|
||||
uses: actions/upload-artifact@v4
|
||||
- name: Upload repository archive
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
path: ${{ github.workspace }}/${{ env.VERILATOR_ARCHIVE }}
|
||||
name: ${{ env.VERILATOR_ARCHIVE }}
|
||||
path: ${{ github.workspace }}/${{ steps.create-archive.outputs.archive }}
|
||||
name: ${{ steps.create-archive.outputs.archive }}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
---
|
||||
# DESCRIPTION: Github actions config
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
name: reusable-lint-py
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
|
||||
env:
|
||||
CI_OS_NAME: linux
|
||||
CI_BUILD_STAGE_NAME: build
|
||||
CI_RUNS_ON: ubuntu-22.04
|
||||
CCACHE_COMPRESS: 1
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_LIMIT_MULTIPLE: 0.95
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
working-directory: repo
|
||||
|
||||
jobs:
|
||||
|
||||
lint-py:
|
||||
runs-on: ubuntu-22.04
|
||||
name: Sub-lint | Python
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
path: repo
|
||||
|
||||
- name: Install packages for build
|
||||
run: ./ci/ci-install.bash
|
||||
|
||||
# We use specific version numbers, otherwise a Python package
|
||||
# update may add a warning and break our build
|
||||
- name: Install packages for lint
|
||||
run: sudo pip3 install mypy==1.18.2 pylint==3.0.2 ruff==0.1.3 clang sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe ruff
|
||||
|
||||
- name: Configure
|
||||
run: autoconf && ./configure --enable-longtests --enable-ccwarn
|
||||
|
||||
- name: Lint
|
||||
run: make -k lint-py
|
||||
|
|
@ -31,6 +31,9 @@ jobs:
|
|||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
echo "path-exclude /usr/share/doc/*" | sudo tee -a /etc/dpkg/dpkg.cfg.d/01_nodoc
|
||||
echo "path-exclude /usr/share/man/*" | sudo tee -a /etc/dpkg/dpkg.cfg.d/01_nodoc
|
||||
echo "path-exclude /usr/share/info/*" | sudo tee -a /etc/dpkg/dpkg.cfg.d/01_nodoc
|
||||
sudo apt update
|
||||
sudo apt install ccache mold help2man libfl-dev libgoogle-perftools-dev libsystemc-dev
|
||||
|
||||
|
|
@ -42,7 +45,7 @@ jobs:
|
|||
restore-keys: rtlmeter-build-ccache-${{ inputs.runs-on }}-${{ inputs.cc }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
path: repo
|
||||
fetch-depth: 0 # Required for 'git describe' used for 'verilator --version'
|
||||
|
|
@ -65,7 +68,7 @@ jobs:
|
|||
run: tar --posix -c -z -f verilator-rtlmeter.tar.gz install
|
||||
|
||||
- name: Upload Verilator installation archive
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
path: verilator-rtlmeter.tar.gz
|
||||
name: verilator-rtlmeter-${{ inputs.runs-on }}-${{ inputs.cc }}
|
||||
|
|
|
|||
|
|
@ -55,11 +55,14 @@ jobs:
|
|||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
echo "path-exclude /usr/share/doc/*" | sudo tee -a /etc/dpkg/dpkg.cfg.d/01_nodoc
|
||||
echo "path-exclude /usr/share/man/*" | sudo tee -a /etc/dpkg/dpkg.cfg.d/01_nodoc
|
||||
echo "path-exclude /usr/share/info/*" | sudo tee -a /etc/dpkg/dpkg.cfg.d/01_nodoc
|
||||
sudo apt update
|
||||
sudo apt install ccache mold libfl-dev libgoogle-perftools-dev libsystemc-dev
|
||||
|
||||
- name: Download Verilator installation archive
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: verilator-rtlmeter-${{ inputs.runs-on }}-${{ inputs.cc }}
|
||||
|
||||
|
|
@ -77,7 +80,7 @@ jobs:
|
|||
restore-keys: rtlmeter-run-ccache-${{ inputs.runs-on }}-${{ inputs.cc }}-${{ inputs.cases }}-${{ inputs.compileArgs }}
|
||||
|
||||
- name: Checkout RTLMeter
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: "verilator/rtlmeter"
|
||||
path: rtlmeter
|
||||
|
|
@ -89,15 +92,13 @@ jobs:
|
|||
- name: Compile cases
|
||||
working-directory: rtlmeter
|
||||
run: |
|
||||
./rtlmeter run --verbose --cases='${{ inputs.cases }}' --compileArgs='${{ inputs.compileArgs }}' --executeArgs='${{ inputs.executeArgs }}' --nExecute=0
|
||||
# My YAML highlighter sucks, so I put this comment here wiht a phony closing quote mark to make it work: '
|
||||
./rtlmeter run --timeout 60 --verbose --cases='${{inputs.cases}}' --compileArgs='${{inputs.compileArgs}}' --executeArgs='${{inputs.executeArgs}}' --nExecute=0
|
||||
|
||||
- name: Execute cases
|
||||
working-directory: rtlmeter
|
||||
continue-on-error: true # Do not fail on error, so we can at leat save the successful results
|
||||
continue-on-error: true # Do not fail on error, so we can at least save the successful results
|
||||
run: |
|
||||
./rtlmeter run --verbose --cases='${{ inputs.cases }}' --compileArgs='${{ inputs.compileArgs }}' --executeArgs='${{ inputs.executeArgs }}'
|
||||
# My YAML highlighter sucks, so I put this comment here wiht a phony closing quote mark to make it work: '
|
||||
./rtlmeter run --timeout 60 --verbose --cases='${{inputs.cases}}' --compileArgs='${{inputs.compileArgs}}' --executeArgs='${{inputs.executeArgs}}'
|
||||
|
||||
- name: Collate results
|
||||
id: results
|
||||
|
|
@ -114,15 +115,14 @@ jobs:
|
|||
./rtlmeter report --steps '*' --metrics '*' ../results-${{ steps.results.outputs.hash }}.json
|
||||
|
||||
- name: Upload results
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
path: results-${{ steps.results.outputs.hash }}.json
|
||||
name: rtlmeter-results-${{ inputs.tag }}-${{ steps.results.outputs.hash }}
|
||||
name: rtlmeter-${{ inputs.tag }}-results-${{ steps.results.outputs.hash }}
|
||||
overwrite: true
|
||||
retention-days: 2
|
||||
|
||||
- name: Report status
|
||||
working-directory: rtlmeter
|
||||
run: | # This will fail the job if any of the runs failed
|
||||
./rtlmeter run --verbose --cases='${{ inputs.cases }}' --compileArgs='${{ inputs.compileArgs }}' --executeArgs='${{ inputs.executeArgs }}'
|
||||
# My YAML highlighter sucks, so I put this comment here wiht a phony closing quote mark to make it work: '
|
||||
./rtlmeter run --verbose --cases='${{inputs.cases}}' --compileArgs='${{inputs.compileArgs}}' --executeArgs='${{inputs.executeArgs}}'
|
||||
|
|
|
|||
|
|
@ -7,6 +7,10 @@ name: reusable-test
|
|||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
archive:
|
||||
description: "Name of the repository archive artifact from reusable-build"
|
||||
required: true
|
||||
type: string
|
||||
os: # e.g. ubuntu-24.04
|
||||
required: true
|
||||
type: string
|
||||
|
|
@ -19,10 +23,12 @@ on:
|
|||
suite: # e.g. dist-vlt-0
|
||||
required: true
|
||||
type: string
|
||||
dev-gcov:
|
||||
required: true
|
||||
type: number
|
||||
|
||||
env:
|
||||
CI_OS_NAME: linux
|
||||
CI_COMMIT: ${{ github.sha }}
|
||||
CCACHE_COMPRESS: 1
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_LIMIT_MULTIPLE: 0.95
|
||||
|
|
@ -38,27 +44,27 @@ jobs:
|
|||
|
||||
test:
|
||||
runs-on: ${{ inputs.os }}
|
||||
name: Sub-test | ${{ inputs.os }} | ${{ inputs.cc }} | ${{inputs.reloc && 'reloc | ' || '' }} ${{ inputs.suite }}
|
||||
name: Test
|
||||
env:
|
||||
CI_BUILD_STAGE_NAME: test
|
||||
CI_RUNS_ON: ${{ inputs.os }}
|
||||
CI_RELOC: ${{inputs.reloc }}
|
||||
CC: ${{ inputs.cc }}
|
||||
CXX: ${{ inputs.cc == 'clang' && 'clang++' || 'g++' }}
|
||||
CACHE_BASE_KEY: test-${{ inputs.os }}-${{ inputs.cc }}-${{inputs.reloc }}-${{ inputs.suite }}
|
||||
CCACHE_MAXSIZE: 100M # Per build per suite (* 5 * 5 = 2500M in total)
|
||||
VERILATOR_ARCHIVE: verilator-${{ github.sha }}-${{ inputs.os }}-${{ inputs.cc }}.tar.gz
|
||||
steps:
|
||||
|
||||
- name: Download tar archive
|
||||
uses: actions/download-artifact@v4
|
||||
- name: Download repository archive
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: ${{ env.VERILATOR_ARCHIVE }}
|
||||
name: ${{ inputs.archive }}
|
||||
path: ${{ github.workspace }}
|
||||
|
||||
- name: Unpack tar archive
|
||||
- name: Unpack repository archive
|
||||
working-directory: ${{ github.workspace }}
|
||||
run: tar -x -z -f ${{ env.VERILATOR_ARCHIVE }}
|
||||
run: |
|
||||
tar -x -z -f ${{ inputs.archive }}
|
||||
ls -lsha
|
||||
|
||||
- name: Cache $CCACHE_DIR
|
||||
uses: actions/cache@v4
|
||||
|
|
@ -74,6 +80,26 @@ jobs:
|
|||
run: ./ci/ci-install.bash
|
||||
|
||||
- name: Test
|
||||
id: run-test
|
||||
continue-on-error: true
|
||||
env:
|
||||
TESTS: ${{ inputs.suite }}
|
||||
run: ./ci/ci-script.bash
|
||||
|
||||
- name: Combine code coverage data
|
||||
if: ${{ inputs.dev-gcov }}
|
||||
run: |
|
||||
make coverage-combine
|
||||
mv obj_coverage/verilator.info obj_coverage/verilator-${{ inputs.suite }}.info
|
||||
ls -lsha obj_coverage
|
||||
|
||||
- name: Upload code coverage data
|
||||
if: ${{ inputs.dev-gcov }}
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
path: ${{ github.workspace }}/repo/obj_coverage/verilator-${{ inputs.suite }}.info
|
||||
name: code-coverage-${{ inputs.suite }}
|
||||
|
||||
- name: Fail job if a test failed
|
||||
if: ${{ steps.run-test.outcome == 'failure' && !cancelled() }}
|
||||
run: exit 1
|
||||
|
|
|
|||
|
|
@ -0,0 +1,48 @@
|
|||
---
|
||||
# DESCRIPTION: Github actions config
|
||||
# This name is key to badges in README.rst, so we use the name build
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
name: RTLMeter PR results
|
||||
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [RTLMeter]
|
||||
types: [completed]
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
name: Publish
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' }}
|
||||
permissions:
|
||||
actions: read
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Download report
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: rtlmeter-pr-results
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Download PR number
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: pr-number
|
||||
run-id: ${{ github.event.workflow_run.id }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# Use the Verilator CI app to post the comment
|
||||
- name: Generate access token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@v2.1.4
|
||||
with:
|
||||
app-id: ${{ vars.VERILATOR_CI_ID }}
|
||||
private-key: ${{ secrets.VERILATOR_CI_KEY }}
|
||||
permission-pull-requests: write
|
||||
- name: Comment on PR
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||
run: |-
|
||||
ls -la
|
||||
cat report.txt
|
||||
gh pr --repo ${{ github.repository }} comment $(cat pr-number.txt) --body-file report.txt
|
||||
|
|
@ -10,12 +10,7 @@ on:
|
|||
schedule:
|
||||
- cron: '0 2 * * *' # Daily, starting at 02:00 UTC
|
||||
pull_request:
|
||||
types:
|
||||
- opened
|
||||
- synchronize
|
||||
- reopened
|
||||
- labeled
|
||||
- unlabeled
|
||||
types: [opened, synchronize, reopened, labeled, unlabeled]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
|
@ -25,7 +20,8 @@ defaults:
|
|||
shell: bash
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.ref }}
|
||||
# At most 1 job per branch. Auto cancel all but scheduled jobs
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name != 'schedule' }}
|
||||
|
||||
jobs:
|
||||
|
|
@ -78,6 +74,9 @@ jobs:
|
|||
max-parallel: ${{ github.event == 'schedule' && 2 || 7 }}
|
||||
matrix:
|
||||
cases:
|
||||
- "BlackParrot:1x1:*"
|
||||
- "BlackParrot:2x2:*"
|
||||
- "BlackParrot:4x4:*"
|
||||
- "NVDLA:*"
|
||||
- "OpenPiton:1x1:*"
|
||||
- "OpenPiton:2x2:*"
|
||||
|
|
@ -120,6 +119,9 @@ jobs:
|
|||
max-parallel: ${{ github.event == 'schedule' && 2 || 7 }}
|
||||
matrix:
|
||||
cases:
|
||||
- "BlackParrot:1x1:*"
|
||||
- "BlackParrot:2x2:*"
|
||||
- "BlackParrot:4x4:*"
|
||||
- "NVDLA:*"
|
||||
- "OpenPiton:1x1:*"
|
||||
- "OpenPiton:2x2:*"
|
||||
|
|
@ -145,9 +147,37 @@ jobs:
|
|||
- "XuanTie-C906:*"
|
||||
- "XuanTie-C910:*"
|
||||
|
||||
run-gcc-hier:
|
||||
name: Run GCC hier | ${{ matrix.cases }}
|
||||
needs: build-gcc
|
||||
uses: ./.github/workflows/reusable-rtlmeter-run.yml
|
||||
with:
|
||||
tag: gcc-hier
|
||||
runs-on: ubuntu-24.04
|
||||
cc: gcc
|
||||
cases: ${{ matrix.cases }}
|
||||
run-name: "gcc --hierarchical"
|
||||
compileArgs: "--hierarchical"
|
||||
executeArgs: ""
|
||||
strategy:
|
||||
fail-fast: false
|
||||
max-parallel: ${{ github.event == 'schedule' && 2 || 7 }}
|
||||
matrix:
|
||||
cases:
|
||||
- "BlackParrot:1x1:* !-hier"
|
||||
- "BlackParrot:2x2:* !-hier"
|
||||
- "BlackParrot:4x4:* !-hier"
|
||||
- "NVDLA:* !-hier"
|
||||
- "OpenPiton:1x1:* !-hier"
|
||||
- "OpenPiton:2x2:* !-hier"
|
||||
- "OpenPiton:4x4:* !-hier"
|
||||
- "OpenPiton:8x8:* !-hier"
|
||||
- "OpenPiton:16x16:dhry !-hier"
|
||||
- "XuanTie-C910:* !-hier"
|
||||
|
||||
combine-results:
|
||||
name: Combine results
|
||||
needs: [run-gcc, run-clang]
|
||||
needs: [run-gcc, run-clang, run-gcc-hier]
|
||||
# Run if any of the dependencies have run, even if failed.
|
||||
# That is: do not run if all skipped, or the workflow was cancelled.
|
||||
if: ${{ (contains(needs.*.result, 'success') || contains(needs.*.result, 'failure')) && !cancelled() }}
|
||||
|
|
@ -155,12 +185,10 @@ jobs:
|
|||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
tag:
|
||||
- gcc
|
||||
- clang
|
||||
tag: [gcc, clang, gcc-hier]
|
||||
steps:
|
||||
- name: Checkout RTLMeter
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: "verilator/rtlmeter"
|
||||
path: rtlmeter
|
||||
|
|
@ -168,9 +196,9 @@ jobs:
|
|||
working-directory: rtlmeter
|
||||
run: make venv
|
||||
- name: Download all results
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
pattern: rtlmeter-results-${{ matrix.tag }}-*
|
||||
pattern: rtlmeter-${{ matrix.tag }}-results-*
|
||||
path: all-results-${{ matrix.tag }}
|
||||
merge-multiple: true
|
||||
- name: Combine results
|
||||
|
|
@ -178,7 +206,7 @@ jobs:
|
|||
run: |
|
||||
./rtlmeter collate ../all-results-${{ matrix.tag }}/*.json > ../all-results-${{ matrix.tag }}.json
|
||||
- name: Upload combined results
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
path: all-results-${{ matrix.tag }}.json
|
||||
name: all-results-${{ matrix.tag }}
|
||||
|
|
@ -197,20 +225,20 @@ jobs:
|
|||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- name: Download combined results
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
pattern: all-results-*
|
||||
path: results
|
||||
merge-multiple: true
|
||||
- name: Upload published results
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
path: results/*.json
|
||||
name: published-results
|
||||
# Pushing to verilator/verilator-rtlmeter-results requires elevated permissions
|
||||
- name: Generate access token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@v2.0.6
|
||||
uses: actions/create-github-app-token@v2.1.4
|
||||
with:
|
||||
app-id: ${{ vars.VERILATOR_CI_ID }}
|
||||
private-key: ${{ secrets.VERILATOR_CI_KEY }}
|
||||
|
|
@ -218,7 +246,7 @@ jobs:
|
|||
repositories: verilator-rtlmeter-results
|
||||
permission-contents: write
|
||||
- name: Checkout verilator-rtlmeter-results
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: "verilator/verilator-rtlmeter-results"
|
||||
token: ${{ steps.generate-token.outputs.token }}
|
||||
|
|
@ -242,55 +270,121 @@ jobs:
|
|||
git commit -m "Verilator CI: Results of 'RTLMeter' workflow run #${{ github.run_number }}"
|
||||
git push origin
|
||||
|
||||
#publish-pr-results:
|
||||
# name: Publish results to Pull Request
|
||||
# needs: combine-results
|
||||
# if: ${{ github.event_name == 'pull_request' && github.repository == 'verilator/verilator' && github.run_attempt == 1 && contains(needs.*.result, 'success') && !cancelled() }}
|
||||
# runs-on: ubuntu-24.04
|
||||
# steps:
|
||||
# - name: Checkout RTLMeter
|
||||
# uses: actions/checkout@v4
|
||||
# with:
|
||||
# repository: "verilator/rtlmeter"
|
||||
# path: rtlmeter
|
||||
# - name: Setup RTLMeter venv
|
||||
# working-directory: rtlmeter
|
||||
# run: make venv
|
||||
# - name: Download combined results
|
||||
# uses: actions/download-artifact@v4
|
||||
# with:
|
||||
# pattern: all-results-*
|
||||
# path: all-results
|
||||
# merge-multiple: true
|
||||
# - name: Get scheduled run info
|
||||
# id: scheduled-info
|
||||
# run:
|
||||
# IDLATEST=$(gh run list --workflow RTLMeter --event schedule --status success --limit 1 --json databaseId --jq ".[0].databaseId")
|
||||
# echo "id=$IDLATEST" >> $GITHUB_OUTPUT
|
||||
# URL=$(gh run view $IDLATEST --json url --jq ".url")
|
||||
# echo "url=$URL" >> $GITHUB_OUTPUT
|
||||
# NUM=$(gh run view $IDLATEST --json number --jq ".number")
|
||||
# echo "num=$NUM" >> $GITHUB_OUTPUT
|
||||
# # Fetching artifacts from different workflow requires elevated privilege
|
||||
# - name: Generate access token
|
||||
# id: generate-token
|
||||
# uses: actions/create-github-app-token@v2.0.6
|
||||
# with:
|
||||
# app-id: ${{ vars.VERILATOR_CI_ID }}
|
||||
# private-key: ${{ secrets.VERILATOR_CI_KEY }}
|
||||
# owner: verilator
|
||||
# repositories: verilator
|
||||
# permission-actions: read
|
||||
# - name: Download scheduled run results
|
||||
# uses: actions/download-artifact@v4
|
||||
# with:
|
||||
# name: published-results
|
||||
# path: nightly-results
|
||||
# run-id: ${{ steps.schedueld-info.outputs.id }}
|
||||
# github-token: ${{ steps.generate-token.outputs.token }}
|
||||
# # TODO: diff and present
|
||||
prepare-pr-results:
|
||||
name: Prepare Pull Request results
|
||||
needs: combine-results
|
||||
if: ${{ github.event_name == 'pull_request' && github.repository == 'verilator/verilator' && contains(needs.*.result, 'success') && !cancelled() }}
|
||||
runs-on: ubuntu-24.04
|
||||
permissions:
|
||||
actions: read
|
||||
steps:
|
||||
- name: Checkout RTLMeter
|
||||
uses: actions/checkout@v5
|
||||
with:
|
||||
repository: "verilator/rtlmeter"
|
||||
path: rtlmeter
|
||||
- name: Setup RTLMeter venv
|
||||
working-directory: rtlmeter
|
||||
run: make venv
|
||||
- name: Download combined results
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
pattern: all-results-*
|
||||
path: all-results
|
||||
merge-multiple: true
|
||||
- name: Get scheduled run info
|
||||
id: scheduled-info
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
ID=$(gh run --repo ${{ github.repository }} list --workflow RTLMeter --event schedule --status success --limit 1 --json databaseId --jq ".[0].databaseId")
|
||||
echo "id=$ID" >> $GITHUB_OUTPUT
|
||||
URL=$(gh run --repo ${{ github.repository }} view $ID --json url --jq ".url")
|
||||
echo "url=$URL" >> $GITHUB_OUTPUT
|
||||
NUM=$(gh run --repo ${{ github.repository }} view $ID --json number --jq ".number")
|
||||
echo "num=$NUM" >> $GITHUB_OUTPUT
|
||||
DATE=$(gh run --repo ${{ github.repository }} view $ID --json createdAt --jq ".createdAt")
|
||||
echo "date=$DATE" >> $GITHUB_OUTPUT
|
||||
- name: Download scheduled run results
|
||||
uses: actions/download-artifact@v6
|
||||
with:
|
||||
name: published-results
|
||||
path: nightly-results
|
||||
run-id: ${{ steps.scheduled-info.outputs.id }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Compare results
|
||||
working-directory: rtlmeter
|
||||
run: |
|
||||
for tag in gcc clang gcc-hier; do
|
||||
ADATA=../nightly-results/all-results-${tag}.json
|
||||
BDATA=../all-results/all-results-${tag}.json
|
||||
touch ../verilate-${tag}.txt
|
||||
touch ../execute-${tag}.txt
|
||||
touch ../cppbuild-${tag}.txt
|
||||
if [[ ! -e $ADATA ]]; then
|
||||
continue
|
||||
fi
|
||||
./rtlmeter compare --cases '* !Example:* !*:hello' --steps "verilate" --metrics "elapsed memory" $ADATA $BDATA > ../verilate-${tag}.txt
|
||||
cat ../verilate-${tag}.txt
|
||||
./rtlmeter compare --cases '* !Example:* !*:hello' --steps "execute" --metrics "speed memory elapsed" $ADATA $BDATA > ../execute-${tag}.txt
|
||||
cat ../execute-${tag}.txt
|
||||
./rtlmeter compare --cases '* !Example:* !*:hello' --steps "cppbuild" --metrics "elapsed memory cpu codeSize" $ADATA $BDATA > ../cppbuild-${tag}.txt
|
||||
cat ../cppbuild-${tag}.txt
|
||||
done
|
||||
- name: Create report
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -x
|
||||
NUM=$(gh run --repo ${{ github.repository }} view ${{ github.run_id }} --json number --jq ".number")
|
||||
URL=$(gh run --repo ${{ github.repository }} view ${{ github.run_id }} --json url --jq ".url")
|
||||
echo -n "Performance metrics for PR workflow [#$NUM]($URL) (B) compared to scheduled run" > report.txt
|
||||
echo -n " [#${{ steps.scheduled-info.outputs.num }}](${{ steps.scheduled-info.outputs.url }}) (A)" >> report.txt
|
||||
echo " from ${{ steps.scheduled-info.outputs.date }}" >> report.txt
|
||||
for tag in gcc clang gcc-hier; do
|
||||
echo "" >> report.txt
|
||||
if [[ $tag == "gcc" ]]; then
|
||||
echo "<details open>" >> report.txt
|
||||
else
|
||||
echo "<details>" >> report.txt
|
||||
fi
|
||||
echo -n "<summary><strong><em>" >> report.txt
|
||||
jq -rj ".[0].runName" all-results/all-results-${tag}.json >> report.txt
|
||||
echo "</em></strong></summary>" >> report.txt
|
||||
awk -v RS= -v tag=${tag} '{print > sprintf("frag-%02d-verilate-%s.txt",NR,tag)}' verilate-${tag}.txt
|
||||
awk -v RS= -v tag=${tag} '{print > sprintf("frag-%02d-execute-%s.txt" ,NR,tag)}' execute-${tag}.txt
|
||||
awk -v RS= -v tag=${tag} '{print > sprintf("frag-$02d-cppbuild-%s.txt",NR,tag)}' cppbuild-${tag}.txt
|
||||
for f in $(ls -1 frag-*-verilate-${tag}.txt | sort) $(ls -1 frag-*-execute-${tag}.txt | sort) $(ls -1 frag-*-cppbuild-${tag}.txt | sort); do
|
||||
if [[ $f == frag-01-verilate-${tag}.txt || $f == frag-01-execute-${tag}.txt ]]; then
|
||||
echo "<details open>" >> report.txt
|
||||
else
|
||||
echo "<details>" >> report.txt
|
||||
fi
|
||||
echo -n "<summary>" >> report.txt
|
||||
head -n 1 $f | tr -d '\n' >> report.txt
|
||||
echo "</summary>" >> report.txt
|
||||
echo '<pre>' >> report.txt
|
||||
tail -n +2 $f >> report.txt
|
||||
echo '</pre>' >> report.txt
|
||||
echo "</details>" >> report.txt
|
||||
done
|
||||
echo "</details>" >> report.txt
|
||||
done
|
||||
cat report.txt
|
||||
- name: Upload report
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
path: report.txt
|
||||
name: rtlmeter-pr-results
|
||||
- name: Save PR number
|
||||
run: echo ${{ github.event.number }} > pr-number.txt
|
||||
- name: Upload PR number
|
||||
uses: actions/upload-artifact@v5
|
||||
with:
|
||||
path: pr-number.txt
|
||||
name: pr-number
|
||||
|
||||
# Create GitHub issue for failed schedueld jobs
|
||||
# Create GitHub issue for failed scheduled jobs
|
||||
# This should always be the last job (we want an issue if anything breaks)
|
||||
create-issue:
|
||||
name: Create issue on failure
|
||||
|
|
@ -301,7 +395,7 @@ jobs:
|
|||
# Creating issues requires elevated privilege
|
||||
- name: Generate access token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@v2.0.6
|
||||
uses: actions/create-github-app-token@v2.1.4
|
||||
with:
|
||||
app-id: ${{ vars.VERILATOR_CI_ID }}
|
||||
private-key: ${{ secrets.VERILATOR_CI_KEY }}
|
||||
|
|
@ -311,7 +405,7 @@ jobs:
|
|||
- name: Create issue
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||
run: |
|
||||
run: |-
|
||||
echo "This issue was created automatically by the GitHub Actions CI due to the failure of a scheduled RTLMeter run." >> body.txt
|
||||
echo "" >> body.txt
|
||||
echo "Workflow status: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" >> body.txt
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ verilator_coverage_bin*
|
|||
/.vscode/
|
||||
/.idea/
|
||||
/cmake-build-*/
|
||||
/obj_coverage/
|
||||
/test_regress/snapshot/
|
||||
xmverilog.*
|
||||
xrun.history
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ cmake_minimum_required(VERSION 3.15)
|
|||
cmake_policy(SET CMP0091 NEW) # Use MSVC_RUNTIME_LIBRARY to select the runtime
|
||||
project(
|
||||
Verilator
|
||||
VERSION 5.040
|
||||
VERSION 5.042
|
||||
HOMEPAGE_URL https://verilator.org
|
||||
LANGUAGES CXX
|
||||
)
|
||||
|
|
@ -49,8 +49,13 @@ if(WIN32)
|
|||
if(DEFINED ENV{WIN_FLEX_BISON})
|
||||
set(WIN_FLEX_BISON "$ENV{WIN_FLEX_BISON}")
|
||||
endif()
|
||||
if(EXISTS ${WIN_FLEX_BISON})
|
||||
if(IS_DIRECTORY ${WIN_FLEX_BISON})
|
||||
list(APPEND CMAKE_PREFIX_PATH ${WIN_FLEX_BISON})
|
||||
else()
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"The path specified by WIN_FLEX_BISON environment variable is not an existing folder: ${WIN_FLEX_BISON}"
|
||||
)
|
||||
endif()
|
||||
if(NOT WIN_FLEX_BISON)
|
||||
message(
|
||||
|
|
|
|||
125
Changes
125
Changes
|
|
@ -8,6 +8,131 @@ The changes in each Verilator version are described below. The
|
|||
contributors that suggested or implemented a given issue are shown in []. Thanks!
|
||||
|
||||
|
||||
Verilator 5.042 2025-11-02
|
||||
==========================
|
||||
|
||||
**Other:**
|
||||
|
||||
* Add HIERPARAM error on hierarchical parameter values (#1626) (#6456) (#6484) (#6587) (#6609) (#6621) (#6623). [Todd Strader] [Luca Rufer] [Paul Swirhun]
|
||||
* Add error on zero/negative unpacked dimensions (#1642). [Stefan Wallentowitz]
|
||||
* Add verilator_gantt profiling of DPI imports (#3084). [Geza Lore]
|
||||
* Add ASSIGNEQEXPR when use `=` inside expressions (#5567). [Ethan Sifferman]
|
||||
* Add error on non-packed struct randc (#5999). [Seth Pellegrino]
|
||||
* Add configure `--enable-dev-asan` to compile verilator_bin with the address sanitizer (#6404). [Geza Lore]
|
||||
* Add $(LDFLAGS) and $(LIBS) to when building shared libraries (#6425) (#6426). [Ahmed El-Mahmoudy]
|
||||
* Add IMPLICITSTATIC also on procedure variables.
|
||||
* Add FUNCTIMCTL error on function invoking task or time-controlling statements (#6385).
|
||||
* Add error on `virtual new` (#6486). [Alex Solomatnikov]
|
||||
* Add error on ranges with tristate values (#6534). [Alex Solomatnikov]
|
||||
* Add NORETURN warning on functions without return values (#6534). [Alex Solomatnikov]
|
||||
* Add `--aslr` and `--no-aslr` options.
|
||||
* Add `$cpure` (#6580). [Igor Zaworski, Antmicro Ltd.]
|
||||
* Add `--preproc-defines`.
|
||||
* Deprecate sensitivity list on public_flat_rw attributes (#6443). [Geza Lore]
|
||||
* Deprecate clocker attribute and --clk option (#6463). [Geza Lore]
|
||||
* Deprecate '--make cmake' option (#6540). [Geza Lore]
|
||||
* Change default `--expand-limit` to 256 (#3419).
|
||||
* Change developer coverage flow and add configure `--enable-dev-gcov` (#6526). [Geza Lore]
|
||||
* Change `verilator_difftree` to return exit code 1 on mismatch, 2 on error.
|
||||
* Change default thread pool sizes to respect processor affinity (#6604). [Geza Lore]
|
||||
* Change `--preproc-comments` to be new name of `--pp-comments` option.
|
||||
* Support modports referencing clocking blocks (#4555) (#6436). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Support class package reference on pattern keys (#5653). [Todd Strader]
|
||||
* Support digits in `$sscanf` field width formats (#6083). [Iztok Jeras]
|
||||
* Support pure functions in sensitivity lists (#6393). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Support simple alias statements (#6339) (#6501). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Support simple cycle delay sequence expressions inside properties (#6508). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Support impure expressions in `inside` (#6562). [Igor Zaworski, Antmicro Ltd.]
|
||||
* Support `case` impure expressions (#6563). [Igor Zaworski, Antmicro Ltd.]
|
||||
* Support dotted access to ports of a direct hier_block instance. (#6595). [Geza Lore]
|
||||
* Improve `lint_off` to allow multiple messages and comments (#2755).
|
||||
* Improve automatic selection of logic for DFG synthesis (#6370). [Geza Lore]
|
||||
* Improve `covergroup with function sample` handling (#6387). [Jakub Wasilewski]
|
||||
* Improve DFG type system (#6390). [Geza Lore]
|
||||
* Improve DFG variable removal and temporary insertion (#6401). [Geza Lore]
|
||||
* Improve memory usage of statistics (#6513). [Geza Lore]
|
||||
* Improve conditional merging to preserve branch prediction. [Geza Lore]
|
||||
* Optimize duplicate 'if' and '?:' conditions (#3807) (#6495)
|
||||
* Optimize dead functions in more cases (#6380) (#6430). [Artur Bieniek, Antmicro Ltd.]
|
||||
* Optimize constant folding in wide expression expansion (#6381). [Geza Lore]
|
||||
* Fix `--trace-max-width` and increase to 4096. (#2385).
|
||||
* Fix missing BLKSEQ when connecting module port to array (#2973).
|
||||
* Fix LATCH warning with CASEINCOMPLETE (#3301).
|
||||
* Fix unused parameterized class causing internal error (#4013). [Alberto Del Rio]
|
||||
* Fix false CONSTVAR error on initializers (#4992).
|
||||
* Fix hierarchical references with parameterized modules and interfaces (#5649) (#6566). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix interface exposure with `--public-depth` or `--trace-depth` (#5758).
|
||||
* Fix cell scoping performance (#6059). [Jerry Tianchen]
|
||||
* Fix hierarchical `--prof-pgo` (#6213). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Fix while loop hang on timing-delayed assignment (#6343) (#6354). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix driver analysis of partially assigned variables (#6364) (#6378). [Geza Lore]
|
||||
* Fix V3Hash MacOS ambiguity (#6350). [Lan Zongwei]
|
||||
* Fix cmake APPLE variable (#6351). [Lan Zongwei]
|
||||
* Fix randomize local after parameters applied (#6371). [Alex Solomatnikov]
|
||||
* Fix package imports not found after parameters applied (#6373). [Alex Solomatnikov]
|
||||
* Fix deep shift pattern performance (#6379) (#6420). [Geza Lore]
|
||||
* Fix COVERAGEIGN-ignored `get_inst_coverage` and other covergroup methods (#6383). [Alex Solomatnikov]
|
||||
* Fix error when modport variable is unresolved (#6386). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix resolving parameters (#6388) (#6418) (#6421) (#6438) (#6429). [Artur Bieniek, Antmicro Ltd.]
|
||||
* Fix wire array with initial assignment (#6391). [Alex Solomatnikov]
|
||||
* Fix import of class with default params (#6396) (#6410) (#6413). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix use after free in elaboration (#6403). [Geza Lore]
|
||||
* Fix address sanitizer issues (#6406). [Geza Lore]
|
||||
* Fix timing control under fork under function (#6407). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix memory leaks and reduce requirements (#6411) (#6417) (#6419) (#6437) (#6439) (#6517). [Geza Lore]
|
||||
* Fix parameter implicit type from string (#6414). [Alex Solomatnikov]
|
||||
* Fix parsing for sequence expressions (#6427). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Fix parameterized class super functions (#6431) (#6438). [Artur Bieniek, Antmicro Ltd.]
|
||||
* Fix external function declarations with class typedef references (#6433).
|
||||
* Fix internal error on out-of-bounds real array access.
|
||||
* Fix pre/post increments in assertions (#6434).
|
||||
* Fix elaboration displays with `%m` and some `%p` (#6445) (#6451). [Alex Solomatnikov]
|
||||
* Fix cast in gdbinit.py (#6447). [Artur Bieniek, Antmicro Ltd.]
|
||||
* Fix false unique assertions on `else ;` (#6450). [Don Owen]
|
||||
* Fix loss of clock attribute in DFG variable removal (#6453). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Fix data types of method calls without parenthesis (#6457). [Artur Bieniek, Antmicro Ltd.]
|
||||
* Fix segfault on unsupported PLI calls (#6458). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix false assertion failure on failed DFG driver tracing (#6459). [Geza Lore]
|
||||
* Fix side effects when using select (#6460). [Igor Zaworski, Antmicro Ltd.]
|
||||
* Fix timeprecision backward assignment (#6469). [Artur Bieniek, Antmicro Ltd.]
|
||||
* Fix splitting hierarchically referenced variables (#6475). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix Windows compilation of Verilator with spaces in the path (#6477). [Fabian Keßler-Schulz]
|
||||
* Fix PROTOTYPEMIS error on implicit logic (#6482). [Alex Solomatnikov]
|
||||
* Fix configure misdetecting C++14 (#6488) (#6515). [Thomas O'Keeffe]
|
||||
* Fix false BLKSEQ on non-edged sensitivity list (#6492). [Oron Port]
|
||||
* Fix .vlt public_flat* and others to support long identifier names (#6516). [Szymon Gizler, Antmicro Ltd.]
|
||||
* Fix always_ff on constants (#6519). [Todd Strader]
|
||||
* Fix fault on operations on uninitialized strings (#6520). [Artur Bieniek, Antmicro Ltd.]
|
||||
* Fix find_index methods of associative arrays (#6525). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix parsing of `eventually[]` and property expression memory leaks (#6530). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Fix memory leak for unsupported `$past` (#6535). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Fix inconsistent force assignment (#6541). [Artur Bieniek, Antmicro Ltd.]
|
||||
* Fix DFG circular driver tracing with partial assignments. [Geza Lore]
|
||||
* Fix passing typedef value as parameter (#6543) (#6547). [Igor Zaworski, Antmicro Ltd.]
|
||||
* Fix indent error on quoted strings (#6544).
|
||||
* Fix incorrect nested interface-class error (#6549). [Matthew Ballance]
|
||||
* Fix std::process::get_randstate to not affect random stability (#6550) (#6565). [Aleksander Kiryk]
|
||||
* Fix exit code signal number reporting (#6554). [Artur Bieniek, Antmicro Ltd.]
|
||||
* Fix `$finish` inside fork blocks (#6555). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Fix single element unpacked array DPI parameters. [Geza Lore]
|
||||
* Fix DFG synthesis non-determinism (#6557) (#6568). [Todd Strader]
|
||||
* Fix side effects for improved function/task/process purity (#6559). [Igor Zaworski, Antmicro Ltd.]
|
||||
* Fix excessive logic replication in DFG circular driver tracing (#6561) (#6594). [Geza Lore]
|
||||
* Fix hierarchical with parameterized instances under hier block (#6572). [Geza Lore]
|
||||
* Fix segfault on type casts (#6574). [David Moberg]
|
||||
* Fix references to interfaces containing generate blocks (#6579). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix missing net type mappings in FST traces (#6582) (#6583). [Matt Stroud]
|
||||
* Fix function call expression coverage (#6589). [Todd Strader]
|
||||
* Fix V3Life eliminating assignments across timing controls (#6593) (#6596). [Geza Lore]
|
||||
* Fix incorrectly resuming process waiting on multiple events (#6597). [Geza Lore]
|
||||
* Fix `--hierarchical` with `--binary` (#6602). [Geza Lore]
|
||||
* Fix mis-ignoring virtual interface member triggers (#5116 reopened) (#6613). [Geza Lore]
|
||||
* Fix ENUMVALUE warning when overriding parameter using `-G/-pvalue` options. [Geza Lore]
|
||||
* Fix `-G` and `-pvalue` with `--hierarchical`. [Geza Lore]
|
||||
* Fix waiving messages with empty contents (#6610). [Yoshitomo KANEDA]
|
||||
* Fix constant-arrayed instance parameters (#6614). [Alex Solomatnikov]
|
||||
|
||||
|
||||
Verilator 5.040 2025-08-30
|
||||
==========================
|
||||
|
||||
|
|
|
|||
182
Makefile.in
182
Makefile.in
|
|
@ -91,6 +91,7 @@ datarootdir = @datarootdir@
|
|||
# Compile options
|
||||
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
|
||||
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
|
||||
CFG_WITH_DEV_GCOV = @CFG_WITH_DEV_GCOV@
|
||||
CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
|
||||
CFG_WITH_SOLVER = @CFG_WITH_SOLVER@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
|
|
@ -185,7 +186,7 @@ test-snap test-diff:
|
|||
|
||||
examples: all_nomsg
|
||||
for p in $(EXAMPLES) ; do \
|
||||
$(MAKE) -C $$p VERILATOR_ROOT=`pwd` || exit 10; \
|
||||
$(MAKE) -C $$p VERILATOR_ROOT=`pwd` || exit 10; \
|
||||
done
|
||||
|
||||
######################################################################
|
||||
|
|
@ -275,7 +276,7 @@ mkbindirs:
|
|||
installbin: | mkbindirs
|
||||
cd $(srcdir)/bin; \
|
||||
for p in $(VL_INST_PUBLIC_SCRIPT_FILES) ; do \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
|
||||
done
|
||||
perl -p -i -e 'use File::Spec;' \
|
||||
-e' $$path = File::Spec->abs2rel("$(realpath $(DESTDIR)$(pkgdatadir))", "$(realpath $(DESTDIR)$(bindir))");' \
|
||||
|
|
@ -283,11 +284,11 @@ installbin: | mkbindirs
|
|||
-- "$(DESTDIR)/$(bindir)/verilator"
|
||||
cd bin; \
|
||||
for p in $(VL_INST_PUBLIC_BIN_FILES) ; do \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p; \
|
||||
done
|
||||
cd $(srcdir)/bin; \
|
||||
for p in $(VL_INST_PRIVATE_SCRIPT_FILES) ; do \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkgdatadir)/bin/$$p; \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkgdatadir)/bin/$$p; \
|
||||
done
|
||||
|
||||
installredirect: installbin | mkbindirs
|
||||
|
|
@ -297,7 +298,7 @@ installredirect: installbin | mkbindirs
|
|||
-e 's/RELPATH.*/"$$path";/g' -- "${srcdir}/bin/redirect.tmp"
|
||||
cd $(srcdir)/bin; \
|
||||
for p in $(VL_INST_PUBLIC_SCRIPT_FILES) $(VL_INST_PUBLIC_BIN_FILES) ; do \
|
||||
$(INSTALL_PROGRAM) redirect.tmp $(DESTDIR)$(pkgdatadir)/bin/$$p; \
|
||||
$(INSTALL_PROGRAM) redirect.tmp $(DESTDIR)$(pkgdatadir)/bin/$$p; \
|
||||
done
|
||||
rm ${srcdir}/bin/redirect.tmp
|
||||
|
||||
|
|
@ -306,14 +307,14 @@ installredirect: installbin | mkbindirs
|
|||
installman: $(VL_INST_MAN_FILES)
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man1
|
||||
for p in $^ ; do \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(mandir)/man1/$$p; \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(mandir)/man1/$$p; \
|
||||
done
|
||||
|
||||
installdata:
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/include/gtkwave
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/include/vltstd
|
||||
for p in $(VL_INST_INC_BLDDIR_FILES) ; do \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
|
||||
done
|
||||
cd $(srcdir) \
|
||||
; for p in $(VL_INST_INC_SRCDIR_FILES) ; do \
|
||||
|
|
@ -472,7 +473,7 @@ format-c clang-format:
|
|||
|| echo "*** You are not using clang-format-18, indents may differ from master's ***"
|
||||
$(CLANGFORMAT) $(CLANGFORMAT_FLAGS) $(CLANGFORMAT_FILES)
|
||||
|
||||
YAMLFIX = YAMLFIX_WHITELINES=1 YAMLFIX_LINE_LENGTH=130 YAMLFIX_preserve_quotes=true yamlfix
|
||||
YAMLFIX = YAMLFIX_WHITELINES=1 YAMLFIX_LINE_LENGTH=200 YAMLFIX_preserve_quotes=true yamlfix
|
||||
|
||||
yamlfix:
|
||||
$(YAMLFIX) .
|
||||
|
|
@ -515,7 +516,6 @@ PY_PROGRAMS = \
|
|||
test_regress/*.py \
|
||||
test_regress/t/*.pf \
|
||||
nodist/clang_check_attributes \
|
||||
nodist/code_coverage \
|
||||
nodist/dot_importer \
|
||||
nodist/fuzzer/actual_fail \
|
||||
nodist/fuzzer/generate_dictionary \
|
||||
|
|
@ -525,7 +525,6 @@ PY_PROGRAMS = \
|
|||
# Python files, subject to format but not lint
|
||||
PY_FILES = \
|
||||
$(PY_PROGRAMS) \
|
||||
nodist/code_coverage.dat \
|
||||
test_regress/t/*.py \
|
||||
|
||||
# Python files, test_regress tests
|
||||
|
|
@ -552,6 +551,9 @@ format-make:
|
|||
|
||||
format-yaml: yamlfix
|
||||
|
||||
MYPY = mypy
|
||||
MYPY_FLAGS = --strict --no-error-summary
|
||||
|
||||
PYLINT = pylint
|
||||
PYLINT_FLAGS = --recursive=n --score=n --disable=R0801
|
||||
PYLINT_TEST_FLAGS = $(PYLINT_FLAGS) --disable=C0103,C0114,C0116,C0209,C0411,C0413,C0301,R0801,R0912,R0915,R0916,R1702,W0511,W0621
|
||||
|
|
@ -561,7 +563,16 @@ RUFF_FLAGS = check --ignore=E402,E501,E701
|
|||
|
||||
# "make -k" so can see all tool result errors
|
||||
lint-py:
|
||||
$(MAKE) -k lint-py-pylint lint-py-pylint-tests lint-py-ruff
|
||||
$(MAKE) -k lint-py-mypy lint-py-mypy-none lint-py-pylint lint-py-pylint-tests lint-py-ruff
|
||||
|
||||
lint-py-mypy:
|
||||
for filename in `fgrep -l '# mypy' $(PY_PROGRAMS)`; do \
|
||||
echo "$(MYPY) $(MYPY_FLAGS) $$filename" ; \
|
||||
$(MYPY) $(MYPY_FLAGS) $$filename ; \
|
||||
done
|
||||
|
||||
lint-py-mypy-none:
|
||||
@echo "mypy not checking: " `fgrep -L '# mypy' $(PY_PROGRAMS)`
|
||||
|
||||
lint-py-pylint:
|
||||
$(PYLINT) $(PYLINT_FLAGS) $(PY_PROGRAMS)
|
||||
|
|
@ -597,6 +608,149 @@ else
|
|||
autoconf
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
# Coverage collection and reporting
|
||||
|
||||
COVERAGE_DIR := obj_coverage
|
||||
|
||||
ifeq ($(CFG_WITH_DEV_GCOV),yes)
|
||||
|
||||
# Figure out base and head refs for coverage report
|
||||
COVERAGE_REF_BASE := $(if $(COVERAGE_BASE),$(shell git rev-parse --short $(COVERAGE_BASE)))
|
||||
COVERAGE_REF_HEAD := $(shell git rev-parse --short HEAD)
|
||||
override undefine COVERAGE_BASE # Use the above variabels instead
|
||||
|
||||
# 'fastcov' setup
|
||||
FASTCOV := nodist/fastcov.py
|
||||
FASTCOV_OPT := -j $(shell nproc)
|
||||
FASTCOV_OPT += --lcov
|
||||
FASTCOV_OPT += --process-gcno
|
||||
FASTCOV_OPT += --branch-coverage
|
||||
FASTCOV_OPT += --dump-statistic
|
||||
# Files matching the following glob patterns will be excluded from coverage
|
||||
FASTCOV_OPT += --exclude-glob
|
||||
FASTCOV_OPT += '/usr/*'
|
||||
FASTCOV_OPT += '*examples/*'
|
||||
FASTCOV_OPT += '*include/gtkwave/*'
|
||||
FASTCOV_OPT += '*src/obj_dbg/*'
|
||||
FASTCOV_OPT += '*src/obj_opt/*.yy.cpp'
|
||||
FASTCOV_OPT += '*src/obj_opt/V3Ast*'
|
||||
FASTCOV_OPT += '*src/obj_opt/V3Dfg*'
|
||||
FASTCOV_OPT += '*src/obj_opt/V3ParseBison.c'
|
||||
FASTCOV_OPT += '*test_regress/*'
|
||||
# Lines *containing* these substrings will be excluded from *all* coverage
|
||||
FASTCOV_OPT += --custom-exclusion-marker
|
||||
FASTCOV_OPT += ASTGEN_MEMBERS
|
||||
FASTCOV_OPT += ERROR_RSVD_WORD
|
||||
FASTCOV_OPT += LCOV_EXCL_LINE
|
||||
FASTCOV_OPT += V3ERROR_NA
|
||||
FASTCOV_OPT += VL_DEFINE_DEBUG_FUNCTIONS
|
||||
FASTCOV_OPT += VL_FATAL
|
||||
FASTCOV_OPT += VL_RTTI_IMPL
|
||||
FASTCOV_OPT += VL_UNREACHABLE
|
||||
FASTCOV_OPT += v3fatalSrc
|
||||
# Lines *starting* with these substrings will be ecluded from *branch* coverage
|
||||
FASTCOV_OPT += --exclude-br-lines-starting-with
|
||||
FASTCOV_OPT += BROKEN_BASE_RTN
|
||||
FASTCOV_OPT += BROKEN_RTN
|
||||
FASTCOV_OPT += NUM_ASSERT
|
||||
FASTCOV_OPT += SELF_CHECK
|
||||
FASTCOV_OPT += UASSERT
|
||||
FASTCOV_OPT += UINFO
|
||||
FASTCOV_OPT += assert
|
||||
FASTCOV_OPT += 'if (VL_UNCOVERABLE'
|
||||
FASTCOV_OPT += '} else if (VL_UNCOVERABLE'
|
||||
|
||||
# 'genhtml' setup
|
||||
GENHTML := genhtml
|
||||
GENHTML_OPT := -j $(shell nproc)
|
||||
GENHTML_OPT += --branch-coverage
|
||||
GENHTML_OPT += --demangle-cpp
|
||||
GENHTML_OPT += --missed
|
||||
GENHTML_OPT += --rc branch_coverage=1
|
||||
GENHTML_OPT += --rc genhtml_hi_limit=100
|
||||
GENHTML_OPT += --ignore-errors negative
|
||||
ifeq ($(COVERAGE_REF_BASE),)
|
||||
GENHTML_OPT += --header-title "Code coverage for Verilator $(shell git describe --dirty)"
|
||||
else
|
||||
GENHTML_OPT += --header-title "Patch coverage for Verilator $(COVERAGE_REF_BASE)..$(COVERAGE_REF_HEAD)$(if $(shell git status --porcelain),-dirty)"
|
||||
endif
|
||||
GENHTML_OPT += --flat
|
||||
GENHTML_OPT += --precision 2
|
||||
GENHTML_OPT += --legend
|
||||
GENHTML_OPT += --show-proportion
|
||||
GENHTML_OPT += --filter brace,blank,range
|
||||
|
||||
# There are loads (~20k combined), but using this seems fine on modern hardware
|
||||
GCNO_FILES = $(shell find . -name '*.gcno')
|
||||
GCDA_FILES = $(shell find . -name '*.gcda')
|
||||
|
||||
# Combine all .gcda coverage date files into lcov .info file
|
||||
$(COVERAGE_DIR)/verilator.info: $(GCNO_FILES) $(GCDA_FILES)
|
||||
@echo "####################################################################"
|
||||
@echo "# fastcov: combining all .gcda files into lcov .info"
|
||||
@echo "####################################################################"
|
||||
@mkdir -p $(COVERAGE_DIR)
|
||||
/usr/bin/time -f "That took %E" \
|
||||
$(FASTCOV) $(FASTCOV_OPT) --output $@
|
||||
|
||||
# Filter combined .info file for patch coverage
|
||||
$(COVERAGE_DIR)/verilator-patch.info: $(COVERAGE_DIR)/verilator.info
|
||||
@echo "####################################################################"
|
||||
@echo "# fastcov: Filtering for patch coverage"
|
||||
@echo "####################################################################"
|
||||
rm -f $(COVERAGE_DIR)/empty-patch
|
||||
git diff $(COVERAGE_REF_BASE) -- include src > $(COVERAGE_DIR)/filter.patch
|
||||
[ -s $(COVERAGE_DIR)/filter.patch ]] || touch $(COVERAGE_DIR)/empty-patch
|
||||
$(FASTCOV) -C $^ --lcov -o $@ --diff-filter $(COVERAGE_DIR)/filter.patch
|
||||
|
||||
# Build coverage report
|
||||
$(COVERAGE_DIR)/report/index.html: $(COVERAGE_DIR)/verilator$(if $(COVERAGE_REF_BASE),-patch).info
|
||||
@echo "####################################################################"
|
||||
@echo "# genhtml: Generating coverage report"
|
||||
@echo "####################################################################"
|
||||
@rm -rf $(COVERAGE_DIR)/report
|
||||
[ -f $(COVERAGE_DIR)/empty-patch ]] || /usr/bin/time -f "That took %E" \
|
||||
$(GENHTML) $(GENHTML_OPT) --output-directory $(COVERAGE_DIR)/report $^ || true
|
||||
@# Uncommitted changes not tracked, force rebuild on next run if patch coverage
|
||||
@$(if $(COVERAGE_REF_BASE),mv $(COVERAGE_DIR)/verilator-patch.info $(COVERAGE_DIR)/verilator-patch-last.info)
|
||||
|
||||
# Convenience targets
|
||||
.PHONY: coverage-combine
|
||||
coverage-combine: $(COVERAGE_DIR)/verilator.info
|
||||
|
||||
# Via recursive make, so the message is always printed
|
||||
.PHONY: coverage-report
|
||||
coverage-report:
|
||||
@$(MAKE) --no-print-directory $(COVERAGE_DIR)/report/index.html || true
|
||||
@if [ -f $(COVERAGE_DIR)/report/index.html ]; then \
|
||||
echo "####################################################################"; \
|
||||
echo "# Coverage report is at: $(COVERAGE_DIR)/report/index.html"; \
|
||||
echo "# Use 'make coverage-view' to open it in your default browser"; \
|
||||
echo "####################################################################"; \
|
||||
elif [ -f $(COVERAGE_DIR)/empty-patch ]; then \
|
||||
echo "####################################################################"; \
|
||||
echo "# Patch is empty"; \
|
||||
echo "####################################################################"; \
|
||||
else \
|
||||
echo "####################################################################"; \
|
||||
echo "# Failed to create coverage report. Maybe no data, or error?"; \
|
||||
echo "####################################################################"; \
|
||||
false; \
|
||||
fi
|
||||
|
||||
# Open covarage report in default web browser
|
||||
.PHONY: coverage-view
|
||||
coverage-view: coverage-report
|
||||
@test -f $(COVERAGE_DIR)/report/index.html && open $(COVERAGE_DIR)/report/index.html || true
|
||||
|
||||
# Deletes all coverage data files (.gcda)
|
||||
.PHONY: coverage-zero
|
||||
coverage-zero: # 'rm $(GCDA_FILES)' might fail with too many args
|
||||
$(FASTCOV) --zerocounters
|
||||
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
# Clean
|
||||
|
||||
|
|
@ -607,8 +761,8 @@ maintainer-clean::
|
|||
|
||||
clean mostlyclean distclean maintainer-clean maintainer-copy::
|
||||
for dir in $(SUBDIRS); do \
|
||||
echo making $@ in $$dir ; \
|
||||
$(MAKE) -C $$dir $@ ; \
|
||||
echo making $@ in $$dir ; \
|
||||
$(MAKE) -C $$dir $@ ; \
|
||||
done
|
||||
|
||||
clean mostlyclean distclean maintainer-clean::
|
||||
|
|
@ -622,7 +776,7 @@ clean mostlyclean distclean maintainer-clean::
|
|||
rm -rf src/*.tidy include/*.tidy examples/*/*.tidy
|
||||
rm -rf .ruff_cache
|
||||
rm -rf nodist/fuzzer/dictionary
|
||||
rm -rf nodist/obj_dir
|
||||
rm -rf $(COVERAGE_DIR)
|
||||
rm -rf verilator.txt
|
||||
|
||||
distclean maintainer-clean::
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ Welcome to Verilator
|
|||
* - **Widely Used**
|
||||
* Wide industry and academic deployment
|
||||
* Out-of-the-box support from Arm and RISC-V vendor IP
|
||||
* Over 700 contributors
|
||||
- |verilator usage|
|
||||
* - |verilator community|
|
||||
- **Community Driven & Openly Licensed**
|
||||
|
|
@ -137,6 +138,9 @@ Related Projects
|
|||
- `Icarus Verilog`_ - Icarus is a highly-featured interpreted Verilog
|
||||
simulator. If Verilator does not support your needs, perhaps Icarus may.
|
||||
|
||||
- `Surfer <https://surfer-project.org/>`_ - Web or offline waveform viewer
|
||||
for Verilator traces.
|
||||
|
||||
|
||||
Open License
|
||||
============
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ autoflush STDOUT 1;
|
|||
autoflush STDERR 1;
|
||||
|
||||
$Debug = 0;
|
||||
my $opt_aslr;
|
||||
my $opt_gdb;
|
||||
my $opt_rr;
|
||||
my $opt_gdbbt;
|
||||
|
|
@ -56,6 +57,7 @@ if (! GetOptions(
|
|||
"debug" => \&debug,
|
||||
# "version!" => \&version, # Also passthru'ed
|
||||
# Switches
|
||||
"aslr!" => \$opt_aslr,
|
||||
"gdb!" => \$opt_gdb,
|
||||
"gdbbt!" => \$opt_gdbbt,
|
||||
"quiet!" => \$opt_quiet_exit, # As -quiet implies -quiet-exit
|
||||
|
|
@ -97,7 +99,7 @@ my @quoted_sw = map { sh_escape($_) } @Opt_Verilator_Sw;
|
|||
if ($opt_gdb) {
|
||||
# Generic GDB interactive
|
||||
run (ulimit_stack_unlimited()
|
||||
. aslr_off()
|
||||
. aslr(0)
|
||||
. ($ENV{VERILATOR_GDB} || "gdb")
|
||||
. " " . verilator_bin()
|
||||
# Note, uncomment to set breakpoints before running:
|
||||
|
|
@ -114,13 +116,13 @@ if ($opt_gdb) {
|
|||
} elsif ($opt_rr) {
|
||||
# Record with rr
|
||||
run (ulimit_stack_unlimited()
|
||||
. aslr_off()
|
||||
. aslr(0)
|
||||
. "rr record " . verilator_bin()
|
||||
. " " . join(' ', @quoted_sw));
|
||||
} elsif ($opt_gdbbt && $Debug) {
|
||||
# Run under GDB to get gdbbt
|
||||
run (ulimit_stack_unlimited()
|
||||
. aslr_off()
|
||||
. aslr(0)
|
||||
. "gdb"
|
||||
. " " . verilator_bin()
|
||||
. " --batch --quiet --return-child-result"
|
||||
|
|
@ -135,19 +137,19 @@ if ($opt_gdb) {
|
|||
);
|
||||
|
||||
run (ulimit_stack_unlimited()
|
||||
. aslr_off()
|
||||
. aslr(0)
|
||||
. $valgrind_bin
|
||||
. " " . verilator_bin()
|
||||
. " " . join(' ', @quoted_sw));
|
||||
} elsif ($Debug) {
|
||||
# Debug
|
||||
run(ulimit_stack_unlimited()
|
||||
. aslr_off()
|
||||
. aslr(0)
|
||||
. verilator_bin()
|
||||
. " " . join(' ', @quoted_sw));
|
||||
} else {
|
||||
# Normal, non gdb
|
||||
run(ulimit_stack_unlimited() . verilator_bin() . " " . join(' ', @quoted_sw));
|
||||
run(ulimit_stack_unlimited() . aslr(1) . verilator_bin() . " " . join(' ', @quoted_sw));
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
|
@ -192,21 +194,37 @@ sub gdb_works {
|
|||
return $status == 0;
|
||||
}
|
||||
|
||||
sub aslr_off {
|
||||
my $ok = `setarch --addr-no-randomize echo ok 2>/dev/null` || "";
|
||||
if ($ok =~ /ok/) {
|
||||
return "setarch --addr-no-randomize ";
|
||||
} else {
|
||||
return "";
|
||||
sub aslr {
|
||||
my $want_on = shift;
|
||||
$want_on = $opt_aslr if defined $opt_aslr;
|
||||
if (!$want_on) {
|
||||
my $ok = `setarch --addr-no-randomize echo ok 2>/dev/null` || "";
|
||||
if ($ok =~ /ok/) {
|
||||
return "setarch --addr-no-randomize ";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
sub ulimit_stack_unlimited {
|
||||
return "" if !$opt_unlimited_stack;
|
||||
system("ulimit -s unlimited 2>/dev/null");
|
||||
my $limit = "unlimited";
|
||||
# AddressSanitizer doesn't work with 'ulimit -s unlimted'
|
||||
if (`${\(verilator_bin())} --get-supported DEV_ASAN` eq "1\n") {
|
||||
# Use host 'physical memory / #cores / 8' instead
|
||||
open(my $fh, "<", "/proc/meminfo") || die "Can't read host memory for asan";
|
||||
while (<$fh>) {
|
||||
if (m/MemTotal:\s+(\d+)\s+kB/) {
|
||||
$limit = int(int($1)/`nproc`/8);
|
||||
last;
|
||||
}
|
||||
}
|
||||
close($fh);
|
||||
}
|
||||
system("ulimit -s $limit 2>/dev/null");
|
||||
my $status = $?;
|
||||
if ($status == 0) {
|
||||
return "ulimit -s unlimited 2>/dev/null; exec ";
|
||||
return "ulimit -s $limit 2>/dev/null; exec ";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
|
@ -227,17 +245,18 @@ sub run {
|
|||
warn "%Error: export VERILATOR_ROOT=" . ($ENV{VERILATOR_ROOT} || "") . "\n";
|
||||
warn "%Error: $command\n";
|
||||
}
|
||||
if ($status & 127) {
|
||||
if (($status & 127) == 4 # SIGILL
|
||||
|| ($status & 127) == 8 # SIGFPA
|
||||
|| ($status & 127) == 11) { # SIGSEGV
|
||||
my $signal = ($status & 127);
|
||||
if ($signal) {
|
||||
if ($signal == 4 # SIGILL
|
||||
|| $signal == 8 # SIGFPA
|
||||
|| $signal == 11) { # SIGSEGV
|
||||
warn "%Error: Verilator internal fault, sorry. "
|
||||
. "Suggest trying --debug --gdbbt\n" if !$Debug;
|
||||
} elsif (($status & 127) == 6) { # SIGABRT
|
||||
} elsif ($signal == 6) { # SIGABRT
|
||||
warn "%Error: Verilator aborted. "
|
||||
. "Suggest trying --debug --gdbbt\n" if !$Debug;
|
||||
} else {
|
||||
warn "%Error: Verilator threw signal $status. "
|
||||
warn "%Error: Verilator threw signal $signal. "
|
||||
. "Suggest trying --debug --gdbbt\n" if !$Debug;
|
||||
}
|
||||
}
|
||||
|
|
@ -245,8 +264,8 @@ sub run {
|
|||
warn "%Error: Command Failed $command\n";
|
||||
}
|
||||
exit $! if $!; # errno
|
||||
exit $? >> 8 if $? >> 8; # child exit status
|
||||
exit 255; # last resort
|
||||
exit $? >> 8 if $? >> 8; # pass along child exit code
|
||||
exit 128 + $signal; # last resort
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -311,6 +330,7 @@ detailed descriptions of these arguments.
|
|||
+1800-2012ext+<ext> Use SystemVerilog 2012 with file extension <ext>
|
||||
+1800-2017ext+<ext> Use SystemVerilog 2017 with file extension <ext>
|
||||
+1800-2023ext+<ext> Use SystemVerilog 2023 with file extension <ext>
|
||||
--no-aslr Disable address space layout randomization
|
||||
--no-assert Disable all assertions
|
||||
--no-assert-case Disable unique/unique0/priority-case assertions
|
||||
--autoflush Flush streams after all $displays
|
||||
|
|
@ -322,8 +342,6 @@ detailed descriptions of these arguments.
|
|||
--build-jobs <jobs> Parallelism for --build
|
||||
--cc Create C++ output
|
||||
-CFLAGS <flags> C++ compiler arguments for makefile
|
||||
--clk <signal-name> Mark specified signal as clock
|
||||
--no-clk <signal-name> Prevent marking specified signal as clock
|
||||
--compiler <compiler-name> Tune for specified C++ compiler
|
||||
--compiler-include Include additional header in the precompiled one
|
||||
--converge-limit <loops> Tune convergence settle time
|
||||
|
|
@ -352,6 +370,7 @@ detailed descriptions of these arguments.
|
|||
--dump-defines Show preprocessor defines with -E
|
||||
--dump-dfg Enable dumping DfgGraphs to .dot files
|
||||
--dump-graph Enable dumping V3Graphs to .dot files
|
||||
--dump-inputs Enable dumping preprocessed input files
|
||||
--dump-tree Enable dumping Ast .tree files
|
||||
--dump-tree-addrids Use short identifiers instead of addresses
|
||||
--dump-tree-dot Enable dumping Ast .tree.dot debug files
|
||||
|
|
@ -382,7 +401,9 @@ detailed descriptions of these arguments.
|
|||
--getenv <var> Get environment variable with defaults
|
||||
--help Show this help
|
||||
--hierarchical Enable hierarchical Verilation
|
||||
--hierarchical-params-file <name> Internal option that specifies parameters file for hier blocks
|
||||
--hierarchical-block <block> Internal use only for --hierarchical
|
||||
--hierarchical-child <block> Internal use only for --hierarchical
|
||||
--hierarchical-params-file <name> Internal option that specifies parameters file for hier blocks
|
||||
--hierarchical-threads <threads> Number of threads for hierarchical scheduling
|
||||
-I<dir> Directory to search for includes
|
||||
--if-depth <value> Tune IFDEPTH warning
|
||||
|
|
@ -400,6 +421,7 @@ detailed descriptions of these arguments.
|
|||
-LDFLAGS <flags> Linker pre-object arguments for makefile
|
||||
--lib-create <name> Create a DPI library
|
||||
+libext+<ext>+[ext]... Extensions for finding modules
|
||||
+librescan Ignored for compatibility
|
||||
--lint-only Lint, but do not make output
|
||||
--localize-max-size <value> Tune localize optimization variable size
|
||||
--main Generate C++ main() file
|
||||
|
|
@ -414,6 +436,8 @@ detailed descriptions of these arguments.
|
|||
+notimingchecks Ignored
|
||||
-o <executable> Name of final executable
|
||||
-O0 Disable optimizations
|
||||
-O1 Default optimizations
|
||||
-O2 Stronger optimizations
|
||||
-O3 High-performance optimizations
|
||||
-O<optimization-letter> Selectable optimizations
|
||||
--output-groups <numfiles> Group .cpp files into larger ones
|
||||
|
|
@ -429,8 +453,9 @@ detailed descriptions of these arguments.
|
|||
--pins-uint8 Specify types for top-level ports
|
||||
--no-pins64 Don't use uint64_t's for 33-64 bit sigs
|
||||
--pipe-filter <command> Filter all input through a script
|
||||
--pp-comments Show preprocessor comments with -E
|
||||
--prefix <topname> Name of top-level class
|
||||
--preproc-comments Include preprocessor comments in the output with -E
|
||||
--preproc-defines Include preprocessor defines in the output with -E
|
||||
--preproc-resolve Include all found modules in the output with -E
|
||||
--preproc-token-limit Maximum tokens on a line allowed by preprocessor
|
||||
--private Debugging; see docs
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
# mypy: disallow-untyped-defs
|
||||
# pylint: disable=C0103,C0114,C0115,C0116,C0123,C0209,C0301,R0902,R0913,R0914,R0912,R0915,W0621
|
||||
######################################################################
|
||||
|
||||
|
|
@ -36,7 +37,7 @@ results = {}
|
|||
elapsed = {}
|
||||
|
||||
|
||||
def toDateTime(s):
|
||||
def toDateTime(s: str) -> datetime:
|
||||
return datetime.strptime(s, "%Y-%m-%dT%H:%M:%S.%f")
|
||||
|
||||
|
||||
|
|
@ -53,6 +54,7 @@ for logfile in args.logdir.iterdir():
|
|||
match = re.match(r'\[(\S+)\s.*Result: (.*)$', line)
|
||||
if match:
|
||||
assert obj is not None
|
||||
assert start is not None
|
||||
elapsed[obj] = toDateTime(match.group(1)) - start
|
||||
results[obj] = match.group(2)
|
||||
|
||||
|
|
|
|||
|
|
@ -118,21 +118,24 @@ sub run {
|
|||
warn "%Error: export VERILATOR_ROOT=" . ($ENV{VERILATOR_ROOT} || "") . "\n";
|
||||
warn "%Error: $command\n";
|
||||
}
|
||||
if ($status & 127) {
|
||||
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
|
||||
my $signal = ($status & 127);
|
||||
if ($signal) {
|
||||
if ($signal == 4 # SIGILL
|
||||
|| $signal == 8 # SIGFPA
|
||||
|| $signal == 11) { # SIGSEGV
|
||||
warn "%Error: Verilator_coverage internal fault, sorry.\n" if !$Debug;
|
||||
} elsif (($status & 127) == 6) { # SIGABRT
|
||||
} elsif ($signal == 6) { # SIGABRT
|
||||
warn "%Error: Verilator_coverage aborted.\n" if !$Debug;
|
||||
} else {
|
||||
warn "%Error: Verilator_coverage threw signal $status.\n" if !$Debug;
|
||||
warn "%Error: Verilator_coverage threw signal $signal.\n" if !$Debug;
|
||||
}
|
||||
}
|
||||
if ($status != 256 || $Debug) { # i.e. not normal exit(1)
|
||||
warn "%Error: Command Failed $command\n";
|
||||
}
|
||||
exit $! if $!; # errno
|
||||
exit $? >> 8 if $? >> 8; # child exit status
|
||||
exit 255; # last resort
|
||||
exit $? >> 8 if $? >> 8; # pass along child exit code
|
||||
exit 128 + $signal; # last resort
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
# pylint: disable=C0103,C0114,C0116,C0209
|
||||
# mypy: disallow-untyped-defs
|
||||
# pylint: disable=C0103,C0114,C0116,C0209,W0603
|
||||
######################################################################
|
||||
|
||||
import argparse
|
||||
|
|
@ -9,25 +10,29 @@ import os.path
|
|||
import re
|
||||
import sys
|
||||
|
||||
exit_code = 0
|
||||
|
||||
def diff(a, b):
|
||||
|
||||
def diff(a: str, b: str) -> None:
|
||||
if not os.path.exists(a):
|
||||
sys.exit("%Error: No old diff filename found: " + a)
|
||||
sys.stderr.write("%Error: No old diff filename found: " + a + "\n")
|
||||
sys.exit(2)
|
||||
if not os.path.exists(b):
|
||||
sys.exit("%Error: No new diff filename found: " + b)
|
||||
sys.stderr.write("%Error: No new diff filename found: " + b + "\n")
|
||||
sys.exit(2)
|
||||
|
||||
if os.path.isdir(a) and os.path.isdir(b):
|
||||
diff_dir(a, b)
|
||||
elif os.path.isfile(a) and os.path.isfile(b):
|
||||
diff_file(a, b)
|
||||
else:
|
||||
sys.exit("%Error: Mix of files and dirs")
|
||||
sys.stderr.write("%Error: Mix of files and dirs")
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
def diff_dir(a, b):
|
||||
def diff_dir(a: str, b: str) -> None:
|
||||
# Diff all files under two directories
|
||||
files = collections.defaultdict(lambda: {})
|
||||
files: dict[str, dict[str, str]] = collections.defaultdict(lambda: {})
|
||||
|
||||
for fn in glob.glob(a + "/*.tree"):
|
||||
base = re.sub(r'.*/', '', fn)
|
||||
|
|
@ -50,7 +55,9 @@ def diff_dir(a, b):
|
|||
sys.stderr.write("%Warning: No .tree files found that have similar base names\n")
|
||||
|
||||
|
||||
def diff_file(a, b):
|
||||
def diff_file(a: str, b: str) -> None:
|
||||
global exit_code
|
||||
|
||||
# Compare the two tree files
|
||||
short_a = re.sub(r'[^a-zA-Z0-9.]+', '_', a)
|
||||
short_b = re.sub(r'[^a-zA-Z0-9.]+', '_', b)
|
||||
|
|
@ -65,25 +72,18 @@ def diff_file(a, b):
|
|||
|
||||
filterf(a, tmp_a)
|
||||
filterf(b, tmp_b)
|
||||
os.system("diff -u " + tmp_a + " " + tmp_b)
|
||||
status = os.system("diff -u " + tmp_a + " " + tmp_b)
|
||||
os.unlink(tmp_a)
|
||||
os.unlink(tmp_b)
|
||||
|
||||
|
||||
def version_from(filename):
|
||||
# Return dump format
|
||||
with open(filename, "r", encoding="utf8") as fh:
|
||||
lineno = 0
|
||||
for line in fh:
|
||||
if lineno > 10:
|
||||
break
|
||||
match = re.search(r'format (0x[0-9.]+)', line)
|
||||
if match:
|
||||
return hex(match.group(1))
|
||||
return 1.0
|
||||
status_exit_code = status >> 8
|
||||
if status_exit_code == 1:
|
||||
exit_code = 1
|
||||
elif status_exit_code:
|
||||
exit_code = 2
|
||||
|
||||
|
||||
def filterf(fn1, fn2):
|
||||
def filterf(fn1: str, fn2: str) -> None:
|
||||
# Remove hex numbers before diffing
|
||||
with open(fn1, "r", encoding="utf8") as fh1:
|
||||
with open(fn2, "w", encoding="utf8") as fh2:
|
||||
|
|
@ -107,7 +107,9 @@ parser = argparse.ArgumentParser(
|
|||
|
||||
Verilator_difftree is used for debugging Verilator tree output files.
|
||||
It performs a diff between two files, or all files common between two
|
||||
directories, ignoring irrelevant pointer differences.""",
|
||||
directories, ignoring irrelevant pointer differences.
|
||||
|
||||
Exit status is 0 if inputs are the same, 1 if different, 2 if trouble.""",
|
||||
epilog="""Copyright 2005-2025 by Wilson Snyder. This program is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
|
|
@ -124,6 +126,7 @@ parser.add_argument('fileb', help='input file b to diff')
|
|||
|
||||
Args = parser.parse_args()
|
||||
diff(Args.filea, Args.fileb)
|
||||
sys.exit(exit_code)
|
||||
|
||||
######################################################################
|
||||
# Local Variables:
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ ThreadScheduleWaitIntervals = [] # list of (start, tick, ecpu) pairs
|
|||
######################################################################
|
||||
|
||||
|
||||
def read_data(filename):
|
||||
def read_data(filename: str) -> None:
|
||||
with open(filename, "r", encoding="utf8") as fh:
|
||||
re_thread = re.compile(r'^VLPROFTHREAD (\d+)$')
|
||||
re_record = re.compile(r'^VLPROFEXEC (\S+) (\d+)(.*)$')
|
||||
|
|
@ -51,6 +51,7 @@ def read_data(filename):
|
|||
re_proc_dat = re.compile(r'VLPROFPROC ([a-z_ ]+)\s*:\s*(.*)$')
|
||||
cpu = None
|
||||
thread = 0
|
||||
thread_last_ecpu = None
|
||||
|
||||
global LongestVcdStrValueLength
|
||||
global ExecGraphTime
|
||||
|
|
@ -109,9 +110,13 @@ def read_data(filename):
|
|||
tick)
|
||||
elif kind == "THREAD_SCHEDULE_WAIT_BEGIN":
|
||||
ecpu = int(re_payload_wait.match(payload).groups()[0])
|
||||
thread_last_ecpu = ecpu
|
||||
ThreadScheduleWait[ecpu].append(tick)
|
||||
elif kind == "THREAD_SCHEDULE_WAIT_END":
|
||||
ecpu = int(re_payload_wait.match(payload).groups()[0])
|
||||
# Might have ended on different CPU then we got THREAD_SCHEDULE_WAIT_BEGIN
|
||||
assert thread_last_ecpu is not None, "THREAD_SCHEDULE_WAIT_END without BEGIN"
|
||||
ecpu = thread_last_ecpu
|
||||
thread_last_ecpu = None
|
||||
start = ThreadScheduleWait[ecpu].pop()
|
||||
WaitingTime += tick - start
|
||||
ThreadScheduleWaitIntervals.append((start, tick, ecpu))
|
||||
|
|
@ -166,7 +171,7 @@ def re_match_result(regexp, line, result_to):
|
|||
######################################################################
|
||||
|
||||
|
||||
def report():
|
||||
def report() -> None:
|
||||
print("Verilator Gantt report")
|
||||
|
||||
print("\nArgument settings:")
|
||||
|
|
@ -215,12 +220,12 @@ def report():
|
|||
print()
|
||||
|
||||
|
||||
def report_numa():
|
||||
def report_numa() -> None:
|
||||
print("\nNUMA assignment:")
|
||||
print(" NUMA status = %s" % Global['info']['numa'])
|
||||
|
||||
|
||||
def report_mtasks():
|
||||
def report_mtasks() -> None:
|
||||
if not Mtasks:
|
||||
return
|
||||
|
||||
|
|
@ -337,7 +342,7 @@ def report_mtasks():
|
|||
print(" e ^ stddev = %0.3f" % math.exp(stddev))
|
||||
|
||||
|
||||
def report_cpus():
|
||||
def report_cpus() -> None:
|
||||
print("\nCPU info:")
|
||||
|
||||
Global['cpu_sockets'] = collections.defaultdict(lambda: 0)
|
||||
|
|
@ -372,14 +377,14 @@ def report_cpus():
|
|||
Global['cpu_socket_cores_warning'] = True
|
||||
|
||||
|
||||
def report_sections():
|
||||
def report_sections() -> None:
|
||||
for thread, section in Sections.items():
|
||||
if section:
|
||||
print(f"\nSection profile for thread {thread}:")
|
||||
report_section(section)
|
||||
|
||||
|
||||
def report_section(section):
|
||||
def report_section(section) -> None:
|
||||
totalTime = collections.defaultdict(lambda: 0)
|
||||
selfTime = collections.defaultdict(lambda: 0)
|
||||
|
||||
|
|
@ -431,7 +436,7 @@ def report_section(section):
|
|||
######################################################################
|
||||
|
||||
|
||||
def write_vcd(filename):
|
||||
def write_vcd(filename: str) -> None:
|
||||
print("Writing %s" % filename)
|
||||
with open(filename, "w", encoding="utf8") as fh:
|
||||
# dict of dicts of hierarchy elements/signal name -> (code, width)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
# mypy: disallow-untyped-defs
|
||||
# pylint: disable=C0114,C0209
|
||||
#
|
||||
# Copyright 2003-2025 by Wilson Snyder. This program is free software; you
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import re
|
|||
######################################################################
|
||||
|
||||
|
||||
def profcfunc(filename):
|
||||
def profcfunc(filename: str) -> None:
|
||||
funcs = {}
|
||||
|
||||
with open(filename, "r", encoding="utf8") as fh:
|
||||
|
|
@ -26,7 +26,7 @@ def profcfunc(filename):
|
|||
calls = float(match.group(3))
|
||||
func = match.group(4)
|
||||
if func not in funcs:
|
||||
funcs[func] = {'pct': 0, 'sec': 0, 'calls': 0}
|
||||
funcs[func] = {'pct': 0.0, 'sec': 0.0, 'calls': 0}
|
||||
funcs[func]['pct'] += pct
|
||||
funcs[func]['sec'] += sec
|
||||
funcs[func]['calls'] += calls
|
||||
|
|
@ -150,7 +150,7 @@ def profcfunc(filename):
|
|||
print((" time seconds seconds calls %-" + str(design_width) +
|
||||
"s type filename and line number") % "design")
|
||||
|
||||
cume = 0
|
||||
cume = 0.0
|
||||
for func in sorted(vfuncs.keys(), key=lambda f: vfuncs[f]['sec'], reverse=True):
|
||||
cume += vfuncs[func]['sec']
|
||||
print(("%6.2f %9.2f %8.2f %10d %-" + str(design_width) + "s %s") %
|
||||
|
|
|
|||
|
|
@ -1,30 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# DESCRIPTION: Verilator: CI ccache maintenance
|
||||
#
|
||||
# Copyright 2020 by Geza Lore. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
################################################################################
|
||||
# This script is run in 'before_script', once ccache has been set up.
|
||||
################################################################################
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
# Show version
|
||||
ccache --version
|
||||
|
||||
# Flush ccache if requested in commit message
|
||||
COMMIT="${CI_PULL_REQUEST_SHA:-$CI_COMMIT}"
|
||||
if git log --format=%B -n 1 "$COMMIT" | grep -q -i '\[CI\s\+ccache\s\+clear\]'; then
|
||||
echo "Flushing ccache due to commit message"
|
||||
ccache -C
|
||||
fi
|
||||
|
||||
# Dump stats, then zero stats
|
||||
# 22.04: ccache -s -v -z
|
||||
ccache -s -z
|
||||
|
|
@ -37,6 +37,13 @@ else
|
|||
fatal "Unknown os: '$CI_OS_NAME'"
|
||||
fi
|
||||
|
||||
if [ "$CI_OS_NAME" = "linux" ]; then
|
||||
# Avoid slow "processing triggers for man db"
|
||||
echo "path-exclude /usr/share/doc/*" | sudo tee -a /etc/dpkg/dpkg.cfg.d/01_nodoc
|
||||
echo "path-exclude /usr/share/man/*" | sudo tee -a /etc/dpkg/dpkg.cfg.d/01_nodoc
|
||||
echo "path-exclude /usr/share/info/*" | sudo tee -a /etc/dpkg/dpkg.cfg.d/01_nodoc
|
||||
fi
|
||||
|
||||
install-vcddiff() {
|
||||
TMP_DIR="$(mktemp -d)"
|
||||
git clone https://github.com/veripool/vcddiff "$TMP_DIR"
|
||||
|
|
@ -70,7 +77,7 @@ if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then
|
|||
fi
|
||||
elif [ "$CI_OS_NAME" = "osx" ]; then
|
||||
brew update
|
||||
brew install ccache perl gperftools
|
||||
brew install ccache perl gperftools autoconf bison flex help2man
|
||||
elif [ "$CI_OS_NAME" = "freebsd" ]; then
|
||||
sudo pkg install -y autoconf bison ccache gmake perl5
|
||||
else
|
||||
|
|
@ -78,7 +85,7 @@ if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then
|
|||
fi
|
||||
|
||||
if [ -n "$CCACHE_DIR" ]; then
|
||||
mkdir -p "$CCACHE_DIR" && ./ci/ci-ccache-maint.bash
|
||||
mkdir -p "$CCACHE_DIR"
|
||||
fi
|
||||
elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
|
||||
##############################################################################
|
||||
|
|
|
|||
|
|
@ -0,0 +1,46 @@
|
|||
#!/usr/bin/env bash
|
||||
# DESCRIPTION: Verilator: CI script for 'pages.yml', notifies PRs
|
||||
#
|
||||
# Copyright 2025 by Geza Lore. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
# Notify PRs via comment that their coverage reports are available
|
||||
|
||||
# Get the current repo URL - might differ on a fork
|
||||
readonly REPO_URL=$(gh repo view --json url --jq .url)
|
||||
|
||||
# Create artifacts root directory
|
||||
ARTIFACTS_ROOT=artifacts
|
||||
mkdir -p ${ARTIFACTS_ROOT}
|
||||
|
||||
for RUN_ID in ${COVERAGE_PR_RUN_IDS//,/ }; do
|
||||
echo "@@@ Processing run ${RUN_ID}"
|
||||
|
||||
# Create workflow artifacts directory
|
||||
ARTIFACTS_DIR=${ARTIFACTS_ROOT}/${RUN_ID}
|
||||
mkdir -p ${ARTIFACTS_DIR}
|
||||
|
||||
# Download artifact of this run, if exists
|
||||
gh run download ${RUN_ID} --name coverage-pr-notification --dir ${ARTIFACTS_DIR} || true
|
||||
ls -lsha ${ARTIFACTS_DIR}
|
||||
|
||||
# Move on if no notification is required
|
||||
if [ ! -f ${ARTIFACTS_DIR}/pr-number.txt ]; then
|
||||
echo "No notification found"
|
||||
continue
|
||||
fi
|
||||
echo "Posting notification found"
|
||||
|
||||
cat ${ARTIFACTS_DIR}/body.txt
|
||||
gh pr comment $(cat ${ARTIFACTS_DIR}/pr-number.txt) --body-file ${ARTIFACTS_DIR}/body.txt
|
||||
|
||||
# Get the artifact ID
|
||||
ARTIFACT_ID=$(gh api "repos/{owner}/{repo}/actions/runs/${RUN_ID}/artifacts" --jq '.artifacts[] | select(.name == "coverage-pr-notification") | .id')
|
||||
|
||||
# Delete it, so we only notify once
|
||||
gh api --method DELETE "repos/{owner}/{repo}/actions/artifacts/${ARTIFACT_ID}"
|
||||
done
|
||||
|
|
@ -0,0 +1,171 @@
|
|||
#!/usr/bin/env bash
|
||||
# DESCRIPTION: Verilator: CI script for 'pages.yml', builds the GitHub Pages
|
||||
#
|
||||
# Copyright 2025 by Geza Lore. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
# This scipt build the content of the GitHub Pages for the repository.
|
||||
# Currently this only hosts code coverage reports, but it would be possible to
|
||||
# add any other contents to the page in parallel here.
|
||||
|
||||
# Developer note: You should be able to run this script in your local checkout
|
||||
# if you have GitHub CLI (command 'gh') setup, authenticated ('gh auth login'),
|
||||
# and have set a default repository ('gh repo set-default').
|
||||
|
||||
# Create pages root directory. The contents of this directory will be deployed
|
||||
# and served via GitHubPages
|
||||
readonly PAGES_ROOT=pages
|
||||
mkdir -p ${PAGES_ROOT}
|
||||
|
||||
# Get the current repo URL - might differ on a fork
|
||||
readonly REPO_URL=$(gh repo view --json url --jq .url)
|
||||
|
||||
# Set GITHUB_OUTPUT when run locally for testing
|
||||
if [[ -z "$GITHUB_OUTPUT" ]]; then
|
||||
GITHUB_OUTPUT=github-output.txt
|
||||
fi
|
||||
|
||||
# Populates ${PAGES_ROOT}/coverage-reports
|
||||
compile_coverage_reports() {
|
||||
# We will process all runs up to and including this date. This is chosen to be
|
||||
# slightly less than the artifact retention period for simplicity.
|
||||
local OLDEST=$(date --date="28 days ago" --iso-8601=date)
|
||||
|
||||
# Gather all coverage workflow runs within the time window
|
||||
gh run list -w coverage.yml --limit 1000 --created ">=${OLDEST}" --json "databaseId,event,status,conclusion,createdAt,number" > recentRuns.json
|
||||
echo @@@ Recent runs:
|
||||
jq "." recentRuns.json
|
||||
|
||||
# Select completd runs that were not cancelled or skipped, sort by descending run number
|
||||
jq 'sort_by(-.number) | map(select(.status == "completed" and (.conclusion == "success" or .conclusion == "failure")))' recentRuns.json > completedRuns.json
|
||||
echo @@@ Completed with success or failure:
|
||||
jq "." completedRuns.json
|
||||
|
||||
# Create artifacts root directory
|
||||
local ARTIFACTS_ROOT=artifacts
|
||||
mkdir -p ${ARTIFACTS_ROOT}
|
||||
|
||||
# Create coverage reports root directory
|
||||
local COVERAGE_ROOT=${PAGES_ROOT}/coverage-reports
|
||||
mkdir -p ${COVERAGE_ROOT}
|
||||
|
||||
# Create index page contents fragment
|
||||
local CONTENTS=contents.tmp
|
||||
echo > ${CONTENTS}
|
||||
|
||||
# Run IDs of PR jobs processed
|
||||
local PR_RUN_IDS=""
|
||||
|
||||
# Iterate over all unique event types that triggered the workflows
|
||||
for EVENT in $(jq -r 'map(.event) | sort | unique | .[]' completedRuns.json); do
|
||||
echo "@@@ Processing '${EVENT}' runs"
|
||||
|
||||
# Emit section header if a report exists with this event type
|
||||
EMIT_SECTION_HEADER=1
|
||||
|
||||
# For each worfklow run that was triggered by this event type
|
||||
for RUN_ID in $(jq ".[] | select(.event == \"${EVENT}\") |.databaseId" completedRuns.json); do
|
||||
echo "@@@ Processing run ${RUN_ID}"
|
||||
|
||||
# Extract the info of this run
|
||||
jq ".[] | select(.databaseId == $RUN_ID)" completedRuns.json > workflow.json
|
||||
jq "." workflow.json
|
||||
|
||||
# Record run ID of PR job
|
||||
if [[ $EVENT == "pull_request" ]]; then
|
||||
if [[ -z "$PR_RUN_IDS" ]]; then
|
||||
PR_RUN_IDS="$RUN_ID"
|
||||
else
|
||||
PR_RUN_IDS="$PR_RUN_IDS,$RUN_ID"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create workflow artifacts directory
|
||||
local ARTIFACTS_DIR=${ARTIFACTS_ROOT}/${RUN_ID}
|
||||
mkdir -p ${ARTIFACTS_DIR}
|
||||
|
||||
# Download artifacts of this run, if exists
|
||||
gh run download ${RUN_ID} --name coverage-report --dir ${ARTIFACTS_DIR} || true
|
||||
ls -lsha ${ARTIFACTS_DIR}
|
||||
|
||||
# Move on if no coverage report is available
|
||||
if [ ! -d ${ARTIFACTS_DIR}/report ]; then
|
||||
echo "No coverage report found"
|
||||
continue
|
||||
fi
|
||||
echo "Coverage report found"
|
||||
|
||||
# Emit section header
|
||||
if [[ -n $EMIT_SECTION_HEADER ]]; then
|
||||
unset EMIT_SECTION_HEADER
|
||||
if [[ $EVENT == "pull_request" ]]; then
|
||||
echo "<h4>Patch coverage reports for '${EVENT}' runs:</h4>" >> ${CONTENTS}
|
||||
else
|
||||
echo "<h4>Code coverage reports for '${EVENT}' runs:</h4>" >> ${CONTENTS}
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create pages subdirectory
|
||||
mv ${ARTIFACTS_DIR}/report ${COVERAGE_ROOT}/${RUN_ID}
|
||||
|
||||
# Add index page content
|
||||
local WORKFLOW_CREATED=$(jq -r '.createdAt' workflow.json)
|
||||
local WOFKRLOW_NUMBER=$(jq -r '.number' workflow.json)
|
||||
cat >> ${CONTENTS} <<CONTENTS_TEMPLATE
|
||||
Run <a href="${RUN_ID}/index.html">#${WOFKRLOW_NUMBER}</a>
|
||||
| GitHub: <a href="${REPO_URL}/actions/runs/${RUN_ID}">${RUN_ID}</a>
|
||||
| started at: ${WORKFLOW_CREATED}
|
||||
CONTENTS_TEMPLATE
|
||||
if [ -e ${ARTIFACTS_DIR}/pr-number.txt ]; then
|
||||
local PRNUMBER=$(cat ${ARTIFACTS_DIR}/pr-number.txt)
|
||||
echo " | Pull request: <a href=\"${REPO_URL}/pull/${PRNUMBER}\">#${PRNUMBER}</a>" >> ${CONTENTS}
|
||||
fi
|
||||
echo "<br>" >> ${CONTENTS}
|
||||
done
|
||||
|
||||
# Section break
|
||||
if [[ -z "$EMIT_SECTION_HEADER" ]]; then
|
||||
echo "<hr>" >> ${CONTENTS}
|
||||
fi
|
||||
done
|
||||
|
||||
# Write coverage report index.html
|
||||
cat > ${COVERAGE_ROOT}/index.html <<INDEX_TEMPLATE
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Verilator CI coverage reports</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: courier, serif;
|
||||
background-color: #f3f3f3;
|
||||
a {
|
||||
color: #008fd7;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
$(cat ${CONTENTS})
|
||||
<h4>Assembled $(date --iso-8601=minutes --utc)</h1>
|
||||
<body>
|
||||
|
||||
</html>
|
||||
INDEX_TEMPLATE
|
||||
|
||||
# Report size
|
||||
du -shc ${COVERAGE_ROOT}/*
|
||||
|
||||
# Set output
|
||||
echo "coverage-pr-run-ids=${PR_RUN_IDS}" >> $GITHUB_OUTPUT
|
||||
}
|
||||
|
||||
# Compilie coverage reports
|
||||
compile_coverage_reports;
|
||||
|
||||
# You can build any other content here to be put under ${PAGES_ROOT}
|
||||
|
|
@ -27,6 +27,8 @@ if [ "$CI_OS_NAME" = "linux" ]; then
|
|||
elif [ "$CI_OS_NAME" = "osx" ]; then
|
||||
export MAKE=make
|
||||
NPROC=$(sysctl -n hw.logicalcpu)
|
||||
# Disable ccache, doesn't always work in GitHub Actions
|
||||
export OBJCACHE=
|
||||
elif [ "$CI_OS_NAME" = "freebsd" ]; then
|
||||
export MAKE=gmake
|
||||
NPROC=$(sysctl -n hw.ncpu)
|
||||
|
|
@ -39,23 +41,27 @@ if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then
|
|||
##############################################################################
|
||||
# Build verilator
|
||||
|
||||
if [ "$COVERAGE" != 1 ]; then
|
||||
autoconf
|
||||
./configure --enable-longtests --enable-ccwarn --prefix="$INSTALL_DIR"
|
||||
ccache -z
|
||||
"$MAKE" -j "$NPROC" -k
|
||||
# 22.04: ccache -s -v
|
||||
ccache -s
|
||||
if [ "$CI_OS_NAME" = "osx" ]; then
|
||||
file bin/verilator_bin
|
||||
file bin/verilator_bin_dbg
|
||||
md5 bin/verilator_bin
|
||||
md5 bin/verilator_bin_dbg
|
||||
stat bin/verilator_bin
|
||||
stat bin/verilator_bin_dbg
|
||||
fi
|
||||
else
|
||||
nodist/code_coverage --stages 0-2
|
||||
autoconf
|
||||
CONFIGURE_ARGS="--enable-longtests --enable-ccwarn"
|
||||
if [ "$CI_DEV_ASAN" = 1 ]; then
|
||||
CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-dev-asan"
|
||||
CXX="$CXX -DVL_LEAK_CHECKS"
|
||||
fi
|
||||
if [ "$CI_DEV_GCOV" = 1 ]; then
|
||||
CONFIGURE_ARGS="$CONFIGURE_ARGS --enable-dev-gcov"
|
||||
fi
|
||||
./configure $CONFIGURE_ARGS --prefix="$INSTALL_DIR"
|
||||
ccache -z
|
||||
"$MAKE" -j "$NPROC" -k
|
||||
# 22.04: ccache -s -v
|
||||
ccache -s
|
||||
if [ "$CI_OS_NAME" = "osx" ]; then
|
||||
file bin/verilator_bin
|
||||
file bin/verilator_bin_dbg
|
||||
md5 bin/verilator_bin
|
||||
md5 bin/verilator_bin_dbg
|
||||
stat bin/verilator_bin
|
||||
stat bin/verilator_bin_dbg
|
||||
fi
|
||||
elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
|
||||
##############################################################################
|
||||
|
|
@ -86,9 +92,6 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
|
|||
export VERILATOR_TEST_NO_GPROF=1 # gprof is a bit different on FreeBSD, disable
|
||||
fi
|
||||
|
||||
# Run sanitize on Ubuntu 22.04 only
|
||||
( [[ "$CI_RUNS_ON" =~ 'ubuntu-22.04' ]] || [[ "$CI_RUNS_ON" =~ 'ubuntu-24.04' ]] ) && sanitize='--sanitize' || sanitize=''
|
||||
|
||||
TEST_REGRESS=test_regress
|
||||
if [ "$CI_RELOC" == 1 ]; then
|
||||
# Testing that the installation is relocatable.
|
||||
|
|
@ -109,16 +112,16 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
|
|||
ccache -z
|
||||
case $TESTS in
|
||||
dist-vlt-0)
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean $sanitize" DRIVER_HASHSET=--hashset=0/4
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean" DRIVER_HASHSET=--hashset=0/4
|
||||
;;
|
||||
dist-vlt-1)
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean $sanitize" DRIVER_HASHSET=--hashset=1/4
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean" DRIVER_HASHSET=--hashset=1/4
|
||||
;;
|
||||
dist-vlt-2)
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean $sanitize" DRIVER_HASHSET=--hashset=2/4
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean" DRIVER_HASHSET=--hashset=2/4
|
||||
;;
|
||||
dist-vlt-3)
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean $sanitize" DRIVER_HASHSET=--hashset=3/4
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt --driver-clean" DRIVER_HASHSET=--hashset=3/4
|
||||
;;
|
||||
vltmt-0)
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt --driver-clean" DRIVER_HASHSET=--hashset=0/3
|
||||
|
|
@ -129,71 +132,68 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
|
|||
vltmt-2)
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt --driver-clean" DRIVER_HASHSET=--hashset=2/3
|
||||
;;
|
||||
coverage-all)
|
||||
nodist/code_coverage --stages 1-
|
||||
;;
|
||||
coverage-dist)
|
||||
nodist/code_coverage --stages 1- --scenarios=--dist
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist"
|
||||
;;
|
||||
coverage-vlt-0)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vlt --hashset=0/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=0/10
|
||||
;;
|
||||
coverage-vlt-1)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vlt --hashset=1/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=1/10
|
||||
;;
|
||||
coverage-vlt-2)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vlt --hashset=2/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=2/10
|
||||
;;
|
||||
coverage-vlt-3)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vlt --hashset=3/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=3/10
|
||||
;;
|
||||
coverage-vlt-4)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vlt --hashset=4/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=4/10
|
||||
;;
|
||||
coverage-vlt-5)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vlt --hashset=5/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=5/10
|
||||
;;
|
||||
coverage-vlt-6)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vlt --hashset=6/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=6/10
|
||||
;;
|
||||
coverage-vlt-7)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vlt --hashset=7/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=7/10
|
||||
;;
|
||||
coverage-vlt-8)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vlt --hashset=8/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=8/10
|
||||
;;
|
||||
coverage-vlt-9)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vlt --hashset=9/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vlt" DRIVER_HASHSET=--hashset=9/10
|
||||
;;
|
||||
coverage-vltmt-0)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vltmt --hashset=0/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=0/10
|
||||
;;
|
||||
coverage-vltmt-1)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vltmt --hashset=1/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=1/10
|
||||
;;
|
||||
coverage-vltmt-2)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vltmt --hashset=2/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=2/10
|
||||
;;
|
||||
coverage-vltmt-3)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vltmt --hashset=3/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=3/10
|
||||
;;
|
||||
coverage-vltmt-4)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vltmt --hashset=4/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=4/10
|
||||
;;
|
||||
coverage-vltmt-5)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vltmt --hashset=5/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=5/10
|
||||
;;
|
||||
coverage-vltmt-6)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vltmt --hashset=6/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=6/10
|
||||
;;
|
||||
coverage-vltmt-7)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vltmt --hashset=7/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=7/10
|
||||
;;
|
||||
coverage-vltmt-8)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vltmt --hashset=8/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=8/10
|
||||
;;
|
||||
coverage-vltmt-9)
|
||||
nodist/code_coverage --stages 1- --scenarios=--vltmt --hashset=9/10
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--vltmt" DRIVER_HASHSET=--hashset=9/10
|
||||
;;
|
||||
*)
|
||||
fatal "Unknown test: $TESTS"
|
||||
|
|
|
|||
BIN
ci/codecov
BIN
ci/codecov
Binary file not shown.
|
|
@ -35,7 +35,7 @@ To change the compiler use the `-e` switch to pass environment variables:
|
|||
|
||||
::
|
||||
|
||||
docker run -ti -e CC=clang-18 -e CXX=clang++-18 verilator/verilator-buildenv test
|
||||
docker run -ti -e CXX=clang++-18 verilator/verilator-buildenv test
|
||||
|
||||
The tests, that involve numactl are not working due to security restrictions.
|
||||
To run those too, add the CAP_SYS_NICE capability during the start of the container:
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
: "${REPO:=https://github.com/verilator/verilator}"
|
||||
: "${REV:=master}"
|
||||
: "${CC:=gcc}"
|
||||
: "${CXX:=g++}"
|
||||
|
||||
SRCS=$PWD/verilator
|
||||
|
|
|
|||
36
codecov.yml
36
codecov.yml
|
|
@ -1,36 +0,0 @@
|
|||
---
|
||||
# DESCRIPTION: codecov.io config
|
||||
#
|
||||
# Copyright 2020-2025 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
####################
|
||||
# Validate:
|
||||
# curl --data-binary @codecov.yml https://codecov.io/validate
|
||||
#
|
||||
codecov:
|
||||
require_ci_to_pass: false
|
||||
coverage:
|
||||
precision: 2
|
||||
round: down
|
||||
range: 50...100
|
||||
ignore:
|
||||
- "ci" #
|
||||
- "docs" #
|
||||
- "examples" #
|
||||
- "include/gtkwave" #
|
||||
- "include/vltstd" #
|
||||
- "test_regress" #
|
||||
parsers:
|
||||
gcov:
|
||||
branch_detection:
|
||||
conditional: true
|
||||
loop: true
|
||||
method: false
|
||||
macro: false
|
||||
comment:
|
||||
layout: "reach,diff,flags,tree"
|
||||
behavior: default
|
||||
require_changes: true
|
||||
104
configure.ac
104
configure.ac
|
|
@ -11,7 +11,7 @@
|
|||
# Then 'make maintainer-dist'
|
||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[5.040 2025-08-30],
|
||||
AC_INIT([Verilator],[5.042 2025-11-02],
|
||||
[https://verilator.org],
|
||||
[verilator],[https://verilator.org])
|
||||
|
||||
|
|
@ -57,6 +57,22 @@ AC_ARG_ENABLE([partial-static],
|
|||
CFG_ENABLE_PARTIAL_STATIC=yes)
|
||||
AC_MSG_RESULT($CFG_ENABLE_PARTIAL_STATIC)
|
||||
|
||||
# Flag to enable compiling with AddressSanitizer
|
||||
AC_MSG_CHECKING(whether to use AddressSanitizer)
|
||||
AC_ARG_ENABLE([dev-asan],
|
||||
[AS_HELP_STRING([--enable-dev-asan],
|
||||
[Enable compiling Verilator with ASAN
|
||||
AddressSanitizer for memory error detection.
|
||||
This disables tcmalloc. Does not affect
|
||||
Verilated models using ASAN.])],
|
||||
[case "${enableval}" in
|
||||
yes) CFG_WITH_DEV_ASAN=yes ;;
|
||||
no) CFG_WITH_DEV_ASAN=no ;;
|
||||
*) AC_MSG_ERROR([bad value '${enableval}' for --enable-dev-asan]) ;;
|
||||
esac],
|
||||
CFG_WITH_DEV_ASAN=no)
|
||||
AC_MSG_RESULT($CFG_WITH_DEV_ASAN)
|
||||
|
||||
# Flag to enable linking Verilator with tcmalloc if available
|
||||
AC_MSG_CHECKING(whether to use tcmalloc)
|
||||
AC_ARG_ENABLE([tcmalloc],
|
||||
|
|
@ -69,22 +85,27 @@ AC_ARG_ENABLE([tcmalloc],
|
|||
*) AC_MSG_ERROR([bad value '${enableval}' for --enable-tcmalloc]) ;;
|
||||
esac],
|
||||
[CFG_WITH_TCMALLOC=check;])
|
||||
AC_SUBST(CFG_WITH_TCMALLOC)
|
||||
AC_MSG_RESULT($CFG_WITH_TCMALLOC)
|
||||
if test "$CFG_WITH_DEV_ASAN" = "yes"; then
|
||||
CFG_WITH_TCMALLOC=no
|
||||
AC_MSG_RESULT("disabled by --enable-dev-asan")
|
||||
else
|
||||
AC_MSG_RESULT($CFG_WITH_TCMALLOC)
|
||||
fi
|
||||
|
||||
# Flag to enable coverage build
|
||||
AC_MSG_CHECKING(whether to build for coverage collection)
|
||||
AC_ARG_ENABLE([coverage],
|
||||
[AS_HELP_STRING([--enable-coverage],
|
||||
[Build Verilator for code coverage collection.
|
||||
# Flag to enable code coverage build with gcov
|
||||
AC_MSG_CHECKING(whether to build for gcov code coverage collection)
|
||||
AC_ARG_ENABLE([dev-gcov],
|
||||
[AS_HELP_STRING([--enable-dev-gcov],
|
||||
[Build Verilator for code coverage collection with gcov.
|
||||
For developers only.])],
|
||||
[case "${enableval}" in
|
||||
yes) CFG_ENABLE_COVERAGE=yes ;;
|
||||
no) CFG_ENABLE_COVERAGE=no ;;
|
||||
*) AC_MSG_ERROR([bad value '${enableval}' for --enable-coverage]) ;;
|
||||
yes) CFG_WITH_DEV_GCOV=yes ;;
|
||||
no) CFG_WITH_DEV_GCOV=no ;;
|
||||
*) AC_MSG_ERROR([bad value '${enableval}' for --enable-dev-gcov]) ;;
|
||||
esac],
|
||||
CFG_ENABLE_COVERAGE=no)
|
||||
AC_MSG_RESULT($CFG_ENABLE_COVERAGE)
|
||||
CFG_WITH_DEV_GCOV=no)
|
||||
AC_SUBST(CFG_WITH_DEV_GCOV)
|
||||
AC_MSG_RESULT($CFG_WITH_DEV_GCOV)
|
||||
|
||||
# Special Substitutions - CFG_WITH_DEFENV
|
||||
AC_MSG_CHECKING(whether to use hardcoded paths)
|
||||
|
|
@ -379,7 +400,7 @@ AC_DEFUN([_MY_LDLIBS_CHECK_OPT],
|
|||
])
|
||||
|
||||
# Add the coverage flags early as they influence later checks.
|
||||
if test "$CFG_ENABLE_COVERAGE" = "yes"; then
|
||||
if test "$CFG_WITH_DEV_GCOV" = "yes"; then
|
||||
_MY_CXX_CHECK_OPT(CXX,--coverage)
|
||||
# Otherwise inline may not show as uncovered
|
||||
# If we use this then e.g. verilated.h functions properly show up
|
||||
|
|
@ -391,11 +412,19 @@ if test "$CFG_ENABLE_COVERAGE" = "yes"; then
|
|||
# _MY_CXX_CHECK_OPT(CXX,-fkeep-inline-functions)
|
||||
# Otherwise static may not show as uncovered
|
||||
_MY_CXX_CHECK_OPT(CXX,-fkeep-static-functions)
|
||||
# Exceptions can pollute the branch coverage data
|
||||
_MY_CXX_CHECK_OPT(CXX,-fno-exceptions)
|
||||
# Define-out some impossible stuff
|
||||
# Similarly for inline functions. - This is too slow. See Makefile_obj instead.
|
||||
#_MY_CXX_CHECK_OPT(CXX,-fkeep-inline-functions)
|
||||
# Make sure profiling is thread-safe
|
||||
_MY_CXX_CHECK_OPT(CXX,-fprofile-update=atomic)
|
||||
# Ensure data files can be written from parallel runs
|
||||
_MY_CXX_CHECK_OPT(CXX,-fprofile-reproducible=parallel-runs)
|
||||
# Save source files as absolute paths in gcno files
|
||||
_MY_CXX_CHECK_OPT(CXX,-fprofile-abs-path)
|
||||
# Define so compiled code can know
|
||||
_MY_CXX_CHECK_OPT(CXX,-DVL_GCOV)
|
||||
AC_DEFINE([HAVE_DEV_GCOV],[1],[Defined if compiled with code coverage collection for gcov])]
|
||||
fi
|
||||
AC_SUBST(HAVE_DEV_GCOV)
|
||||
|
||||
# Compiler flags to enable profiling
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PROFILE,-pg)
|
||||
|
|
@ -433,6 +462,14 @@ AC_SUBST(CFG_CXXFLAGS_COROUTINES)
|
|||
AC_SUBST(HAVE_COROUTINES)
|
||||
|
||||
# Flags for compiling Verilator internals including parser always
|
||||
if test "$CFG_WITH_DEV_ASAN" = "yes"; then
|
||||
_MY_CXX_CHECK_IFELSE(-fsanitize=address -DVL_ASAN,
|
||||
[CFG_CXXFLAGS_SRC="$CFG_CXXFLAGS_SRC -fsanitize=address -DVL_ASAN"
|
||||
CFG_LDFLAGS_SRC="$CFG_LDFLAGS_SRC -fsanitize=address"
|
||||
AC_DEFINE([HAVE_DEV_ASAN],[1],[Defined if built with AddresSanitizer])]
|
||||
)
|
||||
fi
|
||||
AC_SUBST(HAVE_DEV_ASAN)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Qunused-arguments)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-shadow)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-unused-parameter)
|
||||
|
|
@ -448,16 +485,22 @@ _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-unused)
|
|||
AC_SUBST(CFG_CXXFLAGS_PARSER)
|
||||
|
||||
# Flags for compiling the debug version of Verilator (in addition to above CFG_CXXFLAGS_SRC)
|
||||
if test "$CFG_ENABLE_COVERAGE" = "no"; then # Do not optimize for the coverage build
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_DEBUG,-Og)
|
||||
if test "$CFG_WITH_DEV_GCOV" = "no"; then # Do not optimize for the coverage build
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_DBG,-Og)
|
||||
fi
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_DEBUG,-ggdb)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_DEBUG,-gz)
|
||||
AC_SUBST(CFG_CXXFLAGS_DEBUG)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_DBG,-ggdb)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_DBG,-gz)
|
||||
AC_SUBST(CFG_CXXFLAGS_DBG)
|
||||
|
||||
# Flags for linking the debug version of Verilator (in addition to above CFG_LDFLAGS_SRC)
|
||||
_MY_LDLIBS_CHECK_OPT(CFG_LDFLAGS_DEBUG,-gz)
|
||||
AC_SUBST(CFG_LDFLAGS_DEBUG)
|
||||
_MY_LDLIBS_CHECK_OPT(CFG_LDFLAGS_DBG,-gz)
|
||||
AC_SUBST(CFG_LDFLAGS_DBG)
|
||||
|
||||
# Flags for compiling the optimized version of Verilator (in addition to above CFG_CXXFLAGS_SRC)
|
||||
if test "$CFG_WITH_DEV_GCOV" = "no"; then # Do not optimize for the coverage build
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_OPT,-O3)
|
||||
fi
|
||||
AC_SUBST(CFG_CXXFLAGS_OPT)
|
||||
|
||||
# Flags for Verilated makefile
|
||||
# For example, -Wno-div-by-zero isn't in 4.1.2
|
||||
|
|
@ -562,18 +605,15 @@ AC_SUBST(CFG_LIBS)
|
|||
AC_DEFUN([_MY_CXX_CHECK_CXX_VER],
|
||||
[# _MY_CXX_CHECK_CXX_VER(flag) -- Check if compiler runs C++14
|
||||
# Set $_my_result
|
||||
AC_LINK_IFELSE(
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_PROGRAM([#include <thread>
|
||||
#if (__cplusplus < 201402L)
|
||||
# error "Too old"
|
||||
#endif
|
||||
], [[ ]])],
|
||||
[_my_result=yes
|
||||
if test -s conftest.err; then
|
||||
if grep -e "$1" conftest.err >/dev/null; then
|
||||
_my_result=no
|
||||
fi
|
||||
fi],
|
||||
], [[
|
||||
]])],
|
||||
[_my_result=yes],
|
||||
[_my_result=no],
|
||||
[_my_result=no])
|
||||
])
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ Please see the Verilator manual for 200+ additional contributors. Thanks to all.
|
|||
Adam Bagley
|
||||
Adrian Sampson
|
||||
Adrien Le Masle
|
||||
Ahmed El-Mahmoudy
|
||||
أحمد المحمودي (Ahmed El-Mahmoudy)
|
||||
Aidan McNay
|
||||
Aleksander Kiryk
|
||||
Alex Chadwick
|
||||
|
|
@ -32,14 +32,15 @@ Cameron Kirk
|
|||
Chih-Mao Chen
|
||||
Chris Bachhuber
|
||||
Chris Randall
|
||||
Christian Hecken
|
||||
Christopher Taylor
|
||||
Chuxuan Wang
|
||||
Chykon
|
||||
Congcong Cai
|
||||
Conor McCullough
|
||||
Dan Petrisko
|
||||
Danny Oler
|
||||
Daniel Bates
|
||||
Danny Oler
|
||||
Dave Sargeant
|
||||
David Horton
|
||||
David Ledger
|
||||
|
|
@ -58,7 +59,7 @@ Eric Müller
|
|||
Eric Rippey
|
||||
Ethan Sifferman
|
||||
Eyck Jentzsch
|
||||
Fabian Keßler
|
||||
Fabian Keßler-Schulz
|
||||
Fan Shupei
|
||||
Felix Neumärker
|
||||
Felix Yan
|
||||
|
|
@ -94,6 +95,7 @@ Iru Cai
|
|||
Ivan Vnučec
|
||||
Iztok Jeras
|
||||
Jake Merdich
|
||||
Jakub Wasilewski
|
||||
James Bailey
|
||||
James Hanlon
|
||||
James Hutchinson
|
||||
|
|
@ -144,6 +146,7 @@ Krzysztof Obłonczek
|
|||
Krzysztof Starecki
|
||||
Krzysztof Sychla
|
||||
Kuba Ober
|
||||
Lan Zongwei
|
||||
Larry Doolittle
|
||||
Liam Braun
|
||||
Luca Colagrande
|
||||
|
|
@ -160,6 +163,7 @@ Marshal Qiao
|
|||
Martin Schmidt
|
||||
Martin Stadler
|
||||
Mateusz Gancarz
|
||||
Matt Stroud
|
||||
Matthew Ballance
|
||||
Max Wipfli
|
||||
Michael Bedford Taylor
|
||||
|
|
@ -266,6 +270,7 @@ Zhen Yan
|
|||
Zhou Shen
|
||||
Zhouyi Shen
|
||||
Zixi Li
|
||||
dependabot[bot]
|
||||
february cozzocrea
|
||||
sumpster
|
||||
Àlex Torregrosa
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
# mypy: disallow-untyped-defs
|
||||
# pylint: disable=C0112,C0114,C0115,C0116,C0209,C0301,R0903
|
||||
# -*- Python -*- See copyright, etc below
|
||||
######################################################################
|
||||
|
|
@ -11,9 +12,8 @@ import re
|
|||
|
||||
class VlSphinxExtract:
|
||||
debug = 0
|
||||
SkipBasenames = {}
|
||||
|
||||
def process(self, filename):
|
||||
def process(self, filename: str) -> None:
|
||||
with open(filename, "r", encoding="utf8") as fhr:
|
||||
fhw = None
|
||||
for line in fhr:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
# mypy: disallow-untyped-defs
|
||||
# pylint: disable=C0112,C0114,C0115,C0116,C0209,C0301,R0903
|
||||
# -*- Python -*- See copyright, etc below
|
||||
######################################################################
|
||||
|
|
@ -12,19 +13,17 @@ import re
|
|||
|
||||
class VlSphinxFix:
|
||||
debug = 0
|
||||
SkipBasenames = {}
|
||||
|
||||
def process(self, path):
|
||||
def process(self, path: str) -> None:
|
||||
if os.path.isdir(path):
|
||||
for basefile in os.listdir(path):
|
||||
file = os.path.join(path, basefile)
|
||||
if ((basefile != ".") and (basefile != "..") and basefile not in self.SkipBasenames
|
||||
and not os.path.islink(file)):
|
||||
if ((basefile != ".") and (basefile != "..") and not os.path.islink(file)):
|
||||
self.process(file)
|
||||
elif re.search(r'\.(html|tex)$', path):
|
||||
self._edit(path)
|
||||
|
||||
def _edit(self, filename):
|
||||
def _edit(self, filename: str) -> None:
|
||||
is_html = re.search(r'\.(html)$', filename)
|
||||
with open(filename, "r", encoding="utf8") as fhr:
|
||||
origfile = fhr.read()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
.. comment: generated by t_lint_assigneqexpr_bad
|
||||
.. code-block:: sv
|
||||
:linenos:
|
||||
:emphasize-lines: 3
|
||||
|
||||
assign d_o = // Note = not == below
|
||||
(
|
||||
c_o = 1 // <--- Warning: ASSIGNEQEXPR
|
||||
) ? 1 : (
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
.. comment: generated by t_lint_assigneqexpr_bad
|
||||
.. code-block::
|
||||
|
||||
%Warning-ASSIGNEQEXPR: example.v:1:11 Assignment '=' inside expression
|
||||
: ... Was a '==' intended, or suggest use a separate statement
|
||||
|
|
@ -2,4 +2,4 @@
|
|||
.. code-block:: sv
|
||||
:emphasize-lines: 1
|
||||
|
||||
// verilator lintt_off WIDTH //<--- Warning (lint_off misspelled)
|
||||
// verilator lintt_off WIDTH //<--- Warning (lint_off misspelled)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
.. code-block::
|
||||
:emphasize-lines: 1,2
|
||||
|
||||
%Error-BADVLTPRAGMA: example.v:1:4 Unknown verilator comment: '/*verilator lintt_off WIDTH <--- Warning (lint_off misspelled)*/'
|
||||
7 | /*verilator lintt_off WIDTH <--- Warning (lint_off misspelled)*/
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
%Error-BADVLTPRAGMA: example.v:1:3 Unknown verilator comment: '/*verilator lintt_off WIDTH <--- Warning (lint_off misspelled)*/'
|
||||
7 | /*verilator lintt_off WIDTH <--- Warning (lint_off misspelled)*/
|
||||
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@
|
|||
.. code-block:: sv
|
||||
:linenos:
|
||||
|
||||
always_comb b = ~a;
|
||||
always_comb a = b;
|
||||
always_comb b = ~a;
|
||||
always_comb a = b;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
.. comment: generated by t_lint_didnotconverge_bad
|
||||
.. code-block::
|
||||
|
||||
-V{t#,#} 'stl' region trigger index 1 is active: @([hybrid] b)
|
||||
%Error: t/t_lint_didnotconverge_bad.v:7: Settle region did not converge.
|
||||
-V{t#,#} 'stl' region trigger index 0 is active: @([hybrid] a)
|
||||
%Error: t/t_lint_didnotconverge_bad.v:7: Settle region did not converge after 100 tries
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.. comment: generated by t_lint_didnotconverge_nodbg_bad
|
||||
.. code-block::
|
||||
|
||||
%Error: t/t_lint_didnotconverge_bad.v:7: Settle region did not converge.
|
||||
%Error: t/t_lint_didnotconverge_bad.v:7: Settle region did not converge after 100 tries
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
.. comment: generated by t_lint_functimectl_bad
|
||||
.. code-block:: sv
|
||||
:linenos:
|
||||
:emphasize-lines: 2
|
||||
|
||||
function void calls_timing_ctl;
|
||||
@e; // <--- Bad IEEE 1800-2023 13.4 time-controlling
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
.. comment: generated by t_lint_functimectl_bad
|
||||
.. code-block::
|
||||
|
||||
%Error-FUNCTIMECTL: example.v:1:5 Functions cannot contain time-controlling statements (IEEE 1800-2023 13.4)
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
.. comment: generated by t_param_hier_bad
|
||||
.. code-block:: sv
|
||||
:linenos:
|
||||
:emphasize-lines: 3
|
||||
|
||||
sub #(.X(MY_X)) u_sub ();
|
||||
|
||||
localparam int SUB_Y = u_sub.Y; // <--- BAD: IEEE 1800-2023 6.20.2 no hierarchical
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
.. comment: generated by t_param_hier_bad
|
||||
.. code-block::
|
||||
|
||||
%Error-HIERPARAM: example.v:1:32 Parameter values cannot use hierarchical values (IEEE 1800-2023 6.20.2)
|
||||
: ... note: In instance 't'
|
||||
36 | localparam int SUB_Y = u_sub.Y;
|
||||
| ^
|
||||
|
|
@ -3,9 +3,9 @@
|
|||
:linenos:
|
||||
:emphasize-lines: 2,5
|
||||
|
||||
always @(posedge clk) begin
|
||||
out2[7:0] <= d0; // <--- Warning
|
||||
end
|
||||
always @(negedge clk) begin
|
||||
out2[15:8] <= d0; // <--- Warning
|
||||
end
|
||||
always @(posedge clk) begin
|
||||
out2[7:0] <= d0; // <--- Warning
|
||||
end
|
||||
always @(negedge clk) begin
|
||||
out2[15:8] <= d0; // <--- Warning
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
.. comment: generated by t_lint_multidriven_bad
|
||||
.. code-block::
|
||||
|
||||
%Warning-MULTIDRIVEN: example.v:1:22 Signal has multiple driving blocks with different clocking: 'out2'
|
||||
example.v:1:7 ... Location of first driving block
|
||||
example.v:1:7 ... Location of other driving block
|
||||
%Warning-MULTIDRIVEN: example.v:1:21 Signal has multiple driving blocks with different clocking: 'out2'
|
||||
example.v:1:5 ... Location of first driving block
|
||||
example.v:1:5 ... Location of other driving block
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
.. comment: generated by t_lint_noreturn_bad
|
||||
.. code-block:: sv
|
||||
:linenos:
|
||||
:emphasize-lines: 1
|
||||
|
||||
function int no_rtn(); // <--- Warning: No return
|
||||
endfunction
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
.. comment: generated by t_lint_noreturn_bad
|
||||
.. code-block::
|
||||
|
||||
%Warning-NORETURN: example.v:1:16 Non-void function 'no_rtn' has no return value
|
||||
|
|
@ -3,10 +3,10 @@
|
|||
:linenos:
|
||||
:emphasize-lines: 1,5
|
||||
|
||||
logic flop_out = 1; // <--- Warning
|
||||
logic flop_out = 1; // <--- Warning
|
||||
|
||||
always @(posedge clk, negedge reset_l) begin
|
||||
if (enable) begin
|
||||
flop_out <= ~in; // <--- Use of initialized
|
||||
end
|
||||
end
|
||||
always @(posedge clk, negedge reset_l) begin
|
||||
if (enable) begin
|
||||
flop_out <= ~in; // <--- Use of initialized
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@
|
|||
:linenos:
|
||||
:emphasize-lines: 5
|
||||
|
||||
logic flop2_out;
|
||||
logic flop2_out;
|
||||
|
||||
always @(posedge clk, negedge reset_l) begin
|
||||
if (!reset_l) begin
|
||||
flop2_out <= '1; // <--- Added reset init
|
||||
end
|
||||
else if (enable) begin
|
||||
flop2_out <= ~in;
|
||||
end
|
||||
end
|
||||
always @(posedge clk, negedge reset_l) begin
|
||||
if (!reset_l) begin
|
||||
flop2_out <= '1; // <--- Added reset init
|
||||
end
|
||||
else if (enable) begin
|
||||
flop2_out <= ~in;
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,12 +1,12 @@
|
|||
.. comment: generated by t_lint_procassinit_bad
|
||||
.. code-block::
|
||||
|
||||
%Warning-PROCASSINIT: example.v:1:21 Procedural assignment to declaration with initial value: 'flop_out'
|
||||
%Warning-PROCASSINIT: example.v:1:20 Procedural assignment to declaration with initial value: 'flop_out'
|
||||
: ... note: In instance 't'
|
||||
: ... Location of variable initialization
|
||||
26 | logic flop_out = 1;
|
||||
| ^
|
||||
example.v:1:10 ... Location of variable process write
|
||||
: ... Perhaps should initialize instead using a reset in this process
|
||||
30 | flop_out <= ~in;
|
||||
| ^~~~~~~~
|
||||
26 | logic flop_out = 1;
|
||||
| ^
|
||||
example.v:1:7 ... Location of variable process write
|
||||
: ... Perhaps should initialize instead using a reset in this process
|
||||
30 | flop_out <= ~in;
|
||||
| ^~~~~~~~
|
||||
|
|
|
|||
|
|
@ -2,4 +2,4 @@
|
|||
.. code-block:: sv
|
||||
:emphasize-lines: 1
|
||||
|
||||
#100 $finish; //<--- Warning
|
||||
#100 $finish; //<--- Warning
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.. comment: generated by t_lint_stmtdly_bad
|
||||
.. code-block::
|
||||
|
||||
%Warning-STMTDLY: example.v:1:7 Ignoring delay on this statement due to --no-timing
|
||||
%Warning-STMTDLY: example.v:1:5 Ignoring delay on this statement due to --no-timing
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.. comment: generated by t_assert_comp_bad
|
||||
.. code-block:: sv
|
||||
|
||||
$error("User elaboration-time error");
|
||||
$error("User elaboration-time error");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.. comment: generated by t_assert_comp_bad
|
||||
.. code-block::
|
||||
|
||||
%Warning-USERERROR: example.v:1:7 User elaboration-time error
|
||||
%Warning-USERERROR: example.v:1:5 User elaboration-time error
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.. comment: generated by t_assert_comp_bad
|
||||
.. code-block:: sv
|
||||
|
||||
$fatal(0, "User elaboration-time fatal");
|
||||
$fatal(0, "User elaboration-time fatal");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.. comment: generated by t_assert_comp_bad
|
||||
.. code-block::
|
||||
|
||||
%Warning-USERFATAL: example.v:1:7 User elaboration-time fatal
|
||||
%Warning-USERFATAL: example.v:1:5 User elaboration-time fatal
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.. comment: generated by t_assert_comp_bad
|
||||
.. code-block:: sv
|
||||
|
||||
$info("User elaboration-time info");
|
||||
$info("User elaboration-time info");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.. comment: generated by t_assert_comp_bad
|
||||
.. code-block::
|
||||
|
||||
-Info: example.v:1:7 User elaboration-time info
|
||||
-Info: example.v:1:5 User elaboration-time info
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.. comment: generated by t_assert_comp_bad
|
||||
.. code-block:: sv
|
||||
|
||||
$warning("User elaboration-time warning");
|
||||
$warning("User elaboration-time warning");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.. comment: generated by t_assert_comp_bad
|
||||
.. code-block::
|
||||
|
||||
%Warning-USERWARN: example.v:1:7 User elaboration-time warning
|
||||
%Warning-USERWARN: example.v:1:5 User elaboration-time warning
|
||||
|
|
|
|||
|
|
@ -4,5 +4,5 @@
|
|||
:emphasize-lines: 2
|
||||
|
||||
module t;
|
||||
integer t; //<--- Warning ('t' hidden by module 't')
|
||||
integer t; //<--- Warning ('t' hidden by module 't')
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
.. comment: generated by t_var_bad_hide_docs
|
||||
.. code-block::
|
||||
|
||||
%Warning-VARHIDDEN: example.v:2:12 Declaration of signal hides declaration in upper scope: 't'
|
||||
%Warning-VARHIDDEN: example.v:2:11 Declaration of signal hides declaration in upper scope: 't'
|
||||
example.v:1:8 ... Location of original declaration
|
||||
|
|
|
|||
|
|
@ -63,12 +63,19 @@ rst_prolog = """
|
|||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
#
|
||||
# To install:
|
||||
# sudo install enchant
|
||||
# sudo pip3 install sphinx sphinx_rtd_theme breathe sphinxcontrib-spelling
|
||||
# We keep this list empty for now to avoid needing dependencies
|
||||
# python3 -m venv --system-site-packages ~/.verilator_pyenv
|
||||
# source ~/.verilator_pyenv/bin/activate
|
||||
# pip3 install sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe
|
||||
#
|
||||
# We keep this extensions list empty for now to avoid needing dependencies
|
||||
extensions = []
|
||||
# extensions = ['breathe', 'sphinxcontrib.spelling']
|
||||
# For website builds, this will add sphinxcontrib.jquery
|
||||
if 'VERILATOR_SPHINX_EXTENSIONS' in os.environ:
|
||||
extensions.extend(os.environ.get('VERILATOR_SPHINX_EXTENSIONS', '').split(':'))
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
|
|
@ -110,6 +117,8 @@ html_domain_indices = False
|
|||
html_logo = "../_static/verilator_192_150_min.png"
|
||||
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
# Despite a 'WARNING: Calling get_html_theme_path is deprecated'
|
||||
# the HTML output is different without this line
|
||||
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
|
||||
|
||||
html_theme_options = {
|
||||
|
|
|
|||
|
|
@ -184,7 +184,7 @@ Verilog, put in our.v:
|
|||
import "DPI-C" function int add (input int a, input int b);
|
||||
|
||||
initial begin
|
||||
$display("%x + %x = %x", 1, 2, add(1,2));
|
||||
$display("%x + %x = %x", 1, 2, add(1,2));
|
||||
endtask
|
||||
|
||||
Then after Verilating, Verilator will create a file Vour__Dpi.h with the
|
||||
|
|
@ -225,8 +225,8 @@ called from C++:
|
|||
export "DPI-C" task publicSetBool;
|
||||
|
||||
task publicSetBool;
|
||||
input bit in_bool;
|
||||
var_bool = in_bool;
|
||||
input bit in_bool;
|
||||
var_bool = in_bool;
|
||||
endtask
|
||||
|
||||
Then after Verilating, Verilator will create a file Vour__Dpi.h with the
|
||||
|
|
@ -294,11 +294,11 @@ wrapper:
|
|||
import "DPI-C" context function void dpi_that_accesses_din();
|
||||
|
||||
always @(...)
|
||||
dpi_din_args(din);
|
||||
dpi_din_args(din);
|
||||
|
||||
task dpi_din_args(input din);
|
||||
/* verilator no_inline_task */
|
||||
dpi_that_accesses_din();
|
||||
// verilator no_inline_task
|
||||
dpi_that_accesses_din();
|
||||
endtask
|
||||
|
||||
|
||||
|
|
@ -423,9 +423,9 @@ be deferred for later. These delayed values can be flushed to the model with
|
|||
VPI Example
|
||||
-----------
|
||||
|
||||
In the below example, we have readme marked read-only, and writeme which if
|
||||
written from outside the model will have the same semantics as if it
|
||||
changed on the specified clock edge.
|
||||
In the below example, we have readme marked read-only, and writeme marked
|
||||
read-write which if written from outside the model will have the same semantics
|
||||
as if it was a top level input.
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
|
|
@ -434,7 +434,7 @@ changed on the specified clock edge.
|
|||
parameter WIDTH /*verilator public_flat_rd*/ = 32
|
||||
) (input clk);
|
||||
reg [WIDTH-1:0] readme /*verilator public_flat_rd*/;
|
||||
reg [WIDTH-1:0] writeme /*verilator public_flat_rw @(posedge clk) */;
|
||||
reg [WIDTH-1:0] writeme /*verilator public_flat_rw*/;
|
||||
initial $finish;
|
||||
endmodule
|
||||
EOF
|
||||
|
|
|
|||
|
|
@ -77,9 +77,10 @@ reduce a SystemVerilog design to the smallest possible reproducer.
|
|||
It can be used to automatically reduce a design with hundreds of thousands of
|
||||
lines to a minimal test case while preserving the bug-inducing behavior.
|
||||
|
||||
With :vlopt:`--debug`, Verilator will write a *{prefix}*\ __inputs\ .vpp
|
||||
file which has all of the individual input files combined and
|
||||
pre-processed, this is often useful as the input design into `sv-bugpoint`.
|
||||
With :vlopt:`--debug` or :vlopt:`--dump-inputs`, Verilator will write a
|
||||
*{prefix}*\ __inputs\ .vpp file which has all of the individual input files
|
||||
combined and pre-processed, this is often useful as the input design into
|
||||
`sv-bugpoint`.
|
||||
|
||||
Please refer to `sv-bugpoint README
|
||||
<https://github.com/antmicro/sv-bugpoint/blob/main/README.md>`_ for more
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ When possible, please instead report bugs at `Verilator Issues
|
|||
|
||||
The primary author is Wilson Snyder <wsnyder@wsnyder.org>.
|
||||
|
||||
Major concepts by Paul Wasson, Duane Galbi, John Coiner, Geza Lore, Yutetsu
|
||||
Takatsukasa, and Jie Xu.
|
||||
Major concepts by Krzysztof Bieganski, John Coiner, Duane Galbi, Geza Lore,
|
||||
Ryszard Rozak, Yutetsu Takatsukasa, Paul Wasson, and Jie Xu.
|
||||
|
||||
|
||||
Contributors
|
||||
|
|
|
|||
|
|
@ -20,3 +20,9 @@ C++14 compiler support
|
|||
XML output
|
||||
Verilator currently supports XML parser output (enabled with `--xml-only`).
|
||||
Support for `--xml-*` options will be deprecated no sooner than January 2026.
|
||||
|
||||
--make cmake
|
||||
The `--make cmake` options is deprecated and will be removed no sooner than
|
||||
January 2026. Use `--make json` instead. Note that the CMake integration
|
||||
shipping with Verilator (verilator-config.mk) already uses `--make json` so
|
||||
no changes are necessary if using that.
|
||||
|
|
|
|||
|
|
@ -88,12 +88,23 @@ Summary:
|
|||
grammar and other semantic extensions which might not be legal when
|
||||
set to an older standard.
|
||||
|
||||
.. option:: --aslr
|
||||
|
||||
.. option:: --no-aslr
|
||||
|
||||
Rarely needed - for developer use. With `--aslr`, do not change the
|
||||
system default as to using Linux address space layout randomization
|
||||
(ASLR). With `--no-aslr` attempt to disable ASLR. If not specified,
|
||||
ASLR will be disabled only when using :vlopt:`--debug` (or similar
|
||||
debug-related options), so that pointers have more deterministic values,
|
||||
aiding repeatability.
|
||||
|
||||
.. option:: --no-assert
|
||||
|
||||
Disable all assertions. Implies :vlopt:`--no-assert-case`.
|
||||
|
||||
In versions before 5.038, these were disabled by default, and `--assert`
|
||||
was required to enable assertions.
|
||||
In versions before 5.038, assertions were disabled by default, and
|
||||
`--assert` was required to enable assertions.
|
||||
|
||||
.. option:: --no-assert-case
|
||||
|
||||
|
|
@ -157,10 +168,11 @@ Summary:
|
|||
|
||||
.. option:: --build-jobs <value>
|
||||
|
||||
Specify the level of parallelism for :vlopt:`--build`. If zero, uses the
|
||||
number of threads in the current hardware. Otherwise, the <value> must
|
||||
be a positive integer specifying the maximum number of parallel build
|
||||
jobs.
|
||||
Specify the level of parallelism for :vlopt:`--build`. If zero, uses the
|
||||
number of threads available to the process, which is the number of threads
|
||||
assigned by processor affinity (e.g. using `numactl`), or the number of
|
||||
threads in the host hardware if unspecified. Otherwise, the <value> must be
|
||||
a positive integer specifying the maximum number of parallel build jobs.
|
||||
|
||||
If not provided, and :vlopt:`-j` is provided, the :vlopt:`-j` value is
|
||||
used.
|
||||
|
|
@ -188,6 +200,10 @@ Summary:
|
|||
|
||||
.. option:: --clk <signal-name>
|
||||
|
||||
Deprecated and has no effect (ignored).
|
||||
|
||||
In versions before 5.042:
|
||||
|
||||
With :vlopt:`--clk`, the specified signal is marked as a clock signal.
|
||||
|
||||
The provided signal name is specified using a RTL hierarchy path. For
|
||||
|
|
@ -208,6 +224,10 @@ Summary:
|
|||
|
||||
.. option:: --no-clk <signal-name>
|
||||
|
||||
Deprecated and has no effect (ignored).
|
||||
|
||||
In versions before 5.042:
|
||||
|
||||
Prevent the specified signal from being marked as a clock. See
|
||||
:vlopt:`--clk`.
|
||||
|
||||
|
|
@ -450,6 +470,11 @@ Summary:
|
|||
level 3. Before Verilator 4.228, :vlopt:`--dump-tree` used
|
||||
to include this option.
|
||||
|
||||
.. option:: --dump-inputs
|
||||
|
||||
Rarely needed. Enable dumping a *{prefix}*\ __inputs\ .vpp file which
|
||||
has all of the individual input files combined and pre-processed
|
||||
|
||||
.. option:: --dump-tree
|
||||
|
||||
Rarely needed. Enable dumping Ast .tree debug files with dumping level 3,
|
||||
|
|
@ -514,8 +539,8 @@ Summary:
|
|||
out. Beware of enabling debugging messages, as they will also go to
|
||||
standard out. See :vlopt:`--no-std`, which is implied by this.
|
||||
|
||||
See also :vlopt:`--dump-defines`, :vlopt:`-P`, :vlopt:`--pp-comments`
|
||||
and :vlopt:`--preproc-resolve` options.
|
||||
See also :vlopt:`--dump-defines`, :vlopt:`-P`,
|
||||
:vlopt:`--preproc-comments` and :vlopt:`--preproc-resolve` options.
|
||||
|
||||
.. option:: --emit-accessors
|
||||
|
||||
|
|
@ -604,6 +629,10 @@ Summary:
|
|||
|
||||
.. option:: -fno-const-eager
|
||||
|
||||
.. option:: -fno-dead-assigns
|
||||
|
||||
.. option:: -fno-dead-cells
|
||||
|
||||
.. option:: -fno-dedup
|
||||
|
||||
.. option:: -fno-dfg
|
||||
|
|
@ -772,7 +801,8 @@ Summary:
|
|||
be useful in makefiles. See also :vlopt:`-V`, and the various
|
||||
:file:`*.mk` files.
|
||||
|
||||
Feature may be one of the following: COROUTINES, SYSTEMC.
|
||||
Feature may be one of the following: COROUTINES, DEV_ASAN, DEV_GCOV,
|
||||
SYSTEMC.
|
||||
|
||||
.. option:: --getenv <variable>
|
||||
|
||||
|
|
@ -792,6 +822,14 @@ Summary:
|
|||
:option:`/*verilator&32;hier_block*/` metacomment is ignored. See
|
||||
:ref:`Hierarchical Verilation`.
|
||||
|
||||
.. option:: --hierarchical-block <block>
|
||||
|
||||
Internal use only, for :vlopt:`--hierarchical`.
|
||||
|
||||
.. option:: --hierarchical-child <block>
|
||||
|
||||
Internal use only, for :vlopt:`--hierarchical`.
|
||||
|
||||
.. option:: --hierarchical-params-file <filename>
|
||||
|
||||
Rarely needed - internal use. Internal flag inserted used during
|
||||
|
|
@ -849,9 +887,10 @@ Summary:
|
|||
of Verilator if :vlopt:`--verilate-jobs` isn't provided. Also sets
|
||||
:vlopt:`--output-groups` if isn't provided.
|
||||
|
||||
If zero, uses the number of threads in the current hardware. Otherwise,
|
||||
must be a positive integer specifying the maximum number of parallel
|
||||
build jobs.
|
||||
If zero, uses the number of threads available to the process, which is the
|
||||
number of threads assigned by processor affinity (e.g. using `numactl`), or
|
||||
the number of threads in the host hardware if unspecified. Otherwise, must
|
||||
be a positive integer specifying the maximum number of parallel build jobs.
|
||||
|
||||
.. option:: --no-json-edit-nums
|
||||
|
||||
|
|
@ -944,6 +983,10 @@ Summary:
|
|||
"+libext+" is relatively standard across Verilog tools. Defaults to
|
||||
".v+.sv".
|
||||
|
||||
.. option:: +librescan
|
||||
|
||||
Ignored for compatibility with other simulators.
|
||||
|
||||
.. option:: --lint-only
|
||||
|
||||
Check the files for lint violations only, do not create any other
|
||||
|
|
@ -1052,6 +1095,15 @@ Summary:
|
|||
|
||||
Disables optimization of the model.
|
||||
|
||||
.. option:: -O1
|
||||
|
||||
Enables default optimization of the model. This is the default
|
||||
optimization level.
|
||||
|
||||
.. option:: -O2
|
||||
|
||||
Enables stronger than default optimization of the model.
|
||||
|
||||
.. option:: -O3
|
||||
|
||||
Enables slow optimizations for the code Verilator itself generates (as
|
||||
|
|
@ -1215,7 +1267,8 @@ Summary:
|
|||
|
||||
.. option:: --pp-comments
|
||||
|
||||
With :vlopt:`-E`, show comments in preprocessor output.
|
||||
Deprecated. In versions before 5.042, the name for
|
||||
:vlopt:`--preproc-comments`.
|
||||
|
||||
.. option:: --prefix <topname>
|
||||
|
||||
|
|
@ -1223,6 +1276,14 @@ Summary:
|
|||
prepended to the name of the :vlopt:`--top` option, or V prepended to
|
||||
the first Verilog filename passed on the command line.
|
||||
|
||||
.. option:: --preproc-comments
|
||||
|
||||
With :vlopt:`-E`, show comments in preprocessor output.
|
||||
|
||||
.. option:: --preproc-defines
|
||||
|
||||
With :vlopt:`-E`, show defines and undefs in preprocessor output.
|
||||
|
||||
.. option:: --preproc-resolve
|
||||
|
||||
With :vlopt:`-E`, resolve referenced instance modules, to include
|
||||
|
|
@ -1348,13 +1409,12 @@ Summary:
|
|||
.. option:: --public-flat-rw
|
||||
|
||||
Declares all variables, ports, and wires public as if they had
|
||||
:code:`/*verilator public_flat_rw @ (<variable's_source_process_edge>)*/`
|
||||
metacomments. This will make them VPI accessible by their flat name,
|
||||
but not turn off module inlining. This is particularly useful in
|
||||
combination with :vlopt:`--vpi`. This may also in some rare cases result
|
||||
in mis-simulation of generated clocks. Instead of this global option,
|
||||
marking only those signals that need public_flat_rw is typically
|
||||
significantly better performing.
|
||||
:code:`/*verilator public_flat_rw*/` metacomments. This will make them VPI
|
||||
accessible by their flat name, but not turn off module inlining. This is
|
||||
particularly useful in combination with :vlopt:`--vpi`. This may also in
|
||||
some rare cases result in mis-simulation of generated clocks. Instead of
|
||||
this global option, marking only those signals that need public_flat_rw is
|
||||
typically significantly better performing.
|
||||
|
||||
.. option:: --public-ignore
|
||||
|
||||
|
|
@ -1660,14 +1720,15 @@ Summary:
|
|||
.. option:: --trace-max-array <depth>
|
||||
|
||||
Rarely needed. Specify the maximum array depth of a signal that may be
|
||||
traced. Defaults to 32, as tracing large arrays may greatly slow traced
|
||||
simulations.
|
||||
traced. Zero allows any width. Defaults to 32, as tracing large arrays
|
||||
may greatly slow traced simulations.
|
||||
|
||||
.. option:: --trace-max-width <width>
|
||||
|
||||
Rarely needed. Specify the maximum bit width of a signal that may be
|
||||
traced. Defaults to 256, as tracing large vectors may greatly slow
|
||||
traced simulations.
|
||||
Rarely needed. Specify the maximum total bit width of a signal, across
|
||||
all elements if an array, that may be traced. Zero allows any width.
|
||||
Defaults to 4096, as tracing large vectors may greatly slow traced
|
||||
simulations.
|
||||
|
||||
.. option:: --no-trace-params
|
||||
|
||||
|
|
@ -1786,7 +1847,9 @@ Summary:
|
|||
.. option:: --verilate-jobs <value>
|
||||
|
||||
Specify the level of parallelism for the internal compilation steps of
|
||||
Verilator. If zero, uses the number of threads in the current hardware.
|
||||
Verilator. If zero, uses the number of threads available to the process,
|
||||
which is the number of threads assigned by processor affinity (e.g. using
|
||||
`numactl`), or the number of threads in the host hardware if unspecified.
|
||||
Otherwise, must be a positive integer specifying the maximum number of
|
||||
parallel build jobs.
|
||||
|
||||
|
|
@ -1878,7 +1941,7 @@ Summary:
|
|||
.. option:: -Wno-lint
|
||||
|
||||
Disable all lint-related warning messages, and all style warnings. This
|
||||
is equivalent to ``-Wno-ALWCOMBORDER`` ``-Wno-ASCRANGE``
|
||||
is equivalent to ``-Wno-ALWCOMBORDER`` ``-Wno-ASCRANGE`` ``-Wno-ASSIGNEQEXPR``
|
||||
``-Wno-BSSPACE`` ``-Wno-CASEINCOMPLETE`` ``-Wno-CASEOVERLAP``
|
||||
``-Wno-CASEX`` ``-Wno-CASTCONST`` ``-Wno-CASEWITHX`` ``-Wno-CMPCONST``
|
||||
``-Wno-COLONPLUS`` ``-Wno-IMPLICIT`` ``-Wno-IMPLICITSTATIC``
|
||||
|
|
@ -1932,14 +1995,14 @@ Summary:
|
|||
|
||||
Enable all lint-related warning messages (note that by default, they are
|
||||
already enabled), but do not affect style messages. This is equivalent
|
||||
to ``-Wwarn-ALWCOMBORDER`` ``-Wwarn-ASCRANGE`` ``-Wwarn-BSSPACE``
|
||||
``-Wwarn-CASEINCOMPLETE`` ``-Wwarn-CASEOVERLAP`` ``-Wwarn-CASEWITHX``
|
||||
``-Wwarn-CASEX`` ``-Wwarn-CASTCONST`` ``-Wwarn-CMPCONST``
|
||||
``-Wwarn-COLONPLUS`` ``-Wwarn-IMPLICIT`` ``-Wwarn-IMPLICITSTATIC``
|
||||
``-Wwarn-LATCH`` ``-Wwarn-MISINDENT`` ``-Wwarn-NEWERSTD``
|
||||
``-Wwarn-PREPROCZERO`` ``-Wwarn-PINMISSING`` ``-Wwarn-REALCVT``
|
||||
``-Wwarn-STATICVAR`` ``-Wwarn-UNSIGNED`` ``-Wwarn-WIDTHTRUNC``
|
||||
``-Wwarn-WIDTHEXPAND`` ``-Wwarn-WIDTHXZEXPAND``.
|
||||
to ``-Wwarn-ALWCOMBORDER`` ``-Wwarn-ASCRANGE`` ``-Wno-ASSIGNEQEXPR``
|
||||
``-Wwarn-BSSPACE`` ``-Wwarn-CASEINCOMPLETE`` ``-Wwarn-CASEOVERLAP``
|
||||
``-Wwarn-CASEWITHX`` ``-Wwarn-CASEX`` ``-Wwarn-CASTCONST``
|
||||
``-Wwarn-CMPCONST`` ``-Wwarn-COLONPLUS`` ``-Wwarn-IMPLICIT``
|
||||
``-Wwarn-IMPLICITSTATIC`` ``-Wwarn-LATCH`` ``-Wwarn-MISINDENT``
|
||||
``-Wwarn-NEWERSTD`` ``-Wwarn-PREPROCZERO`` ``-Wwarn-PINMISSING``
|
||||
``-Wwarn-REALCVT`` ``-Wwarn-STATICVAR`` ``-Wwarn-UNSIGNED``
|
||||
``-Wwarn-WIDTHTRUNC`` ``-Wwarn-WIDTHEXPAND`` ``-Wwarn-WIDTHXZEXPAND``.
|
||||
|
||||
.. option:: -Wwarn-style
|
||||
|
||||
|
|
@ -2031,12 +2094,12 @@ Summary:
|
|||
|
||||
.. code-block:: sv
|
||||
|
||||
reg res_n = 1'b0;
|
||||
logic res_n = 1'b0;
|
||||
|
||||
always @(negedge rst_n) begin
|
||||
if (rst_n == 1'b0) begin
|
||||
res_n <= 1'b1;
|
||||
end
|
||||
if (rst_n == 1'b0) begin
|
||||
res_n <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
In Verilator, by default, uninitialized clocks are given a value of
|
||||
|
|
@ -2054,6 +2117,26 @@ Summary:
|
|||
iterations. This may be another indication of problems with the
|
||||
modeled design that should be addressed.
|
||||
|
||||
Instead of using this option, one technique is to explicitly create the
|
||||
appropriate edge by creating a value at construction, and a value in an
|
||||
initial block at time zero:
|
||||
|
||||
.. code-block:: sv
|
||||
|
||||
logic rst_n = 1; // value at construction
|
||||
|
||||
initial begin
|
||||
rst_n = 0; // value at time zero
|
||||
// ... rest
|
||||
end
|
||||
|
||||
always @(negedge rst_n) begin
|
||||
if (rst_n == 1'b0) begin
|
||||
res_n <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
.. option:: --xml-only
|
||||
|
||||
Create XML output only, do not create any other output.
|
||||
|
|
@ -2151,6 +2234,10 @@ The grammar of control commands is as follows:
|
|||
|
||||
.. option:: no_clocker -module "<modulename>" [-task "<taskname>"] -var "<signame>"
|
||||
|
||||
Deprecated and has no effect (ignored).
|
||||
|
||||
In versions before 5.042:
|
||||
|
||||
Indicates whether the signal is used as clock or not. Verilator uses
|
||||
this information to mark the signal and any derived signals as clocker.
|
||||
See :vlopt:`--clk`.
|
||||
|
|
@ -2318,7 +2405,7 @@ The grammar of control commands is as follows:
|
|||
|
||||
.. option:: public_flat_rd [-module "<modulename>"] [-task/-function "<taskname>"] [-var "<signame>"]
|
||||
|
||||
.. option:: public_flat_rw [-module "<modulename>"] [-task/-function "<taskname>"] [-var "<signame>" "@(edge)"]
|
||||
.. option:: public_flat_rw [-module "<modulename>"] [-task/-function "<taskname>"] [-var "<signame>"] ["@(edge)"]
|
||||
|
||||
Sets the variable to be public. Same as
|
||||
:option:`/*verilator&32;public*/` or
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ or "`ifdef`"'s may break other tools.
|
|||
|
||||
.. t_dist_docs_style restart_sort
|
||||
|
||||
.. option:: $c([string], ...);
|
||||
.. option:: $c([string], ...);, $cpure([string], ...);
|
||||
|
||||
The string will be embedded directly in the output C++ code at the point
|
||||
where the surrounding Verilog code is compiled. It may either be a
|
||||
|
|
@ -196,6 +196,11 @@ or "`ifdef`"'s may break other tools.
|
|||
compatibility with other simulators, which require a differently named
|
||||
PLI function name for each different output width.
|
||||
|
||||
`$cpure` is similar to `$c` except that it indicates the
|
||||
expression is pure, versus `$c` which is assumed impure.
|
||||
`$cpure` is for internal use only, and it might change
|
||||
without notice in any future version or Verilator.
|
||||
|
||||
.. option:: $display, $write, $fdisplay, $fwrite, $sformat, $swrite
|
||||
|
||||
Format arguments may use C fprintf sizes after the % escape. Per the
|
||||
|
|
@ -240,7 +245,7 @@ or "`ifdef`"'s may break other tools.
|
|||
reg enable_r /*verilator clock_enable*/;
|
||||
wire gated_clk = clk & enable_r;
|
||||
always_ff @(posedge clk)
|
||||
enable_r <= enable_early;
|
||||
enable_r <= enable_early;
|
||||
|
||||
The clock_enable attribute will cause the clock gate to be ignored in
|
||||
the scheduling algorithm, sometimes required for correct clock behavior,
|
||||
|
|
@ -255,6 +260,10 @@ or "`ifdef`"'s may break other tools.
|
|||
|
||||
.. option:: /*verilator&32;no_clocker*/
|
||||
|
||||
Deprecated and has no effect (ignored).
|
||||
|
||||
In versions before 5.042:
|
||||
|
||||
Specifies whether the signal is used as clock or not. See :vlopt:`--clk`.
|
||||
|
||||
Same as :option:`clocker` and :option:`no_clocker` in configuration
|
||||
|
|
@ -331,8 +340,8 @@ or "`ifdef`"'s may break other tools.
|
|||
// Note the placement of the semicolon above
|
||||
always_comb begin
|
||||
if (....) begin
|
||||
splitme = ....;
|
||||
other assignments
|
||||
splitme = ....;
|
||||
other assignments
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -346,27 +355,32 @@ or "`ifdef`"'s may break other tools.
|
|||
// All assignments excluding those to splitme
|
||||
always_comb begin
|
||||
if (....) begin
|
||||
other assignments
|
||||
other assignments
|
||||
end
|
||||
end
|
||||
// All assignments to splitme
|
||||
always_comb begin
|
||||
if (....) begin
|
||||
splitme = ....;
|
||||
splitme = ....;
|
||||
end
|
||||
end
|
||||
|
||||
Same as :option:`isolate_assignments` control file option.
|
||||
|
||||
.. option:: /*verilator&32;lint_off <msg>*/
|
||||
.. option:: /*verilator&32;lint_off <msgs>*/
|
||||
|
||||
Disable the specified warning message for any warnings following the
|
||||
comment.
|
||||
Disable the specified warning message(s) for any warnings following the
|
||||
comment. Multiple messages may be specified, separated with commas.
|
||||
|
||||
.. option:: /*verilator&32;lint_on <msg>*/
|
||||
If a one-line slash-slash-format comment is used, then the metacomment
|
||||
ends at the newline or at an earlier next slash-slash. This allow
|
||||
commenting the reason for the disable, e.g. :code:`// verilator lint_off
|
||||
MSG // Because...`.
|
||||
|
||||
Re-enable the specified warning message for any warnings following the
|
||||
comment.
|
||||
.. option:: /*verilator&32;lint_on <msgs>*/
|
||||
|
||||
Re-enable the specified warning message(s) for any warnings following
|
||||
the comment. Multiple messages may be specified, separated with commas.
|
||||
|
||||
.. option:: /*verilator&32;lint_restore*/
|
||||
|
||||
|
|
@ -505,13 +519,16 @@ or "`ifdef`"'s may break other tools.
|
|||
|
||||
Same as :option:`public_flat_rd` control file option.
|
||||
|
||||
.. option:: /*verilator&32;public_flat_rw @(<edge_list>)*/ (on variable)
|
||||
.. option:: /*verilator&32;public_flat_rw [@(<edge_list>)]*/ (on variable)
|
||||
|
||||
Used after an input, output, register, or wire declaration to indicate
|
||||
the signal should be declared public_flat_rd (see above), and writable,
|
||||
where writes should be considered to have the timing specified by the
|
||||
given sensitivity edge list. Use of this is implied when using the
|
||||
:vlopt:`--public-flat-rw` option.
|
||||
Used after an input, output, register, or wire declaration to indicate the
|
||||
signal should be declared public_flat_rd (see above), and writable. Use of
|
||||
this is implied when using the :vlopt:`--public-flat-rw` option.
|
||||
|
||||
The edge list is optional and has no effect (is ignored). Prior to
|
||||
Verilator 5.024 the edge list specified the timing when writes took
|
||||
place. This is no longer necessary and is accepted only for
|
||||
compatibility.
|
||||
|
||||
Same as :option:`public_flat_rw` control file option.
|
||||
|
||||
|
|
|
|||
|
|
@ -42,8 +42,8 @@ For --cc/--sc, it creates:
|
|||
|
||||
.. list-table::
|
||||
|
||||
* - *{prefix}*\ .cmake
|
||||
- CMake include script for compiling (from --make cmake)
|
||||
* - *{prefix}*\ .json
|
||||
- JSON build definition compiling (from --make json)
|
||||
* - *{prefix}*\ .mk
|
||||
- Make include file for compiling (from --make gmake)
|
||||
* - *{prefix}*\ _classes.mk
|
||||
|
|
@ -58,12 +58,8 @@ For --cc/--sc, it creates:
|
|||
- Top-level internal C++ file (from SystemVerilog $root)
|
||||
* - *{prefix}*\ ___024root\ *{__n}*\ .cpp
|
||||
- Additional top-level internal C++ files
|
||||
* - *{prefix}*\ ___024root\ *{__DepSet_hash__n}*\ .cpp
|
||||
- Additional top-level internal C++ files (hashed to reduce build times)
|
||||
* - *{prefix}*\ ___024root__Slow\ *{__n}*\ .cpp
|
||||
- Infrequent cold routines
|
||||
* - *{prefix}*\ ___024root\ *{__DepSet_hash__n}*\ .cpp
|
||||
- Infrequent cold routines (hashed to reduce build times)
|
||||
* - *{prefix}*\ ___024root__Trace\ *{__n}*\ .cpp
|
||||
- Wave file generation code (from --trace-\*)
|
||||
* - *{prefix}*\ ___024root__Trace__Slow\ *{__n}*\ .cpp
|
||||
|
|
@ -86,8 +82,6 @@ For --cc/--sc, it creates:
|
|||
- Lower level internal C++ files
|
||||
* - *{prefix}{each_verilog_module}{__n}*\ .cpp
|
||||
- Additional lower C++ files
|
||||
* - *{prefix}{each_verilog_module}{__DepSet_hash__n}*\ .cpp
|
||||
- Additional lower C++ files (hashed to reduce build times)
|
||||
|
||||
For --hierarchical mode, it creates:
|
||||
|
||||
|
|
@ -99,8 +93,8 @@ For --hierarchical mode, it creates:
|
|||
- Make dependencies of the top module (from --hierarchical)
|
||||
* - *{prefix}*\ _hier.mk
|
||||
- Make file for hierarchical blocks (from --make gmake)
|
||||
* - *{prefix}*\ __hierCMakeArgs.f
|
||||
- Arguments for hierarchical Verilation (from --make cmake)
|
||||
* - *{prefix}*\ __hierMkJsonArgs.f
|
||||
- Arguments for hierarchical Verilation (from --make json)
|
||||
* - *{prefix}*\ __hierMkArgs.f
|
||||
- Arguments for hierarchical Verilation (from --make gmake)
|
||||
* - *{prefix}*\ __hierParameters.v
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ started. (Note distribution packages almost never have the most recent
|
|||
Verilator version, so we recommend following :ref:`Git Install` below,
|
||||
instead.) To install as a package:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
apt-get install verilator # On Ubuntu
|
||||
|
||||
|
|
@ -56,7 +56,7 @@ options and details, see :ref:`Detailed Build Instructions` below.
|
|||
|
||||
In brief, to install from git:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
# Prerequisites:
|
||||
#sudo apt-get install git help2man perl python3 make autoconf g++ flex bison ccache
|
||||
|
|
@ -97,11 +97,10 @@ OS Requirements
|
|||
---------------
|
||||
|
||||
Verilator is developed and has primary testing on Ubuntu, with additional
|
||||
testing on FreeBSD and Apple OS-X. Versions have also been built on Red Hat
|
||||
Linux, other flavors of GNU/Linux-ish platforms, Windows Subsystem for
|
||||
Linux (WSL2), Windows under Cygwin, and Windows under MinGW (gcc
|
||||
-mno-cygwin). Verilated output (not Verilator itself) compiles under all
|
||||
the options above, plus using MSVC++.
|
||||
testing on Apple OS-X, FreeBSD and Windows MSVC. Versions have also been
|
||||
built on Red Hat Linux, other flavors of GNU/Linux-ish platforms, Windows
|
||||
Subsystem for Linux (WSL2), Windows under Cygwin, and Windows under MinGW
|
||||
(gcc -mno-cygwin).
|
||||
|
||||
|
||||
Install Prerequisites
|
||||
|
|
@ -109,7 +108,7 @@ Install Prerequisites
|
|||
|
||||
To build or run Verilator, you need these standard packages:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt-get install git help2man perl python3 make
|
||||
sudo apt-get install g++ # Alternatively, clang
|
||||
|
|
@ -120,27 +119,27 @@ To build or run Verilator, you need these standard packages:
|
|||
|
||||
For SystemC:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt-get install libsystemc libsystemc-dev
|
||||
|
||||
For constraints:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt-get install z3 # Optional solver
|
||||
|
||||
The following is optional but is recommended for nicely rendered command line
|
||||
help when running Verilator:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt-get install perl-doc
|
||||
|
||||
To build or run Verilator, the following are optional but should be installed
|
||||
for good performance:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt-get install ccache # If present at build, needed for run
|
||||
sudo apt-get install mold # If present at build, needed for run
|
||||
|
|
@ -149,19 +148,25 @@ for good performance:
|
|||
To build Verilator you will need to install these packages; these do not
|
||||
need to be present to run Verilator:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt-get install git autoconf flex bison
|
||||
|
||||
Those developing Verilator itself also need these (see internals.rst):
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt-get install clang clang-format-18 cmake gdb gprof graphviz lcov
|
||||
sudo apt-get install python3-clang python3-distro yapf3 bear jq
|
||||
sudo pip3 install sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe gersemi mbake ruff sarif-tools
|
||||
sudo pip3 install git+https://github.com/antmicro/astsee.git
|
||||
sudo apt-get install python3-clang python3-distro pipx yapf3 bear jq
|
||||
python3 -m venv --system-site-packages ~/.verilator_pyenv
|
||||
source ~/.verilator_pyenv/bin/activate
|
||||
pip3 install sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe gersemi mbake mypy ruff
|
||||
pip3 install git+https://github.com/antmicro/astsee.git
|
||||
pipx install sarif-tools
|
||||
cpan install Pod::Perldoc
|
||||
#
|
||||
# Later, when building or testing Verilator, you will need
|
||||
source ~/.verilator_pyenv/bin/activate
|
||||
|
||||
|
||||
Install SystemC
|
||||
|
|
@ -185,7 +190,7 @@ To make use of Verilator FST tracing you will want `GTKwave
|
|||
<https://gtkwave.sourceforge.net/>`__ installed, however this is not
|
||||
required at Verilator build time.
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
sudo apt-get install gtkwave # Optional Waveform viewer
|
||||
|
||||
|
|
@ -209,14 +214,14 @@ Obtain Sources
|
|||
Get the sources from the git repository: (You need to do this only once,
|
||||
ever.)
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
git clone https://github.com/verilator/verilator # Only first time
|
||||
## Note the URL above is not a page you can see with a browser; it's for git only
|
||||
|
||||
Enter the checkout and determine what version/branch to use:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
cd verilator
|
||||
git pull # Make sure we're up-to-date
|
||||
|
|
@ -231,7 +236,7 @@ Auto Configure
|
|||
|
||||
Create the configuration script:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
autoconf # Create ./configure script
|
||||
|
||||
|
|
@ -257,7 +262,7 @@ directory (don't run ``make install``). This allows the easiest
|
|||
experimentation and upgrading, and allows many versions of Verilator to
|
||||
co-exist on a system.
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
export VERILATOR_ROOT=`pwd` # if your shell is bash
|
||||
setenv VERILATOR_ROOT `pwd` # if your shell is csh
|
||||
|
|
@ -279,7 +284,7 @@ that may support multiple versions of every tool. Tell configure the
|
|||
eventual destination directory name. We recommend that the destination
|
||||
location include the Verilator version name:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
unset VERILATOR_ROOT # if your shell is bash
|
||||
unsetenv VERILATOR_ROOT # if your shell is csh
|
||||
|
|
@ -291,7 +296,7 @@ the ``bin`` directory to your ``PATH``. Or, if you use `modulecmd
|
|||
<https://modules.sourceforge.net/>`__, you'll want a module file like the
|
||||
following:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
set install_root /CAD_DISK/verilator/{version-number-used-above}
|
||||
unsetenv VERILATOR_ROOT
|
||||
|
|
@ -306,7 +311,7 @@ following:
|
|||
The final option is to eventually install Verilator globally, using
|
||||
configure's default system paths:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
unset VERILATOR_ROOT # if your shell is bash
|
||||
unsetenv VERILATOR_ROOT # if your shell is csh
|
||||
|
|
@ -323,7 +328,7 @@ The command to configure the package was described in the previous step.
|
|||
Developers should configure to have more complete developer tests.
|
||||
Additional packages may be required for these tests.
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
export VERILATOR_AUTHOR_SITE=1 # Put in your .bashrc
|
||||
./configure --enable-longtests ...above options...
|
||||
|
|
@ -334,7 +339,7 @@ Compile
|
|||
|
||||
Compile Verilator:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
make -j `nproc` # Or if error on `nproc`, the number of CPUs in system
|
||||
|
||||
|
|
@ -344,7 +349,7 @@ Test
|
|||
|
||||
Check the compilation by running self-tests:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
make test
|
||||
|
||||
|
|
@ -356,7 +361,7 @@ If you used any install option other than the `1. Run-in-Place from
|
|||
VERILATOR_ROOT <#_1_run_in_place_from_verilator_root>`__ scheme, install
|
||||
the files:
|
||||
|
||||
.. code-block:: shell
|
||||
.. code-block:: bash
|
||||
|
||||
make install
|
||||
|
||||
|
|
|
|||
|
|
@ -130,8 +130,9 @@ same time slot.
|
|||
Rising/falling/turn-off delays are currently unsupported and cause the
|
||||
:option:`RISEFALLDLY` warning.
|
||||
|
||||
Minimum/typical/maximum delays are currently unsupported. The typical delay is
|
||||
always the one chosen. Such expressions cause the :option:`MINTYPMAX` warning.
|
||||
Minimum/typical/maximum delays are currently unsupported. The typical delay
|
||||
is always the one chosen. Such expressions cause the :option:`MINTYPMAXDLY`
|
||||
warning.
|
||||
|
||||
Another consequence of using :vlopt:`--timing` is that the :vlopt:`--main`
|
||||
option generates a main file with a proper timing eval loop, eliminating the
|
||||
|
|
|
|||
|
|
@ -166,11 +166,6 @@ Unfortunately, using the optimizer with SystemC files can result in
|
|||
compilation taking several minutes. (The SystemC libraries have many little
|
||||
inlined functions that drive the compiler nuts.)
|
||||
|
||||
If using your own makefiles, you may want to compile the Verilated
|
||||
code with ``--MAKEFLAGS -DVL_INLINE_OPT=inline``. This will inline
|
||||
functions; however, this requires that all cpp files be compiled in a single
|
||||
compiler run.
|
||||
|
||||
You may uncover further tuning possibilities by profiling the Verilog code.
|
||||
See :ref:`profiling`.
|
||||
|
||||
|
|
|
|||
|
|
@ -18,9 +18,8 @@ Verilator may be used in five major ways:
|
|||
* With the :vlopt:`--lint-only` option, Verilator will lint the design to
|
||||
check for warnings but will not typically create any output files.
|
||||
|
||||
* With the :vlopt:`--xml-only` option, Verilator will create XML output
|
||||
that may be used to feed into other user-designed tools. See
|
||||
:file:`docs/xml.rst` in the distribution.
|
||||
* With the :vlopt:`--json-only` option, Verilator will create JSON output
|
||||
that may be used to feed into other user-designed tools.
|
||||
|
||||
* With the :vlopt:`-E` option, Verilator will preprocess the code according
|
||||
to IEEE preprocessing rules and write the output to standard out. This
|
||||
|
|
@ -60,7 +59,7 @@ When using these options:
|
|||
makefiles to generate an archive (.a) containing the objects.
|
||||
|
||||
#. If :vlopt:`--binary` or :vlopt:`--build` is used, it calls :ref:`GNU
|
||||
Make` or :ref:`CMake` to build the model.
|
||||
Make` to build the model.
|
||||
|
||||
Once a model is built, the next step is typically for the user to run it,
|
||||
see :ref:`Simulating`.
|
||||
|
|
@ -144,8 +143,11 @@ Limitations
|
|||
|
||||
Hierarchy blocks have some limitations, including:
|
||||
|
||||
* The hierarchy block cannot be accessed using dot (.) from the upper
|
||||
module(s) or other hierarchy blocks.
|
||||
* Internals of the hierarchy block cannot be accessed using dot (.) from
|
||||
the upper module(s) or other hierarchy blocks, except that ports of a
|
||||
hierarchy block instance can be accessed from the directly enclosing
|
||||
nested hierarchy block, or from the top level non-hierarchical portions
|
||||
of the design if not a nested hierarchy block.
|
||||
|
||||
* Modport cannot be used at the hierarchical block boundary.
|
||||
|
||||
|
|
|
|||
|
|
@ -103,8 +103,8 @@ List Of Warnings
|
|||
.. code-block:: sv
|
||||
|
||||
always_comb begin
|
||||
a = b;
|
||||
b = 1;
|
||||
a = b;
|
||||
b = 1;
|
||||
end
|
||||
|
||||
Ignoring this warning will only suppress the lint check; it will
|
||||
|
|
@ -169,6 +169,29 @@ List Of Warnings
|
|||
This warning is issued only if Verilator is run with :vlopt:`--no-timing`.
|
||||
|
||||
|
||||
.. option:: ASSIGNEQEXPR
|
||||
|
||||
Warning that an assignment with `=` appears in a complex expression.
|
||||
The intent may have been to use `==`, or, if `=` is correct this may be
|
||||
a readability issue.
|
||||
|
||||
Faulty example:
|
||||
|
||||
.. include:: ../../docs/gen/ex_ASSIGNEQEXPR_faulty.rst
|
||||
|
||||
Results in:
|
||||
|
||||
.. include:: ../../docs/gen/ex_ASSIGNEQEXPR_msg.rst
|
||||
|
||||
To repair, make the assignment into a separate statement.
|
||||
|
||||
Disabled by default as this is a code-style warning; it will simulate
|
||||
correctly.
|
||||
|
||||
Ignoring this warning will only suppress the lint check; it will
|
||||
simulate correctly.
|
||||
|
||||
|
||||
.. option:: ASSIGNIN
|
||||
|
||||
.. TODO better example
|
||||
|
|
@ -275,11 +298,11 @@ List Of Warnings
|
|||
.. code-block:: sv
|
||||
|
||||
always @(posedge clk)
|
||||
if (~reset_l)
|
||||
for (i=0; i<`ARRAY_SIZE; i++)
|
||||
array[i] <= 0; // Non-blocking assignment inside loop
|
||||
else
|
||||
array[address] <= data;
|
||||
if (~reset_l)
|
||||
for (i=0; i<`ARRAY_SIZE; i++)
|
||||
array[i] <= 0; // Non-blocking assignment inside loop
|
||||
else
|
||||
array[address] <= data;
|
||||
|
||||
While this is supported in typical synthesizeable code (including the
|
||||
example above), some complicated cases are not supported. Namely:
|
||||
|
|
@ -485,6 +508,17 @@ List Of Warnings
|
|||
from other simulators.
|
||||
|
||||
|
||||
.. option:: CONSTWRITTEN
|
||||
|
||||
Error that a :code:`const` data typed variable is being assigned a
|
||||
value.
|
||||
|
||||
IEEE 1800-2023 6.20.6 requires this error.
|
||||
|
||||
Suppressing this error will suppress the error message check; it will
|
||||
simulate as if the :code:`const` as not present.
|
||||
|
||||
|
||||
.. option:: CONTASSREG
|
||||
|
||||
.. TODO better example
|
||||
|
|
@ -577,7 +611,7 @@ List Of Warnings
|
|||
:emphasize-lines: 5
|
||||
|
||||
module parameterized
|
||||
#(parameter int MY_PARAM = 0);
|
||||
#(parameter int MY_PARAM = 0);
|
||||
endmodule
|
||||
module upper;
|
||||
defparam p0.MY_PARAM = 1; //<--- Warning
|
||||
|
|
@ -598,12 +632,12 @@ List Of Warnings
|
|||
:emphasize-lines: 6
|
||||
|
||||
module parameterized
|
||||
#(parameter int MY_PARAM = 0);
|
||||
#(parameter int MY_PARAM = 0);
|
||||
endmodule
|
||||
module upper
|
||||
parameterized
|
||||
#(.MY_PARAM(1)) //<--- Repaired
|
||||
p0();
|
||||
#(.MY_PARAM(1)) //<--- Repaired
|
||||
p0();
|
||||
endmodule
|
||||
|
||||
Other tools with similar warnings: Verible's forbid_defparam_rule.
|
||||
|
|
@ -683,7 +717,7 @@ List Of Warnings
|
|||
generated C++ code to add appropriate prints to see what is going on.
|
||||
|
||||
|
||||
.. option:: ENDCAPSULATED
|
||||
.. option:: ENCAPSULATED
|
||||
|
||||
Warns that a class member is declared :code:`local` or
|
||||
:code:`protected`, but is being accessed from outside that class (if
|
||||
|
|
@ -745,7 +779,7 @@ List Of Warnings
|
|||
:emphasize-lines: 2
|
||||
|
||||
typedef enum [3:0] {
|
||||
WRONG_WIDTH = 33'h3 //<--- Warning
|
||||
WRONG_WIDTH = 33'h3 //<--- Warning
|
||||
} enum_t;
|
||||
|
||||
To repair, correct the size of the item's value directly, or use a cast,
|
||||
|
|
@ -801,6 +835,25 @@ List Of Warnings
|
|||
with a newline."
|
||||
|
||||
|
||||
.. option:: FUNCTIMECTL
|
||||
|
||||
Error that a function contains a time-controlling statement or call of a
|
||||
task. IEEE 1800-2023 13.4 requires this error.
|
||||
|
||||
Faulty example:
|
||||
|
||||
.. include:: ../../docs/gen/ex_FUNCTIMECTL_faulty.rst
|
||||
|
||||
Results in:
|
||||
|
||||
.. include:: ../../docs/gen/ex_FUNCTIMECTL_msg.rst
|
||||
|
||||
Suppressing this error will only suppress the IEEE-required check; in
|
||||
most cases Verilator treats functions and tasks identically and relies
|
||||
on analysis to determine what functions/tasks need to allow time to
|
||||
pass.
|
||||
|
||||
|
||||
.. option:: GENCLK
|
||||
|
||||
Historical, never issued since version 5.000.
|
||||
|
|
@ -831,8 +884,8 @@ List Of Warnings
|
|||
:emphasize-lines: 2
|
||||
|
||||
generate
|
||||
if (PARAM == 1) begin //<--- Warning
|
||||
end
|
||||
if (PARAM == 1) begin //<--- Warning
|
||||
end
|
||||
|
||||
Results in:
|
||||
|
||||
|
|
@ -848,8 +901,8 @@ List Of Warnings
|
|||
:emphasize-lines: 2
|
||||
|
||||
generate
|
||||
if (PARAM == 1) begin : gen_param_1 //<--- Repaired
|
||||
end
|
||||
if (PARAM == 1) begin : gen_param_1 //<--- Repaired
|
||||
end
|
||||
|
||||
Other tools with similar warnings: Verible's generate-label, "All
|
||||
generate block statements must have a label."
|
||||
|
|
@ -862,6 +915,28 @@ List Of Warnings
|
|||
This setting on the top module will be ignored.
|
||||
|
||||
|
||||
.. option:: HIERPARAM
|
||||
|
||||
An error that a hierarchical value or function is being used to assign a parameter.
|
||||
IEEE 1800-2023 6.20.2 requires this error.
|
||||
|
||||
Faulty example:
|
||||
|
||||
.. include:: ../../docs/gen/ex_HIERPARAM_faulty.rst
|
||||
|
||||
Results in:
|
||||
|
||||
.. include:: ../../docs/gen/ex_HIERPARAM_msg.rst
|
||||
|
||||
Suppressing this error may allow some hierarchical references to work (especially hierarchical
|
||||
references into interface references), however not all cases are possible, e.g. it cannot
|
||||
reference the parameter of a lower module in a way that affects determining the parameters
|
||||
that elaborate that lower module.
|
||||
|
||||
An exception is made for IEEE 1800-2023 25.10 for interfaces/modports which appear in a module's
|
||||
port list, since these are references to interfaces/modports declared at a higher level and are
|
||||
already specialized. These types of accesses do not require waiving HIERPARAM.
|
||||
|
||||
.. option:: IFDEPTH
|
||||
|
||||
Warns that if/if else statements have exceeded the depth specified with
|
||||
|
|
@ -885,7 +960,7 @@ List Of Warnings
|
|||
:emphasize-lines: 5
|
||||
|
||||
function int function_being_called_as_task;
|
||||
return 1;
|
||||
return 1;
|
||||
endfunction
|
||||
|
||||
initial function_being_called_as_task(); //<--- Warning
|
||||
|
|
@ -904,7 +979,7 @@ List Of Warnings
|
|||
:emphasize-lines: 5
|
||||
|
||||
function int function_being_called_as_task;
|
||||
return 1;
|
||||
return 1;
|
||||
endfunction
|
||||
|
||||
initial void'(function_being_called_as_task()); //<--- Repaired
|
||||
|
|
@ -1074,10 +1149,10 @@ List Of Warnings
|
|||
:emphasize-lines: 3
|
||||
|
||||
task foo(int local_var);
|
||||
fork
|
||||
#10 local_var++;
|
||||
#20 $display("local_var = %d", local_var);
|
||||
join_none
|
||||
fork
|
||||
#10 local_var++;
|
||||
#20 $display("local_var = %d", local_var);
|
||||
join_none
|
||||
endtask
|
||||
|
||||
In the example above 'local_var' exists only within scope of 'foo', once foo
|
||||
|
|
@ -1099,19 +1174,19 @@ List Of Warnings
|
|||
:emphasize-lines: 4
|
||||
|
||||
task foo(int local_var);
|
||||
fork
|
||||
#10 begin
|
||||
int forked_var = local_var;
|
||||
forked_var++;
|
||||
end
|
||||
#20 begin
|
||||
// Note that we are going to print the original value here,
|
||||
// as `forked_var`is a local copy that was initialized while
|
||||
// `foo` was still alive.
|
||||
int forked_var = local_var;
|
||||
$display("forked_var = %d", forked_var)
|
||||
end
|
||||
join_none
|
||||
fork
|
||||
#10 begin
|
||||
int forked_var = local_var;
|
||||
forked_var++;
|
||||
end
|
||||
#20 begin
|
||||
// Note that we are going to print the original value here,
|
||||
// as `forked_var`is a local copy that was initialized while
|
||||
// `foo` was still alive.
|
||||
int forked_var = local_var;
|
||||
$display("forked_var = %d", forked_var)
|
||||
end
|
||||
join_none
|
||||
endtask
|
||||
|
||||
If you need to share its state, another strategy is to ensure it's allocated
|
||||
|
|
@ -1124,10 +1199,10 @@ List Of Warnings
|
|||
int static_var;
|
||||
|
||||
task foo();
|
||||
fork
|
||||
#10 static_var++;
|
||||
#20 $display("static_var = %d", static_var);
|
||||
join_none
|
||||
fork
|
||||
#10 static_var++;
|
||||
#20 $display("static_var = %d", static_var);
|
||||
join_none
|
||||
endtask
|
||||
|
||||
However, if you need to be able to instantiate at runtime, the solution would be to
|
||||
|
|
@ -1139,23 +1214,23 @@ List Of Warnings
|
|||
:emphasize-lines: 2
|
||||
|
||||
class Wrapper;
|
||||
int m_var;
|
||||
int m_var;
|
||||
|
||||
// Here we implicitly hold a reference to `this`
|
||||
task foo();
|
||||
fork
|
||||
#10 m_var++;
|
||||
#20 $display("this.m_var = %d", m_var);
|
||||
join_none
|
||||
endtask
|
||||
// Here we implicitly hold a reference to `this`
|
||||
task foo();
|
||||
fork
|
||||
#10 m_var++;
|
||||
#20 $display("this.m_var = %d", m_var);
|
||||
join_none
|
||||
endtask
|
||||
endclass
|
||||
|
||||
// Here we explicitly hold a handle to an object
|
||||
task bar(Wrapper wrapper);
|
||||
fork
|
||||
#10 wrapper.m_var++;
|
||||
#20 $display("wrapper.m_var = %d", wrapper.m_var);
|
||||
join_none
|
||||
fork
|
||||
#10 wrapper.m_var++;
|
||||
#20 $display("wrapper.m_var = %d", wrapper.m_var);
|
||||
join_none
|
||||
endtask
|
||||
|
||||
.. option:: LITENDIAN
|
||||
|
|
@ -1166,7 +1241,7 @@ List Of Warnings
|
|||
backwards compatibility, new projects should use :option:`ASCRANGE`.
|
||||
|
||||
|
||||
.. option:: MINTYPMAX
|
||||
.. option:: MINTYPMAXDLY
|
||||
|
||||
.. code-block:: sv
|
||||
|
||||
|
|
@ -1197,8 +1272,8 @@ List Of Warnings
|
|||
:emphasize-lines: 3
|
||||
|
||||
if (something)
|
||||
statement_in_if;
|
||||
statement_not_in_if; //<--- Warning
|
||||
statement_in_if;
|
||||
statement_not_in_if; //<--- Warning
|
||||
|
||||
Results in:
|
||||
|
||||
|
|
@ -1214,7 +1289,7 @@ List Of Warnings
|
|||
:emphasize-lines: 3
|
||||
|
||||
if (something)
|
||||
statement_in_if;
|
||||
statement_in_if;
|
||||
statement_not_in_if; //<--- Repaired
|
||||
|
||||
Other tools with similar warnings: GCC -Wmisleading-indentation,
|
||||
|
|
@ -1367,6 +1442,27 @@ List Of Warnings
|
|||
simulate correctly.
|
||||
|
||||
|
||||
.. option:: NORETURN
|
||||
|
||||
Warns that a non-void function has no return statement, nor sets the
|
||||
output result of the function.
|
||||
|
||||
Faulty example:
|
||||
|
||||
.. include:: ../../docs/gen/ex_NORETURN_faulty.rst
|
||||
|
||||
Results in:
|
||||
|
||||
.. include:: ../../docs/gen/ex_NORETURN_msg.rst
|
||||
|
||||
To fix the issue, add a :code:`return` statement, or set the output
|
||||
variable of the function, or make the function of data type
|
||||
:code:`void`.
|
||||
|
||||
Ignoring this warning will only suppress the lint check; it will
|
||||
simulate correctly.
|
||||
|
||||
|
||||
.. option:: NOTIMING
|
||||
|
||||
Error when a timing-related construct that requires :vlopt:`--timing` has
|
||||
|
|
@ -1489,11 +1585,11 @@ List Of Warnings
|
|||
module a;
|
||||
localparam A=1;
|
||||
generate
|
||||
if (A==0) begin
|
||||
b b_inst1 (.x(1'b0)); //<--- error nonexistent port
|
||||
b #(.PX(1'b0)) b_inst2 (); //<--- error nonexistent parameter
|
||||
end
|
||||
endgenerate
|
||||
if (A==0) begin
|
||||
b b_inst1 (.x(1'b0)); //<--- error nonexistent port
|
||||
b #(.PX(1'b0)) b_inst2 (); //<--- error nonexistent parameter
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module b;
|
||||
|
|
@ -1766,9 +1862,9 @@ List Of Warnings
|
|||
|
||||
wire vec[6:0];
|
||||
initial begin
|
||||
index = 7;
|
||||
...
|
||||
if (index < 7) out = vec[index]; // Never will use vec[7]
|
||||
index = 7;
|
||||
...
|
||||
if (index < 7) out = vec[index]; // Never will use vec[7]
|
||||
|
||||
Other tools with similar warnings: Icarus Verilog's select-range,
|
||||
"warning: ... [...] is selecting before vector" or "is selecting before
|
||||
|
|
@ -1952,7 +2048,7 @@ List Of Warnings
|
|||
task foo(inout sig); ... endtask
|
||||
// ...
|
||||
always @* begin
|
||||
foo(bus_we_select_from[2]); // Will get TASKNSVAR error
|
||||
foo(bus_we_select_from[2]); // Will get TASKNSVAR error
|
||||
end
|
||||
|
||||
Change this to:
|
||||
|
|
@ -1963,8 +2059,8 @@ List Of Warnings
|
|||
// ...
|
||||
reg foo_temp_out;
|
||||
always @* begin
|
||||
foo(foo_temp_out);
|
||||
bus_we_select_from[2] = foo_temp_out;
|
||||
foo(foo_temp_out);
|
||||
bus_we_select_from[2] = foo_temp_out;
|
||||
end
|
||||
|
||||
Verilator doesn't do this conversion for you, as some more complicated
|
||||
|
|
@ -2209,6 +2305,14 @@ List Of Warnings
|
|||
:option:`UNUSEDSIGNAL`.
|
||||
|
||||
|
||||
.. option:: UNUSEDLOOP
|
||||
|
||||
.. TODO better example
|
||||
|
||||
Warns that a loop condition is always false, and so the body of the loop
|
||||
will never be executed.
|
||||
|
||||
|
||||
.. option:: UNUSEDPARAM
|
||||
|
||||
.. TODO better example
|
||||
|
|
|
|||
|
|
@ -1656,6 +1656,54 @@ significant variance. Experience shows that a ~20% time difference can be
|
|||
reliably measured on GitHub hosted runners, and smaller differences are
|
||||
noticeable over a few days of reruns as trends emerge from the noise.
|
||||
|
||||
Code coverage
|
||||
-------------
|
||||
|
||||
Code coverage for developing Verilator itself can be collected using ``gcc``
|
||||
and ``gcov`` with the following flow. Note that configuring with
|
||||
``--enable-dev-gcov`` disables optimization for both the debug and optimized
|
||||
builds of Verilator, so running the resulting executables can be slow:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
./configure --enable-longtests --enable-dev-gcov
|
||||
make -j$(nproc) # Build verilator
|
||||
make test # Run the tests - this will generate .gcda files
|
||||
make coverage-view # Create and open HTML coverate reprot
|
||||
|
||||
|
||||
The ``coverage-view`` make target opens the generated coverage report. This
|
||||
depends on ``coverage-report``, which generates the HTML coverage report. That
|
||||
turn depends on ``coverage-combine``, which combines all ``.gcda`` files into
|
||||
an lcov data file. Each of these make targets can be used separately if
|
||||
desired.
|
||||
|
||||
You can also use the ``coverage-zero`` target to remove all ``.gcda`` files,
|
||||
which in effect clears all collected coverage data. This can be useful when
|
||||
checking individual test cases while modifying them.
|
||||
|
||||
To collect coverage only for select tests, instead of ``make test``, run the
|
||||
individual ``test_regress/t/*.py`` cases, then use ``make coverage-view`` as
|
||||
before.
|
||||
|
||||
Note that every time binary built with coverage collection is invoked, it will
|
||||
add the coverage data collected during that invocation to the existing
|
||||
``.gcda`` files. This means that ``verilator`` can also be run on any other
|
||||
external files or projects to collect code coverage on those invocations.
|
||||
|
||||
Be aware if changing a test, if that test no longer covers some item, the
|
||||
report will still contain the old coverage. Use ``make coverage-zero`` and
|
||||
rerun all tests if this is a concern.
|
||||
|
||||
It is also possible to generate a 'patch coverage' report, which will only
|
||||
contain information about lines modified compared to a Git ref specified by the
|
||||
``COVERAGE_BASE`` Make variable (including uncommitted changes). For example,
|
||||
to see coverage of changes compared to upstream, use:
|
||||
|
||||
.. code:: shell
|
||||
|
||||
make coverage-view COVERAGE_BASE=origin/master
|
||||
|
||||
Fuzzing
|
||||
-------
|
||||
|
||||
|
|
@ -2194,17 +2242,15 @@ driver.py Non-Scenario Arguments
|
|||
--rrsim
|
||||
Run Verilator generated executable and record with ``rr``.
|
||||
|
||||
--sanitize
|
||||
Enable address sanitizer to compile Verilated C++ code. This may detect
|
||||
misuses of memory, such as out-of-bound accesses, use-after-free, and
|
||||
memory leaks.
|
||||
|
||||
--site
|
||||
Run site-specific tests also.
|
||||
|
||||
--stop
|
||||
Stop on the first error.
|
||||
|
||||
--top-filename <file>
|
||||
Override the default Verilog file name.
|
||||
|
||||
--trace
|
||||
Set the simulator-specific flags to request waveform tracing.
|
||||
|
||||
|
|
|
|||
|
|
@ -218,6 +218,7 @@ Katzman
|
|||
Kelin
|
||||
Keren
|
||||
Keyi
|
||||
Keßler
|
||||
Kimmitt
|
||||
Kindgren
|
||||
Kirkham
|
||||
|
|
@ -361,6 +362,7 @@ Rolfe
|
|||
Rontionov
|
||||
Roodselaar
|
||||
Roshit
|
||||
Rufer
|
||||
Runtime
|
||||
Ruud
|
||||
Rystsov
|
||||
|
|
@ -428,6 +430,7 @@ Terpstra
|
|||
Thiede
|
||||
Thierry
|
||||
Thyer
|
||||
Tianchen
|
||||
Tianrui
|
||||
Tichelaar
|
||||
Timi
|
||||
|
|
@ -527,6 +530,8 @@ ar
|
|||
architected
|
||||
args
|
||||
arrarys
|
||||
asan
|
||||
aslr
|
||||
assertOn
|
||||
assertcontrol
|
||||
astgen
|
||||
|
|
@ -610,6 +615,7 @@ covergroup
|
|||
cpp
|
||||
cppstyle
|
||||
cpu
|
||||
cpure
|
||||
ctor
|
||||
ctrace
|
||||
cutable
|
||||
|
|
@ -644,6 +650,7 @@ detections
|
|||
dev
|
||||
devcontainer
|
||||
devel
|
||||
difftree
|
||||
dir
|
||||
disambiguates
|
||||
displayb
|
||||
|
|
@ -745,7 +752,9 @@ fwrite
|
|||
gantt
|
||||
gcc
|
||||
gcda
|
||||
gcov
|
||||
gdb
|
||||
gdbinit
|
||||
genblk
|
||||
genvar
|
||||
genvars
|
||||
|
|
@ -763,8 +772,8 @@ hdr
|
|||
hdzhangdoc
|
||||
hh
|
||||
hier
|
||||
hierCMakeArgs
|
||||
hierMkArgs
|
||||
hierMkJsonArgs
|
||||
hierParameters
|
||||
hierVer
|
||||
html
|
||||
|
|
@ -844,6 +853,7 @@ miree
|
|||
mis
|
||||
misconnected
|
||||
misconversion
|
||||
misdetecting
|
||||
misoptimized
|
||||
missized
|
||||
mk
|
||||
|
|
@ -1098,6 +1108,7 @@ unbased
|
|||
uncomment
|
||||
undef
|
||||
undefineall
|
||||
undefs
|
||||
undriven
|
||||
ungetc
|
||||
unhandled
|
||||
|
|
|
|||
|
|
@ -256,8 +256,8 @@ std::string _vl_string_vprintf(const char* formatp, va_list ap) VL_MT_SAFE {
|
|||
}
|
||||
|
||||
uint64_t _vl_dbg_sequence_number() VL_MT_SAFE {
|
||||
static std::atomic<uint64_t> sequence;
|
||||
return ++sequence;
|
||||
static std::atomic<uint64_t> s_sequence;
|
||||
return ++s_sequence;
|
||||
}
|
||||
|
||||
uint32_t VL_THREAD_ID() VL_MT_SAFE {
|
||||
|
|
@ -294,6 +294,16 @@ void VL_PRINTF_MT(const char* formatp, ...) VL_MT_SAFE {
|
|||
}});
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Process -- parts of std::process implementation
|
||||
|
||||
std::string VlProcess::randstate() const VL_MT_UNSAFE {
|
||||
return VlRNG::vl_thread_rng().get_randstate();
|
||||
}
|
||||
void VlProcess::randstate(const std::string& state) VL_MT_UNSAFE {
|
||||
VlRNG::vl_thread_rng().set_randstate(state);
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// Random -- Mostly called at init time, so not inline.
|
||||
|
||||
|
|
@ -1322,6 +1332,19 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
|||
_vl_vsss_advance(fp, floc);
|
||||
break;
|
||||
}
|
||||
case '0': // FALLTHRU
|
||||
case '1': // FALLTHRU
|
||||
case '2': // FALLTHRU
|
||||
case '3': // FALLTHRU
|
||||
case '4': // FALLTHRU
|
||||
case '5': // FALLTHRU
|
||||
case '6': // FALLTHRU
|
||||
case '7': // FALLTHRU
|
||||
case '8': // FALLTHRU
|
||||
case '9': {
|
||||
inPct = true;
|
||||
break;
|
||||
}
|
||||
case '*':
|
||||
inPct = true;
|
||||
inIgnore = true;
|
||||
|
|
@ -1329,7 +1352,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
|||
default: {
|
||||
// Deal with all read-and-scan somethings
|
||||
// Note LSBs are preserved if there's an overflow
|
||||
const int obits = inIgnore ? 0 : va_arg(ap, int);
|
||||
int obits = inIgnore ? 0 : va_arg(ap, int);
|
||||
VlWide<VL_WQ_WORDS_E> qowp;
|
||||
VL_SET_WQ(qowp, 0ULL);
|
||||
WDataOutP owp = qowp;
|
||||
|
|
@ -1390,7 +1413,26 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
|||
VL_SET_WQ(owp, u.ld);
|
||||
break;
|
||||
}
|
||||
case 't': // FALLTHRU // Time
|
||||
case 't': { // Time
|
||||
_vl_vsss_skipspace(fp, floc, fromp, fstr);
|
||||
_vl_vsss_read_str(fp, floc, fromp, fstr, t_tmp, "+-.0123456789eE");
|
||||
if (!t_tmp[0]) goto done;
|
||||
union {
|
||||
double r;
|
||||
int64_t ld;
|
||||
} u;
|
||||
// Get pointer argument first, as proceeds the timeunit value
|
||||
if (obits != 64) goto done;
|
||||
QData* const realp = va_arg(ap, QData*);
|
||||
const int timeunit = va_arg(ap, int);
|
||||
const int userUnits
|
||||
= Verilated::threadContextp()->impp()->timeFormatUnits(); // 0..-15
|
||||
const int shift = -userUnits + timeunit; // 0..-15
|
||||
u.r = std::strtod(t_tmp, nullptr) * vl_time_multiplier(-shift);
|
||||
*realp = VL_CLEAN_QQ(obits, obits, u.ld);
|
||||
obits = 0; // Already loaded the value, don't read arg
|
||||
break;
|
||||
}
|
||||
case '#': { // Unsigned decimal
|
||||
_vl_vsss_skipspace(fp, floc, fromp, fstr);
|
||||
_vl_vsss_read_str(fp, floc, fromp, fstr, t_tmp, "0123456789+-xXzZ?_");
|
||||
|
|
@ -2461,11 +2503,11 @@ void VL_WRITEMEM_N(bool hex, // Hex format, else binary
|
|||
// Timescale conversion
|
||||
|
||||
static const char* vl_time_str(int scale) VL_PURE {
|
||||
static const char* const names[]
|
||||
static const char* const s_names[]
|
||||
= {"100s", "10s", "1s", "100ms", "10ms", "1ms", "100us", "10us", "1us",
|
||||
"100ns", "10ns", "1ns", "100ps", "10ps", "1ps", "100fs", "10fs", "1fs"};
|
||||
if (VL_UNLIKELY(scale > 2 || scale < -15)) scale = 0;
|
||||
return names[2 - scale];
|
||||
return s_names[2 - scale];
|
||||
}
|
||||
double vl_time_multiplier(int scale) VL_PURE {
|
||||
// Return timescale multiplier -18 to +18
|
||||
|
|
@ -2765,11 +2807,11 @@ void VerilatedContext::threads(unsigned n) {
|
|||
|
||||
if (m_threads == n) return; // To avoid unnecessary warnings
|
||||
m_threads = n;
|
||||
const unsigned hardwareThreadsAvailable = std::thread::hardware_concurrency();
|
||||
if (m_threads > hardwareThreadsAvailable) {
|
||||
VL_PRINTF_MT("%%Warning: System has %u hardware threads but simulation thread count set "
|
||||
"to %u. This will likely cause significant slowdown.\n",
|
||||
hardwareThreadsAvailable, m_threads);
|
||||
const unsigned threadsAvailableToProcess = VlOs::getProcessDefaultParallelism();
|
||||
if (m_threads > threadsAvailableToProcess) {
|
||||
VL_PRINTF_MT("%%Warning: Process has %u hardware threads available, but simulation thread "
|
||||
"count set to %u. This will likely cause significant slowdown.\n",
|
||||
threadsAvailableToProcess, m_threads);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2817,11 +2859,13 @@ void VerilatedContext::addModel(const VerilatedModel* modelp) {
|
|||
|
||||
// We look for time passing, as opposed to post-eval(), as embedded
|
||||
// models might get added inside initial blocks.
|
||||
if (VL_UNLIKELY(time()))
|
||||
VL_FATAL_MT(
|
||||
"", 0, "",
|
||||
"Adding model when time is non-zero. ... Suggest check time(), or for restarting"
|
||||
" model use a new VerilatedContext");
|
||||
if (VL_UNLIKELY(time())) {
|
||||
const std::string msg
|
||||
= "Adding model '"s + modelp->hierName()
|
||||
+ "' when time is non-zero. ... Suggest check time(), or for restarting"
|
||||
" model use a new VerilatedContext";
|
||||
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||
}
|
||||
|
||||
threadPoolp(); // Ensure thread pool is created, so m_threads cannot change any more
|
||||
m_threadsInModels += modelp->threads();
|
||||
|
|
|
|||
|
|
@ -186,15 +186,6 @@ struct VlIsCustomStruct : public std::false_type {};
|
|||
template <typename T>
|
||||
struct VlContainsCustomStruct : VlIsCustomStruct<T> {};
|
||||
|
||||
//=============================================================================
|
||||
// Utility functions
|
||||
|
||||
template <size_t N>
|
||||
inline constexpr size_t roundUpToMultipleOf(size_t value) {
|
||||
static_assert((N & (N - 1)) == 0, "'N' must be a power of 2");
|
||||
return (value + N - 1) & ~(N - 1);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Mutex and threading support
|
||||
|
||||
|
|
@ -451,7 +442,7 @@ protected:
|
|||
// Implementation details
|
||||
const std::unique_ptr<VerilatedContextImpData> m_impdatap;
|
||||
// Number of threads to use for simulation (size of m_threadPool + 1 for main thread)
|
||||
unsigned m_threads = std::thread::hardware_concurrency();
|
||||
unsigned m_threads = VlOs::getProcessDefaultParallelism();
|
||||
// Number of threads in added models
|
||||
unsigned m_threadsInModels = 0;
|
||||
// The thread pool shared by all models added to this context
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ PYTHON3 = @PYTHON3@
|
|||
|
||||
# Configuration time options
|
||||
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
|
||||
CFG_WITH_DEV_GCOV = @CFG_WITH_DEV_GCOV@
|
||||
CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
|
||||
|
||||
# Compiler version found during configure. This make variable is not used
|
||||
|
|
@ -144,6 +145,13 @@ OPT_FAST = -Os
|
|||
# to change this as the library is small, but can have significant speed impact.
|
||||
OPT_GLOBAL = -Os
|
||||
|
||||
# Disable optimization when collecing code coverage for Verilator itself
|
||||
ifeq ($(CFG_WITH_DEV_GCOV),yes)
|
||||
OPT_SLOW = -O0
|
||||
OPT_FAST = -O0
|
||||
OPT_GLOBAL = -O0
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
##### Profile builds
|
||||
|
||||
|
|
@ -322,12 +330,11 @@ ifneq ($(findstring ccache-report,$(MAKECMDGOALS)),)
|
|||
$(VK_CCACHE_REPORT): $(VK_OBJS)
|
||||
$(VERILATOR_CCACHE_REPORT) -o $@ $(VK_CCACHE_LOGDIR)
|
||||
|
||||
# ccache-report runs last
|
||||
.PHONY: ccache-report
|
||||
ccache-report: $(VK_CCACHE_REPORT)
|
||||
ccache-report: $(VK_CCACHE_REPORT) $(VK_OTHER_GOALS)
|
||||
@cat $<
|
||||
|
||||
# ccache-report runs last
|
||||
ccache-report: $(VK_OTHER_GOALS)
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
|
|
|
|||
|
|
@ -42,10 +42,18 @@ static inline void VL_SET_W_SVBV(int obits, WDataOutP owp, const svBitVecVal* lw
|
|||
for (int i = 0; i < words - 1; ++i) owp[i] = lwp[i];
|
||||
owp[words - 1] = lwp[words - 1] & VL_MASK_I(obits);
|
||||
}
|
||||
static inline QData VL_SET_Q_SVBV(const svBitVecVal* lwp) VL_MT_SAFE {
|
||||
return VL_SET_QII(lwp[1], lwp[0]);
|
||||
static inline void VL_SET_Q_SVBV(int obits, QData& out, const svBitVecVal* lwp) VL_MT_SAFE {
|
||||
out = VL_MASK_Q(obits) & VL_SET_QII(lwp[1], lwp[0]);
|
||||
}
|
||||
static inline void VL_SET_I_SVBV(int obits, IData& out, const svBitVecVal* lwp) VL_MT_SAFE {
|
||||
out = VL_MASK_I(obits) & lwp[0];
|
||||
}
|
||||
static inline void VL_SET_S_SVBV(int obits, SData& out, const svBitVecVal* lwp) VL_MT_SAFE {
|
||||
out = VL_MASK_I(obits) & lwp[0];
|
||||
}
|
||||
static inline void VL_SET_C_SVBV(int obits, CData& out, const svBitVecVal* lwp) VL_MT_SAFE {
|
||||
out = VL_MASK_I(obits) & lwp[0];
|
||||
}
|
||||
static inline IData VL_SET_I_SVBV(const svBitVecVal* lwp) VL_MT_SAFE { return lwp[0]; }
|
||||
|
||||
// Convert Verilator internal data to svBitVecVal
|
||||
static inline void VL_SET_SVBV_W(int obits, svBitVecVal* owp, const WDataInP lwp) VL_MT_SAFE {
|
||||
|
|
@ -65,10 +73,18 @@ static inline void VL_SET_W_SVLV(int obits, WDataOutP owp, const svLogicVecVal*
|
|||
for (int i = 0; i < words - 1; ++i) owp[i] = lwp[i].aval;
|
||||
owp[words - 1] = lwp[words - 1].aval & VL_MASK_I(obits);
|
||||
}
|
||||
static inline QData VL_SET_Q_SVLV(const svLogicVecVal* lwp) VL_MT_SAFE {
|
||||
return VL_SET_QII(lwp[1].aval, lwp[0].aval);
|
||||
static inline void VL_SET_Q_SVLV(int obits, QData& out, const svLogicVecVal* lwp) VL_MT_SAFE {
|
||||
out = VL_MASK_Q(obits) & VL_SET_QII(lwp[1].aval, lwp[0].aval);
|
||||
}
|
||||
static inline void VL_SET_I_SVLV(int obits, IData& out, const svLogicVecVal* lwp) VL_MT_SAFE {
|
||||
out = VL_MASK_I(obits) & lwp[0].aval;
|
||||
}
|
||||
static inline void VL_SET_S_SVLV(int obits, SData& out, const svLogicVecVal* lwp) VL_MT_SAFE {
|
||||
out = VL_MASK_I(obits) & lwp[0].aval;
|
||||
}
|
||||
static inline void VL_SET_C_SVLV(int obits, CData& out, const svLogicVecVal* lwp) VL_MT_SAFE {
|
||||
out = VL_MASK_I(obits) & lwp[0].aval;
|
||||
}
|
||||
static inline IData VL_SET_I_SVLV(const svLogicVecVal* lwp) VL_MT_SAFE { return lwp[0].aval; }
|
||||
|
||||
// Convert Verilator internal data to svLogicVecVal
|
||||
// Note these functions never create X/Z in svLogicVecVal
|
||||
|
|
|
|||
|
|
@ -230,6 +230,9 @@ void VerilatedFst::declare(uint32_t code, const char* name, int dtypenum,
|
|||
else if (kind == VerilatedTraceSigKind::TRI) varType = FST_VT_VCD_TRI;
|
||||
else if (kind == VerilatedTraceSigKind::TRI0) varType = FST_VT_VCD_TRI0;
|
||||
else if (kind == VerilatedTraceSigKind::TRI1) varType = FST_VT_VCD_TRI1;
|
||||
else if (kind == VerilatedTraceSigKind::TRIAND) varType = FST_VT_VCD_TRIAND;
|
||||
else if (kind == VerilatedTraceSigKind::TRIOR) varType = FST_VT_VCD_TRIOR;
|
||||
else if (kind == VerilatedTraceSigKind::TRIREG) varType = FST_VT_VCD_TRIREG;
|
||||
else if (kind == VerilatedTraceSigKind::WIRE) varType = FST_VT_VCD_WIRE;
|
||||
//
|
||||
else if (type == VerilatedTraceSigType::INTEGER) varType = FST_VT_VCD_INTEGER;
|
||||
|
|
|
|||
|
|
@ -82,6 +82,9 @@ extern void VL_PRINTF_MT(const char* formatp, ...) VL_ATTR_PRINTF(1) VL_MT_SAFE;
|
|||
/// Print a debug message from internals with standard prefix, with printf style format
|
||||
extern void VL_DBG_MSGF(const char* formatp, ...) VL_ATTR_PRINTF(1) VL_MT_SAFE;
|
||||
|
||||
/// Print a debug message from string via VL_DBG_MSGF
|
||||
inline void VL_DBG_MSGS(const std::string& str) VL_MT_SAFE { VL_DBG_MSGF("%s", str.c_str()); }
|
||||
|
||||
// EMIT_RULE: VL_RANDOM: oclean=dirty
|
||||
inline IData VL_RANDOM_I() VL_MT_SAFE { return vl_rand64(); }
|
||||
inline QData VL_RANDOM_Q() VL_MT_SAFE { return vl_rand64(); }
|
||||
|
|
|
|||
|
|
@ -220,12 +220,24 @@ class VlPgoProfiler final {
|
|||
// Counters are stored packed, all together to reduce cache effects
|
||||
std::array<uint64_t, N_Entries> m_counters{}; // Time spent on this record
|
||||
std::vector<Record> m_records; // Record information
|
||||
// An original cost of a profiled hier block. During Verilation with
|
||||
// collected profiling data, costs of hier blocks change thus hashes of
|
||||
// original mtasks does not match those from the previous,
|
||||
// instrumented, run. We shall not assume that a single top-level mtask
|
||||
// will correspond to the hier block as multiple hier block DPIs can be
|
||||
// contracted into a single mtask. Therefore, the old cost, from
|
||||
// previous instrumented run, is used to stabilize profiled scheduling.
|
||||
const uint64_t m_currentHierBlockCost;
|
||||
|
||||
public:
|
||||
// METHODS
|
||||
VlPgoProfiler() = default;
|
||||
explicit VlPgoProfiler(uint64_t currentHierBlockCost = 0)
|
||||
: m_currentHierBlockCost{currentHierBlockCost} {}
|
||||
~VlPgoProfiler() = default;
|
||||
void write(const char* modelp, const std::string& filename, bool firstHierCall) VL_MT_SAFE;
|
||||
VL_UNMOVABLE(VlPgoProfiler);
|
||||
VL_UNCOPYABLE(VlPgoProfiler);
|
||||
void writeHeader(const std::string& filename) VL_MT_SAFE;
|
||||
void write(const char* modelp, const std::string& filename) VL_MT_SAFE;
|
||||
void addCounter(size_t counter, const std::string& name) {
|
||||
VL_DEBUG_IF(assert(counter < N_Entries););
|
||||
m_records.emplace_back(Record{name, counter});
|
||||
|
|
@ -239,8 +251,7 @@ public:
|
|||
};
|
||||
|
||||
template <std::size_t N_Entries>
|
||||
void VlPgoProfiler<N_Entries>::write(const char* modelp, const std::string& filename,
|
||||
bool firstHierCall) VL_MT_SAFE {
|
||||
void VlPgoProfiler<N_Entries>::writeHeader(const std::string& filename) VL_MT_SAFE {
|
||||
static VerilatedMutex s_mutex;
|
||||
const VerilatedLockGuard lock{s_mutex};
|
||||
|
||||
|
|
@ -250,22 +261,38 @@ void VlPgoProfiler<N_Entries>::write(const char* modelp, const std::string& file
|
|||
// each will collect is own data correctly. However when each is
|
||||
// destroyed we need to get all the data, not keep overwriting and only
|
||||
// get the last model's data.
|
||||
static bool s_firstCall = firstHierCall;
|
||||
|
||||
VL_DEBUG_IF(VL_DBG_MSGF("+prof+vlt+file writing to '%s'\n", filename.c_str()););
|
||||
|
||||
FILE* const fp = std::fopen(filename.c_str(), s_firstCall ? "w" : "a");
|
||||
FILE* const fp = std::fopen(filename.c_str(), "w");
|
||||
if (VL_UNLIKELY(!fp)) {
|
||||
VL_FATAL_MT(filename.c_str(), 0, "", "+prof+vlt+file file not writable");
|
||||
}
|
||||
if (s_firstCall) {
|
||||
// TODO Perhaps merge with verilated_coverage output format, so can
|
||||
// have a common merging and reporting tool, etc.
|
||||
fprintf(fp, "// Verilated model profile-guided optimization data dump file\n");
|
||||
fprintf(fp, "`verilator_config\n");
|
||||
|
||||
VL_DEBUG_IF(VL_DBG_MSGF("+prof+vlt+file initializing '%s'\n", filename.c_str()););
|
||||
|
||||
// TODO Perhaps merge with verilated_coverage output format, so can
|
||||
// have a common merging and reporting tool, etc.
|
||||
fprintf(fp, "// Verilated model profile-guided optimization data dump file\n");
|
||||
fprintf(fp, "`verilator_config\n");
|
||||
|
||||
std::fclose(fp);
|
||||
}
|
||||
|
||||
template <std::size_t N_Entries>
|
||||
void VlPgoProfiler<N_Entries>::write(const char* modelp, const std::string& filename) VL_MT_SAFE {
|
||||
static VerilatedMutex s_mutex;
|
||||
const VerilatedLockGuard lock{s_mutex};
|
||||
|
||||
FILE* const fp = std::fopen(filename.c_str(), "a");
|
||||
if (VL_UNLIKELY(!fp)) {
|
||||
VL_FATAL_MT(filename.c_str(), 0, "", "+prof+vlt+file file not writable");
|
||||
}
|
||||
|
||||
s_firstCall = false;
|
||||
VL_DEBUG_IF(VL_DBG_MSGF("+prof+vlt+file writing to '%s'\n", filename.c_str()););
|
||||
|
||||
if (m_currentHierBlockCost) {
|
||||
fprintf(fp, "profile_data -hier-dpi \"%s\" -cost 64'd%lu\n", modelp,
|
||||
m_currentHierBlockCost);
|
||||
}
|
||||
|
||||
for (const Record& rec : m_records) {
|
||||
fprintf(fp, "profile_data -model \"%s\" -mtask \"%s\" -cost 64'd%" PRIu64 "\n", modelp,
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
#endif
|
||||
// clang-format on
|
||||
|
||||
class Process final : private std::streambuf, public std::iostream {
|
||||
class VlRProcess final : private std::streambuf, public std::iostream {
|
||||
static constexpr int BUFFER_SIZE = 4096;
|
||||
const char* const* m_cmd = nullptr; // fork() process argv
|
||||
#ifdef _VL_SOLVER_PIPE
|
||||
|
|
@ -69,6 +69,7 @@ protected:
|
|||
if (pbase() == pptr()) return 0;
|
||||
size_t size = pptr() - pbase();
|
||||
ssize_t n = ::write(m_writeFd, pbase(), size);
|
||||
// VL_PRINTF_MT("solver-write '%s'\n", std::string(pbase(), size).c_str());
|
||||
if (n == -1) perror("write");
|
||||
if (n <= 0) {
|
||||
wait_report();
|
||||
|
|
@ -98,7 +99,7 @@ protected:
|
|||
}
|
||||
|
||||
public:
|
||||
explicit Process(const char* const* const cmd = nullptr)
|
||||
explicit VlRProcess(const char* const* const cmd = nullptr)
|
||||
: std::streambuf{}
|
||||
, std::iostream{this}
|
||||
, m_cmd{cmd} {
|
||||
|
|
@ -120,7 +121,7 @@ public:
|
|||
else if (WIFEXITED(m_pidStatus))
|
||||
msg << "exit status " << WEXITSTATUS(m_pidStatus);
|
||||
const std::string str = msg.str();
|
||||
VL_WARN_MT("", 0, "Process", str.c_str());
|
||||
VL_WARN_MT("", 0, "VlRProcess", str.c_str());
|
||||
}
|
||||
#endif
|
||||
m_pidExited = true;
|
||||
|
|
@ -151,11 +152,11 @@ public:
|
|||
constexpr int P_WR = 1;
|
||||
|
||||
if (pipe(fd_stdin) != 0) {
|
||||
perror("Process::open: pipe");
|
||||
perror("VlRProcess::open: pipe");
|
||||
return false;
|
||||
}
|
||||
if (pipe(fd_stdout) != 0) {
|
||||
perror("Process::open: pipe");
|
||||
perror("VlRProcess::open: pipe");
|
||||
close(fd_stdin[P_RD]);
|
||||
close(fd_stdin[P_WR]);
|
||||
return false;
|
||||
|
|
@ -175,7 +176,7 @@ public:
|
|||
|
||||
const pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
perror("Process::open: fork");
|
||||
perror("VlRProcess::open: fork");
|
||||
close(fd_stdin[P_RD]);
|
||||
close(fd_stdin[P_WR]);
|
||||
close(fd_stdout[P_RD]);
|
||||
|
|
@ -190,7 +191,7 @@ public:
|
|||
dup2(fd_stdout[P_WR], STDOUT_FILENO);
|
||||
execvp(cmd[0], const_cast<char* const*>(cmd));
|
||||
std::stringstream msg;
|
||||
msg << "Process::open: execvp(" << cmd[0] << ")";
|
||||
msg << "VlRProcess::open: execvp(" << cmd[0] << ")";
|
||||
const std::string str = msg.str();
|
||||
perror(str.c_str());
|
||||
_exit(127);
|
||||
|
|
@ -212,8 +213,8 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
static Process& getSolver() {
|
||||
static Process s_solver;
|
||||
static VlRProcess& getSolver() {
|
||||
static VlRProcess s_solver;
|
||||
static bool s_done = false;
|
||||
if (s_done) return s_solver;
|
||||
s_done = true;
|
||||
|
|
@ -251,7 +252,7 @@ static Process& getSolver() {
|
|||
return s_solver;
|
||||
}
|
||||
|
||||
std::string readUntilBalanced(std::istream& stream) {
|
||||
static std::string readUntilBalanced(std::istream& stream) {
|
||||
std::string result;
|
||||
std::string token;
|
||||
int parenCount = 1;
|
||||
|
|
@ -269,8 +270,8 @@ std::string readUntilBalanced(std::istream& stream) {
|
|||
return result;
|
||||
}
|
||||
|
||||
std::string parseNestedSelect(const std::string& nested_select_expr,
|
||||
std::vector<std::string>& indices) {
|
||||
static std::string parseNestedSelect(const std::string& nested_select_expr,
|
||||
std::vector<std::string>& indices) {
|
||||
std::istringstream nestedStream(nested_select_expr);
|
||||
std::string name, idx;
|
||||
nestedStream >> name;
|
||||
|
|
@ -367,47 +368,47 @@ void VlRandomizer::randomConstraint(std::ostream& os, VlRNG& rngr, int bits) {
|
|||
|
||||
bool VlRandomizer::next(VlRNG& rngr) {
|
||||
if (m_vars.empty()) return true;
|
||||
std::iostream& f = getSolver();
|
||||
if (!f) return false;
|
||||
std::iostream& os = getSolver();
|
||||
if (!os) return false;
|
||||
|
||||
f << "(set-option :produce-models true)\n";
|
||||
f << "(set-logic QF_ABV)\n";
|
||||
f << "(define-fun __Vbv ((b Bool)) (_ BitVec 1) (ite b #b1 #b0))\n";
|
||||
f << "(define-fun __Vbool ((v (_ BitVec 1))) Bool (= #b1 v))\n";
|
||||
os << "(set-option :produce-models true)\n";
|
||||
os << "(set-logic QF_ABV)\n";
|
||||
os << "(define-fun __Vbv ((b Bool)) (_ BitVec 1) (ite b #b1 #b0))\n";
|
||||
os << "(define-fun __Vbool ((v (_ BitVec 1))) Bool (= #b1 v))\n";
|
||||
for (const auto& var : m_vars) {
|
||||
if (var.second->dimension() > 0) {
|
||||
auto arrVarsp = std::make_shared<const ArrayInfoMap>(m_arr_vars);
|
||||
var.second->setArrayInfo(arrVarsp);
|
||||
}
|
||||
f << "(declare-fun " << var.first << " () ";
|
||||
var.second->emitType(f);
|
||||
f << ")\n";
|
||||
os << "(declare-fun " << var.first << " () ";
|
||||
var.second->emitType(os);
|
||||
os << ")\n";
|
||||
}
|
||||
for (const std::string& constraint : m_constraints) {
|
||||
f << "(assert (= #b1 " << constraint << "))\n";
|
||||
os << "(assert (= #b1 " << constraint << "))\n";
|
||||
}
|
||||
f << "(check-sat)\n";
|
||||
os << "(check-sat)\n";
|
||||
|
||||
bool sat = parseSolution(f);
|
||||
bool sat = parseSolution(os);
|
||||
if (!sat) {
|
||||
f << "(reset)\n";
|
||||
os << "(reset)\n";
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < _VL_SOLVER_HASH_LEN_TOTAL && sat; ++i) {
|
||||
f << "(assert ";
|
||||
randomConstraint(f, rngr, _VL_SOLVER_HASH_LEN);
|
||||
f << ")\n";
|
||||
f << "\n(check-sat)\n";
|
||||
sat = parseSolution(f);
|
||||
os << "(assert ";
|
||||
randomConstraint(os, rngr, _VL_SOLVER_HASH_LEN);
|
||||
os << ")\n";
|
||||
os << "\n(check-sat)\n";
|
||||
sat = parseSolution(os);
|
||||
}
|
||||
|
||||
f << "(reset)\n";
|
||||
os << "(reset)\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VlRandomizer::parseSolution(std::iostream& f) {
|
||||
bool VlRandomizer::parseSolution(std::iostream& os) {
|
||||
std::string sat;
|
||||
do { std::getline(f, sat); } while (sat == "");
|
||||
do { std::getline(os, sat); } while (sat == "");
|
||||
|
||||
if (sat == "unsat") return false;
|
||||
if (sat != "sat") {
|
||||
|
|
@ -418,25 +419,25 @@ bool VlRandomizer::parseSolution(std::iostream& f) {
|
|||
return false;
|
||||
}
|
||||
|
||||
f << "(get-value (";
|
||||
os << "(get-value (";
|
||||
for (const auto& var : m_vars) {
|
||||
if (var.second->dimension() > 0) {
|
||||
auto arrVarsp = std::make_shared<const ArrayInfoMap>(m_arr_vars);
|
||||
var.second->setArrayInfo(arrVarsp);
|
||||
}
|
||||
var.second->emitGetValue(f);
|
||||
var.second->emitGetValue(os);
|
||||
}
|
||||
f << "))\n";
|
||||
os << "))\n";
|
||||
// Quasi-parse S-expression of the form ((x #xVALUE) (y #bVALUE) (z #xVALUE))
|
||||
char c;
|
||||
f >> c;
|
||||
os >> c;
|
||||
if (c != '(') {
|
||||
VL_WARN_MT(__FILE__, __LINE__, "randomize",
|
||||
"Internal: Unable to parse solver's response: invalid S-expression");
|
||||
return false;
|
||||
}
|
||||
while (true) {
|
||||
f >> c;
|
||||
os >> c;
|
||||
if (c == ')') break;
|
||||
if (c != '(') {
|
||||
VL_WARN_MT(__FILE__, __LINE__, "randomize",
|
||||
|
|
@ -445,13 +446,13 @@ bool VlRandomizer::parseSolution(std::iostream& f) {
|
|||
}
|
||||
std::string name, idx, value;
|
||||
std::vector<std::string> indices;
|
||||
f >> name;
|
||||
os >> name;
|
||||
indices.clear();
|
||||
if (name == "(select") {
|
||||
const std::string selectExpr = readUntilBalanced(f);
|
||||
const std::string selectExpr = readUntilBalanced(os);
|
||||
name = parseNestedSelect(selectExpr, indices);
|
||||
}
|
||||
std::getline(f, value, ')');
|
||||
std::getline(os, value, ')');
|
||||
const auto it = m_vars.find(name);
|
||||
if (it == m_vars.end()) continue;
|
||||
const VlRandomVar& varr = *it->second;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include <sstream>
|
||||
|
||||
//=============================================================================
|
||||
|
||||
// VlRandomExpr and subclasses represent expressions for the constraint solver.
|
||||
class ArrayInfo final {
|
||||
public:
|
||||
|
|
@ -110,7 +111,7 @@ public:
|
|||
return it->second->m_datap;
|
||||
} else {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "randomize", "indexed_name not found in m_arr_vars");
|
||||
return nullptr;
|
||||
return nullptr; // LCOV_EXCL_BR_LINE
|
||||
}
|
||||
}
|
||||
void emitHexs(std::ostream& s, const std::vector<IData>& indices, const size_t bit_width,
|
||||
|
|
@ -192,8 +193,10 @@ public:
|
|||
s << ')';
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VlRandomizer is the object holding constraints and variable references.
|
||||
|
||||
// Object holding constraints and variable references.
|
||||
class VlRandomizer final {
|
||||
// MEMBERS
|
||||
std::vector<std::string> m_constraints; // Solver-dependent constraints
|
||||
|
|
@ -216,9 +219,7 @@ public:
|
|||
// Finds the next solution satisfying the constraints
|
||||
bool next(VlRNG& rngr);
|
||||
|
||||
// -----------------------------------------------
|
||||
// --- Process the key for associative array ---
|
||||
// -----------------------------------------------
|
||||
|
||||
// process_key: Handle integral keys (<= 32-bit)
|
||||
template <typename T_Key>
|
||||
|
|
@ -313,9 +314,7 @@ public:
|
|||
"supported currently.");
|
||||
}
|
||||
|
||||
// -----------------------------------------
|
||||
// --- write_var to register variables ---
|
||||
// -----------------------------------------
|
||||
|
||||
// Register scalar variable (non-struct, basic type)
|
||||
template <typename T>
|
||||
|
|
@ -402,9 +401,8 @@ public:
|
|||
std::uint32_t randmodeIdx = std::numeric_limits<std::uint32_t>::max()) {
|
||||
if (dimension > 0) record_struct_arr(var, name, dimension, {}, {});
|
||||
}
|
||||
// ----------------------------------------
|
||||
|
||||
// --- Record Arrays: flat and struct ---
|
||||
// ----------------------------------------
|
||||
|
||||
// Record a flat (non-class) element into the array variable table
|
||||
template <typename T>
|
||||
|
|
@ -546,9 +544,8 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
// --------------------------
|
||||
|
||||
// --- Helper functions ---
|
||||
// --------------------------
|
||||
|
||||
// Helper: Register all members of a user-defined struct
|
||||
template <typename T, std::size_t... I>
|
||||
|
|
@ -581,8 +578,8 @@ public:
|
|||
};
|
||||
|
||||
//=============================================================================
|
||||
// VlStdRandomizer provides a light wrapper for RNG used by std::randomize()
|
||||
// to support scope-level randomization.
|
||||
|
||||
// Light wrapper for RNG used by std::randomize() to support scope-level randomization.
|
||||
class VlStdRandomizer final {
|
||||
// MEMBERS
|
||||
VlRNG m_rng; // Random number generator
|
||||
|
|
@ -598,4 +595,5 @@ public:
|
|||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue