mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
44ce83cd8e | ||
|
|
c199930943 | ||
|
|
81fc1d48a6 | ||
|
|
f330f16bf6 | ||
|
|
10a6b566ef | ||
|
|
cff5485821 | ||
|
|
dcbdac1b81 | ||
|
|
a59777aa75 | ||
|
|
d82b9128d0 | ||
|
|
ab4f18c892 | ||
|
|
4480938b25 | ||
|
|
11a1b201a9 | ||
|
|
1a8b192e40 | ||
|
|
aee3a32354 | ||
|
|
35e9489f33 | ||
|
|
5c6d74cd80 | ||
|
|
8611ff230d | ||
|
|
8ef4097f00 | ||
|
|
fe684e8733 | ||
|
|
96f8bbd023 | ||
|
|
95ffcad12e | ||
|
|
ebed1a9000 | ||
|
|
2240f42bfa | ||
|
|
ac4f0da9ee | ||
|
|
559852f60b | ||
|
|
b0669f3aca | ||
|
|
00979ede14 | ||
|
|
13569ed98b | ||
|
|
809a6de9cd | ||
|
|
d65d8fda54 | ||
|
|
2076b0219d | ||
|
|
32f93a8a1e | ||
|
|
e28175108f | ||
|
|
b81295230a | ||
|
|
6ae7f7b152 | ||
|
|
03026b63b9 | ||
|
|
38e586fabe | ||
|
|
3d6e8e9eb0 | ||
|
|
df192f2b61 | ||
|
|
17ad59394f | ||
|
|
682c2a610f | ||
|
|
59782266b9 | ||
|
|
4885bcb93c | ||
|
|
d47d3b5162 | ||
|
|
99455a16bf | ||
|
|
a86e1953eb | ||
|
|
f63dfd7028 | ||
|
|
7a413a121d | ||
|
|
0f6b625db8 | ||
|
|
f134ac4f2f | ||
|
|
39eeda50c6 | ||
|
|
09ca4ce791 | ||
|
|
2ff22d9050 | ||
|
|
c726ad0142 | ||
|
|
0c0198cf55 | ||
|
|
d480c2f033 | ||
|
|
8ebe86e54b | ||
|
|
62af9dbed4 | ||
|
|
3eb0ff8aa0 | ||
|
|
ce5a70fbca | ||
|
|
c36d9a68f5 | ||
|
|
8c5aa21a11 | ||
|
|
47b5e36e60 | ||
|
|
a481638edb | ||
|
|
de7caad710 | ||
|
|
b1c14e485a | ||
|
|
66727670f9 | ||
|
|
b9322206d7 | ||
|
|
617424e04a | ||
|
|
e9c4ffa04e | ||
|
|
30c2e53f9e | ||
|
|
a250decfaa | ||
|
|
21a380def0 | ||
|
|
77e30d4920 | ||
|
|
98dcbc6b3e | ||
|
|
6ce81698e7 | ||
|
|
30be381aa8 | ||
|
|
e04bc16ffa | ||
|
|
2b26ca2c07 | ||
|
|
ce178ec987 | ||
|
|
fcb733e8d0 | ||
|
|
f87107e757 | ||
|
|
cf9f466f0a | ||
|
|
28cbf39995 | ||
|
|
4767083a72 | ||
|
|
704f40b1a2 | ||
|
|
c5f859c9a3 | ||
|
|
abe95f3ab3 | ||
|
|
2eda38c4d1 | ||
|
|
5811ec07e6 | ||
|
|
8a5d13bce2 | ||
|
|
3232bdf016 | ||
|
|
7ef620dc64 | ||
|
|
8043a9c666 | ||
|
|
f1b10e2b4c | ||
|
|
c1a9ada279 | ||
|
|
2aed499e00 | ||
|
|
b2c5f8e74e | ||
|
|
9ef200d5a3 | ||
|
|
8a3227697e | ||
|
|
530ab17c8b | ||
|
|
ca8da1f54f | ||
|
|
cc4cb4e006 | ||
|
|
e40ad4a095 | ||
|
|
67a0ad02d2 | ||
|
|
055a978866 | ||
|
|
67d52372e5 | ||
|
|
a28896d967 | ||
|
|
9ff5ef4ad5 | ||
|
|
25f08b29c6 | ||
|
|
7febeab275 | ||
|
|
c0c038c887 | ||
|
|
8a5b8d5f38 | ||
|
|
ff0dd26fe5 | ||
|
|
f781085755 | ||
|
|
8f6efdaf5c | ||
|
|
4b5f0fd173 | ||
|
|
1224c69126 | ||
|
|
bcb766b4ce | ||
|
|
63373f6f4c | ||
|
|
40bdd85a07 | ||
|
|
974bf1d643 | ||
|
|
8ce60e955f | ||
|
|
171960635e | ||
|
|
2ab819aef0 | ||
|
|
647c321437 | ||
|
|
2bbb9dccb1 | ||
|
|
bac5d32582 | ||
|
|
3ebd6915f3 | ||
|
|
f852ba8a33 | ||
|
|
8f6015aad5 | ||
|
|
352adbed74 | ||
|
|
0cbfd29ac5 | ||
|
|
9f977ed419 | ||
|
|
baa6a2c31a | ||
|
|
3b33438e91 | ||
|
|
17ee8579a4 | ||
|
|
94f7133c6f | ||
|
|
6d58d32a0f | ||
|
|
c9d000467b | ||
|
|
e15d3afb7b | ||
|
|
712bc43a06 | ||
|
|
71fa09a25b | ||
|
|
89c3c5f952 | ||
|
|
7311c84937 | ||
|
|
8078fc0965 | ||
|
|
31a6a968cc | ||
|
|
1e4f471049 | ||
|
|
1232746395 | ||
|
|
1852ae1cc8 | ||
|
|
77f79f0114 | ||
|
|
6081c262f2 | ||
|
|
46ab907f6a | ||
|
|
8700564197 | ||
|
|
af8cc9127f | ||
|
|
c73336f8f5 | ||
|
|
4361fb838f | ||
|
|
6b8afe8137 | ||
|
|
a7c2037b7a | ||
|
|
9b09309f51 | ||
|
|
da0da9e258 | ||
|
|
58a42834a6 | ||
|
|
8c836e1222 | ||
|
|
ce179bd2e3 | ||
|
|
68e5c95b82 | ||
|
|
07db53e54f | ||
|
|
0ed58a4217 | ||
|
|
8e6d68147c | ||
|
|
e08b9b84b5 | ||
|
|
2f28c5f5b4 | ||
|
|
91f1acd85f | ||
|
|
ed1e5fb509 | ||
|
|
99b2ab7540 | ||
|
|
763b9909f1 |
+115
@@ -0,0 +1,115 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
# BasedOnStyle: LLVM
|
||||||
|
AccessModifierOffset: -4
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: false
|
||||||
|
AlignConsecutiveDeclarations: false
|
||||||
|
AlignEscapedNewlines: DontAlign
|
||||||
|
AlignOperands: true
|
||||||
|
AlignTrailingComments: false
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowShortBlocksOnASingleLine: true
|
||||||
|
AllowShortCaseLabelsOnASingleLine: true
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: true
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AlwaysBreakTemplateDeclarations: false
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackParameters: true
|
||||||
|
BraceWrapping:
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: false
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakBeforeBinaryOperators: All
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeInheritanceComma: false
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializersBeforeComma: false
|
||||||
|
BreakConstructorInitializers: BeforeComma
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakStringLiterals: true
|
||||||
|
ColumnLimit: 99
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentWidth: 4
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PointerAlignment: Left
|
||||||
|
RawStringFormats:
|
||||||
|
- Delimiter: pb
|
||||||
|
Language: TextProto
|
||||||
|
BasedOnStyle: google
|
||||||
|
ReflowComments: true
|
||||||
|
SortIncludes: false
|
||||||
|
SortUsingDeclarations: true
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 2
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Cpp11
|
||||||
|
TabWidth: 8
|
||||||
|
UseTab: Never
|
||||||
|
...
|
||||||
|
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
exclude_paths:
|
||||||
|
- 'ci/build_verilator.sh'
|
||||||
|
- 'include/vltstd/**'
|
||||||
@@ -30,4 +30,6 @@ verilator.txt
|
|||||||
verilator_bin*
|
verilator_bin*
|
||||||
verilator_coverage_bin*
|
verilator_coverage_bin*
|
||||||
verilator.pc
|
verilator.pc
|
||||||
|
verilator-config.cmake
|
||||||
|
verilator-config-version.cmake
|
||||||
**/obj_dir/*
|
**/obj_dir/*
|
||||||
|
|||||||
+160
-95
@@ -4,108 +4,173 @@
|
|||||||
# redistribute it and/or modify it under the terms of either the GNU Lesser
|
# 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.
|
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
|
|
||||||
|
version: ~> 1.0
|
||||||
|
|
||||||
|
os: linux
|
||||||
language: cpp
|
language: cpp
|
||||||
|
|
||||||
matrix:
|
|
||||||
include:
|
|
||||||
# Non-cron build will just run on whatever linux flavor we get
|
|
||||||
- if: type != cron
|
|
||||||
os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env:
|
|
||||||
- SCENARIOS=--dist
|
|
||||||
- if: type != cron
|
|
||||||
os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env:
|
|
||||||
- SCENARIOS=--vlt
|
|
||||||
- if: type != cron
|
|
||||||
os: linux
|
|
||||||
compiler: gcc
|
|
||||||
env:
|
|
||||||
- SCENARIOS=--vltmt
|
|
||||||
# Cron builds try different OS/compiler combinations
|
|
||||||
- if: type = cron
|
|
||||||
dist: xenial
|
|
||||||
compiler: gcc
|
|
||||||
env:
|
|
||||||
- SCENARIOS=--dist
|
|
||||||
- if: type = cron
|
|
||||||
dist: xenial
|
|
||||||
compiler: gcc
|
|
||||||
env:
|
|
||||||
- SCENARIOS=--vlt
|
|
||||||
- if: type = cron
|
|
||||||
dist: xenial
|
|
||||||
compiler: gcc
|
|
||||||
env:
|
|
||||||
- SCENARIOS=--vltmt
|
|
||||||
- if: type = cron
|
|
||||||
dist: xenial
|
|
||||||
compiler: clang
|
|
||||||
env:
|
|
||||||
- SCENARIOS=--dist
|
|
||||||
- if: type = cron
|
|
||||||
dist: xenial
|
|
||||||
compiler: clang
|
|
||||||
env:
|
|
||||||
- SCENARIOS=--vlt
|
|
||||||
- if: type = cron
|
|
||||||
dist: xenial
|
|
||||||
compiler: clang
|
|
||||||
env:
|
|
||||||
- SCENARIOS=--vltmt
|
|
||||||
# - if: type = cron
|
|
||||||
# os: osx
|
|
||||||
# compiler: gcc
|
|
||||||
# env:
|
|
||||||
# - SCENARIOS=--dist
|
|
||||||
# - if: type = cron
|
|
||||||
# os: osx
|
|
||||||
# compiler: gcc
|
|
||||||
# env:
|
|
||||||
# - SCENARIOS=--vlt
|
|
||||||
# - if: type = cron
|
|
||||||
# os: osx
|
|
||||||
# compiler: gcc
|
|
||||||
# env:
|
|
||||||
# - SCENARIOS=--vltmt
|
|
||||||
- if: type = cron
|
|
||||||
dist: trusty
|
|
||||||
compiler: gcc
|
|
||||||
env:
|
|
||||||
- SCENARIOS=--dist
|
|
||||||
- if: type = cron
|
|
||||||
dist: trusty
|
|
||||||
compiler: gcc
|
|
||||||
env:
|
|
||||||
- SCENARIOS=--vlt
|
|
||||||
- if: type = cron
|
|
||||||
dist: trusty
|
|
||||||
compiler: gcc
|
|
||||||
env:
|
|
||||||
- SCENARIOS=--vltmt
|
|
||||||
|
|
||||||
cache: ccache
|
cache: ccache
|
||||||
|
|
||||||
# Some tests require gdb
|
env:
|
||||||
addons:
|
global:
|
||||||
apt:
|
- VERILATOR_CACHE=$HOME/verilator_cache
|
||||||
packages:
|
- VERILATOR_ROOT=$PWD
|
||||||
- gdb
|
- VERILATOR_NUM_JOBS=$(echo `nproc` + 1 | bc)
|
||||||
|
- VERILATOR_CONFIG_FLAGS="--enable-maintainer-mode --enable-longtests"
|
||||||
|
- OBJCACHE=ccache
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- $VERILATOR_CACHE
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
# Perl modules needed for testing
|
# Perl modules needed for testing
|
||||||
- yes yes | sudo cpan -fi Unix::Processors Parallel::Forker Bit::Vector
|
- yes yes | sudo cpan -fi Unix::Processors Parallel::Forker Bit::Vector
|
||||||
|
- sudo apt-get install gdb gtkwave
|
||||||
before_script:
|
before_script:
|
||||||
- export VLT_JOBS=$((`nproc` + 1))
|
- bash -x ci/build_verilator.sh
|
||||||
- export OBJCACHE=ccache
|
|
||||||
- export VERILATOR_ROOT=`pwd`
|
|
||||||
- autoconf
|
|
||||||
script:
|
|
||||||
- >
|
|
||||||
./configure --enable-maintainer-mode --enable-longtests &&
|
|
||||||
make -j $VLT_JOBS &&
|
|
||||||
make test_regress DRIVER_FLAGS="-j 0 --quiet --rerun"
|
|
||||||
after_script:
|
after_script:
|
||||||
- ccache -s
|
- ccache -s
|
||||||
|
|
||||||
|
stages:
|
||||||
|
- "Build Verilator"
|
||||||
|
- test
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
include:
|
||||||
|
- if: type != cron
|
||||||
|
stage: "Build Verilator"
|
||||||
|
name: Build Verilator
|
||||||
|
compiler: gcc
|
||||||
|
script: echo "Done building Verilator"
|
||||||
|
# Non-cron build will just run on whatever linux flavor we get
|
||||||
|
- if: type != cron
|
||||||
|
stage: test
|
||||||
|
name: Dist test
|
||||||
|
compiler: gcc
|
||||||
|
script: ci/test.sh dist
|
||||||
|
- if: type != cron
|
||||||
|
stage: test
|
||||||
|
name: Vlt test
|
||||||
|
compiler: gcc
|
||||||
|
script: ci/test.sh vlt
|
||||||
|
- if: type != cron
|
||||||
|
stage: test
|
||||||
|
name: Vltmt test
|
||||||
|
compiler: gcc
|
||||||
|
script: ci/test.sh vltmt
|
||||||
|
# Cron builds try different OS/compiler combinations
|
||||||
|
- if: type = cron
|
||||||
|
stage: "Build Verilator"
|
||||||
|
name: Build xenial gcc Verilator
|
||||||
|
os: linux
|
||||||
|
dist: xenial
|
||||||
|
compiler: gcc
|
||||||
|
script: echo "Done building Verilator"
|
||||||
|
- if: type = cron
|
||||||
|
stage: test
|
||||||
|
name: Xenial gcc dist test
|
||||||
|
os: linux
|
||||||
|
dist: xenial
|
||||||
|
compiler: gcc
|
||||||
|
script: ci/test.sh dist
|
||||||
|
- if: type = cron
|
||||||
|
stage: test
|
||||||
|
name: Xenial gcc vlt test
|
||||||
|
os: linux
|
||||||
|
dist: xenial
|
||||||
|
compiler: gcc
|
||||||
|
script: ci/test.sh vlt
|
||||||
|
- if: type = cron
|
||||||
|
stage: test
|
||||||
|
name: Xenial gcc vltmt test
|
||||||
|
os: linux
|
||||||
|
dist: xenial
|
||||||
|
compiler: gcc
|
||||||
|
script: ci/test.sh vltmt
|
||||||
|
- if: type = cron
|
||||||
|
stage: "Build Verilator"
|
||||||
|
name: Build xenial clang Verilator
|
||||||
|
os: linux
|
||||||
|
dist: xenial
|
||||||
|
compiler: clang
|
||||||
|
script: echo "Done building Verilator"
|
||||||
|
- if: type = cron
|
||||||
|
stage: test
|
||||||
|
name: Xenial clang dist test
|
||||||
|
os: linux
|
||||||
|
dist: xenial
|
||||||
|
compiler: clang
|
||||||
|
script: ci/test.sh dist
|
||||||
|
- if: type = cron
|
||||||
|
stage: test
|
||||||
|
name: Xenial clang vlt test
|
||||||
|
os: linux
|
||||||
|
dist: xenial
|
||||||
|
compiler: clang
|
||||||
|
script: ci/test.sh vlt
|
||||||
|
- if: type = cron
|
||||||
|
stage: test
|
||||||
|
name: Xenial clang vltmt test
|
||||||
|
os: linux
|
||||||
|
dist: xenial
|
||||||
|
compiler: clang
|
||||||
|
script: ci/test.sh vltmt
|
||||||
|
# - if: type = cron
|
||||||
|
# stage: "Build Verilator"
|
||||||
|
# name: Build OSX gcc Verilator
|
||||||
|
# os: osx
|
||||||
|
# compiler: gcc
|
||||||
|
# script: echo "Done building Verilator"
|
||||||
|
# - if: type = cron
|
||||||
|
# stage: test
|
||||||
|
# name: OSX gcc dist test
|
||||||
|
# os: osx
|
||||||
|
# compiler: gcc
|
||||||
|
# script: ci/test.sh dist
|
||||||
|
# - if: type = cron
|
||||||
|
# stage: test
|
||||||
|
# name: OSX gcc vlt test
|
||||||
|
# os: osx
|
||||||
|
# compiler: gcc
|
||||||
|
# script: ci/test.sh vlt
|
||||||
|
# - if: type = cron
|
||||||
|
# stage: test
|
||||||
|
# name: OSX gcc vltmt test
|
||||||
|
# os: osx
|
||||||
|
# compiler: gcc
|
||||||
|
# script: ci/test.sh vltmt
|
||||||
|
- if: type = cron
|
||||||
|
stage: "Build Verilator"
|
||||||
|
name: Build trusty gcc Verilator
|
||||||
|
os: linux
|
||||||
|
dist: trusty
|
||||||
|
compiler: gcc
|
||||||
|
script: echo "Done building Verilator"
|
||||||
|
- if: type = cron
|
||||||
|
stage: test
|
||||||
|
name: Trusty gcc dist test
|
||||||
|
os: linux
|
||||||
|
dist: trusty
|
||||||
|
compiler: gcc
|
||||||
|
script: ci/test.sh dist
|
||||||
|
- if: type = cron
|
||||||
|
stage: test
|
||||||
|
name: Trusty gcc vlt test
|
||||||
|
os: linux
|
||||||
|
dist: trusty
|
||||||
|
compiler: gcc
|
||||||
|
script: ci/test.sh vlt
|
||||||
|
- if: type = cron
|
||||||
|
stage: test
|
||||||
|
os: linux
|
||||||
|
dist: trusty
|
||||||
|
name: Trusty gcc vltmt test
|
||||||
|
compiler: gcc
|
||||||
|
script: ci/test.sh vltmt
|
||||||
|
|
||||||
|
notifications:
|
||||||
|
email:
|
||||||
|
if: repo = verilator/verilator
|
||||||
|
recipients:
|
||||||
|
- [email protected]
|
||||||
|
- [email protected]
|
||||||
|
|||||||
@@ -2,6 +2,89 @@ Revision history for Verilator
|
|||||||
|
|
||||||
The contributors that suggested a given feature are shown in []. Thanks!
|
The contributors that suggested a given feature are shown in []. Thanks!
|
||||||
|
|
||||||
|
* Verilator 4.024 2019-12-08
|
||||||
|
|
||||||
|
** Support associative arrays (excluding [*] and pattern assignments), bug544.
|
||||||
|
|
||||||
|
** Support queues (excluding {} notation and pattern assignments), bug545.
|
||||||
|
|
||||||
|
*** Add +verilator+error+limit to see more assertion errors. [Peter Monsson]
|
||||||
|
|
||||||
|
*** Support string.toupper and string.tolower.
|
||||||
|
|
||||||
|
*** Support $rewind and $ungetc.
|
||||||
|
|
||||||
|
*** Support shortreal as real, with a SHORTREAL warning.
|
||||||
|
|
||||||
|
**** Add -Wpedantic and -Wno-context for compliance testing.
|
||||||
|
|
||||||
|
**** Add error on redefining preprocessor directives. [Piotr Binkowski]
|
||||||
|
|
||||||
|
**** Support $value$plusargs float and shorts, bug1592, bug1619. [Garrett Smith]
|
||||||
|
|
||||||
|
**** Fix gate lvalue optimization error, bug831. [Jonathon Donaldson, Driss Hafdi]
|
||||||
|
|
||||||
|
**** Fix color assertion on empty if, bug1604. [Andrew Holme]
|
||||||
|
|
||||||
|
**** Fix for loop missing initializer, bug1605. [Andrew Holme]
|
||||||
|
|
||||||
|
**** Fix hang on concat error, bug1608. [Bogdan Vukobratovic]
|
||||||
|
|
||||||
|
**** Fix VPI timed callbacks to be one-shot, pull5. [Matthew Ballance]
|
||||||
|
|
||||||
|
**** Fix // in filenames, bug1610. [Peter Nelson]
|
||||||
|
|
||||||
|
**** Fix $display("%p") to be closer to IEEE.
|
||||||
|
|
||||||
|
**** Fix labels on functions with returns, bug1614. [Mitch Hayenga]
|
||||||
|
|
||||||
|
**** Fix false unused message on __Vemumtab, msg3180. [Tobias Rosenkranz]
|
||||||
|
|
||||||
|
**** Fix assertion on dotted parameter arrayed function, bug1620. [Rich Porter]
|
||||||
|
|
||||||
|
**** Fix interface reference tracing, bug1595. [Todd Strader]
|
||||||
|
|
||||||
|
**** Fix error on unpacked concatenations, bug1627. [Driss Hafdi]
|
||||||
|
|
||||||
|
|
||||||
|
* Verilator 4.022 2019-11-10
|
||||||
|
|
||||||
|
** Add --protect-lib, bug1490. [Todd Strader]
|
||||||
|
|
||||||
|
** Add cmake support, bug1363. [Patrick Stewart]
|
||||||
|
|
||||||
|
*** Examples have been renamed.
|
||||||
|
|
||||||
|
*** Add --protect-ids to obscure information in objects, bug1521. [Todd Strader]
|
||||||
|
|
||||||
|
*** Add --trace-coverage.
|
||||||
|
|
||||||
|
*** Add --xml-output.
|
||||||
|
|
||||||
|
*** Support multithreading on Windows. [Patrick Stewart]
|
||||||
|
|
||||||
|
*** Suppress 'command failed' on normal errors.
|
||||||
|
|
||||||
|
*** Support some unpacked arrays in parameters, bug1315. [Marshal Qiao]
|
||||||
|
|
||||||
|
*** Add interface port visibility in traces, bug1594. [Todd Strader]
|
||||||
|
|
||||||
|
**** Increase case duplicate/incomplete to 16 bit tables, bug1545. [Yossi Nivin]
|
||||||
|
|
||||||
|
**** Support quoted arguments in -f files, bug1535. [Yves Mathieu]
|
||||||
|
|
||||||
|
**** Optimize modulus by power-of-two constants, and masked conditionals.
|
||||||
|
|
||||||
|
**** Fix detecting missing reg types, bug1570. [Jacko Dirks]
|
||||||
|
|
||||||
|
**** Fix multithreaded yield behavior when no work. [Patrick Stewart]
|
||||||
|
|
||||||
|
**** Fix bad-syntax crashes, bug1548, bug1550-1553, bug1557-1560, bug1563,
|
||||||
|
bug1573-1577, bug1579, bug1582-1591. [Eric Rippey]
|
||||||
|
|
||||||
|
**** Fix false CMPCONST/UNSIGNED warnings on "inside", bug1581. [Mitch Hayenga]
|
||||||
|
|
||||||
|
|
||||||
* Verilator 4.020 2019-10-06
|
* Verilator 4.020 2019-10-06
|
||||||
|
|
||||||
*** Support $fseek, $ftell, $frewind, bug1496. [Howard Su]
|
*** Support $fseek, $ftell, $frewind, bug1496. [Howard Su]
|
||||||
|
|||||||
+11
-1
@@ -1,3 +1,4 @@
|
|||||||
|
\.clang-format
|
||||||
\.clang-tidy
|
\.clang-tidy
|
||||||
\.git/
|
\.git/
|
||||||
\.git$
|
\.git$
|
||||||
@@ -14,7 +15,9 @@
|
|||||||
.*\.key
|
.*\.key
|
||||||
.*\.vcd
|
.*\.vcd
|
||||||
.*\.1
|
.*\.1
|
||||||
|
\.codacy\.yml
|
||||||
\.travis\.yml
|
\.travis\.yml
|
||||||
|
/build/
|
||||||
/obj_dir/
|
/obj_dir/
|
||||||
/obj_dbg/
|
/obj_dbg/
|
||||||
/obj_nc/
|
/obj_nc/
|
||||||
@@ -27,10 +30,14 @@
|
|||||||
/cov_work/
|
/cov_work/
|
||||||
/logs/
|
/logs/
|
||||||
^Makefile$
|
^Makefile$
|
||||||
|
README.html
|
||||||
bin/verilator_bin.*
|
bin/verilator_bin.*
|
||||||
bin/verilator_coverage_bin.*
|
bin/verilator_coverage_bin.*
|
||||||
|
docs/.*\.html$
|
||||||
docs/Makefile$
|
docs/Makefile$
|
||||||
docs/doxygen-doc/.*
|
docs/doxygen-doc/.*
|
||||||
|
examples/xml_py/copied/
|
||||||
|
examples/xml_py/graph.*
|
||||||
src/Makefile$
|
src/Makefile$
|
||||||
src/Makefile_obj$
|
src/Makefile_obj$
|
||||||
include/verilated.mk$
|
include/verilated.mk$
|
||||||
@@ -39,6 +46,8 @@ config.cache$
|
|||||||
config.status$
|
config.status$
|
||||||
verilator\.log
|
verilator\.log
|
||||||
verilator\.tex
|
verilator\.tex
|
||||||
|
verilator-config.cmake$
|
||||||
|
verilator-config-version.cmake$
|
||||||
verilator.pc$
|
verilator.pc$
|
||||||
verilator_bin.*
|
verilator_bin.*
|
||||||
verilator_coverage_bin.*
|
verilator_coverage_bin.*
|
||||||
@@ -46,10 +55,11 @@ verilator_coverage_bin.*
|
|||||||
ncverilog.history
|
ncverilog.history
|
||||||
autom4te\.cache/
|
autom4te\.cache/
|
||||||
nodist/
|
nodist/
|
||||||
|
ci/
|
||||||
/simv$
|
/simv$
|
||||||
/simv.daidir/
|
/simv.daidir/
|
||||||
/vc_hdrs.h$
|
/vc_hdrs.h$
|
||||||
/csrc/
|
/csrc/
|
||||||
obj_dir/.*
|
obj_dir.*
|
||||||
TAGS
|
TAGS
|
||||||
.*~
|
.*~
|
||||||
|
|||||||
+61
-38
@@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
# This file is part of Verilator.
|
# This file is part of Verilator.
|
||||||
#
|
#
|
||||||
# Code available from: http://www.veripool.org/verilator
|
# Code available from: https://verilator.org
|
||||||
#
|
#
|
||||||
#*****************************************************************************
|
#*****************************************************************************
|
||||||
#
|
#
|
||||||
@@ -104,11 +104,20 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
|
|||||||
SHELL = /bin/sh
|
SHELL = /bin/sh
|
||||||
|
|
||||||
SUBDIRS = src test_regress \
|
SUBDIRS = src test_regress \
|
||||||
examples/hello_world_c examples/hello_world_sc \
|
examples/cmake_hello_c \
|
||||||
examples/tracing_c examples/tracing_sc \
|
examples/cmake_hello_sc \
|
||||||
|
examples/cmake_tracing_c \
|
||||||
|
examples/cmake_tracing_sc \
|
||||||
|
examples/cmake_protect_lib \
|
||||||
|
examples/make_hello_c \
|
||||||
|
examples/make_hello_sc \
|
||||||
|
examples/make_tracing_c \
|
||||||
|
examples/make_tracing_sc \
|
||||||
|
examples/make_protect_lib \
|
||||||
|
|
||||||
INFOS = README README.html README.pdf \
|
INFOS = verilator.txt verilator.html verilator.pdf
|
||||||
verilator.txt verilator.html verilator.pdf
|
|
||||||
|
INFOS_OLD = README README.html README.pdf
|
||||||
|
|
||||||
# Files that can be generated, but should be up to date for a distribution.
|
# Files that can be generated, but should be up to date for a distribution.
|
||||||
DISTDEP = info Makefile
|
DISTDEP = info Makefile
|
||||||
@@ -119,6 +128,9 @@ DISTFILES_INC = $(INFOS) .gitignore \
|
|||||||
Changes \
|
Changes \
|
||||||
LICENSE \
|
LICENSE \
|
||||||
MANIFEST.SKIP \
|
MANIFEST.SKIP \
|
||||||
|
README.adoc \
|
||||||
|
verilator-config.cmake.in \
|
||||||
|
verilator-config-version.cmake.in \
|
||||||
bin/verilator \
|
bin/verilator \
|
||||||
bin/verilator_coverage \
|
bin/verilator_coverage \
|
||||||
bin/verilator_difftree \
|
bin/verilator_difftree \
|
||||||
@@ -132,6 +144,7 @@ DISTFILES_INC = $(INFOS) .gitignore \
|
|||||||
docs/TODO \
|
docs/TODO \
|
||||||
docs/doxygen-mainpage \
|
docs/doxygen-mainpage \
|
||||||
docs/doxygen.config \
|
docs/doxygen.config \
|
||||||
|
docs/install.adoc \
|
||||||
docs/internals.adoc \
|
docs/internals.adoc \
|
||||||
docs/verilator_logo.png \
|
docs/verilator_logo.png \
|
||||||
install-sh configure *.pod \
|
install-sh configure *.pod \
|
||||||
@@ -147,9 +160,15 @@ DISTFILES_INC = $(INFOS) .gitignore \
|
|||||||
src/.gdbinit \
|
src/.gdbinit \
|
||||||
src/*.pl src/*.pod \
|
src/*.pl src/*.pod \
|
||||||
examples/*/.*ignore examples/*/Makefile* \
|
examples/*/.*ignore examples/*/Makefile* \
|
||||||
examples/*/*.[chv]* examples/*/*.pl \
|
examples/*/*.[chv]* examples/*/vl_* \
|
||||||
|
examples/*/CMakeLists.txt \
|
||||||
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
|
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
|
||||||
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \
|
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \
|
||||||
|
test_regress/*.pl \
|
||||||
|
test_regress/Makefile \
|
||||||
|
test_regress/Makefile_obj \
|
||||||
|
test_regress/input.vc \
|
||||||
|
test_regress/CMakeLists.txt \
|
||||||
test_regress/t/t*/*.sv* \
|
test_regress/t/t*/*.sv* \
|
||||||
test_regress/t/t*/*.v* \
|
test_regress/t/t*/*.v* \
|
||||||
test_regress/t/t*/*/*.sv* \
|
test_regress/t/t*/*/*.sv* \
|
||||||
@@ -182,8 +201,8 @@ INST_PROJ_BIN_FILES = \
|
|||||||
DISTFILES := $(DISTFILES_INC)
|
DISTFILES := $(DISTFILES_INC)
|
||||||
|
|
||||||
EXAMPLES_FIRST = \
|
EXAMPLES_FIRST = \
|
||||||
examples/hello_world_c \
|
examples/make_hello_c \
|
||||||
examples/hello_world_sc \
|
examples/make_hello_sc \
|
||||||
|
|
||||||
EXAMPLES = $(EXAMPLES_FIRST) $(filter-out $(EXAMPLES_FIRST), $(sort $(wildcard examples/*)))
|
EXAMPLES = $(EXAMPLES_FIRST) $(filter-out $(EXAMPLES_FIRST), $(sort $(wildcard examples/*)))
|
||||||
|
|
||||||
@@ -218,7 +237,9 @@ msg_test: all_nomsg
|
|||||||
|
|
||||||
.PHONY: test
|
.PHONY: test
|
||||||
ifeq ($(CFG_WITH_LONGTESTS),yes) # Local... Else don't burden users
|
ifeq ($(CFG_WITH_LONGTESTS),yes) # Local... Else don't burden users
|
||||||
test: smoke-test examples test_regress
|
test: smoke-test test_regress
|
||||||
|
# examples is part of test_regress's test_regress/t/t_a2_examples.pl
|
||||||
|
# (because that allows it to run in parallel with other test_regress's)
|
||||||
else
|
else
|
||||||
test: smoke-test examples
|
test: smoke-test examples
|
||||||
endif
|
endif
|
||||||
@@ -229,8 +250,8 @@ endif
|
|||||||
@echo
|
@echo
|
||||||
|
|
||||||
smoke-test: all_nomsg
|
smoke-test: all_nomsg
|
||||||
test_regress/t/t_a_first_cc.pl
|
test_regress/t/t_a1_first_cc.pl
|
||||||
test_regress/t/t_a_first_sc.pl
|
test_regress/t/t_a2_first_sc.pl
|
||||||
|
|
||||||
test_regress: all_nomsg
|
test_regress: all_nomsg
|
||||||
$(MAKE) -C test_regress
|
$(MAKE) -C test_regress
|
||||||
@@ -263,22 +284,6 @@ verilator.pdf: ${srcdir}/bin/verilator Makefile $(POD2LATEXFIX)
|
|||||||
pdflatex verilator.tex
|
pdflatex verilator.tex
|
||||||
-rm -f verilator.toc verilator.aux verilator.idx verilator.out
|
-rm -f verilator.toc verilator.aux verilator.idx verilator.out
|
||||||
|
|
||||||
README: README.pod
|
|
||||||
-rm -f $@
|
|
||||||
$(POD2TEXT) --loose $< > $@
|
|
||||||
|
|
||||||
README.html: README.pod
|
|
||||||
pod2html $< >$@
|
|
||||||
|
|
||||||
# PDF needs DIST variables; but having configure.ac as dependency isn't detected
|
|
||||||
README.pdf: README.pod Makefile $(POD2LATEXFIX)
|
|
||||||
pod2latex --full --out README.tex $<
|
|
||||||
$(PERL) $(POD2LATEXFIX) "$(DISTTITLE) README File" "${DISTDATE}" < README.tex > README2.tex
|
|
||||||
mv README2.tex README.tex
|
|
||||||
pdflatex README.tex
|
|
||||||
pdflatex README.tex
|
|
||||||
-rm -f README.toc README.aux README.idx README.out
|
|
||||||
|
|
||||||
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
|
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
|
||||||
VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg verilator_coverage_bin_dbg \
|
VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg verilator_coverage_bin_dbg \
|
||||||
verilator_coverage verilator_gantt verilator_includer verilator_profcfunc
|
verilator_coverage verilator_gantt verilator_includer verilator_profcfunc
|
||||||
@@ -297,6 +302,7 @@ VL_INST_INC_SRCDIR_FILES = \
|
|||||||
|
|
||||||
VL_INST_DATA_SRCDIR_FILES = \
|
VL_INST_DATA_SRCDIR_FILES = \
|
||||||
examples/*/*.[chv]* examples/*/Makefile* \
|
examples/*/*.[chv]* examples/*/Makefile* \
|
||||||
|
examples/*/CMakeLists.txt
|
||||||
|
|
||||||
installbin:
|
installbin:
|
||||||
$(MKINSTALLDIRS) $(DESTDIR)$(bindir)
|
$(MKINSTALLDIRS) $(DESTDIR)$(bindir)
|
||||||
@@ -328,16 +334,24 @@ installdata:
|
|||||||
; for p in $(VL_INST_INC_SRCDIR_FILES) ; do \
|
; for p in $(VL_INST_INC_SRCDIR_FILES) ; do \
|
||||||
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
|
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
|
||||||
done
|
done
|
||||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/hello_world_c
|
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/make_hello_c
|
||||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/hello_world_sc
|
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/make_hello_sc
|
||||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/tracing_c
|
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/make_tracing_c
|
||||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/tracing_sc
|
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/make_tracing_sc
|
||||||
|
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/make_protect_lib
|
||||||
|
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_hello_c
|
||||||
|
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_hello_sc
|
||||||
|
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_c
|
||||||
|
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_sc
|
||||||
|
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_protect_lib
|
||||||
cd $(srcdir) \
|
cd $(srcdir) \
|
||||||
; for p in $(VL_INST_DATA_SRCDIR_FILES) ; do \
|
; for p in $(VL_INST_DATA_SRCDIR_FILES) ; do \
|
||||||
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
|
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
|
||||||
done
|
done
|
||||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgconfigdir)
|
$(MKINSTALLDIRS) $(DESTDIR)$(pkgconfigdir)
|
||||||
$(INSTALL_DATA) verilator.pc $(DESTDIR)$(pkgconfigdir)
|
$(INSTALL_DATA) verilator.pc $(DESTDIR)$(pkgconfigdir)
|
||||||
|
$(INSTALL_DATA) verilator-config.cmake $(DESTDIR)$(pkgdatadir)
|
||||||
|
$(INSTALL_DATA) verilator-config-version.cmake $(DESTDIR)$(pkgdatadir)
|
||||||
|
|
||||||
# We don't trust rm -rf, so rmdir instead as it will fail if user put in other files
|
# We don't trust rm -rf, so rmdir instead as it will fail if user put in other files
|
||||||
uninstall:
|
uninstall:
|
||||||
@@ -348,15 +362,24 @@ uninstall:
|
|||||||
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_SRCDIR_FILES)
|
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_SRCDIR_FILES)
|
||||||
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_DATA_SRCDIR_FILES)
|
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_DATA_SRCDIR_FILES)
|
||||||
-rm $(DESTDIR)$(pkgconfigdir)/verilator.pc
|
-rm $(DESTDIR)$(pkgconfigdir)/verilator.pc
|
||||||
|
-rm $(DESTDIR)$(pkgdatadir)/verilator-config.cmake
|
||||||
|
-rm $(DESTDIR)$(pkgdatadir)/verilator-config-version.cmake
|
||||||
-rmdir $(DESTDIR)$(pkgdatadir)/bin
|
-rmdir $(DESTDIR)$(pkgdatadir)/bin
|
||||||
-rmdir $(DESTDIR)$(pkgdatadir)/include/gtkwave
|
-rmdir $(DESTDIR)$(pkgdatadir)/include/gtkwave
|
||||||
-rmdir $(DESTDIR)$(pkgdatadir)/include/vltstd
|
-rmdir $(DESTDIR)$(pkgdatadir)/include/vltstd
|
||||||
-rmdir $(DESTDIR)$(pkgdatadir)/include
|
-rmdir $(DESTDIR)$(pkgdatadir)/include
|
||||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/hello_world_c
|
-rmdir $(DESTDIR)$(pkgdatadir)/examples/make_hello_c
|
||||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/hello_world_sc
|
-rmdir $(DESTDIR)$(pkgdatadir)/examples/make_hello_sc
|
||||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/tracing_c
|
-rmdir $(DESTDIR)$(pkgdatadir)/examples/make_tracing_c
|
||||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/tracing_sc
|
-rmdir $(DESTDIR)$(pkgdatadir)/examples/make_tracing_sc
|
||||||
|
-rmdir $(DESTDIR)$(pkgdatadir)/examples/make_protect_lib
|
||||||
|
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_hello_c
|
||||||
|
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_hello_sc
|
||||||
|
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_c
|
||||||
|
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_sc
|
||||||
|
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_protect_lib
|
||||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples
|
-rmdir $(DESTDIR)$(pkgdatadir)/examples
|
||||||
|
-rmdir $(DESTDIR)$(pkgdatadir)/cmake
|
||||||
-rmdir $(DESTDIR)$(pkgdatadir)
|
-rmdir $(DESTDIR)$(pkgdatadir)
|
||||||
-rmdir $(DESTDIR)$(pkgconfigdir)
|
-rmdir $(DESTDIR)$(pkgconfigdir)
|
||||||
|
|
||||||
@@ -449,7 +472,7 @@ install-msg:
|
|||||||
@echo "Installed examples to $(DESTDIR)$(pkgdatadir)/examples"
|
@echo "Installed examples to $(DESTDIR)$(pkgdatadir)/examples"
|
||||||
@echo
|
@echo
|
||||||
@echo "For documentation see 'man verilator' or 'verilator --help'"
|
@echo "For documentation see 'man verilator' or 'verilator --help'"
|
||||||
@echo "For forums and to report bugs see http://www.veripool.org/verilator"
|
@echo "For forums and to report bugs see https://verilator.org"
|
||||||
@echo
|
@echo
|
||||||
|
|
||||||
IN_WILD := ${srcdir}/*.in ${srcdir}/*/*.in
|
IN_WILD := ${srcdir}/*.in ${srcdir}/*/*.in
|
||||||
@@ -488,12 +511,12 @@ clean mostlyclean distclean maintainer-clean::
|
|||||||
rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs *.idx
|
rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs *.idx
|
||||||
rm -f *.ev *.evs *.ov *.ovs *.cv *.cvs *.ma *.mas
|
rm -f *.ev *.evs *.ov *.ovs *.cv *.cvs *.ma *.mas
|
||||||
rm -f *.tex
|
rm -f *.tex
|
||||||
rm -rf examples/*/obj_dir examples/*/logs
|
rm -rf examples/*/obj_dir* examples/*/logs
|
||||||
rm -rf test_*/obj_dir
|
rm -rf test_*/obj_dir
|
||||||
rm -rf nodist/obj_dir
|
rm -rf nodist/obj_dir
|
||||||
|
|
||||||
distclean maintainer-clean::
|
distclean maintainer-clean::
|
||||||
rm -f *.info* *.1 $(INFOS) $(VL_INST_MAN_FILES)
|
rm -f *.info* *.1 $(INFOS) $(INFOS_OLD) $(VL_INST_MAN_FILES)
|
||||||
rm -f Makefile config.status config.cache config.log TAGS
|
rm -f Makefile config.status config.cache config.log TAGS
|
||||||
rm -f verilator_bin* verilator_coverage_bin*
|
rm -f verilator_bin* verilator_coverage_bin*
|
||||||
rm -f bin/verilator_bin* bin/verilator_coverage_bin*
|
rm -f bin/verilator_bin* bin/verilator_coverage_bin*
|
||||||
|
|||||||
+140
@@ -0,0 +1,140 @@
|
|||||||
|
// Github doesn't render images unless absolute URL
|
||||||
|
:!toc:
|
||||||
|
|
||||||
|
ifdef::env-github[]
|
||||||
|
image:https://img.shields.io/badge/License-LGPL%20v3-blue.svg[license LGPLv3,link=https://www.gnu.org/licenses/lgpl-3.0]
|
||||||
|
image:https://img.shields.io/badge/License-Artistic%202.0-0298c3.svg[license Artistic-2.0,link=https://opensource.org/licenses/Artistic-2.0]
|
||||||
|
image:https://api.codacy.com/project/badge/Grade/ff998fdaa6f64b9a95eb5f342ee6bf4d[Code Quality,link=https://www.codacy.com/manual/wsnyder/verilator]
|
||||||
|
image:https://travis-ci.com/verilator/verilator.svg?branch=master[Build Status (Travis CI),link=https://travis-ci.com/verilator/verilator]
|
||||||
|
endif::[]
|
||||||
|
|
||||||
|
ifdef::env-github[]
|
||||||
|
:link_verilator_contributing: link:docs/CONTRIBUTING.adoc
|
||||||
|
:link_verilator_install: link:docs/install.adoc
|
||||||
|
endif::[]
|
||||||
|
ifndef::env-github[]
|
||||||
|
:link_verilator_contributing: https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.adoc
|
||||||
|
:link_verilator_install: https://verilator.org/install
|
||||||
|
endif::[]
|
||||||
|
|
||||||
|
== Welcome to Verilator
|
||||||
|
|
||||||
|
[cols="a,a",indent=0,frame="none"]
|
||||||
|
|===
|
||||||
|
^.^| *Welcome to Verilator, the fastest free Verilog HDL simulator.*
|
||||||
|
+++ <br/> +++ • Accepts synthesizable Verilog or SystemVerilog
|
||||||
|
+++ <br/> +++ • Performs lint code-quality checks
|
||||||
|
+++ <br/> +++ • Compiles into multithreaded {cpp}, SystemC, or (soon) {cpp}-under-Python
|
||||||
|
+++ <br/> +++ • Creates XML to front-end your own tools
|
||||||
|
<.^|image:https://www.veripool.org/img/verilator_256_200_min.png[Logo,256,200]
|
||||||
|
|
||||||
|
>.^|image:https://www.veripool.org/img/verilator_multithreaded_performance_bg-min.png[,388,178]
|
||||||
|
^.^| *Fast*
|
||||||
|
+++ <br/> +++ • Outperforms many commercial simulators
|
||||||
|
+++ <br/> +++ • Single- and multi-threaded output models
|
||||||
|
|
||||||
|
^.^| *Widely Used*
|
||||||
|
+++ <br/> +++ • Wide industry and academic deployment
|
||||||
|
+++ <br/> +++ • Out-of-the-box support from Arm, and RISC-V vendor IP
|
||||||
|
<.^|image:https://www.veripool.org/img/verilator_usage_400x200-min.png[,400,200]
|
||||||
|
|
||||||
|
>.^|image:https://www.veripool.org/img/chips_alliance_logo_225x75-min.png[CHIPS Alliance,link=https://chipsalliance.org]
|
||||||
|
image:https://www.veripool.org/img/osi_logo_125x125-min.png[,125,125]
|
||||||
|
^.^| *Community Driven & Openly Licensed*
|
||||||
|
+++ <br/> +++ • Guided by the https://chipsalliance.org/[CHIPS Alliance] and https://www.linuxfoundation.org/[Linux Foundation]
|
||||||
|
+++ <br/> +++ • Open, and free as in both speech and beer
|
||||||
|
+++ <br/> +++ • More simulation for your verification budget
|
||||||
|
|===
|
||||||
|
|
||||||
|
== What Verilator Does
|
||||||
|
|
||||||
|
Verilator is invoked with parameters similar to GCC or Synopsys's VCS. It
|
||||||
|
"Verilates" the specified synthesizable Verilog or SystemVerilog code by
|
||||||
|
reading it, performing lint checks, and optionally inserting assertion
|
||||||
|
checks and coverage-analysis points. It outputs single- or multi-threaded
|
||||||
|
.cpp and .h files, the "Verilated" code.
|
||||||
|
|
||||||
|
The user writes a little {cpp}/SystemC wrapper file, which instantiates the
|
||||||
|
"Verilated" model of the user's top level module. These {cpp}/SystemC
|
||||||
|
files are then compiled by a {cpp} compiler (gcc/clang/MSVC++). The
|
||||||
|
resulting executable performs the design simulation. Verilator also
|
||||||
|
supports linking its generated libraries, optionally encrypted, into other
|
||||||
|
simulators.
|
||||||
|
|
||||||
|
Verilator may not be the best choice if you are expecting a full featured
|
||||||
|
replacement for NC-Verilog, VCS or another commercial Verilog simulator, or
|
||||||
|
if you are looking for a behavioral Verilog simulator e.g. for a quick
|
||||||
|
class project (we recommend http://iverilog.icarus.com[Icarus Verilog] for
|
||||||
|
this.) However, if you are looking for a path to migrate synthesizable
|
||||||
|
Verilog to {cpp} or SystemC, and your team is comfortable writing just a
|
||||||
|
touch of {cpp} code, Verilator is the tool for you.
|
||||||
|
|
||||||
|
== Performance
|
||||||
|
|
||||||
|
Verilator does not simply convert Verilog HDL to {cpp} or SystemC. Rather
|
||||||
|
than only translate, Verilator compiles your code into a much faster
|
||||||
|
optimized and optionally thread-partitioned model, which is in turn wrapped
|
||||||
|
inside a {cpp}/SystemC/Python module. The results are a compiled Verilog
|
||||||
|
model that executes even on a single-thread over 10x faster than standalone
|
||||||
|
SystemC, and on a single thread is about 100 times faster than interpreted
|
||||||
|
Verilog simulators such as http://iverilog.icarus.com[Icarus
|
||||||
|
Verilog]. Another 2-10x speedup might be gained from multithreading
|
||||||
|
(yielding 200-1000x total over interpreted simulators).
|
||||||
|
|
||||||
|
Verilator has typically similar or better performance versus the commercial
|
||||||
|
Verilog simulators (Carbon Design Systems Carbonator, Modelsim, Cadence
|
||||||
|
Incisive/NC-Verilog, Synopsys VCS, VTOC, and Pragmatic CVer/CVC). But,
|
||||||
|
Verilator is free, so you can spend on computes rather than licenses. Thus
|
||||||
|
Verilator gives you more cycles/dollar than anything else available.
|
||||||
|
|
||||||
|
For more information on how Verilator stacks up to some of the other
|
||||||
|
commercial and free Verilog simulators, see the
|
||||||
|
https://www.veripool.org/verilog_sim_benchmarks.html[Verilog Simulator
|
||||||
|
Benchmarks]. (If you benchmark Verilator, please see the notes in the
|
||||||
|
https://verilator.org/verilator_doc.pdf[Verilator manual (PDF)], and also
|
||||||
|
if possible post on the forums the results; there may be additional tweaks
|
||||||
|
possible.)
|
||||||
|
|
||||||
|
== Installation & Documentation
|
||||||
|
|
||||||
|
For more information:
|
||||||
|
|
||||||
|
* {link_verilator_install}[Verilator installation and package directory
|
||||||
|
structure]
|
||||||
|
|
||||||
|
* https://verilator.org/verilator_doc.html[Verilator manual (HTML)],
|
||||||
|
or https://verilator.org/verilator_doc.pdf[Verilator manual (PDF)]
|
||||||
|
|
||||||
|
* https://verilator.org/forum[Verilator forum]
|
||||||
|
|
||||||
|
* https://verilator.org/issues[Verilator Issues]
|
||||||
|
|
||||||
|
== Community Supported
|
||||||
|
|
||||||
|
Verilator is a community project, guided by the
|
||||||
|
https://chipsalliance.org/[CHIPS Alliance] under the
|
||||||
|
https://www.linuxfoundation.org/[Linux Foundation].
|
||||||
|
|
||||||
|
We appreciate and welcome your contributions in whatever form; please see
|
||||||
|
{link_verilator_contributing}[Contributing to Verilator]. Thanks to our
|
||||||
|
https://verilator.org/verilator_doc.html#CONTRIBUTORS[Contributors and
|
||||||
|
Sponsors].
|
||||||
|
|
||||||
|
== Related Projects
|
||||||
|
|
||||||
|
* http://gtkwave.sourceforge.net/[GTKwave] - Waveform viewer for Verilator
|
||||||
|
traces.
|
||||||
|
|
||||||
|
* http://iverilog.icarus.com[Icarus Verilog] - Icarus is a full featured
|
||||||
|
interpreted Verilog simulator. If Verilator does not support your needs,
|
||||||
|
perhaps Icarus may.
|
||||||
|
|
||||||
|
== Open License
|
||||||
|
|
||||||
|
Verilator is Copyright 2003-2019 by Wilson Snyder. (Report bugs to
|
||||||
|
https://verilator.org/issues[Verilator Issues].)
|
||||||
|
|
||||||
|
Verilator 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. (See the documentation for more
|
||||||
|
details.)
|
||||||
-284
@@ -1,284 +0,0 @@
|
|||||||
# DESCRIPTION: DOCUMENT source run through perl to produce README file
|
|
||||||
# Use 'make README' to produce the output file
|
|
||||||
|
|
||||||
=pod
|
|
||||||
|
|
||||||
=for html <a href="https://travis-ci.com/verilator/verilator"><img src="https://travis-ci.com/verilator/verilator.svg?branch=master"></a>
|
|
||||||
|
|
||||||
=head1 NAME
|
|
||||||
|
|
||||||
Welcome to Verilator. This is the Verilator package's README file.
|
|
||||||
|
|
||||||
This document describes how to initially install Verilator. For more
|
|
||||||
general information please see L<http://verilator.org>.
|
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
|
||||||
|
|
||||||
Verilator is a simulator which "Verilates" synthesizable (generally not
|
|
||||||
behavioral) Verilog code into "Verilated" C++ or SystemC code.
|
|
||||||
|
|
||||||
Verilator is invoked with parameters similar to GCC or Synopsys's VCS. It
|
|
||||||
reads the specified Verilog code, lints it, and optionally adds coverage
|
|
||||||
code. For C++ format, it outputs .cpp and .h files. For SystemC format,
|
|
||||||
it outputs .cpp and .h files using the standard SystemC headers.
|
|
||||||
|
|
||||||
The resulting files are then compiled with C++. The user writes a little
|
|
||||||
C++ wrapper file, which instantiates the top level module. This is
|
|
||||||
compiled in C++, and linked with the Verilated files.
|
|
||||||
|
|
||||||
The resulting executable will perform the actual simulation.
|
|
||||||
|
|
||||||
=head1 SUPPORTED SYSTEMS
|
|
||||||
|
|
||||||
Verilator is developed and has primary testing on Ubuntu. Versions have
|
|
||||||
also built on Redhat Linux, Macs OS-X, HPUX and Solaris. It should run
|
|
||||||
with minor porting on any Linux-ish platform. Verilator also works on
|
|
||||||
Windows under Cygwin, and Windows under MinGW (gcc -mno-cygwin). Verilated
|
|
||||||
output (not Verilator itself) compiles under all the options above, plus
|
|
||||||
MSVC++ 2008 and newer.
|
|
||||||
|
|
||||||
=head1 INSTALLATION
|
|
||||||
|
|
||||||
The following are detailed installation instructions.
|
|
||||||
Alternatively, for a quick summary please see
|
|
||||||
L<http://www.veripool.org/projects/verilator/wiki/Installing>.
|
|
||||||
|
|
||||||
=over 4
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
Obtain binary or sources:
|
|
||||||
|
|
||||||
There are three methods to obtain Verilator, a prebuilt binary as part of
|
|
||||||
your Linux distribution, via git, or using a tarball. If you will be
|
|
||||||
modifying Verilator, you should use the "git" method as it will let you
|
|
||||||
track changes and hopefully contribute in the future.
|
|
||||||
|
|
||||||
=over 4
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
Prebuilt binary:
|
|
||||||
|
|
||||||
You may install a binary on Ubuntu or other distributions using a package
|
|
||||||
manager. This is unlikely to be the most recent version.
|
|
||||||
|
|
||||||
apt-get install verilator
|
|
||||||
|
|
||||||
You may now skip the remaining installation steps.
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
Git:
|
|
||||||
|
|
||||||
Get the sources from the repository.
|
|
||||||
|
|
||||||
git clone http://git.veripool.org/git/verilator # Only first time
|
|
||||||
## Note the URL above is not a page you can see with a browser, it's for git only
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
Tarball:
|
|
||||||
|
|
||||||
Get a recent tarball package from L<http://www.veripool.org/verilator>.
|
|
||||||
Click the "Download" tab, scroll down to the latest package
|
|
||||||
(i.e. verilator-#.###.tgz), download it, and decompress with:
|
|
||||||
|
|
||||||
tar xvzf verilator_#-###.tgz
|
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
Install prerequisites:
|
|
||||||
|
|
||||||
=over 4
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
To use Verilator you will need the C<perl>, C<make> (or C<gmake>), and
|
|
||||||
C<g++> (or C<clang>) packages. To compile Verilator in addition to the above you need the C<flex>,
|
|
||||||
C<bison> and C<texi2html> packages installed.
|
|
||||||
|
|
||||||
sudo apt-get install git make autoconf g++ flex bison # First time prerequisites
|
|
||||||
sudo apt-get install libgz # Non-Ubuntu (ignore if gives error)
|
|
||||||
sudo apt-get install libfl2 libfl-dev zlibc zlib1g zlib1g-dev # Ubuntu only (ignore if gives error)
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
If you will be using SystemC (vs straight C++ output), download SystemC
|
|
||||||
from L<http://www.systemc.org>. Follow their installation instructions.
|
|
||||||
You will need to set SYSTEMC_INCLUDE to point to the include directory with
|
|
||||||
systemc.h in it, and SYSTEMC_LIBDIR to points to the directory with
|
|
||||||
libsystemc.a in it. (Older installations may set SYSTEMC and SYSTEMC_ARCH
|
|
||||||
instead.)
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
To use Verilator FST tracing you will need the C<gtkwave> and C<libgz> (and on
|
|
||||||
Ubuntu C<zlibc> C<zlib1g> C<zlib1g-dev>) packages installed.
|
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
Prepare for building:
|
|
||||||
|
|
||||||
cd verilator # Needed if not already in the package
|
|
||||||
unsetenv VERILATOR_ROOT # For csh; ignore error if on bash
|
|
||||||
unset VERILATOR_ROOT # For bash; ignore error if on bash
|
|
||||||
# If using git:
|
|
||||||
git pull # Make sure we're up-to-date
|
|
||||||
git tag # See what versions exist
|
|
||||||
#git checkout master # Use development branch (e.g. recent bug fix)
|
|
||||||
#git checkout stable # Use most recent release
|
|
||||||
#git checkout v{version} # Switch to specified release version
|
|
||||||
#
|
|
||||||
autoconf # Create ./configure script
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
Installation Choices
|
|
||||||
|
|
||||||
You have to decide how you're going to eventually install the kit.
|
|
||||||
|
|
||||||
Note Verilator builds the current value of VERILATOR_ROOT, SYSTEMC_INCLUDE,
|
|
||||||
and SYSTEMC_LIBDIR as defaults into the executable, so try to have them
|
|
||||||
correct before configuring.
|
|
||||||
|
|
||||||
=over 4
|
|
||||||
|
|
||||||
=item 1.
|
|
||||||
|
|
||||||
Our personal favorite is to always run Verilator from its git directory.
|
|
||||||
This allows the easiest experimentation and upgrading, and allows many
|
|
||||||
versions of Verilator to co-exist on a system. To run you point to the
|
|
||||||
program's files, no install is needed.
|
|
||||||
|
|
||||||
export VERILATOR_ROOT=`pwd` # if your shell is bash
|
|
||||||
setenv VERILATOR_ROOT `pwd` # if your shell is csh
|
|
||||||
./configure
|
|
||||||
|
|
||||||
Note after installing (below steps), a calling program should set the
|
|
||||||
environment variable VERILATOR_ROOT to point to this git directory, then
|
|
||||||
execute $VERILATOR_ROOT/bin/verilator, which will find the path to all
|
|
||||||
needed files.
|
|
||||||
|
|
||||||
=item 2.
|
|
||||||
|
|
||||||
You may eventually be installing onto a project/company-wide "CAD" tools
|
|
||||||
disk that may support multiple versions of every tool.
|
|
||||||
|
|
||||||
unset VERILATOR_ROOT # if your shell is bash
|
|
||||||
unsetenv VERILATOR_ROOT # if your shell is csh
|
|
||||||
# For the tarball, use the version number instead of git describe
|
|
||||||
./configure --prefix /CAD_DISK/verilator/`git describe | sed "s/verilator_//"`
|
|
||||||
|
|
||||||
Note after installing (below steps), if you use C<modulecmd>, you'll want a
|
|
||||||
module file like the following:
|
|
||||||
|
|
||||||
set install_root /CAD_DISK/verilator/{version-number-used-above}
|
|
||||||
unsetenv VERILATOR_ROOT
|
|
||||||
prepend-path PATH $install_root/bin
|
|
||||||
prepend-path MANPATH $install_root/man
|
|
||||||
prepend-path PKG_CONFIG_PATH $install_root/share/pkgconfig
|
|
||||||
|
|
||||||
=item 3.
|
|
||||||
|
|
||||||
The next option is to eventually install it globally, using the normal system paths:
|
|
||||||
|
|
||||||
unset VERILATOR_ROOT # if your shell is bash
|
|
||||||
unsetenv VERILATOR_ROOT # if your shell is csh
|
|
||||||
./configure
|
|
||||||
|
|
||||||
Then after installing (below) the binary directories should already be in
|
|
||||||
your PATH.
|
|
||||||
|
|
||||||
=item 4.
|
|
||||||
|
|
||||||
Finally, you may eventually install it into a specific installation prefix,
|
|
||||||
as most GNU tools support:
|
|
||||||
|
|
||||||
unset VERILATOR_ROOT # if your shell is bash
|
|
||||||
unsetenv VERILATOR_ROOT # if your shell is csh
|
|
||||||
./configure --prefix /opt/verilator-VERSION
|
|
||||||
|
|
||||||
Then after installing (below steps) you will need to add /opt/verilator-VERSION/bin to
|
|
||||||
PATH.
|
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
Note all of the options above did:
|
|
||||||
|
|
||||||
./configure ... some options ...
|
|
||||||
|
|
||||||
Add to this line C<--enable-longtests> for more complete developer tests.
|
|
||||||
Additional packages may be required for these tests.
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
Type C<make> to compile Verilator.
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
Type C<make test> to check the compilation.
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
If you used the prefix scheme, now do a C<make install>.
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
You may now wish to consult the examples directory. Type C<make> inside any
|
|
||||||
example directory to run the example.
|
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
=head1 USAGE DOCUMENTATION
|
|
||||||
|
|
||||||
Detailed documentation and the man page can be seen by running:
|
|
||||||
|
|
||||||
bin/verilator --help
|
|
||||||
|
|
||||||
or reading verilator.pdf in the same directory as this README.
|
|
||||||
|
|
||||||
or see L<https://www.veripool.org/ftp/verilator_doc.pdf> (which is the most
|
|
||||||
recent version and thus may differ in some respects from the version you installed).
|
|
||||||
|
|
||||||
=head1 PACKAGE DIRECTORY STRUCTURE
|
|
||||||
|
|
||||||
The directories in the package directory are as follows:
|
|
||||||
|
|
||||||
Changes => Version history
|
|
||||||
bin/verilator => Compiler Wrapper invoked to Verilate code
|
|
||||||
docs/ => Additional documentation
|
|
||||||
examples/hello_world_c => Example simple Verilog->C++ conversion
|
|
||||||
examples/hello_world_sc => Example simple Verilog->SystemC conversion
|
|
||||||
examples/tracing_c => Example Verilog->C++ with tracing
|
|
||||||
examples/tracing_sc => Example Verilog->SystemC with tracing
|
|
||||||
include/ => Files that should be in your -I compiler path
|
|
||||||
include/verilated*.cpp => Global routines to link into your simulator
|
|
||||||
include/verilated*.h => Global headers
|
|
||||||
include/verilated.mk => Common Makefile
|
|
||||||
include/verilated.v => Stub defines for linting
|
|
||||||
src/ => Translator source code
|
|
||||||
test_regress => Internal tests
|
|
||||||
verilator.pdf => Primary documentation
|
|
||||||
verilator.txt => Primary documentation (text)
|
|
||||||
|
|
||||||
For files created after Verilation, see the manual.
|
|
||||||
|
|
||||||
=head1 DISTRIBUTION
|
|
||||||
|
|
||||||
This package is Copyright 2003-2019 by Wilson Snyder. (Report bugs to
|
|
||||||
L<http://www.veripool.org/>.)
|
|
||||||
|
|
||||||
Verilator 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. (See the documentation for more
|
|
||||||
details.)
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
||||||
more details.
|
|
||||||
+517
-200
File diff suppressed because it is too large
Load Diff
@@ -134,7 +134,12 @@ sub run {
|
|||||||
warn "%Error: Verilator_coverage threw signal $status.\n" if !$Debug;
|
warn "%Error: Verilator_coverage threw signal $status.\n" if !$Debug;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
die "%Error: Command Failed $command\n";
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -264,7 +269,7 @@ Specifies a module search directory.
|
|||||||
|
|
||||||
=head1 DISTRIBUTION
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
The latest version is available from L<http://www.veripool.org/>.
|
The latest version is available from L<https://verilator.org>.
|
||||||
|
|
||||||
Copyright 2003-2019 by Wilson Snyder. Verilator is free software; you can
|
Copyright 2003-2019 by Wilson Snyder. Verilator is free software; you can
|
||||||
redistribute it and/or modify the Verilator internals under the terms of
|
redistribute it and/or modify the Verilator internals under the terms of
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ Do not show differences in line numbering.
|
|||||||
|
|
||||||
=head1 DISTRIBUTION
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
The latest version is available from L<http://www.veripool.org/verilator>.
|
The latest version is available from L<https://verilator.org>.
|
||||||
|
|
||||||
Copyright 2005-2019 by Wilson Snyder. This package is free software; you can
|
Copyright 2005-2019 by Wilson Snyder. This package is free software; you can
|
||||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||||
|
|||||||
+1
-1
@@ -538,7 +538,7 @@ verilator_gantt.vcd.
|
|||||||
|
|
||||||
=head1 DISTRIBUTION
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
The latest version is available from L<http://www.veripool.org/>.
|
The latest version is available from L<https://verilator.org>.
|
||||||
|
|
||||||
Copyright 2018-2019 by Wilson Snyder. Verilator is free software; you can
|
Copyright 2018-2019 by Wilson Snyder. Verilator is free software; you can
|
||||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ Displays this message and program version and exits.
|
|||||||
|
|
||||||
=head1 DISTRIBUTION
|
=head1 DISTRIBUTION
|
||||||
|
|
||||||
The latest version is available from L<http://www.veripool.org/>.
|
The latest version is available from L<https://verilator.org>.
|
||||||
|
|
||||||
Copyright 2007-2019 by Wilson Snyder. Verilator is free software; you can
|
Copyright 2007-2019 by Wilson Snyder. Verilator is free software; you can
|
||||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||||
|
|||||||
Executable
+64
@@ -0,0 +1,64 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# DESCRIPTION: Verilator: Travis CI build script
|
||||||
|
#
|
||||||
|
# Copyright 2019 by Todd Strader. 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.
|
||||||
|
#
|
||||||
|
# This script builds and caches the Verilator binaries for Travis CI
|
||||||
|
# (and possibly other CI platforms). The Verilator CI system uses this
|
||||||
|
# script, but other CI systems that depend on Verilator may also use
|
||||||
|
# the script.
|
||||||
|
# see: https://github.com/verilator/verilator_ext_tests/blob/master/.travis.yml
|
||||||
|
# To use this script, either checkout Verilator as part of the CI build
|
||||||
|
# process or add Verilator as a Git submodule. Verilator tarballs can
|
||||||
|
# not be used as the script relies on Git revisions for caching.
|
||||||
|
set -e
|
||||||
|
|
||||||
|
if [ -z "${VERILATOR_NUM_JOBS}" ]; then
|
||||||
|
VERILATOR_NUM_JOBS=$(nproc)
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Caching would be simpler if we installed without VERILATOR_ROOT, but
|
||||||
|
# it's needed for driver.pl outside of the repo
|
||||||
|
if [ -z "${VERILATOR_ROOT}" ]; then
|
||||||
|
echo "VERILATOR_ROOT not set"
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "${VERILATOR_CACHE}" ]; then
|
||||||
|
echo "VERILATOR_CACHE not set"
|
||||||
|
exit -1
|
||||||
|
fi
|
||||||
|
|
||||||
|
VERILATOR_REV=$(cd "${VERILATOR_ROOT}" && git rev-parse HEAD)
|
||||||
|
echo "Found Verilator rev ${VERILATOR_REV}"
|
||||||
|
|
||||||
|
CACHED_REV_FILE=${VERILATOR_CACHE}/.rev.txt
|
||||||
|
|
||||||
|
if [[ ! -f "${CACHED_REV_FILE}" || \
|
||||||
|
$(< "${CACHED_REV_FILE}") != "${VERILATOR_REV}" ]]; then
|
||||||
|
echo "Building Verilator"
|
||||||
|
|
||||||
|
# Unsure why Travis monkies with the capitalization of the stage name, but it does
|
||||||
|
if [[ -n ${TRAVIS_BUILD_STAGE_NAME} && \
|
||||||
|
${TRAVIS_BUILD_STAGE_NAME} != "Build verilator" ]]; then
|
||||||
|
echo "WARNING: Building Verilator in Travis build stage other than \"Build verilator\": ${TRAVIS_BUILD_STAGE_NAME}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cd "${VERILATOR_ROOT}"
|
||||||
|
autoconf && ./configure ${VERILATOR_CONFIG_FLAGS} && make -j ${VERILATOR_NUM_JOBS}
|
||||||
|
# Copy the Verilator build artifacts
|
||||||
|
mkdir -p "${VERILATOR_CACHE}"
|
||||||
|
rm -rf ${VERILATOR_CACHE}/*
|
||||||
|
cp bin/*bin* "${VERILATOR_CACHE}"
|
||||||
|
# Remember the Git revision
|
||||||
|
echo "${VERILATOR_REV}" > "${CACHED_REV_FILE}"
|
||||||
|
else
|
||||||
|
echo "Using cached Verilator"
|
||||||
|
cd "${VERILATOR_ROOT}"
|
||||||
|
# Create include/verilated_config.h and maybe other things
|
||||||
|
autoconf && ./configure ${VERILATOR_CONFIG_FLAGS}
|
||||||
|
cp ${VERILATOR_CACHE}/* bin
|
||||||
|
fi
|
||||||
Executable
+26
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# DESCRIPTION: Verilator: Travis CI test script
|
||||||
|
#
|
||||||
|
# Copyright 2019 by Todd Strader. 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.
|
||||||
|
set -e
|
||||||
|
|
||||||
|
export DRIVER_FLAGS='-j 0 --quiet --rerun'
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
dist)
|
||||||
|
make -C test_regress SCENARIOS=--dist
|
||||||
|
;;
|
||||||
|
vlt)
|
||||||
|
make -C test_regress SCENARIOS=--vlt
|
||||||
|
;;
|
||||||
|
vltmt)
|
||||||
|
make -C test_regress SCENARIOS=--vltmt
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Usage: test.sh (dist|vlt|vltmt)"
|
||||||
|
exit -1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
+33
-18
@@ -6,14 +6,14 @@
|
|||||||
|
|
||||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||||
#AC_INIT([Verilator],[#.### devel])
|
#AC_INIT([Verilator],[#.### devel])
|
||||||
AC_INIT([Verilator],[4.020 2019-10-06],
|
AC_INIT([Verilator],[4.024 2019-12-08],
|
||||||
[https://www.veripool.org/verilator],
|
[https://verilator.org],
|
||||||
[verilator],[https://www.veripool.org/verilator])
|
[verilator],[https://verilator.org])
|
||||||
# When releasing, also update header of Changes file
|
# When releasing, also update header of Changes file
|
||||||
# and commit using "devel release" or "Version bump" message
|
# and commit using "devel release" or "Version bump" message
|
||||||
|
|
||||||
AC_CONFIG_HEADER(src/config_build.h)
|
AC_CONFIG_HEADER(src/config_build.h)
|
||||||
AC_CONFIG_FILES(Makefile docs/Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc)
|
AC_CONFIG_FILES(Makefile docs/Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc verilator-config.cmake verilator-config-version.cmake)
|
||||||
|
|
||||||
AC_MSG_RESULT([configuring for $PACKAGE_STRING])
|
AC_MSG_RESULT([configuring for $PACKAGE_STRING])
|
||||||
|
|
||||||
@@ -276,24 +276,39 @@ AC_SUBST(CFG_CXXFLAGS_PARSER)
|
|||||||
# For some reason -faligned-new does not work under Travis w/ clang but the
|
# For some reason -faligned-new does not work under Travis w/ clang but the
|
||||||
# configure test doesn't catch this either
|
# configure test doesn't catch this either
|
||||||
AS_IF([test "x$TRAVIS_COMPILER" != xclang], [_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-faligned-new)])
|
AS_IF([test "x$TRAVIS_COMPILER" != xclang], [_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-faligned-new)])
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-fbracket-depth=4096)
|
CFG_CXX_FLAGS_CMAKE="-faligned-new"
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Qunused-arguments)
|
m4_foreach([cflag],[
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-bool-operation)
|
[-fbracket-depth=4096],
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-parentheses-equality)
|
[-fcf-protection=none],
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-sign-compare)
|
[-mno-cet],
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-uninitialized)
|
[-Qunused-arguments],
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-but-set-variable)
|
[-Wno-bool-operation],
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-parameter)
|
[-Wno-parentheses-equality],
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-variable)
|
[-Wno-sign-compare],
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-shadow)
|
[-Wno-uninitialized],
|
||||||
|
[-Wno-unused-but-set-variable],
|
||||||
|
[-Wno-unused-parameter],
|
||||||
|
[-Wno-unused-variable],
|
||||||
|
[-Wno-shadow]],[
|
||||||
|
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,cflag)
|
||||||
|
# CMake will test what flags work itself, so pass all flags through to it
|
||||||
|
CFG_CXX_FLAGS_CMAKE="$CFG_CXX_FLAGS_CMAKE cflag"
|
||||||
|
])
|
||||||
AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
|
AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
|
||||||
|
AC_SUBST(CFG_CXX_FLAGS_CMAKE)
|
||||||
|
|
||||||
# Find multithread linker flags
|
# Find multithread linker flags
|
||||||
_MY_LDLIBS_CHECK_OPT(CFG_LDLIBS_THREADS,-mt)
|
m4_foreach([ldflag], [
|
||||||
_MY_LDLIBS_CHECK_OPT(CFG_LDLIBS_THREADS,-pthread)
|
[-mt],
|
||||||
_MY_LDLIBS_CHECK_OPT(CFG_LDLIBS_THREADS,-lpthread)
|
[-pthread],
|
||||||
_MY_LDLIBS_CHECK_OPT(CFG_LDLIBS_THREADS,-latomic)
|
[-lpthread],
|
||||||
|
[-latomic]],[
|
||||||
|
_MY_LDLIBS_CHECK_OPT(CFG_LDLIBS_THREADS,ldflag)
|
||||||
|
# CMake will test what flags work itself, so pass all flags through to it
|
||||||
|
CFG_LDFLAGS_THREADS_CMAKE="$CFG_LDFLAGS_THREADS_CMAKE ldflag"
|
||||||
|
])
|
||||||
AC_SUBST(CFG_LDLIBS_THREADS)
|
AC_SUBST(CFG_LDLIBS_THREADS)
|
||||||
|
AC_SUBST(CFG_LDFLAGS_THREADS_CMAKE)
|
||||||
|
|
||||||
# Set CFG_WITH_THREADED if can support threading
|
# Set CFG_WITH_THREADED if can support threading
|
||||||
AC_MSG_CHECKING(whether $CXX supports Verilated threads)
|
AC_MSG_CHECKING(whether $CXX supports Verilated threads)
|
||||||
|
|||||||
@@ -1 +1,4 @@
|
|||||||
|
*.1
|
||||||
|
*.html
|
||||||
|
*.pdf
|
||||||
Makefile
|
Makefile
|
||||||
|
|||||||
+11
-11
@@ -8,10 +8,10 @@ contributions flow more efficiently.
|
|||||||
==== Did you find a bug?
|
==== Did you find a bug?
|
||||||
|
|
||||||
* Please **Ensure the bug was not already reported** by searching
|
* Please **Ensure the bug was not already reported** by searching
|
||||||
https://www.veripool.org/projects/verilator/issues[Verilator Issues].
|
https://verilator.org/issues[Verilator Issues].
|
||||||
|
|
||||||
* If you're unable to find an open issue addressing the problem,
|
* If you're unable to find an open issue addressing the problem,
|
||||||
https://www.veripool.org/projects/verilator/issues/new[open a new issue].
|
https://verilator.org/issues/new[open a new issue].
|
||||||
|
|
||||||
** Be sure to include a **code sample** or an **executable test case**
|
** Be sure to include a **code sample** or an **executable test case**
|
||||||
demonstrating the bug and expected behavior that is not occurring.
|
demonstrating the bug and expected behavior that is not occurring.
|
||||||
@@ -22,14 +22,13 @@ contributions flow more efficiently.
|
|||||||
|
|
||||||
==== Did you write a patch that fixes a bug?
|
==== Did you write a patch that fixes a bug?
|
||||||
|
|
||||||
* Please https://www.veripool.org/projects/verilator/issues/new[Open a new
|
* Please https://verilator.org/issues/new[Open a new issue].
|
||||||
issue].
|
|
||||||
|
|
||||||
* You may attach a patch to the issue, or (preferred) may point to a github
|
* You may attach a patch to the issue, or (preferred) may point to a GitHub
|
||||||
repository branch within your github account.
|
repository branch within your GitHub account.
|
||||||
|
|
||||||
** Verilator uses Travis CI to provide continuous integration. You may
|
** Verilator uses Travis CI to provide continuous integration. You may
|
||||||
want to setup Travis CI on your github branch to ensure your changes
|
want to setup Travis CI on your GitHub branch to ensure your changes
|
||||||
keep the tests passing. See link:internals.adoc[docs/internals].
|
keep the tests passing. See link:internals.adoc[docs/internals].
|
||||||
|
|
||||||
* Your source-code contributions must be certified as open source, under
|
* Your source-code contributions must be certified as open source, under
|
||||||
@@ -48,7 +47,7 @@ contributions flow more efficiently.
|
|||||||
contributions.
|
contributions.
|
||||||
|
|
||||||
** In any of these cases your name will be added to
|
** In any of these cases your name will be added to
|
||||||
link:CONTRIBUTORS[docs/CONTRIBUTRORS] and you are agreeing all future
|
link:CONTRIBUTORS[docs/CONTRIBUTORS] and you are agreeing all future
|
||||||
contributions are also certified.
|
contributions are also certified.
|
||||||
|
|
||||||
** We occasionally accept contributions where people do not want their
|
** We occasionally accept contributions where people do not want their
|
||||||
@@ -66,11 +65,12 @@ contributions flow more efficiently.
|
|||||||
|
|
||||||
==== Do you have questions?
|
==== Do you have questions?
|
||||||
|
|
||||||
* Please see the
|
* Please see FAQ section and rest of the
|
||||||
https://www.veripool.org/projects/verilator/wiki/Faq[Verilator FAQ].
|
https://verilator.org/verilator_doc.html[Verilator manual],
|
||||||
|
or https://verilator.org/verilator_doc.pdf[Verilator manual (PDF)].
|
||||||
|
|
||||||
* Ask any question in the
|
* Ask any question in the
|
||||||
https://www.veripool.org/projects/verilator/boards[Verilator forums].
|
https://verilator.org/forum[Verilator forum].
|
||||||
|
|
||||||
==== Code of Conduct
|
==== Code of Conduct
|
||||||
|
|
||||||
|
|||||||
+13
-1
@@ -2,16 +2,28 @@ The contributors listed below have certified their Verilator contributions
|
|||||||
under the Developer Certificate of Origin
|
under the Developer Certificate of Origin
|
||||||
(https://developercertificate.org/).
|
(https://developercertificate.org/).
|
||||||
|
|
||||||
Please see the Verilator manual for additional contributors.
|
Please see the Verilator manual for 200+ additional contributors. Thanks to
|
||||||
|
all.
|
||||||
|
|
||||||
|
Ahmed El-Mahmoudy
|
||||||
Alex Chadwick
|
Alex Chadwick
|
||||||
|
Chris Randall
|
||||||
|
Driss Hafdi
|
||||||
|
Eric Rippey
|
||||||
|
Garrett Smith
|
||||||
Gianfranco Costamagna
|
Gianfranco Costamagna
|
||||||
Howard Su
|
Howard Su
|
||||||
|
Iztok Jeras
|
||||||
Jeremy Bennett
|
Jeremy Bennett
|
||||||
John Coiner
|
John Coiner
|
||||||
|
Julien Margetts
|
||||||
Kanad Kanhere
|
Kanad Kanhere
|
||||||
|
Kevin Kiningham
|
||||||
Lukasz Dalek
|
Lukasz Dalek
|
||||||
Maarten De Braekeleer
|
Maarten De Braekeleer
|
||||||
|
Matthew Ballance
|
||||||
|
Mike Popoloski
|
||||||
|
Patrick Stewart
|
||||||
Philipp Wagner
|
Philipp Wagner
|
||||||
Richard Myers
|
Richard Myers
|
||||||
Sebastien Van Cauwenberghe
|
Sebastien Van Cauwenberghe
|
||||||
|
|||||||
+6
-2
@@ -3,7 +3,7 @@
|
|||||||
#
|
#
|
||||||
# This file is part of Verilator.
|
# This file is part of Verilator.
|
||||||
#
|
#
|
||||||
# Code available from: http://www.veripool.org/verilator
|
# Code available from: https://verilator.org
|
||||||
#
|
#
|
||||||
#*****************************************************************************
|
#*****************************************************************************
|
||||||
#
|
#
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#### Start of system configuration section. ####
|
#### Start of system configuration section. ####
|
||||||
|
|
||||||
|
ASCIIDOCTOR = asciidoctor
|
||||||
DOXYGEN = doxygen
|
DOXYGEN = doxygen
|
||||||
|
|
||||||
#### End of system configuration section. ####
|
#### End of system configuration section. ####
|
||||||
@@ -33,6 +34,9 @@ DOXYGEN = doxygen
|
|||||||
default:
|
default:
|
||||||
@echo "error: make not supported here, run 'make docs' from Verilator top-level"
|
@echo "error: make not supported here, run 'make docs' from Verilator top-level"
|
||||||
|
|
||||||
|
%.html: %.adoc
|
||||||
|
$(ASCIIDOCTOR) $< -n -o $@
|
||||||
|
|
||||||
clean mostlyclean distclean maintainer-clean::
|
clean mostlyclean distclean maintainer-clean::
|
||||||
rm -f $(SCRIPTS) *.tmp
|
rm -f $(SCRIPTS) *.tmp
|
||||||
rm -f *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.kys *.log
|
rm -f *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.kys *.log
|
||||||
@@ -41,7 +45,7 @@ clean mostlyclean distclean maintainer-clean::
|
|||||||
rm -f *.tex
|
rm -f *.tex
|
||||||
|
|
||||||
distclean maintainer-clean::
|
distclean maintainer-clean::
|
||||||
rm -f *.info* *.1 $(INFOS)
|
rm -f *.info* *.1 *.html *.pdf $(INFOS)
|
||||||
rm -f Makefile
|
rm -f Makefile
|
||||||
|
|
||||||
.PHONY: doxygen
|
.PHONY: doxygen
|
||||||
|
|||||||
@@ -0,0 +1,294 @@
|
|||||||
|
= Verilator Installation
|
||||||
|
:toc: right
|
||||||
|
|
||||||
|
// Github doesn't render unless absolute URL
|
||||||
|
image::https://www.veripool.org/img/verilator_256_200_min.png[Logo,256,200,role="right"]
|
||||||
|
|
||||||
|
== Introduction
|
||||||
|
|
||||||
|
This discusses how to install Verilator. For more general information
|
||||||
|
please see https://verilator.org[verilator.org].
|
||||||
|
|
||||||
|
== Quick-start
|
||||||
|
|
||||||
|
=== Install From a Package Manager
|
||||||
|
|
||||||
|
Using a distribution's package manager is the easiest way to get
|
||||||
|
started. (Note packages are unlikely to have the most recent version, so
|
||||||
|
Git, below, maybe a better alternative.) To install as a package:
|
||||||
|
|
||||||
|
apt-get install verilator
|
||||||
|
|
||||||
|
If this works, skip down to <<Running Verilator>>.
|
||||||
|
|
||||||
|
=== Git
|
||||||
|
|
||||||
|
Alternatively, installing Verilator with Git provides the most flexibility.
|
||||||
|
For additional options and details see the additional sections below. In
|
||||||
|
brief:
|
||||||
|
|
||||||
|
// Also update README
|
||||||
|
....
|
||||||
|
# Prerequisites:
|
||||||
|
#sudo apt-get install git make autoconf g++ flex bison
|
||||||
|
#sudo apt-get install libfl2 # Ubuntu only (ignore if gives error)
|
||||||
|
#sudo apt-get install libfl-dev # Ubuntu only (ignore if gives error)
|
||||||
|
|
||||||
|
git clone https://git.veripool.org/git/verilator # Only first time
|
||||||
|
## Note the URL above is not a page you can see with a browser, it's for git only
|
||||||
|
|
||||||
|
# Every time you need to build:
|
||||||
|
unsetenv VERILATOR_ROOT # For csh; ignore error if on bash
|
||||||
|
unset VERILATOR_ROOT # For bash
|
||||||
|
cd verilator
|
||||||
|
git pull # Make sure git repository is up-to-date
|
||||||
|
git tag # See what versions exist
|
||||||
|
#git checkout master # Use development branch (e.g. recent bug fixes)
|
||||||
|
#git checkout stable # Use most recent stable release
|
||||||
|
#git checkout v{version} # Switch to specified release version
|
||||||
|
|
||||||
|
autoconf # Create ./configure script
|
||||||
|
./configure
|
||||||
|
make
|
||||||
|
sudo make install
|
||||||
|
# Now see "man verilator" or online verilator.pdf's for the example tutorials
|
||||||
|
....
|
||||||
|
|
||||||
|
If this works, skip down to <<Running Verilator>>.
|
||||||
|
|
||||||
|
== Detailed Build Instructions
|
||||||
|
|
||||||
|
This section describes details of the build process, and assumes you are
|
||||||
|
building from Git or a tarball. For using a pre-built binary for your
|
||||||
|
Linux distribution, see instead <<Install From a Package Manager>>.
|
||||||
|
|
||||||
|
=== OS Requirements
|
||||||
|
|
||||||
|
Verilator is developed and has primary testing on Ubuntu. Versions have
|
||||||
|
also built on Redhat Linux, Apple OS-X, HPUX and Solaris. It should run
|
||||||
|
with minor porting on any GNU/Linux-ish platform. Verilator also works on
|
||||||
|
Windows under Cygwin, and Windows under MinGW (gcc -mno-cygwin). Verilated
|
||||||
|
output (not Verilator itself) compiles under all the options above, plus
|
||||||
|
MSVC++.
|
||||||
|
|
||||||
|
=== Install Prerequisites
|
||||||
|
|
||||||
|
To build Verilator you will need to install some standard packages:
|
||||||
|
|
||||||
|
sudo apt-get install git
|
||||||
|
sudo apt-get install autoconf
|
||||||
|
sudo apt-get install flex bison
|
||||||
|
|
||||||
|
Additionally, to build or run Verilator you need these standard packages:
|
||||||
|
|
||||||
|
sudo apt-get install perl python3
|
||||||
|
sudo apt-get install make
|
||||||
|
sudo apt-get install g++ # Alternatively, clang
|
||||||
|
sudo apt-get install libgz # Non-Ubuntu (ignore if gives error)
|
||||||
|
sudo apt-get install libfl2 libfl-dev zlibc zlib1g zlib1g-dev # Ubuntu only (ignore if gives error)
|
||||||
|
|
||||||
|
Those developing Verilator may also want these (see internals.adoc):
|
||||||
|
|
||||||
|
sudo apt-get install gdb asciidoctor graphviz
|
||||||
|
cpan install Pod::Perldoc
|
||||||
|
cpan install Unix::Processors
|
||||||
|
|
||||||
|
==== Install SystemC
|
||||||
|
|
||||||
|
If you will be using SystemC (vs straight C++ output), download
|
||||||
|
http://www.systemc.org[SystemC]. Follow their installation instructions.
|
||||||
|
You will need to set `SYSTEMC_INCLUDE` to point to the include directory
|
||||||
|
with systemc.h in it, and `SYSTEMC_LIBDIR` to points to the directory with
|
||||||
|
libsystemc.a in it. (Older installations may set `SYSTEMC` and
|
||||||
|
`SYSTEMC_ARCH` instead.)
|
||||||
|
|
||||||
|
==== Install GTKWave
|
||||||
|
|
||||||
|
To make use of Verilator FST tracing you will want
|
||||||
|
http://gtkwave.sourceforge.net/[GTKwave] installed, however this is not
|
||||||
|
required at Verilator build time.
|
||||||
|
|
||||||
|
=== Obtain Sources
|
||||||
|
|
||||||
|
You may use Git or a tarball for the sources. Git is the supported option.
|
||||||
|
(If using a historical build that uses a tarball, tarballs are obtained
|
||||||
|
from https://www.veripool.org/projects/verilator/wiki/Download[Verilator
|
||||||
|
Downloads]; we presume you know how to use it, and is not described here.)
|
||||||
|
|
||||||
|
Get the sources from the repository: (You need do this only once, ever.)
|
||||||
|
|
||||||
|
git clone https://git.veripool.org/git/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:
|
||||||
|
|
||||||
|
cd verilator
|
||||||
|
git pull # Make sure we're up-to-date
|
||||||
|
git tag # See what versions exist
|
||||||
|
#git checkout master # Use development branch (e.g. recent bug fix)
|
||||||
|
#git checkout stable # Use most recent release
|
||||||
|
#git checkout v{version} # Switch to specified release version
|
||||||
|
|
||||||
|
=== Auto Configure
|
||||||
|
|
||||||
|
Create the configuration script:
|
||||||
|
|
||||||
|
autoconf # Create ./configure script
|
||||||
|
|
||||||
|
=== Eventual Installation Options
|
||||||
|
|
||||||
|
Before configuring the build, you have to decide how you're going to
|
||||||
|
eventually install the kit. Verilator will be compiling the current value
|
||||||
|
of `VERILATOR_ROOT`, `SYSTEMC_INCLUDE`, and `SYSTEMC_LIBDIR` as defaults
|
||||||
|
into the executable, so they must be correct before configuring.
|
||||||
|
|
||||||
|
These are the options:
|
||||||
|
|
||||||
|
==== 1. Run-in-Place from VERILATOR_ROOT
|
||||||
|
|
||||||
|
Our personal favorite is to always run Verilator in-place from its Git
|
||||||
|
directory. This allows the easiest experimentation and upgrading, and
|
||||||
|
allows many versions of Verilator to co-exist on a system.
|
||||||
|
|
||||||
|
export VERILATOR_ROOT=`pwd` # if your shell is bash
|
||||||
|
setenv VERILATOR_ROOT `pwd` # if your shell is csh
|
||||||
|
./configure
|
||||||
|
# Running will use files from $VERILATOR_ROOT, so no install needed
|
||||||
|
|
||||||
|
Note after installing (below steps), a calling program or shell must set
|
||||||
|
the environment variable `VERILATOR_ROOT` to point to this Git directory,
|
||||||
|
then execute `$VERILATOR_ROOT/bin/verilator`, which will find the path to
|
||||||
|
all needed files.
|
||||||
|
|
||||||
|
==== 2. Install into a CAD Disk
|
||||||
|
|
||||||
|
You may eventually be installing onto a project/company-wide "CAD" tools
|
||||||
|
disk that may support multiple versions of every tool. Target the build to
|
||||||
|
a destination directory name that includes the Verilator version name:
|
||||||
|
|
||||||
|
unset VERILATOR_ROOT # if your shell is bash
|
||||||
|
unsetenv VERILATOR_ROOT # if your shell is csh
|
||||||
|
# For the tarball, use the version number instead of git describe
|
||||||
|
./configure --prefix /CAD_DISK/verilator/`git describe | sed "s/verilator_//"`
|
||||||
|
|
||||||
|
Note after installing (below steps), if you use
|
||||||
|
http://modules.sourceforge.net/[modulecmd], you'll want a module file like
|
||||||
|
the following:
|
||||||
|
|
||||||
|
.modulecmd's verilator/version file
|
||||||
|
----
|
||||||
|
set install_root /CAD_DISK/verilator/{version-number-used-above}
|
||||||
|
unsetenv VERILATOR_ROOT
|
||||||
|
prepend-path PATH $install_root/bin
|
||||||
|
prepend-path MANPATH $install_root/man
|
||||||
|
prepend-path PKG_CONFIG_PATH $install_root/share/pkgconfig
|
||||||
|
----
|
||||||
|
|
||||||
|
==== 3. Install into a Specific Path
|
||||||
|
|
||||||
|
You may eventually install Verilator into a specific installation prefix,
|
||||||
|
as most GNU tools support:
|
||||||
|
|
||||||
|
unset VERILATOR_ROOT # if your shell is bash
|
||||||
|
unsetenv VERILATOR_ROOT # if your shell is csh
|
||||||
|
./configure --prefix /opt/verilator-VERSION
|
||||||
|
|
||||||
|
Then after installing (below steps) you will need to add
|
||||||
|
`/opt/verilator-VERSION/bin` to `$PATH`.
|
||||||
|
|
||||||
|
==== 4. Install System Globally
|
||||||
|
|
||||||
|
The final option is to eventually install Verilator globally, using the
|
||||||
|
normal system paths:
|
||||||
|
|
||||||
|
unset VERILATOR_ROOT # if your shell is bash
|
||||||
|
unsetenv VERILATOR_ROOT # if your shell is csh
|
||||||
|
./configure
|
||||||
|
|
||||||
|
Then after installing (below) the binary directories should already be in
|
||||||
|
your `$PATH`.
|
||||||
|
|
||||||
|
=== Configure
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
export VERILATOR_AUTHOR_SITE=1 # Put in your .bashrc
|
||||||
|
./configure --enable-longtests ...above options...
|
||||||
|
|
||||||
|
=== Compile
|
||||||
|
|
||||||
|
Compile Verilator:
|
||||||
|
|
||||||
|
make -j
|
||||||
|
|
||||||
|
=== Test
|
||||||
|
|
||||||
|
Check the compilation by running self-tests:
|
||||||
|
|
||||||
|
make test
|
||||||
|
|
||||||
|
=== Install
|
||||||
|
|
||||||
|
If you used any but the <<1. Run-in-Place from VERILATOR_ROOT>> scheme,
|
||||||
|
install to the OS-standard place:
|
||||||
|
|
||||||
|
make install
|
||||||
|
|
||||||
|
== Running Verilator
|
||||||
|
|
||||||
|
To run Verilator, see the example sections in the
|
||||||
|
https://verilator.org/verilator_doc.html[Verilator manual (HTML)],
|
||||||
|
or https://verilator.org/verilator_doc.pdf[Verilator manual (PDF)].
|
||||||
|
|
||||||
|
Also see the `examples/` directory that is part of the kit, and is installed
|
||||||
|
(in a OS-specific place, often in e.g. `/usr/local/share/verilator/examples`).
|
||||||
|
|
||||||
|
cd examples/make_hello_c
|
||||||
|
make
|
||||||
|
|
||||||
|
Note if you did a `make install` above you should not have `VERILATOR_ROOT`
|
||||||
|
set in your environment; it is built into the executable.
|
||||||
|
|
||||||
|
== Announcements
|
||||||
|
|
||||||
|
To get notified of new releases, login to
|
||||||
|
https://www.veripool.org[Veripool], and click the "watch" button near the
|
||||||
|
top right under https://www.veripool.org/projects/verilator/news[Verilator
|
||||||
|
News].
|
||||||
|
|
||||||
|
== Directory Structure
|
||||||
|
|
||||||
|
Some relevant files and directories in this package are as follows:
|
||||||
|
|
||||||
|
Changes => Version history
|
||||||
|
README.adoc => This document
|
||||||
|
bin/verilator => Compiler wrapper invoked to Verilate code
|
||||||
|
docs/ => Additional documentation
|
||||||
|
examples/make_hello_c => Example GNU-make simple Verilog->C++ conversion
|
||||||
|
examples/make_hello_sc => Example GNU-make simple Verilog->SystemC conversion
|
||||||
|
examples/make_tracing_c => Example GNU-make Verilog->C++ with tracing
|
||||||
|
examples/make_tracing_sc => Example GNU-make Verilog->SystemC with tracing
|
||||||
|
examples/make_protect_lib => Example using --protect-lib
|
||||||
|
examples/cmake_hello_c => Example building make_hello_c with CMake
|
||||||
|
examples/cmake_hello_sc => Example building make_hello_sc with CMake
|
||||||
|
examples/cmake_tracing_c => Example building make_tracing_c with CMake
|
||||||
|
examples/cmake_tracing_sc => Example building make_tracing_sc with CMake
|
||||||
|
examples/cmake_protect_lib => Example building make_protect_lib with CMake
|
||||||
|
include/ => Files that should be in your -I compiler path
|
||||||
|
include/verilated*.cpp => Global routines to link into your simulator
|
||||||
|
include/verilated*.h => Global headers
|
||||||
|
include/verilated.mk => Common Makefile
|
||||||
|
src/ => Translator source code
|
||||||
|
test_regress => Internal tests
|
||||||
|
|
||||||
|
For files created after a design is Verilated, see the
|
||||||
|
https://verilator.org/verilator_doc.html[Verilator manual (HTML)],
|
||||||
|
or https://verilator.org/verilator_doc.pdf[Verilator manual (PDF)].
|
||||||
|
|
||||||
|
== License
|
||||||
|
|
||||||
|
Copyright 2008-2019 by Wilson Snyder. Verilator 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.
|
||||||
+37
-15
@@ -9,7 +9,7 @@ image::https://www.veripool.org/img/verilator_256_200_min.png[Logo,256,200,role=
|
|||||||
This file discusses internal and programming details for Verilator. It's a
|
This file discusses internal and programming details for Verilator. It's a
|
||||||
reference for developers and debugging problems.
|
reference for developers and debugging problems.
|
||||||
|
|
||||||
See also the Verilator internals presentation at http://www.veripool.org.
|
See also the Verilator internals presentation at https://www.veripool.org.
|
||||||
|
|
||||||
== Code Flows
|
== Code Flows
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ the pass.
|
|||||||
A number of passes use graph algorithms, and the class `V3Graph` is
|
A number of passes use graph algorithms, and the class `V3Graph` is
|
||||||
provided to represent those graphs. Graphs are directed, and algorithms are
|
provided to represent those graphs. Graphs are directed, and algorithms are
|
||||||
provided to manipulate the graphs and to output them in
|
provided to manipulate the graphs and to output them in
|
||||||
http://www.graphviz.org/[GraphViz] dot format. `V3Graph.h` provides
|
https://www.graphviz.org[GraphViz] dot format. `V3Graph.h` provides
|
||||||
documentation of this class.
|
documentation of this class.
|
||||||
|
|
||||||
==== `V3GraphVertex`
|
==== `V3GraphVertex`
|
||||||
@@ -382,7 +382,7 @@ changed; if clear, checking those signals for changes may be skipped.
|
|||||||
|
|
||||||
== Coding Conventions
|
== Coding Conventions
|
||||||
|
|
||||||
=== Indentation style
|
=== Indentation and Naming Style
|
||||||
|
|
||||||
We will work with contributors to fix up indentation style issues, but it
|
We will work with contributors to fix up indentation style issues, but it
|
||||||
is appreciated if you could match our style:
|
is appreciated if you could match our style:
|
||||||
@@ -399,11 +399,18 @@ style indentation; the `c-set-style` undoes that.)
|
|||||||
|
|
||||||
* Use 2 spaces between the end of source and the beginning of a comment.
|
* Use 2 spaces between the end of source and the beginning of a comment.
|
||||||
|
|
||||||
* Use "mixedCapsSymbols" instead of "underlined_symbls".
|
* Use 1 space after if/for/switch/while and similar keywords.
|
||||||
|
|
||||||
|
* No spaces before semicolons, nor between a function's name and open
|
||||||
|
parenthesis (only applies to functions; if/else has a following space).
|
||||||
|
|
||||||
|
* Use "mixedCapsSymbols" instead of "underlined_symbols".
|
||||||
|
|
||||||
|
* Uas a "p" suffix on variables that are pointers, e.g. "nodep".
|
||||||
|
|
||||||
* Comment every member variable.
|
* Comment every member variable.
|
||||||
|
|
||||||
=== The `astgen` script
|
=== The `astgen` Script
|
||||||
|
|
||||||
Some of the code implementing passes is extremely repetitive, and must be
|
Some of the code implementing passes is extremely repetitive, and must be
|
||||||
implemented for each sub-class of `AstNode`. However, while repetitive,
|
implemented for each sub-class of `AstNode`. However, while repetitive,
|
||||||
@@ -424,7 +431,7 @@ into `V3Const__gen.cpp`.
|
|||||||
Verilator uses the "Visitor" design pattern to implement its refinement and
|
Verilator uses the "Visitor" design pattern to implement its refinement and
|
||||||
optimization passes. This allows separation of the pass algorithm from the
|
optimization passes. This allows separation of the pass algorithm from the
|
||||||
AST on which it operates. Wikipedia provides an introduction to the concept
|
AST on which it operates. Wikipedia provides an introduction to the concept
|
||||||
at http://en.wikipedia.org/wiki/Visitor_pattern.
|
at https://en.wikipedia.org/wiki/Visitor_pattern.
|
||||||
|
|
||||||
As noted above, all visitors are derived classes of `AstNVisitor`. All
|
As noted above, all visitors are derived classes of `AstNVisitor`. All
|
||||||
derived classes of `AstNode` implement the `accept` method, which takes as
|
derived classes of `AstNode` implement the `accept` method, which takes as
|
||||||
@@ -561,7 +568,7 @@ follow `nextp()` links.
|
|||||||
|
|
||||||
lp = acceptSubtreeReturnEdits(lp)
|
lp = acceptSubtreeReturnEdits(lp)
|
||||||
|
|
||||||
=== Identifying derived classes
|
=== Identifying Derived Classes
|
||||||
|
|
||||||
A common requirement is to identify the specific `AstNode` class we are
|
A common requirement is to identify the specific `AstNode` class we are
|
||||||
dealing with. For example a visitor might not implement separate `visit`
|
dealing with. For example a visitor might not implement separate `visit`
|
||||||
@@ -707,7 +714,7 @@ also runs a daily cron job to validate all of the tests against different OS and
|
|||||||
compiler versions.
|
compiler versions.
|
||||||
|
|
||||||
Developers can connect Travis CI to their GitHub account so that the CI
|
Developers can connect Travis CI to their GitHub account so that the CI
|
||||||
enviroment can check their branches too by doing the following:
|
environment can check their branches too by doing the following:
|
||||||
|
|
||||||
* Go to https://github.com/marketplace/travis-ci and follow the prompts
|
* Go to https://github.com/marketplace/travis-ci and follow the prompts
|
||||||
|
|
||||||
@@ -716,6 +723,17 @@ enviroment can check their branches too by doing the following:
|
|||||||
* Under a Travis CI project click More options > Settings in order to set up a
|
* Under a Travis CI project click More options > Settings in order to set up a
|
||||||
cron job on a particular branch
|
cron job on a particular branch
|
||||||
|
|
||||||
|
=== Fuzzing
|
||||||
|
|
||||||
|
There are scripts included to facilitate fuzzing of Verilator. These have
|
||||||
|
been successfully used to find a number of bugs in the frontend.
|
||||||
|
|
||||||
|
The scripts are based on using http://lcamtuf.coredump.cx/afl/[American fuzzy lop]
|
||||||
|
on a Debian-like system.
|
||||||
|
|
||||||
|
To get started, cd to "nodist/fuzzer/" and run "./all". A sudo password
|
||||||
|
may be required to setup the system for fuzzing.
|
||||||
|
|
||||||
== Debugging
|
== Debugging
|
||||||
|
|
||||||
=== --debug
|
=== --debug
|
||||||
@@ -723,10 +741,10 @@ cron job on a particular branch
|
|||||||
When you run with `--debug` there are two primary output file types placed
|
When you run with `--debug` there are two primary output file types placed
|
||||||
into the obj_dir, .tree and .dot files.
|
into the obj_dir, .tree and .dot files.
|
||||||
|
|
||||||
=== .dot output
|
=== .dot Output
|
||||||
|
|
||||||
Dot files are dumps of internal graphs in
|
Dot files are dumps of internal graphs in
|
||||||
http://www.graphviz.org/[Graphviz] dot format. When a dot file is dumped,
|
https://www.graphviz.org[Graphviz] dot format. When a dot file is dumped,
|
||||||
Verilator will also print a line on stdout that can be used to format the
|
Verilator will also print a line on stdout that can be used to format the
|
||||||
output, for example:
|
output, for example:
|
||||||
|
|
||||||
@@ -735,11 +753,11 @@ output, for example:
|
|||||||
You can then print a.ps. You may prefer gif format, which doesn't get
|
You can then print a.ps. You may prefer gif format, which doesn't get
|
||||||
scaled so can be more useful with large graphs.
|
scaled so can be more useful with large graphs.
|
||||||
|
|
||||||
For dynamic graph viewing consider ZGRViewer
|
For dynamic graph viewing consider
|
||||||
http://zvtm.sourceforge.net/zgrviewer.html. If you know of better
|
http://zvtm.sourceforge.net/zgrviewer.html[ZGRViewer]. If you know of
|
||||||
viewers let us know; ZGRViewer isn't great for large graphs.
|
better viewers let us know; ZGRViewer isn't great for large graphs.
|
||||||
|
|
||||||
=== .tree output
|
=== .tree Output
|
||||||
|
|
||||||
Tree files are dumps of the AST Tree and are produced between every major
|
Tree files are dumps of the AST Tree and are produced between every major
|
||||||
algorithmic stage. An example:
|
algorithmic stage. An example:
|
||||||
@@ -898,6 +916,10 @@ what made a <e####> line in the tree dumps):
|
|||||||
|
|
||||||
watch AstNode::s_editCntGbl==####
|
watch AstNode::s_editCntGbl==####
|
||||||
|
|
||||||
|
Then, when the watch fires, to break at every following change to that node:
|
||||||
|
|
||||||
|
watch m_editCount
|
||||||
|
|
||||||
To print a node:
|
To print a node:
|
||||||
|
|
||||||
pn nodep
|
pn nodep
|
||||||
@@ -939,7 +961,7 @@ sections above on debugging.
|
|||||||
|
|
||||||
. Modify the later visitor functions to process the new feature as needed.
|
. Modify the later visitor functions to process the new feature as needed.
|
||||||
|
|
||||||
=== Adding a new pass
|
=== Adding a New Pass
|
||||||
|
|
||||||
For more substantial changes you may need to add a new pass. The simplest
|
For more substantial changes you may need to add a new pass. The simplest
|
||||||
way to do this is to copy the `.cpp` and `.h` files from an existing
|
way to do this is to copy the `.cpp` and `.h` files from an existing
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
build*
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Verilator CMake Example: Small CMakeLists.txt
|
||||||
|
#
|
||||||
|
# This is an example cmake script to build a verilog to systemc project
|
||||||
|
# using cmake and verilator.
|
||||||
|
#
|
||||||
|
# Copyright 2003-2019 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.
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# This example builds the tracing_c example using CMake
|
||||||
|
# To use it, run the following:
|
||||||
|
|
||||||
|
# cd /path/to/verilator/examples/cmake_c
|
||||||
|
# rm -rf build && mkdir build && cd build
|
||||||
|
# cmake ..
|
||||||
|
# cmake --build .
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.8)
|
||||||
|
project(cmake_hello_c)
|
||||||
|
|
||||||
|
find_package(verilator HINTS $ENV{VERILATOR_ROOT} ${VERILATOR_ROOT})
|
||||||
|
if (NOT verilator_FOUND)
|
||||||
|
message(FATAL_ERROR "Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Create a new executable target that will contain all your sources
|
||||||
|
add_executable(example ../make_hello_c/sim_main.cpp)
|
||||||
|
|
||||||
|
# Add the Verilated circuit to the target
|
||||||
|
verilate(example
|
||||||
|
INCLUDE_DIRS "../make_hello_c"
|
||||||
|
SOURCES ../make_hello_c/top.v)
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Verilator CMake example usage
|
||||||
|
#
|
||||||
|
# This file shows usage of the CMake script.
|
||||||
|
# This makefile is here for testing the examples and should
|
||||||
|
# generally not be added to a CMake project.
|
||||||
|
#
|
||||||
|
# Copyright 2003-2019 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.
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Set up variables
|
||||||
|
|
||||||
|
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
|
||||||
|
# package install, and verilator is in your path. Otherwise find the
|
||||||
|
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||||
|
|
||||||
|
ifeq ($(VERILATOR_ROOT),)
|
||||||
|
VERILATOR_COVERAGE = verilator_coverage
|
||||||
|
else
|
||||||
|
export VERILATOR_ROOT
|
||||||
|
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||||
|
endif
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# Check if CMake is installed and of correct version
|
||||||
|
ifeq ($(shell which cmake),)
|
||||||
|
TARGET := nocmake
|
||||||
|
else
|
||||||
|
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
|
||||||
|
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
|
||||||
|
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
|
||||||
|
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
|
||||||
|
ifeq ($(CMAKE_GT_3_8),true)
|
||||||
|
TARGET := run
|
||||||
|
else
|
||||||
|
TARGET := oldcmake
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
default: $(TARGET)
|
||||||
|
|
||||||
|
run:
|
||||||
|
@echo
|
||||||
|
@echo "-- Verilator CMake hello world example"
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- CMake ----------------"
|
||||||
|
mkdir -p build && cd build && cmake ..
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- COMPILE -----------------"
|
||||||
|
cmake --build build
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- RUN ---------------------"
|
||||||
|
build/example
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- DONE --------------------"
|
||||||
|
@echo
|
||||||
|
|
||||||
|
clean mostlyclean distclean maintainer-clean:
|
||||||
|
@rm -rf build logs
|
||||||
|
|
||||||
|
nocmake:
|
||||||
|
@echo
|
||||||
|
@echo "%Skip: CMake has not been found"
|
||||||
|
@echo
|
||||||
|
|
||||||
|
oldcmake:
|
||||||
|
@echo
|
||||||
|
@echo "%Skip: CMake version is too old (need at least 3.8)"
|
||||||
|
@echo
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
build*
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Verilator CMake Example: Small CMakeLists.txt with SystemC
|
||||||
|
#
|
||||||
|
# This is an example cmake script to build a verilog to SystemC project
|
||||||
|
# using CMake and Verilator.
|
||||||
|
#
|
||||||
|
# Copyright 2003-2019 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.
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# This example builds the tracing_sc example using CMake
|
||||||
|
# To use it, run the following:
|
||||||
|
|
||||||
|
# cd /path/to/verilator/examples/cmake_sc
|
||||||
|
# rm -rf build && mkdir build && cd build
|
||||||
|
# cmake ..
|
||||||
|
# cmake --build .
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.8)
|
||||||
|
project(cmake_hello_sc)
|
||||||
|
|
||||||
|
find_package(verilator HINTS $ENV{VERILATOR_ROOT} ${VERILATOR_ROOT})
|
||||||
|
if (NOT verilator_FOUND)
|
||||||
|
message(FATAL_ERROR "Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# SystemC dependencies
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
|
# Find SystemC using SystemC's CMake integration
|
||||||
|
find_package(SystemCLanguage QUIET)
|
||||||
|
|
||||||
|
# Create a new executable target that will contain all your sources
|
||||||
|
add_executable(example ../make_hello_sc/sc_main.cpp)
|
||||||
|
|
||||||
|
# Add the Verilated circuit to the target
|
||||||
|
verilate(example SYSTEMC
|
||||||
|
INCLUDE_DIRS "../make_hello_sc"
|
||||||
|
SOURCES ../make_hello_sc/top.v)
|
||||||
|
|
||||||
|
verilator_link_systemc(example)
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Verilator CMake example usage
|
||||||
|
#
|
||||||
|
# This file shows usage of the CMake script.
|
||||||
|
# This makefile is here for testing the examples and should
|
||||||
|
# generally not be added to a CMake project.
|
||||||
|
#
|
||||||
|
# Copyright 2003-2019 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.
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Set up variables
|
||||||
|
|
||||||
|
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
|
||||||
|
# package install, and verilator is in your path. Otherwise find the
|
||||||
|
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||||
|
|
||||||
|
ifeq ($(VERILATOR_ROOT),)
|
||||||
|
VERILATOR_COVERAGE = verilator_coverage
|
||||||
|
else
|
||||||
|
export VERILATOR_ROOT
|
||||||
|
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||||
|
endif
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# Check if CMake is installed and of correct version
|
||||||
|
ifeq ($(shell which cmake),)
|
||||||
|
TARGET := nocmake
|
||||||
|
else
|
||||||
|
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
|
||||||
|
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
|
||||||
|
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
|
||||||
|
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
|
||||||
|
ifneq ($(CMAKE_GT_3_8),true)
|
||||||
|
TARGET := oldcmake
|
||||||
|
else
|
||||||
|
|
||||||
|
# Test existence of SYSTEMC_INCLUDE and SYSTEMC_LIBDIR environment variabless
|
||||||
|
ifneq (,$(SYSTEMC_INCLUDE))
|
||||||
|
ifneq (,${SYSTEMC_LIBDIR})
|
||||||
|
SYSTEMC_SET := true
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Test existence of SYSTEMC_ROOT environment variable
|
||||||
|
ifneq (SYSTEMC_SET, true)
|
||||||
|
ifneq (,${SYSTEMC_ROOT})
|
||||||
|
SYSTEMC_SET := true
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Test existence of SYSTEMC environment variable
|
||||||
|
ifneq (SYSTEMC_SET, true)
|
||||||
|
ifneq (,${SYSTEMC})
|
||||||
|
SYSTEMC_SET := true
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Test whether SystemC is installed with CMake support
|
||||||
|
# This will print a CMake error about processing arguments that can (currently) be ignored.
|
||||||
|
ifneq (SYSTEMC_SET, true)
|
||||||
|
FINDSC := $(shell mkdir -p build && cd build && cmake --find-package -DNAME=SystemCLanguage -DCMAKE_USE_PTHREADS_INIT=ON -DCOMPILER_ID=GNU -DLANGUAGE=CXX -DMODE=EXIST -DThreads_FOUND=ON)
|
||||||
|
ifneq (,$(findstring SystemCLanguage found,$(FINDSC)))
|
||||||
|
SYSTEMC_SET := true
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SYSTEMC_SET), true)
|
||||||
|
TARGET := run
|
||||||
|
else
|
||||||
|
TARGET := nosc
|
||||||
|
endif
|
||||||
|
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
default: $(TARGET)
|
||||||
|
|
||||||
|
run:
|
||||||
|
@echo
|
||||||
|
@echo "-- Verilator CMake SystemC hello-world simple example"
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- CMake ----------------"
|
||||||
|
mkdir -p build && cd build && cmake ..
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- COMPILE -----------------"
|
||||||
|
cmake --build build
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- RUN ---------------------"
|
||||||
|
@mkdir -p logs
|
||||||
|
build/example
|
||||||
|
|
||||||
|
@echo "-- DONE --------------------"
|
||||||
|
@echo "Note: Once this example is understood, see examples/cmake_tracing_sc."
|
||||||
|
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
|
||||||
|
|
||||||
|
clean mostlyclean distclean maintainer-clean:
|
||||||
|
@rm -rf build logs
|
||||||
|
|
||||||
|
nocmake:
|
||||||
|
@echo
|
||||||
|
@echo "%Skip: CMake has not been found"
|
||||||
|
@echo
|
||||||
|
|
||||||
|
oldcmake:
|
||||||
|
@echo
|
||||||
|
@echo "%Skip: CMake version is too old (need at least 3.8)"
|
||||||
|
@echo
|
||||||
|
|
||||||
|
nosc:
|
||||||
|
@echo
|
||||||
|
@echo "%Skip: CMake could not find SystemC."
|
||||||
|
@echo "% Make sure that either:"
|
||||||
|
@echo "% - The environment variables SYSTEMC_INCLUDE and SYSTEMC_LIBDIR are exported."
|
||||||
|
@echo "% - Or, the environment variable SYSTEMC_ROOT is exported."
|
||||||
|
@echo "% - Or, The environment variable SYSTEMC is exported."
|
||||||
|
@echo "% - Or, if the SystemC installation provides CMake support,"
|
||||||
|
@echo "% that its installation prefix is in CMAKE_PREFIX_PATH."
|
||||||
|
@echo "% Also that the C++ standard of the SystemC library is the same as this example."
|
||||||
|
@echo "% Please see the Verilator documentation's CMake section for more information."
|
||||||
|
@echo
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
build*
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Verilator CMake Example: Small CMakeLists.txt
|
||||||
|
#
|
||||||
|
# This is an example cmake script to build a verilog to systemc project
|
||||||
|
# using cmake and verilator.
|
||||||
|
#
|
||||||
|
# Copyright 2003-2019 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.
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# This example builds the tracing_c example using CMake
|
||||||
|
# To use it, run the following:
|
||||||
|
|
||||||
|
# cd /path/to/verilator/examples/cmake_c
|
||||||
|
# rm -rf build && mkdir build && cd build
|
||||||
|
# cmake ..
|
||||||
|
# cmake --build .
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.8)
|
||||||
|
project(cmake_protect_lib)
|
||||||
|
|
||||||
|
find_package(verilator HINTS $ENV{VERILATOR_ROOT} ${VERILATOR_ROOT})
|
||||||
|
if (NOT verilator_FOUND)
|
||||||
|
message(FATAL_ERROR "Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Create the main executable target
|
||||||
|
add_executable(example ../make_protect_lib/sim_main.cpp)
|
||||||
|
|
||||||
|
# Create a secret library
|
||||||
|
add_library(verilated_secret STATIC) # or SHARED for a shared library
|
||||||
|
target_link_libraries(example PRIVATE verilated_secret)
|
||||||
|
# To create both libraries on CMake >= 3.12 replace the above 2 lines with the following:
|
||||||
|
# add_library(verilated_secret OBJECT)
|
||||||
|
# set_property(TARGET verilated_secret PROPERTY POSITION_INDEPENDENT_CODE 1)
|
||||||
|
# add_library(verilated_secret_static STATIC $<TARGET_OBJECTS:verilated_secret>)
|
||||||
|
# set_target_properties(verilated_secret_static PROPERTIES OUTPUT_NAME verilated_secret)
|
||||||
|
# add_library(verilated_secret_shared SHARED $<TARGET_OBJECTS:verilated_secret>)
|
||||||
|
# set_target_properties(verilated_secret_shared PROPERTIES OUTPUT_NAME verilated_secret)
|
||||||
|
# target_link_libraries(example PRIVATE verilated_secret_static)
|
||||||
|
|
||||||
|
# Setup random seed
|
||||||
|
verilator_generate_key(KEY_INIT)
|
||||||
|
set(PROTECT_KEY ${KEY_INIT} CACHE STRING "Random seed for protection")
|
||||||
|
|
||||||
|
# Add the Verilated modules to the targets
|
||||||
|
verilate(verilated_secret
|
||||||
|
VERILATOR_ARGS --protect-lib verilated_secret
|
||||||
|
--protect-key ${PROTECT_KEY}
|
||||||
|
DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/verilated_secret
|
||||||
|
SOURCES ../make_protect_lib/secret_impl.v)
|
||||||
|
|
||||||
|
# Include location of verilated_secret.sv wrapper
|
||||||
|
verilate(example
|
||||||
|
VERILATOR_ARGS "-I${CMAKE_CURRENT_BINARY_DIR}/verilated_secret"
|
||||||
|
SOURCES ../make_protect_lib/top.v)
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Verilator CMake example usage
|
||||||
|
#
|
||||||
|
# This file shows usage of the CMake script.
|
||||||
|
# This makefile is here for testing the examples and should
|
||||||
|
# generally not be added to a CMake project.
|
||||||
|
#
|
||||||
|
# Copyright 2003-2019 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.
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Set up variables
|
||||||
|
|
||||||
|
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
|
||||||
|
# package install, and verilator is in your path. Otherwise find the
|
||||||
|
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||||
|
|
||||||
|
ifeq ($(VERILATOR_ROOT),)
|
||||||
|
VERILATOR_COVERAGE = verilator_coverage
|
||||||
|
else
|
||||||
|
export VERILATOR_ROOT
|
||||||
|
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||||
|
endif
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# Check if CMake is installed and of correct version
|
||||||
|
ifeq ($(shell which cmake),)
|
||||||
|
TARGET := nocmake
|
||||||
|
else
|
||||||
|
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
|
||||||
|
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
|
||||||
|
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
|
||||||
|
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
|
||||||
|
ifeq ($(CMAKE_GT_3_8),true)
|
||||||
|
TARGET := run
|
||||||
|
else
|
||||||
|
TARGET := oldcmake
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
default: $(TARGET)
|
||||||
|
|
||||||
|
run:
|
||||||
|
@echo
|
||||||
|
@echo "-- Verilator CMake protect_lib example"
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- CMake ----------------"
|
||||||
|
mkdir -p build && cd build && cmake ..
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- COMPILE -----------------"
|
||||||
|
cmake --build build
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- RUN ---------------------"
|
||||||
|
build/example
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- DONE --------------------"
|
||||||
|
@echo
|
||||||
|
|
||||||
|
clean mostlyclean distclean maintainer-clean:
|
||||||
|
@rm -rf build logs
|
||||||
|
|
||||||
|
nocmake:
|
||||||
|
@echo
|
||||||
|
@echo "%Skip: CMake has not been found"
|
||||||
|
@echo
|
||||||
|
|
||||||
|
oldcmake:
|
||||||
|
@echo
|
||||||
|
@echo "%Skip: CMake version is too old (need at least 3.8)"
|
||||||
|
@echo
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
build*
|
||||||
|
logs
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Verilator CMake Example: Small CMakeLists.txt with tracing
|
||||||
|
#
|
||||||
|
# This is an example cmake script to build a verilog to systemc project
|
||||||
|
# using cmake and verilator.
|
||||||
|
#
|
||||||
|
# Copyright 2003-2019 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.
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# This example builds the make_tracing_c example using CMake
|
||||||
|
# To use it, run the following:
|
||||||
|
|
||||||
|
# cd /path/to/verilator/examples/cmake_tracing_c
|
||||||
|
# rm -rf build && mkdir build && cd build
|
||||||
|
# cmake ..
|
||||||
|
# cmake --build .
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.8)
|
||||||
|
project(cmake_tracing_c)
|
||||||
|
|
||||||
|
find_package(verilator HINTS $ENV{VERILATOR_ROOT} ${VERILATOR_ROOT})
|
||||||
|
if (NOT verilator_FOUND)
|
||||||
|
message(FATAL_ERROR "Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Create a new executable target that will contain all your sources
|
||||||
|
add_executable(example ../make_tracing_c/sim_main.cpp)
|
||||||
|
|
||||||
|
# Add the Verilated circuit to the target
|
||||||
|
verilate(example COVERAGE TRACE
|
||||||
|
INCLUDE_DIRS "../make_tracing_c"
|
||||||
|
VERILATOR_ARGS -f ../make_tracing_c/input.vc -O2 -x-assign 0
|
||||||
|
SOURCES ../make_tracing_c/top.v)
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Verilator CMake example usage
|
||||||
|
#
|
||||||
|
# This file shows usage of the CMake script.
|
||||||
|
# This makefile is here for testing the examples and should
|
||||||
|
# generally not be added to a CMake project.
|
||||||
|
#
|
||||||
|
# Copyright 2003-2019 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.
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Set up variables
|
||||||
|
|
||||||
|
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
|
||||||
|
# package install, and verilator is in your path. Otherwise find the
|
||||||
|
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||||
|
|
||||||
|
ifeq ($(VERILATOR_ROOT),)
|
||||||
|
VERILATOR_COVERAGE = verilator_coverage
|
||||||
|
else
|
||||||
|
export VERILATOR_ROOT
|
||||||
|
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||||
|
endif
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# Check if CMake is installed and of correct version
|
||||||
|
ifeq ($(shell which cmake),)
|
||||||
|
TARGET := nocmake
|
||||||
|
else
|
||||||
|
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
|
||||||
|
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
|
||||||
|
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
|
||||||
|
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
|
||||||
|
ifeq ($(CMAKE_GT_3_8),true)
|
||||||
|
TARGET := run
|
||||||
|
else
|
||||||
|
TARGET := oldcmake
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
default: $(TARGET)
|
||||||
|
|
||||||
|
run:
|
||||||
|
@echo
|
||||||
|
@echo "-- Verilator CMake tracing example"
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- CMake ----------------"
|
||||||
|
mkdir -p build && cd build && cmake ..
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- COMPILE -----------------"
|
||||||
|
cmake --build build
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- RUN ---------------------"
|
||||||
|
@mkdir -p logs
|
||||||
|
build/example +trace
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- COVERAGE ----------------"
|
||||||
|
$(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- DONE --------------------"
|
||||||
|
@echo "To see waveforms, open vlt_dump.vcd in a waveform viewer"
|
||||||
|
@echo
|
||||||
|
|
||||||
|
clean mostlyclean distclean maintainer-clean:
|
||||||
|
@rm -rf build logs
|
||||||
|
|
||||||
|
nocmake:
|
||||||
|
@echo
|
||||||
|
@echo "%Skip: CMake has not been found"
|
||||||
|
@echo
|
||||||
|
|
||||||
|
oldcmake:
|
||||||
|
@echo
|
||||||
|
@echo "%Skip: CMake version is too old (need at least 3.8)"
|
||||||
|
@echo
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
*.dmp
|
||||||
|
*.log
|
||||||
|
*.csrc
|
||||||
|
*.vcd
|
||||||
|
obj_*
|
||||||
|
logs
|
||||||
|
build*
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Verilator CMake Example: Small CMakeLists.txt with SystemC tracing
|
||||||
|
#
|
||||||
|
# This is an example cmake script to build a verilog to SystemC project
|
||||||
|
# using CMake and Verilator.
|
||||||
|
#
|
||||||
|
# Copyright 2003-2019 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.
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# This example builds the tracing_sc example using CMake
|
||||||
|
# To use it, run the following:
|
||||||
|
|
||||||
|
# cd /path/to/verilator/examples/cmake_tracing_sc
|
||||||
|
# rm -rf build && mkdir build && cd build
|
||||||
|
# cmake ..
|
||||||
|
# cmake --build .
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.8)
|
||||||
|
project(cmake_tracing_sc_example)
|
||||||
|
|
||||||
|
find_package(verilator HINTS $ENV{VERILATOR_ROOT} ${VERILATOR_ROOT})
|
||||||
|
if (NOT verilator_FOUND)
|
||||||
|
message(FATAL_ERROR "Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# SystemC dependencies
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
|
# Find SystemC using SystemC's CMake integration
|
||||||
|
find_package(SystemCLanguage QUIET)
|
||||||
|
|
||||||
|
# Create a new executable target that will contain all your sources
|
||||||
|
add_executable(example ../make_tracing_sc/sc_main.cpp)
|
||||||
|
|
||||||
|
# Add the Verilated circuit to the target
|
||||||
|
verilate(example SYSTEMC COVERAGE TRACE
|
||||||
|
INCLUDE_DIRS "../make_tracing_sc"
|
||||||
|
VERILATOR_ARGS -f ../make_tracing_sc/input.vc -O2 -x-assign 0
|
||||||
|
SOURCES ../make_tracing_sc/top.v)
|
||||||
|
|
||||||
|
verilator_link_systemc(example)
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Verilator CMake example usage
|
||||||
|
#
|
||||||
|
# This file shows usage of the CMake script.
|
||||||
|
# This makefile is here for testing the examples and should
|
||||||
|
# generally not be added to a CMake project.
|
||||||
|
#
|
||||||
|
# Copyright 2003-2019 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.
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Set up variables
|
||||||
|
|
||||||
|
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
|
||||||
|
# package install, and verilator is in your path. Otherwise find the
|
||||||
|
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||||
|
|
||||||
|
ifeq ($(VERILATOR_ROOT),)
|
||||||
|
VERILATOR_COVERAGE = verilator_coverage
|
||||||
|
else
|
||||||
|
export VERILATOR_ROOT
|
||||||
|
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||||
|
endif
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# Check if CMake is installed and of correct version
|
||||||
|
ifeq ($(shell which cmake),)
|
||||||
|
TARGET := nocmake
|
||||||
|
else
|
||||||
|
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
|
||||||
|
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
|
||||||
|
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
|
||||||
|
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
|
||||||
|
ifneq ($(CMAKE_GT_3_8),true)
|
||||||
|
TARGET := oldcmake
|
||||||
|
else
|
||||||
|
|
||||||
|
# Test existence of SYSTEMC_INCLUDE and SYSTEMC_LIBDIR environment variabless
|
||||||
|
ifneq (,$(SYSTEMC_INCLUDE))
|
||||||
|
ifneq (,${SYSTEMC_LIBDIR})
|
||||||
|
SYSTEMC_SET := true
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Test existence of SYSTEMC_ROOT environment variable
|
||||||
|
ifneq (SYSTEMC_SET, true)
|
||||||
|
ifneq (,${SYSTEMC_ROOT})
|
||||||
|
SYSTEMC_SET := true
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Test existence of SYSTEMC environment variable
|
||||||
|
ifneq (SYSTEMC_SET, true)
|
||||||
|
ifneq (,${SYSTEMC})
|
||||||
|
SYSTEMC_SET := true
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
# Test whether SystemC is installed with CMake support
|
||||||
|
# This will print a CMake error about processing arguments that can (currently) be ignored.
|
||||||
|
ifneq (SYSTEMC_SET, true)
|
||||||
|
FINDSC := $(shell mkdir -p build && cd build && cmake --find-package -DNAME=SystemCLanguage -DCMAKE_USE_PTHREADS_INIT=ON -DCOMPILER_ID=GNU -DLANGUAGE=CXX -DMODE=EXIST -DThreads_FOUND=ON)
|
||||||
|
ifneq (,$(findstring SystemCLanguage found,$(FINDSC)))
|
||||||
|
SYSTEMC_SET := true
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SYSTEMC_SET), true)
|
||||||
|
TARGET := run
|
||||||
|
else
|
||||||
|
TARGET := nosc
|
||||||
|
endif
|
||||||
|
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
default: $(TARGET)
|
||||||
|
|
||||||
|
run:
|
||||||
|
@echo
|
||||||
|
@echo "-- Verilator CMake SystemC tracing example"
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- CMake ----------------"
|
||||||
|
mkdir -p build && cd build && cmake ..
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- COMPILE -----------------"
|
||||||
|
cmake --build build
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- RUN ---------------------"
|
||||||
|
@mkdir -p logs
|
||||||
|
build/example +trace
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- COVERAGE ----------------"
|
||||||
|
$(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- DONE --------------------"
|
||||||
|
@echo "To see waveforms, open vlt_dump.vcd in a waveform viewer"
|
||||||
|
@echo
|
||||||
|
|
||||||
|
clean mostlyclean distclean maintainer-clean:
|
||||||
|
@rm -rf build logs
|
||||||
|
|
||||||
|
nocmake:
|
||||||
|
@echo
|
||||||
|
@echo "%Skip: CMake has not been found"
|
||||||
|
@echo
|
||||||
|
|
||||||
|
oldcmake:
|
||||||
|
@echo
|
||||||
|
@echo "%Skip: CMake version is too old (need at least 3.8)"
|
||||||
|
@echo
|
||||||
|
|
||||||
|
nosc:
|
||||||
|
@echo
|
||||||
|
@echo "%Skip: CMake could not find SystemC."
|
||||||
|
@echo "% Make sure that either:"
|
||||||
|
@echo "% - The environment variables SYSTEMC_INCLUDE and SYSTEMC_LIBDIR are exported."
|
||||||
|
@echo "% - Or, the environment variable SYSTEMC_ROOT is exported."
|
||||||
|
@echo "% - Or, The environment variable SYSTEMC is exported."
|
||||||
|
@echo "% - Or, if the SystemC installation provides CMake support,"
|
||||||
|
@echo "% that its installation prefix is in CMAKE_PREFIX_PATH."
|
||||||
|
@echo "% Also that the C++ standard of the SystemC library is the same as this example."
|
||||||
|
@echo "% Please see the Verilator documentation's CMake section for more information."
|
||||||
|
@echo
|
||||||
@@ -21,7 +21,7 @@ endif
|
|||||||
|
|
||||||
# This is intended to be a minimal example. Before copying this to start a
|
# This is intended to be a minimal example. Before copying this to start a
|
||||||
# real project, it is better to start with a more complete example,
|
# real project, it is better to start with a more complete example,
|
||||||
# e.g. examples/tracing_c.
|
# e.g. examples/make_tracing_c.
|
||||||
|
|
||||||
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
|
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
|
||||||
# package install, and verilator is in your path. Otherwise find the
|
# package install, and verilator is in your path. Otherwise find the
|
||||||
@@ -42,7 +42,7 @@ default:
|
|||||||
@echo "-- RUN ---------------------"
|
@echo "-- RUN ---------------------"
|
||||||
obj_dir/Vtop
|
obj_dir/Vtop
|
||||||
@echo "-- DONE --------------------"
|
@echo "-- DONE --------------------"
|
||||||
@echo "Note: Once this example is understood, see examples/tracing_c."
|
@echo "Note: Once this example is understood, see examples/make_tracing_c."
|
||||||
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
|
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
@@ -21,7 +21,7 @@ endif
|
|||||||
|
|
||||||
# This is intended to be a minimal example. Before copying this to start a
|
# This is intended to be a minimal example. Before copying this to start a
|
||||||
# real project, it is better to start with a more complete example,
|
# real project, it is better to start with a more complete example,
|
||||||
# e.g. examples/tracing_sc.
|
# e.g. examples/make_tracing_sc.
|
||||||
|
|
||||||
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
|
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
|
||||||
# package install, and verilator is in your path. Otherwise find the
|
# package install, and verilator is in your path. Otherwise find the
|
||||||
@@ -51,7 +51,7 @@ run:
|
|||||||
@echo "-- RUN ---------------------"
|
@echo "-- RUN ---------------------"
|
||||||
obj_dir/Vtop
|
obj_dir/Vtop
|
||||||
@echo "-- DONE --------------------"
|
@echo "-- DONE --------------------"
|
||||||
@echo "Note: Once this example is understood, see examples/tracing_sc."
|
@echo "Note: Once this example is understood, see examples/make_tracing_sc."
|
||||||
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
|
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
obj_*
|
||||||
|
logs
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Verilator Example: --protect-lib Makefile
|
||||||
|
#
|
||||||
|
# This calls the object directory makefiles. That allows the objects to
|
||||||
|
# be placed in the "current directory" which simplifies the Makefile.
|
||||||
|
#
|
||||||
|
# Copyright 2019 by Todd Strader. 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.
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
# Check for sanity to avoid later confusion
|
||||||
|
|
||||||
|
ifneq ($(words $(CURDIR)),1)
|
||||||
|
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
|
||||||
|
endif
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Set up variables
|
||||||
|
|
||||||
|
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
|
||||||
|
# package install, and verilator is in your path. Otherwise find the
|
||||||
|
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||||
|
ifeq ($(VERILATOR_ROOT),)
|
||||||
|
VERILATOR = verilator
|
||||||
|
else
|
||||||
|
export VERILATOR_ROOT
|
||||||
|
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
|
||||||
|
endif
|
||||||
|
|
||||||
|
VERILATOR_FLAGS =
|
||||||
|
# Generate C++
|
||||||
|
VERILATOR_FLAGS += -cc
|
||||||
|
# Optimize
|
||||||
|
VERILATOR_FLAGS += -O2 -x-assign 0
|
||||||
|
# Warn abount lint issues; may not want this on less solid designs
|
||||||
|
VERILATOR_FLAGS += -Wall
|
||||||
|
# Make waveforms
|
||||||
|
TOP_VERILATOR_FLAGS = $(VERILATOR_FLAGS) --trace
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
default: run
|
||||||
|
|
||||||
|
run:
|
||||||
|
@echo
|
||||||
|
@echo "-- Verilator --protect-lib example -_--------------------------"
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- VERILATE secret module -------------------------------------"
|
||||||
|
@echo " --protect-lib will produce both a static and shared library"
|
||||||
|
@echo " In this example the static library is used, but some"
|
||||||
|
@echo " simulators may require the shared library."
|
||||||
|
@echo "---------------------------------------------------------------"
|
||||||
|
$(VERILATOR) $(VERILATOR_FLAGS) --protect-lib verilated_secret -Mdir obj_dir_secret/ secret_impl.v
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- COMPILE protected library ----------------------------------"
|
||||||
|
@echo " This builds verilated_secret.sv, libverilated_secret.a and"
|
||||||
|
@echo " libverilated_secret.so which can be distributed apart from"
|
||||||
|
@echo " the source"
|
||||||
|
@echo "---------------------------------------------------------------"
|
||||||
|
$(MAKE) -j 4 -C obj_dir_secret -f Vsecret_impl.mk
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- VERILATE top module ----------------------------------------"
|
||||||
|
@echo " Use the SystemVerilog wrapper (verilated_secret.sv) and the"
|
||||||
|
@echo " library (libverilated_secret.a) generated from the previous"
|
||||||
|
@echo " step"
|
||||||
|
@echo "---------------------------------------------------------------"
|
||||||
|
$(VERILATOR) $(TOP_VERILATOR_FLAGS) --exe -LDFLAGS '-L../obj_dir_secret -lverilated_secret -static' top.v obj_dir_secret/verilated_secret.sv sim_main.cpp
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- COMPILE entire design --------------------------------------"
|
||||||
|
$(MAKE) -j 4 -C obj_dir -f Vtop.mk
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- RUN --------------------------------------------------------"
|
||||||
|
@mkdir -p logs
|
||||||
|
obj_dir/Vtop +trace
|
||||||
|
|
||||||
|
@echo
|
||||||
|
@echo "-- DONE -------------------------------------------------------"
|
||||||
|
@echo "To see waveforms, open logs/vlt_dump.vcd in a waveform viewer"
|
||||||
|
@echo
|
||||||
|
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
# Other targets
|
||||||
|
|
||||||
|
show-config:
|
||||||
|
$(VERILATOR) -V
|
||||||
|
|
||||||
|
maintainer-copy::
|
||||||
|
clean mostlyclean distclean maintainer-clean::
|
||||||
|
-rm -rf obj_dir* logs *.log core
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
// DESCRIPTION: Verilator: --protect-lib example secret module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2019 by Todd Strader.
|
||||||
|
|
||||||
|
// This module will be used as libsecret.a or libsecret.so without
|
||||||
|
// exposing the source.
|
||||||
|
module secret_impl(
|
||||||
|
input [31:0] a,
|
||||||
|
input [31:0] b,
|
||||||
|
output logic [31:0] x,
|
||||||
|
input clk);
|
||||||
|
|
||||||
|
logic [31:0] accum_q = 0;
|
||||||
|
logic [31:0] secret_value = 9;
|
||||||
|
|
||||||
|
initial $display("%m: initialized");
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
accum_q <= accum_q + a;
|
||||||
|
if (accum_q > 10)
|
||||||
|
x <= b;
|
||||||
|
else
|
||||||
|
x <= a + b + secret_value;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
// DESCRIPTION: Verilator: --protect-lib example module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2019 by Todd Strader.
|
||||||
|
//======================================================================
|
||||||
|
|
||||||
|
// See examples/tracing_c for notes on tracing
|
||||||
|
|
||||||
|
// Include common routines
|
||||||
|
#include <verilated.h>
|
||||||
|
|
||||||
|
#include "Vtop.h"
|
||||||
|
|
||||||
|
#if VM_TRACE
|
||||||
|
# include <verilated_vcd_c.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vluint64_t main_time = 0;
|
||||||
|
double sc_time_stamp() {
|
||||||
|
return main_time;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv, char** env) {
|
||||||
|
if (0 && argc && argv && env) {}
|
||||||
|
|
||||||
|
Verilated::debug(0);
|
||||||
|
Verilated::randReset(2);
|
||||||
|
Verilated::commandArgs(argc, argv);
|
||||||
|
|
||||||
|
// Construct the Verilated model, including the secret module
|
||||||
|
Vtop* top = new Vtop;
|
||||||
|
|
||||||
|
#if VM_TRACE
|
||||||
|
// When tracing, the contents of the secret module will not be seen
|
||||||
|
VerilatedVcdC* tfp = NULL;
|
||||||
|
const char* flag = Verilated::commandArgsPlusMatch("trace");
|
||||||
|
if (flag && 0==strcmp(flag, "+trace")) {
|
||||||
|
Verilated::traceEverOn(true);
|
||||||
|
VL_PRINTF("Enabling waves into logs/vlt_dump.vcd...\n");
|
||||||
|
tfp = new VerilatedVcdC;
|
||||||
|
top->trace(tfp, 99);
|
||||||
|
Verilated::mkdir("logs");
|
||||||
|
tfp->open("logs/vlt_dump.vcd");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
top->clk = 0;
|
||||||
|
|
||||||
|
// Simulate until $finish
|
||||||
|
while (!Verilated::gotFinish()) {
|
||||||
|
main_time++;
|
||||||
|
top->clk = ~top->clk & 0x1;
|
||||||
|
top->eval();
|
||||||
|
#if VM_TRACE
|
||||||
|
if (tfp) tfp->dump(main_time);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final model cleanup
|
||||||
|
top->final();
|
||||||
|
|
||||||
|
// Close trace if opened
|
||||||
|
#if VM_TRACE
|
||||||
|
if (tfp) { tfp->close(); tfp = NULL; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Destroy model
|
||||||
|
delete top; top = NULL;
|
||||||
|
|
||||||
|
// Fin
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
// DESCRIPTION: Verilator: --protect-lib example module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2019 by Todd Strader.
|
||||||
|
|
||||||
|
// See also the EXAMPLE section in the verilator manpage/document.
|
||||||
|
module top (input clk);
|
||||||
|
|
||||||
|
integer cyc = 0;
|
||||||
|
logic [31:0] a = 0;
|
||||||
|
logic [31:0] b = 0;
|
||||||
|
logic [31:0] x;
|
||||||
|
|
||||||
|
verilated_secret secret (.a, .b, .x, .clk);
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
$display("[%0t] cyc=%0d a=%0d b=%0d x=%0d", $time, cyc, a, b, x);
|
||||||
|
cyc <= cyc + 1;
|
||||||
|
if (cyc == 0) begin
|
||||||
|
a <= 5;
|
||||||
|
b <= 7;
|
||||||
|
end else if (cyc == 1) begin
|
||||||
|
a <= 6;
|
||||||
|
b <= 2;
|
||||||
|
end else if (cyc == 2) begin
|
||||||
|
a <= 1;
|
||||||
|
b <= 9;
|
||||||
|
end else if (cyc > 3) begin
|
||||||
|
$display("Done");
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
@@ -23,7 +23,7 @@ double sc_time_stamp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv, char** env) {
|
int main(int argc, char** argv, char** env) {
|
||||||
// This is a more complicated example, please also see the simpler examples/hello_world_c.
|
// This is a more complicated example, please also see the simpler examples/make_hello_c.
|
||||||
|
|
||||||
// Prevent unused variable warnings
|
// Prevent unused variable warnings
|
||||||
if (0 && argc && argv && env) {}
|
if (0 && argc && argv && env) {}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
// This is intended to be a complex example of several features, please also
|
// This is intended to be a complex example of several features, please also
|
||||||
// see the simpler examples/hello_world_c.
|
// see the simpler examples/make_hello_c.
|
||||||
|
|
||||||
module top
|
module top
|
||||||
(
|
(
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
#include "Vtop.h"
|
#include "Vtop.h"
|
||||||
|
|
||||||
int sc_main(int argc, char* argv[]) {
|
int sc_main(int argc, char* argv[]) {
|
||||||
// This is a more complicated example, please also see the simpler examples/hello_world_c.
|
// This is a more complicated example, please also see the simpler examples/make_hello_c.
|
||||||
|
|
||||||
// Prevent unused variable warnings
|
// Prevent unused variable warnings
|
||||||
if (0 && argc && argv) {}
|
if (0 && argc && argv) {}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
// ======================================================================
|
// ======================================================================
|
||||||
|
|
||||||
// This is intended to be a complex example of several features, please also
|
// This is intended to be a complex example of several features, please also
|
||||||
// see the simpler examples/hello_world_c.
|
// see the simpler examples/make_hello_c.
|
||||||
|
|
||||||
module top
|
module top
|
||||||
(
|
(
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
obj_*
|
||||||
|
copied
|
||||||
|
*.csv
|
||||||
|
*.dot
|
||||||
|
*.dmp
|
||||||
|
*.pdf
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
######################################################################
|
||||||
|
#
|
||||||
|
# DESCRIPTION: Verilator Example: XML tests
|
||||||
|
#
|
||||||
|
# Copyright 2003-2019 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.
|
||||||
|
#
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# This makefile is not intended to be useful as an example itself,
|
||||||
|
# it is just to run the small example scripts in this directory.
|
||||||
|
|
||||||
|
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
|
||||||
|
# package install, and verilator is in your path. Otherwise find the
|
||||||
|
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||||
|
ifeq ($(VERILATOR_ROOT),)
|
||||||
|
VERILATOR = verilator
|
||||||
|
else
|
||||||
|
export VERILATOR_ROOT
|
||||||
|
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
|
||||||
|
endif
|
||||||
|
|
||||||
|
DOT = dot
|
||||||
|
PYTHON = python3
|
||||||
|
|
||||||
|
PYTHON_VERSION := $(shell ${PYTHON} --version 2>&1)
|
||||||
|
PYTHON_VERSION_FULL := $(wordlist 2,4,$(subst ., ,${PYTHON_VERSION}))
|
||||||
|
PYTHON_VERSION_MAJOR := $(word 1,${PYTHON_VERSION_FULL})
|
||||||
|
PYTHON_VERSION_MINOR := $(word 2,${PYTHON_VERSION_FULL})
|
||||||
|
PYTHON_GE_3_5 := $(shell [ ${PYTHON_VERSION_MAJOR} -eq 3 -a ${PYTHON_VERSION_MINOR} -ge 5 ] && echo true)
|
||||||
|
|
||||||
|
ifeq (${PYTHON_GE_3_5},true)
|
||||||
|
default: test
|
||||||
|
else
|
||||||
|
default: python_message
|
||||||
|
endif
|
||||||
|
|
||||||
|
python_message:
|
||||||
|
@echo "Found Python version ${PYTHON_VERSION}, but require >= 3.5"
|
||||||
|
|
||||||
|
test: \
|
||||||
|
test-vl_file_copy \
|
||||||
|
test-vl_hier_graph \
|
||||||
|
|
||||||
|
test-vl_file_copy:
|
||||||
|
@echo "-- vl_file_copy example"
|
||||||
|
$(PYTHON) vl_file_copy -odir copied top.v
|
||||||
|
@cmp copied/top.v top.v
|
||||||
|
@cmp copied/sub.v sub.v
|
||||||
|
|
||||||
|
test-vl_hier_graph:
|
||||||
|
@echo "-- vl_hier_graph example"
|
||||||
|
$(PYTHON) vl_hier_graph -o graph.dot top.v
|
||||||
|
@echo "Manually run: " $(DOT) -Tpdf -o graph.pdf graph.dot
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
maintainer-copy::
|
||||||
|
clean mostlyclean distclean maintainer-clean::
|
||||||
|
-rm -rf obj_dir *.log *.csv *.dmp *.dot *.vpd *.pdf core copied
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// DESCRIPTION: Verilator: Verilog Test module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2019 by Wilson Snyder.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
module sub
|
||||||
|
#(parameter type TYPE_t = logic)
|
||||||
|
(
|
||||||
|
input TYPE_t in,
|
||||||
|
output TYPE_t out
|
||||||
|
);
|
||||||
|
|
||||||
|
// Some simple logic
|
||||||
|
always_comb out = ~ in;
|
||||||
|
|
||||||
|
endmodule
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
// DESCRIPTION: Verilator: Verilog example module
|
||||||
|
//
|
||||||
|
// This file ONLY is placed into the Public Domain, for any use,
|
||||||
|
// without warranty, 2019 by Wilson Snyder.
|
||||||
|
// ======================================================================
|
||||||
|
|
||||||
|
module top
|
||||||
|
(
|
||||||
|
input clk,
|
||||||
|
input fastclk,
|
||||||
|
input reset_l,
|
||||||
|
|
||||||
|
output wire [1:0] out_small,
|
||||||
|
output wire [39:0] out_quad,
|
||||||
|
output wire [69:0] out_wide,
|
||||||
|
input [1:0] in_small,
|
||||||
|
input [39:0] in_quad,
|
||||||
|
input [69:0] in_wide
|
||||||
|
);
|
||||||
|
|
||||||
|
sub #(.TYPE_t(logic [1:0])) sub_small
|
||||||
|
(.in(in_small),
|
||||||
|
.out(out_small));
|
||||||
|
|
||||||
|
sub #(.TYPE_t(logic [39:0])) sub_quad
|
||||||
|
(.in(in_quad),
|
||||||
|
.out(out_quad));
|
||||||
|
|
||||||
|
sub #(.TYPE_t(logic [69:0])) sub_wide
|
||||||
|
(.in(in_wide),
|
||||||
|
.out(out_wide));
|
||||||
|
endmodule
|
||||||
Executable
+112
@@ -0,0 +1,112 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- Python -*- See copyright, etc below
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
from shutil import copy2
|
||||||
|
from pprint import pprint,pformat
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
class VlFileCopy:
|
||||||
|
def __init__(self,
|
||||||
|
verilator_args, # presently all verilator options are passed-thru
|
||||||
|
# ideally this script would check against options mentioned in help
|
||||||
|
debug=0,
|
||||||
|
output_dir='copied'): # directory name we output file uses
|
||||||
|
self.debug = debug
|
||||||
|
|
||||||
|
xml_temp = tempfile.NamedTemporaryFile()
|
||||||
|
|
||||||
|
args = ['--xml-output', xml_temp.name,
|
||||||
|
'--bbox-sys', # Parse some stuff can't translate
|
||||||
|
'--bbox-unsup',
|
||||||
|
'--prefix vlxml'] # So we know name of .xml output
|
||||||
|
args += verilator_args
|
||||||
|
self.run_verilator(args)
|
||||||
|
self.tree = ET.parse(xml_temp.name)
|
||||||
|
|
||||||
|
os.makedirs(output_dir, 0o777, True)
|
||||||
|
|
||||||
|
# Find and copy the files
|
||||||
|
root = self.tree.getroot()
|
||||||
|
xfiles = root.find('files')
|
||||||
|
for xfile in xfiles.findall('file'):
|
||||||
|
filename = xfile.get('filename')
|
||||||
|
if not re.match('^<', filename): # e.g. <built-in>
|
||||||
|
if self.debug:
|
||||||
|
print("\tcp %s %s" % (filename, output_dir))
|
||||||
|
copy2(filename, output_dir)
|
||||||
|
|
||||||
|
def run_verilator(self, args):
|
||||||
|
"""Run Verilator command, check errors"""
|
||||||
|
if os.getenv("VERILATOR_ROOT"):
|
||||||
|
command = os.getenv("VERILATOR_ROOT") + "/bin/verilator"
|
||||||
|
else:
|
||||||
|
command = "verilator"
|
||||||
|
command += ' ' + ' '.join(args)
|
||||||
|
if self.debug:
|
||||||
|
print("\t%s " % command)
|
||||||
|
status = subprocess.call(command, shell=True)
|
||||||
|
if status != 0:
|
||||||
|
raise Exception("Command failed running Verilator with '"+command+"', stopped")
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
if __name__=='__main__':
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
allow_abbrev=False,
|
||||||
|
formatter_class=argparse.RawTextHelpFormatter,
|
||||||
|
description=
|
||||||
|
"""Example of using Verilator XML output to copy a list of files to an
|
||||||
|
output directory (-odir, defaults to 'copied'), e.g. to easily create a
|
||||||
|
tarball of the design to pass to others.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
vl_file_copy -f input.vc top.v -odir mycopy
|
||||||
|
# This will make at least mycopy/top.v
|
||||||
|
""",
|
||||||
|
epilog=
|
||||||
|
"""All other arguments are pass-thru to Verilator: e.g.:
|
||||||
|
|
||||||
|
+define+<var>=<value> Set preprocessor define
|
||||||
|
-F <file> Parse options from a file, relatively
|
||||||
|
-f <file> Parse options from a file
|
||||||
|
-G<name>=<value> Overwrite toplevel parameter
|
||||||
|
+incdir+<dir> Directory to search for includes
|
||||||
|
+libext+<ext>+[ext]... Extensions for finding modules
|
||||||
|
-v <filename> Verilog library
|
||||||
|
-y <dir> Directory to search for modules
|
||||||
|
|
||||||
|
This file ONLY is placed into the Public Domain, for any use, without
|
||||||
|
warranty, 2019 by Wilson Snyder."""
|
||||||
|
)
|
||||||
|
parser.add_argument('-debug', '--debug',
|
||||||
|
action='store_const', const=9,
|
||||||
|
help='enable debug')
|
||||||
|
parser.add_argument('-odir', '--odir',
|
||||||
|
action='store', metavar='directory', required=True,
|
||||||
|
help='target output directory')
|
||||||
|
(args, rem) = parser.parse_known_args()
|
||||||
|
|
||||||
|
print("NOTE: vl_file_copy is only an example starting point for writing your own tool.")
|
||||||
|
# That is:
|
||||||
|
# 1. We will accept basic patches
|
||||||
|
# 2. We are not expecting to make this globally useful. (e.g. we don't cleanup obj_dir)
|
||||||
|
# 3. "make install" will not install this.
|
||||||
|
# 4. This has not had production-worthy validation.
|
||||||
|
|
||||||
|
fc = VlFileCopy(output_dir = args.odir,
|
||||||
|
debug = args.debug,
|
||||||
|
verilator_args = rem)
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
### Local Variables:
|
||||||
|
### compile-command: "./vl_file_copy -h ; VERILATOR_ROOT=$V4 ./vl_file_copy +define+thru top.v"
|
||||||
|
### End:
|
||||||
Executable
+136
@@ -0,0 +1,136 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# -*- Python -*- See copyright, etc below
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import xml.etree.ElementTree as ET
|
||||||
|
from shutil import copy2
|
||||||
|
from pprint import pprint,pformat
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
class VlHierGraph:
|
||||||
|
def __init__(self,
|
||||||
|
verilator_args, # presently all verilator options are passed-thru
|
||||||
|
# ideally this script would check against options mentioned in help
|
||||||
|
debug=0,
|
||||||
|
output_filename='graph.dot'): # output filename
|
||||||
|
self.debug = debug
|
||||||
|
self.next_vertex_number = 0
|
||||||
|
self.name_to_number = {}
|
||||||
|
|
||||||
|
xml_temp = tempfile.NamedTemporaryFile()
|
||||||
|
|
||||||
|
args = ['--xml-output', xml_temp.name,
|
||||||
|
'--bbox-sys', # Parse some stuff can't translate
|
||||||
|
'--bbox-unsup',
|
||||||
|
'--prefix vlxml'] # So we know name of .xml output
|
||||||
|
args += verilator_args
|
||||||
|
self.run_verilator(args)
|
||||||
|
self.tree = ET.parse(xml_temp.name)
|
||||||
|
|
||||||
|
with open(output_filename, "w") as fh:
|
||||||
|
# For more serious purposes, use the python graphviz package instead
|
||||||
|
fh.write("digraph {\n")
|
||||||
|
fh.write(" dpi=300;\n")
|
||||||
|
fh.write(" order=LR;\n")
|
||||||
|
fh.write(" node [fontsize=8 shape=\"box\" margin=0.01 width=0 height=0]")
|
||||||
|
fh.write(" edge [fontsize=6]")
|
||||||
|
# Find cells
|
||||||
|
root = self.tree.getroot()
|
||||||
|
netlist = root.find('netlist')
|
||||||
|
for module in netlist.findall('module'):
|
||||||
|
# origNames are before parameterization, name if after
|
||||||
|
mod_name = module.get('name')
|
||||||
|
mod_number = self.name_to_vertex_number(mod_name)
|
||||||
|
fh.write(" n%d [label=\"%s\""
|
||||||
|
% (mod_number, mod_name))
|
||||||
|
if module.get('topModule'):
|
||||||
|
fh.write(" color=\"red\" rank=1")
|
||||||
|
fh.write("];\n")
|
||||||
|
|
||||||
|
for instance in module.findall('instance'):
|
||||||
|
inst_name = instance.get('name')
|
||||||
|
def_name = instance.get('defName')
|
||||||
|
def_number = self.name_to_vertex_number(def_name)
|
||||||
|
fh.write(" n%d->n%d [label=\"%s\"];\n"
|
||||||
|
% (mod_number, def_number, inst_name));
|
||||||
|
|
||||||
|
fh.write("}\n")
|
||||||
|
|
||||||
|
def name_to_vertex_number(self, name):
|
||||||
|
if not name in self.name_to_number:
|
||||||
|
self.next_vertex_number += 1
|
||||||
|
self.name_to_number[name] = self.next_vertex_number
|
||||||
|
return self.name_to_number[name]
|
||||||
|
|
||||||
|
def run_verilator(self, args):
|
||||||
|
"""Run Verilator command, check errors"""
|
||||||
|
if os.getenv("VERILATOR_ROOT"):
|
||||||
|
command = os.getenv("VERILATOR_ROOT") + "/bin/verilator"
|
||||||
|
else:
|
||||||
|
command = "verilator"
|
||||||
|
command += ' ' + ' '.join(args)
|
||||||
|
if self.debug:
|
||||||
|
print("\t%s " % command)
|
||||||
|
status = subprocess.call(command, shell=True)
|
||||||
|
if status != 0:
|
||||||
|
raise Exception("Command failed running Verilator with '"+command+"', stopped")
|
||||||
|
|
||||||
|
#######################################################################
|
||||||
|
|
||||||
|
if __name__=='__main__':
|
||||||
|
parser = argparse.ArgumentParser(
|
||||||
|
allow_abbrev=False,
|
||||||
|
formatter_class=argparse.RawTextHelpFormatter,
|
||||||
|
description=
|
||||||
|
"""Example of using Verilator XML output to create a .dot file showing the
|
||||||
|
design module hierarchy.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
vl_hier_graph -f input.vc top.v -o graph.dot
|
||||||
|
dot -Tpdf -o graph.pdf graph.dot
|
||||||
|
""",
|
||||||
|
epilog=
|
||||||
|
"""All other arguments are pass-thru to Verilator: e.g.:
|
||||||
|
|
||||||
|
+define+<var>=<value> Set preprocessor define
|
||||||
|
-F <file> Parse options from a file, relatively
|
||||||
|
-f <file> Parse options from a file
|
||||||
|
-G<name>=<value> Overwrite toplevel parameter
|
||||||
|
+incdir+<dir> Directory to search for includes
|
||||||
|
+libext+<ext>+[ext]... Extensions for finding modules
|
||||||
|
-v <filename> Verilog library
|
||||||
|
-y <dir> Directory to search for modules
|
||||||
|
|
||||||
|
This file ONLY is placed into the Public Domain, for any use, without
|
||||||
|
warranty, 2019 by Wilson Snyder."""
|
||||||
|
)
|
||||||
|
parser.add_argument('-debug', '--debug',
|
||||||
|
action='store_const', const=9,
|
||||||
|
help='enable debug')
|
||||||
|
parser.add_argument('-o', '--o',
|
||||||
|
action='store', metavar='filename', required=True,
|
||||||
|
help='output filename')
|
||||||
|
(args, rem) = parser.parse_known_args()
|
||||||
|
|
||||||
|
print("NOTE: vl_hier_graph is only an example starting point for writing your own tool.")
|
||||||
|
# That is:
|
||||||
|
# 1. We will accept basic patches
|
||||||
|
# 2. We are not expecting to make this globally useful. (e.g. we don't cleanup obj_dir)
|
||||||
|
# 3. "make install" will not install this.
|
||||||
|
# 4. This has not had production-worthy validation.
|
||||||
|
|
||||||
|
fc = VlHierGraph(output_filename = args.o,
|
||||||
|
debug = args.debug,
|
||||||
|
verilator_args = rem)
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
### Local Variables:
|
||||||
|
### compile-command: "./vl_hier_graph -h ; VERILATOR_ROOT=$V4 ./vl_hier_graph +define+thru top.v"
|
||||||
|
### End:
|
||||||
@@ -418,7 +418,9 @@ static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void
|
|||||||
const flzuint8* ip = (const flzuint8*) input;
|
const flzuint8* ip = (const flzuint8*) input;
|
||||||
const flzuint8* ip_limit = ip + length;
|
const flzuint8* ip_limit = ip + length;
|
||||||
flzuint8* op = (flzuint8*) output;
|
flzuint8* op = (flzuint8*) output;
|
||||||
|
#ifdef FASTLZ_SAFE
|
||||||
flzuint8* op_limit = op + maxout;
|
flzuint8* op_limit = op + maxout;
|
||||||
|
#endif
|
||||||
flzuint32 ctrl = (*ip++) & 31;
|
flzuint32 ctrl = (*ip++) & 31;
|
||||||
int loop = 1;
|
int loop = 1;
|
||||||
|
|
||||||
|
|||||||
+66
-23
@@ -37,13 +37,15 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Verilator: use hardcoded config file
|
#ifndef FST_CONFIG_INCLUDE
|
||||||
//#include <config.h>
|
# define FST_CONFIG_INCLUDE <config.h>
|
||||||
#include "fst_config.h"
|
#endif
|
||||||
|
#include FST_CONFIG_INCLUDE
|
||||||
|
|
||||||
#include "fstapi.h"
|
#include "fstapi.h"
|
||||||
#include "fastlz.h"
|
#include "fastlz.h"
|
||||||
#include "lz4.h"
|
#include "lz4.h"
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#ifndef HAVE_LIBPTHREAD
|
#ifndef HAVE_LIBPTHREAD
|
||||||
#undef FST_WRITER_PARALLEL
|
#undef FST_WRITER_PARALLEL
|
||||||
@@ -130,6 +132,16 @@ void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint3
|
|||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
// Boolean expression more often true than false
|
||||||
|
#define FST_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||||
|
// Boolean expression more often false than true
|
||||||
|
#define FST_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||||
|
#else
|
||||||
|
#define FST_LIKELY(x) (!!(x))
|
||||||
|
#define FST_UNLIKELY(x) (!!(x))
|
||||||
|
#endif
|
||||||
|
|
||||||
#define FST_APIMESS "FSTAPI | "
|
#define FST_APIMESS "FSTAPI | "
|
||||||
|
|
||||||
/***********************/
|
/***********************/
|
||||||
@@ -954,6 +966,19 @@ fflush(xc->handle);
|
|||||||
/*
|
/*
|
||||||
* mmap functions
|
* mmap functions
|
||||||
*/
|
*/
|
||||||
|
static void fstWriterMmapSanity(void *pnt, const char *file, int line, const char *usage)
|
||||||
|
{
|
||||||
|
#if !defined(__CYGWIN__) && !defined(__MINGW32__)
|
||||||
|
if(pnt == MAP_FAILED)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "fstMmap() assigned to %s failed: errno: %d, file %s, line %d.\n", usage, errno, file, line);
|
||||||
|
perror("Why");
|
||||||
|
pnt = NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void fstWriterCreateMmaps(struct fstWriterContext *xc)
|
static void fstWriterCreateMmaps(struct fstWriterContext *xc)
|
||||||
{
|
{
|
||||||
off_t curpos = ftello(xc->handle);
|
off_t curpos = ftello(xc->handle);
|
||||||
@@ -976,12 +1001,20 @@ fflush(xc->handle);
|
|||||||
if(!xc->valpos_mem)
|
if(!xc->valpos_mem)
|
||||||
{
|
{
|
||||||
fflush(xc->valpos_handle);
|
fflush(xc->valpos_handle);
|
||||||
xc->valpos_mem = (uint32_t *)fstMmap(NULL, xc->maxhandle * 4 * sizeof(uint32_t), PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->valpos_handle), 0);
|
errno = 0;
|
||||||
|
if(xc->maxhandle)
|
||||||
|
{
|
||||||
|
fstWriterMmapSanity(xc->valpos_mem = (uint32_t *)fstMmap(NULL, xc->maxhandle * 4 * sizeof(uint32_t), PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->valpos_handle), 0), __FILE__, __LINE__, "xc->valpos_mem");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(!xc->curval_mem)
|
if(!xc->curval_mem)
|
||||||
{
|
{
|
||||||
fflush(xc->curval_handle);
|
fflush(xc->curval_handle);
|
||||||
xc->curval_mem = (unsigned char *)fstMmap(NULL, xc->maxvalpos, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->curval_handle), 0);
|
errno = 0;
|
||||||
|
if(xc->maxvalpos)
|
||||||
|
{
|
||||||
|
fstWriterMmapSanity(xc->curval_mem = (unsigned char *)fstMmap(NULL, xc->maxvalpos, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->curval_handle), 0), __FILE__, __LINE__, "xc->curval_handle");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1684,7 +1717,8 @@ fflush(xc->tchn_handle);
|
|||||||
tlen = ftello(xc->tchn_handle);
|
tlen = ftello(xc->tchn_handle);
|
||||||
fstWriterFseeko(xc, xc->tchn_handle, 0, SEEK_SET);
|
fstWriterFseeko(xc, xc->tchn_handle, 0, SEEK_SET);
|
||||||
|
|
||||||
tmem = (unsigned char *)fstMmap(NULL, tlen, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->tchn_handle), 0);
|
errno = 0;
|
||||||
|
fstWriterMmapSanity(tmem = (unsigned char *)fstMmap(NULL, tlen, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->tchn_handle), 0), __FILE__, __LINE__, "tmem");
|
||||||
if(tmem)
|
if(tmem)
|
||||||
{
|
{
|
||||||
unsigned long destlen = tlen;
|
unsigned long destlen = tlen;
|
||||||
@@ -1876,7 +1910,7 @@ if(xc)
|
|||||||
|
|
||||||
if(xc && !xc->already_in_close && !xc->already_in_flush)
|
if(xc && !xc->already_in_close && !xc->already_in_flush)
|
||||||
{
|
{
|
||||||
unsigned char *tmem;
|
unsigned char *tmem = NULL;
|
||||||
off_t fixup_offs, tlen, hlen;
|
off_t fixup_offs, tlen, hlen;
|
||||||
|
|
||||||
xc->already_in_close = 1; /* never need to zero this out as it is freed at bottom */
|
xc->already_in_close = 1; /* never need to zero this out as it is freed at bottom */
|
||||||
@@ -1892,7 +1926,7 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
|
|||||||
xc->skip_writing_section_hdr = 1;
|
xc->skip_writing_section_hdr = 1;
|
||||||
if(!xc->size_limit_locked)
|
if(!xc->size_limit_locked)
|
||||||
{
|
{
|
||||||
if(xc->is_initial_time) /* simulation time never advanced so mock up the changes as time zero ones */
|
if(FST_UNLIKELY(xc->is_initial_time)) /* simulation time never advanced so mock up the changes as time zero ones */
|
||||||
{
|
{
|
||||||
fstHandle dupe_idx;
|
fstHandle dupe_idx;
|
||||||
|
|
||||||
@@ -1914,7 +1948,12 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
|
|||||||
/* write out geom section */
|
/* write out geom section */
|
||||||
fflush(xc->geom_handle);
|
fflush(xc->geom_handle);
|
||||||
tlen = ftello(xc->geom_handle);
|
tlen = ftello(xc->geom_handle);
|
||||||
tmem = (unsigned char *)fstMmap(NULL, tlen, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->geom_handle), 0);
|
errno = 0;
|
||||||
|
if(tlen)
|
||||||
|
{
|
||||||
|
fstWriterMmapSanity(tmem = (unsigned char *)fstMmap(NULL, tlen, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->geom_handle), 0), __FILE__, __LINE__, "tmem");
|
||||||
|
}
|
||||||
|
|
||||||
if(tmem)
|
if(tmem)
|
||||||
{
|
{
|
||||||
unsigned long destlen = tlen;
|
unsigned long destlen = tlen;
|
||||||
@@ -2022,14 +2061,18 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
|
|||||||
{
|
{
|
||||||
int lz4_maxlen;
|
int lz4_maxlen;
|
||||||
unsigned char *mem;
|
unsigned char *mem;
|
||||||
unsigned char *hmem;
|
unsigned char *hmem = NULL;
|
||||||
int packed_len;
|
int packed_len;
|
||||||
|
|
||||||
fflush(xc->handle);
|
fflush(xc->handle);
|
||||||
|
|
||||||
lz4_maxlen = LZ4_compressBound(xc->hier_file_len);
|
lz4_maxlen = LZ4_compressBound(xc->hier_file_len);
|
||||||
mem = (unsigned char *)malloc(lz4_maxlen);
|
mem = (unsigned char *)malloc(lz4_maxlen);
|
||||||
hmem = (unsigned char *)fstMmap(NULL, xc->hier_file_len, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->hier_handle), 0);
|
errno = 0;
|
||||||
|
if(xc->hier_file_len)
|
||||||
|
{
|
||||||
|
fstWriterMmapSanity(hmem = (unsigned char *)fstMmap(NULL, xc->hier_file_len, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->hier_handle), 0), __FILE__, __LINE__, "hmem");
|
||||||
|
}
|
||||||
packed_len = LZ4_compress((char *)hmem, (char *)mem, xc->hier_file_len);
|
packed_len = LZ4_compress((char *)hmem, (char *)mem, xc->hier_file_len);
|
||||||
fstMunmap(hmem, xc->hier_file_len);
|
fstMunmap(hmem, xc->hier_file_len);
|
||||||
|
|
||||||
@@ -2845,12 +2888,12 @@ const unsigned char *buf = (const unsigned char *)val;
|
|||||||
uint32_t offs;
|
uint32_t offs;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if((xc) && (handle <= xc->maxhandle))
|
if(FST_LIKELY((xc) && (handle <= xc->maxhandle)))
|
||||||
{
|
{
|
||||||
uint32_t fpos;
|
uint32_t fpos;
|
||||||
uint32_t *vm4ip;
|
uint32_t *vm4ip;
|
||||||
|
|
||||||
if(!xc->valpos_mem)
|
if(FST_UNLIKELY(!xc->valpos_mem))
|
||||||
{
|
{
|
||||||
xc->vc_emitted = 1;
|
xc->vc_emitted = 1;
|
||||||
fstWriterCreateMmaps(xc);
|
fstWriterCreateMmaps(xc);
|
||||||
@@ -2860,17 +2903,17 @@ if((xc) && (handle <= xc->maxhandle))
|
|||||||
vm4ip = &(xc->valpos_mem[4*handle]);
|
vm4ip = &(xc->valpos_mem[4*handle]);
|
||||||
|
|
||||||
len = vm4ip[1];
|
len = vm4ip[1];
|
||||||
if(len) /* len of zero = variable length, use fstWriterEmitVariableLengthValueChange */
|
if(FST_LIKELY(len)) /* len of zero = variable length, use fstWriterEmitVariableLengthValueChange */
|
||||||
{
|
{
|
||||||
if(!xc->is_initial_time)
|
if(FST_LIKELY(!xc->is_initial_time))
|
||||||
{
|
{
|
||||||
fpos = xc->vchg_siz;
|
fpos = xc->vchg_siz;
|
||||||
|
|
||||||
if((fpos + len + 10) > xc->vchg_alloc_siz)
|
if(FST_UNLIKELY((fpos + len + 10) > xc->vchg_alloc_siz))
|
||||||
{
|
{
|
||||||
xc->vchg_alloc_siz += (xc->fst_break_add_size + len); /* +len added in the case of extremely long vectors and small break add sizes */
|
xc->vchg_alloc_siz += (xc->fst_break_add_size + len); /* +len added in the case of extremely long vectors and small break add sizes */
|
||||||
xc->vchg_mem = (unsigned char *)realloc(xc->vchg_mem, xc->vchg_alloc_siz);
|
xc->vchg_mem = (unsigned char *)realloc(xc->vchg_mem, xc->vchg_alloc_siz);
|
||||||
if(!xc->vchg_mem)
|
if(VL_UNLIKELY(!xc->vchg_mem))
|
||||||
{
|
{
|
||||||
fprintf(stderr, FST_APIMESS "Could not realloc() in fstWriterEmitValueChange, exiting.\n");
|
fprintf(stderr, FST_APIMESS "Could not realloc() in fstWriterEmitValueChange, exiting.\n");
|
||||||
exit(255);
|
exit(255);
|
||||||
@@ -2961,12 +3004,12 @@ void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const v
|
|||||||
struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
|
struct fstWriterContext *xc = (struct fstWriterContext *)ctx;
|
||||||
const unsigned char *buf = (const unsigned char *)val;
|
const unsigned char *buf = (const unsigned char *)val;
|
||||||
|
|
||||||
if((xc) && (handle <= xc->maxhandle))
|
if(FST_LIKELY((xc) && (handle <= xc->maxhandle)))
|
||||||
{
|
{
|
||||||
uint32_t fpos;
|
uint32_t fpos;
|
||||||
uint32_t *vm4ip;
|
uint32_t *vm4ip;
|
||||||
|
|
||||||
if(!xc->valpos_mem)
|
if(FST_UNLIKELY(!xc->valpos_mem))
|
||||||
{
|
{
|
||||||
xc->vc_emitted = 1;
|
xc->vc_emitted = 1;
|
||||||
fstWriterCreateMmaps(xc);
|
fstWriterCreateMmaps(xc);
|
||||||
@@ -2976,15 +3019,15 @@ if((xc) && (handle <= xc->maxhandle))
|
|||||||
vm4ip = &(xc->valpos_mem[4*handle]);
|
vm4ip = &(xc->valpos_mem[4*handle]);
|
||||||
|
|
||||||
/* there is no initial time dump for variable length value changes */
|
/* there is no initial time dump for variable length value changes */
|
||||||
if(!vm4ip[1]) /* len of zero = variable length */
|
if(FST_LIKELY(!vm4ip[1])) /* len of zero = variable length */
|
||||||
{
|
{
|
||||||
fpos = xc->vchg_siz;
|
fpos = xc->vchg_siz;
|
||||||
|
|
||||||
if((fpos + len + 10 + 5) > xc->vchg_alloc_siz)
|
if(FST_UNLIKELY((fpos + len + 10 + 5) > xc->vchg_alloc_siz))
|
||||||
{
|
{
|
||||||
xc->vchg_alloc_siz += (xc->fst_break_add_size + len + 5); /* +len added in the case of extremely long vectors and small break add sizes */
|
xc->vchg_alloc_siz += (xc->fst_break_add_size + len + 5); /* +len added in the case of extremely long vectors and small break add sizes */
|
||||||
xc->vchg_mem = (unsigned char *)realloc(xc->vchg_mem, xc->vchg_alloc_siz);
|
xc->vchg_mem = (unsigned char *)realloc(xc->vchg_mem, xc->vchg_alloc_siz);
|
||||||
if(!xc->vchg_mem)
|
if(FST_UNLIKELY(!xc->vchg_mem))
|
||||||
{
|
{
|
||||||
fprintf(stderr, FST_APIMESS "Could not realloc() in fstWriterEmitVariableLengthValueChange, exiting.\n");
|
fprintf(stderr, FST_APIMESS "Could not realloc() in fstWriterEmitVariableLengthValueChange, exiting.\n");
|
||||||
exit(255);
|
exit(255);
|
||||||
@@ -3006,7 +3049,7 @@ unsigned int i;
|
|||||||
int skip = 0;
|
int skip = 0;
|
||||||
if(xc)
|
if(xc)
|
||||||
{
|
{
|
||||||
if(xc->is_initial_time)
|
if(FST_UNLIKELY(xc->is_initial_time))
|
||||||
{
|
{
|
||||||
if(xc->size_limit_locked) /* this resets xc->is_initial_time to one */
|
if(xc->size_limit_locked) /* this resets xc->is_initial_time to one */
|
||||||
{
|
{
|
||||||
|
|||||||
+94
-19
@@ -19,7 +19,7 @@
|
|||||||
/// This file must be compiled and linked against all objects
|
/// This file must be compiled and linked against all objects
|
||||||
/// created from Verilator.
|
/// created from Verilator.
|
||||||
///
|
///
|
||||||
/// Code available from: http://www.veripool.org/verilator
|
/// Code available from: https://verilator.org
|
||||||
///
|
///
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
@@ -71,6 +71,8 @@ VerilatedImp VerilatedImp::s_s;
|
|||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
// User definable functions
|
// User definable functions
|
||||||
|
// Note a TODO is a future version of the API will pass a structure so that
|
||||||
|
// the calling arguments allow for extension
|
||||||
|
|
||||||
#ifndef VL_USER_FINISH ///< Define this to override this function
|
#ifndef VL_USER_FINISH ///< Define this to override this function
|
||||||
void vl_finish(const char* filename, int linenum, const char* hier) VL_MT_UNSAFE {
|
void vl_finish(const char* filename, int linenum, const char* hier) VL_MT_UNSAFE {
|
||||||
@@ -109,6 +111,18 @@ void vl_fatal(const char* filename, int linenum, const char* hier, const char* m
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef VL_USER_STOP_MAYBE ///< Define this to override this function
|
||||||
|
void vl_stop_maybe(const char* filename, int linenum, const char* hier, bool maybe) VL_MT_UNSAFE {
|
||||||
|
Verilated::errorCountInc();
|
||||||
|
if (maybe && Verilated::errorCount() < Verilated::errorLimit()) {
|
||||||
|
VL_PRINTF( // Not VL_PRINTF_MT, already on main thread
|
||||||
|
"-Info: %s:%d: %s\n", filename, linenum, "Verilog $stop, ignored due to +verilator+error+limit");
|
||||||
|
} else {
|
||||||
|
vl_stop(filename, linenum, hier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Wrapper to call certain functions via messages when multithreaded
|
// Wrapper to call certain functions via messages when multithreaded
|
||||||
|
|
||||||
@@ -122,13 +136,13 @@ void VL_FINISH_MT(const char* filename, int linenum, const char* hier) VL_MT_SAF
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void VL_STOP_MT(const char* filename, int linenum, const char* hier) VL_MT_SAFE {
|
void VL_STOP_MT(const char* filename, int linenum, const char* hier, bool maybe) VL_MT_SAFE {
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
VerilatedThreadMsgQueue::post(VerilatedMsg([=](){
|
VerilatedThreadMsgQueue::post(VerilatedMsg([=](){
|
||||||
vl_stop(filename, linenum, hier);
|
vl_stop_maybe(filename, linenum, hier, maybe);
|
||||||
}));
|
}));
|
||||||
#else
|
#else
|
||||||
vl_stop(filename, linenum, hier);
|
vl_stop_maybe(filename, linenum, hier, maybe);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,13 +229,15 @@ void VL_PRINTF_MT(const char* formatp, ...) VL_MT_SAFE {
|
|||||||
// Overall class init
|
// Overall class init
|
||||||
|
|
||||||
Verilated::Serialized::Serialized() {
|
Verilated::Serialized::Serialized() {
|
||||||
s_randReset = 0;
|
|
||||||
s_randSeed = 0;
|
|
||||||
s_debug = 0;
|
s_debug = 0;
|
||||||
s_calcUnusedSigs = false;
|
s_calcUnusedSigs = false;
|
||||||
s_gotFinish = false;
|
s_gotFinish = false;
|
||||||
s_assertOn = true;
|
s_assertOn = true;
|
||||||
s_fatalOnVpiError = true; // retains old default behaviour
|
s_fatalOnVpiError = true; // retains old default behaviour
|
||||||
|
s_errorCount = 0;
|
||||||
|
s_errorLimit = 1;
|
||||||
|
s_randReset = 0;
|
||||||
|
s_randSeed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Verilated::NonSerialized::NonSerialized() {
|
Verilated::NonSerialized::NonSerialized() {
|
||||||
@@ -529,10 +545,10 @@ QData VL_POWSS_QQW(int obits, int, int rbits,
|
|||||||
QData lhs, WDataInP rwp, bool lsign, bool rsign) VL_MT_SAFE {
|
QData lhs, WDataInP rwp, bool lsign, bool rsign) VL_MT_SAFE {
|
||||||
// Skip check for rhs == 0, as short-circuit doesn't save time
|
// Skip check for rhs == 0, as short-circuit doesn't save time
|
||||||
if (rsign && VL_SIGN_W(rbits, rwp)) {
|
if (rsign && VL_SIGN_W(rbits, rwp)) {
|
||||||
if (lhs==0) return 0; // "X"
|
if (lhs == 0) return 0; // "X"
|
||||||
else if (lhs==1) return 1;
|
else if (lhs == 1) return 1;
|
||||||
else if (lsign && lhs==VL_MASK_I(obits)) { // -1
|
else if (lsign && lhs == VL_MASK_Q(obits)) { // -1
|
||||||
if (rwp[0] & 1) return VL_MASK_I(obits); // -1^odd=-1
|
if (rwp[0] & 1) return VL_MASK_Q(obits); // -1^odd=-1
|
||||||
else return 1; // -1^even=1
|
else return 1; // -1^even=1
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -607,7 +623,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
|||||||
width = 0;
|
width = 0;
|
||||||
} else if (!inPct) { // Normal text
|
} else if (!inPct) { // Normal text
|
||||||
// Fast-forward to next escape and add to output
|
// Fast-forward to next escape and add to output
|
||||||
const char *ep = pos;
|
const char* ep = pos;
|
||||||
while (ep[0] && ep[0]!='%') ep++;
|
while (ep[0] && ep[0]!='%') ep++;
|
||||||
if (ep != pos) {
|
if (ep != pos) {
|
||||||
output.append(pos, ep-pos);
|
output.append(pos, ep-pos);
|
||||||
@@ -1692,9 +1708,24 @@ IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) VL_M
|
|||||||
_vl_vsss_setbit(rwp, rbits, lsb, 8, dp[posp]); lsb+=8;
|
_vl_vsss_setbit(rwp, rbits, lsb, 8, dp[posp]); lsb+=8;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'e': // FALLTHRU - Unsupported
|
case 'e': {
|
||||||
case 'f': // FALLTHRU - Unsupported
|
double temp = 0.f;
|
||||||
case 'g': // FALLTHRU - Unsupported
|
sscanf(dp, "%le", &temp);
|
||||||
|
VL_SET_WQ(rwp, VL_CVT_Q_D(temp));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'f': {
|
||||||
|
double temp = 0.f;
|
||||||
|
sscanf(dp, "%lf", &temp);
|
||||||
|
VL_SET_WQ(rwp, VL_CVT_Q_D(temp));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'g': {
|
||||||
|
double temp = 0.f;
|
||||||
|
sscanf(dp, "%lg", &temp);
|
||||||
|
VL_SET_WQ(rwp, VL_CVT_Q_D(temp));
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: // Other simulators simply return 0 in these cases and don't error out
|
default: // Other simulators simply return 0 in these cases and don't error out
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1740,7 +1771,35 @@ const char* vl_mc_scan_plusargs(const char* prefixp) VL_MT_SAFE {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Heavy functions
|
// Heavy string functions
|
||||||
|
|
||||||
|
std::string VL_TO_STRING(CData lhs) {
|
||||||
|
return VL_SFORMATF_NX("'h%0x", 8, lhs);
|
||||||
|
}
|
||||||
|
std::string VL_TO_STRING(SData lhs) {
|
||||||
|
return VL_SFORMATF_NX("'h%0x", 16, lhs);
|
||||||
|
}
|
||||||
|
std::string VL_TO_STRING(IData lhs) {
|
||||||
|
return VL_SFORMATF_NX("'h%0x", 32, lhs);
|
||||||
|
}
|
||||||
|
std::string VL_TO_STRING(QData lhs) {
|
||||||
|
return VL_SFORMATF_NX("'h%0x", 64, lhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string VL_TOLOWER_NN(const std::string& ld) VL_MT_SAFE {
|
||||||
|
std::string out = ld;
|
||||||
|
for (std::string::iterator it = out.begin(); it != out.end(); ++it) {
|
||||||
|
*it = tolower(*it);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
std::string VL_TOUPPER_NN(const std::string& ld) VL_MT_SAFE {
|
||||||
|
std::string out = ld;
|
||||||
|
for (std::string::iterator it = out.begin(); it != out.end(); ++it) {
|
||||||
|
*it = toupper(*it);
|
||||||
|
}
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) VL_MT_SAFE {
|
std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) VL_MT_SAFE {
|
||||||
// See also _VL_VINT_TO_STRING
|
// See also _VL_VINT_TO_STRING
|
||||||
@@ -1785,7 +1844,8 @@ void Verilated::debug(int level) VL_MT_SAFE {
|
|||||||
" Message prefix indicates {<thread>,<sequence_number>}.\n"););
|
" Message prefix indicates {<thread>,<sequence_number>}.\n"););
|
||||||
#else
|
#else
|
||||||
VL_PRINTF_MT("- Verilated::debug attempted,"
|
VL_PRINTF_MT("- Verilated::debug attempted,"
|
||||||
" but compiled without VL_DEBUG, so messages suppressed.\n");
|
" but compiled without VL_DEBUG, so messages suppressed.\n"
|
||||||
|
"- Suggest remake using 'make ... CPPFLAGS=-DVL_DEBUG'\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1801,6 +1861,18 @@ void Verilated::calcUnusedSigs(bool flag) VL_MT_SAFE {
|
|||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
s_s.s_calcUnusedSigs = flag;
|
s_s.s_calcUnusedSigs = flag;
|
||||||
}
|
}
|
||||||
|
void Verilated::errorCount(int val) VL_MT_SAFE {
|
||||||
|
VerilatedLockGuard lock(m_mutex);
|
||||||
|
s_s.s_errorCount = val;
|
||||||
|
}
|
||||||
|
void Verilated::errorCountInc() VL_MT_SAFE {
|
||||||
|
VerilatedLockGuard lock(m_mutex);
|
||||||
|
++s_s.s_errorCount;
|
||||||
|
}
|
||||||
|
void Verilated::errorLimit(int val) VL_MT_SAFE {
|
||||||
|
VerilatedLockGuard lock(m_mutex);
|
||||||
|
s_s.s_errorLimit = val;
|
||||||
|
}
|
||||||
void Verilated::gotFinish(bool flag) VL_MT_SAFE {
|
void Verilated::gotFinish(bool flag) VL_MT_SAFE {
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
s_s.s_gotFinish = flag;
|
s_s.s_gotFinish = flag;
|
||||||
@@ -1828,19 +1900,19 @@ void Verilated::profThreadsFilenamep(const char* flagp) VL_MT_SAFE {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const char* Verilated::catName(const char* n1, const char* n2) VL_MT_SAFE {
|
const char* Verilated::catName(const char* n1, const char* n2, const char* delimiter) VL_MT_SAFE {
|
||||||
// Returns new'ed data
|
// Returns new'ed data
|
||||||
// Used by symbol table creation to make module names
|
// Used by symbol table creation to make module names
|
||||||
static VL_THREAD_LOCAL char* strp = NULL;
|
static VL_THREAD_LOCAL char* strp = NULL;
|
||||||
static VL_THREAD_LOCAL size_t len = 0;
|
static VL_THREAD_LOCAL size_t len = 0;
|
||||||
size_t newlen = strlen(n1)+strlen(n2)+2;
|
size_t newlen = strlen(n1)+strlen(n2)+strlen(delimiter)+1;
|
||||||
if (!strp || newlen > len) {
|
if (!strp || newlen > len) {
|
||||||
if (strp) delete [] strp;
|
if (strp) delete [] strp;
|
||||||
strp = new char[newlen];
|
strp = new char[newlen];
|
||||||
len = newlen;
|
len = newlen;
|
||||||
}
|
}
|
||||||
strcpy(strp, n1);
|
strcpy(strp, n1);
|
||||||
if (*n1) strcat(strp, ".");
|
if (*n1) strcat(strp, delimiter);
|
||||||
strcat(strp, n2);
|
strcat(strp, n2);
|
||||||
return strp;
|
return strp;
|
||||||
}
|
}
|
||||||
@@ -1990,6 +2062,9 @@ void VerilatedImp::commandArgVl(const std::string& arg) {
|
|||||||
else if (commandArgVlValue(arg, "+verilator+debugi+", value/*ref*/)) {
|
else if (commandArgVlValue(arg, "+verilator+debugi+", value/*ref*/)) {
|
||||||
Verilated::debug(atoi(value.c_str()));
|
Verilated::debug(atoi(value.c_str()));
|
||||||
}
|
}
|
||||||
|
else if (commandArgVlValue(arg, "+verilator+error+limit+", value/*ref*/)) {
|
||||||
|
Verilated::errorLimit(atoi(value.c_str()));
|
||||||
|
}
|
||||||
else if (arg == "+verilator+help") {
|
else if (arg == "+verilator+help") {
|
||||||
versionDump();
|
versionDump();
|
||||||
VL_PRINTF_MT("For help, please see 'verilator --help'\n");
|
VL_PRINTF_MT("For help, please see 'verilator --help'\n");
|
||||||
|
|||||||
+39
-27
@@ -20,11 +20,10 @@
|
|||||||
/// all C++ files it generates. It contains standard macros and
|
/// all C++ files it generates. It contains standard macros and
|
||||||
/// classes required by the Verilated code.
|
/// classes required by the Verilated code.
|
||||||
///
|
///
|
||||||
/// Code available from: http://www.veripool.org/verilator
|
/// Code available from: https://verilator.org
|
||||||
///
|
///
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
|
|
||||||
#ifndef _VERILATED_H_
|
#ifndef _VERILATED_H_
|
||||||
#define _VERILATED_H_ 1 ///< Header Guard
|
#define _VERILATED_H_ 1 ///< Header Guard
|
||||||
|
|
||||||
@@ -45,6 +44,11 @@
|
|||||||
# include <thread>
|
# include <thread>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Allow user to specify their own include file
|
||||||
|
#ifdef VL_VERILATED_INCLUDE
|
||||||
|
# include VL_VERILATED_INCLUDE
|
||||||
|
#endif
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Switches
|
// Switches
|
||||||
|
|
||||||
@@ -141,7 +145,7 @@ class VL_CAPABILITY("mutex") VerilatedMutex {
|
|||||||
bool try_lock() VL_TRY_ACQUIRE(true) { return m_mutex.try_lock(); }
|
bool try_lock() VL_TRY_ACQUIRE(true) { return m_mutex.try_lock(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Lock guard for mutex (ala std::lock_guard), wrapped to allow -fthread_safety checks
|
/// Lock guard for mutex (ala std::unique_lock), wrapped to allow -fthread_safety checks
|
||||||
class VL_SCOPED_CAPABILITY VerilatedLockGuard {
|
class VL_SCOPED_CAPABILITY VerilatedLockGuard {
|
||||||
VL_UNCOPYABLE(VerilatedLockGuard);
|
VL_UNCOPYABLE(VerilatedLockGuard);
|
||||||
private:
|
private:
|
||||||
@@ -154,6 +158,8 @@ class VL_SCOPED_CAPABILITY VerilatedLockGuard {
|
|||||||
~VerilatedLockGuard() VL_RELEASE() {
|
~VerilatedLockGuard() VL_RELEASE() {
|
||||||
m_mutexr.unlock();
|
m_mutexr.unlock();
|
||||||
}
|
}
|
||||||
|
void lock() VL_ACQUIRE() { m_mutexr.lock(); }
|
||||||
|
void unlock() VL_RELEASE() { m_mutexr.unlock(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#else // !VL_THREADED
|
#else // !VL_THREADED
|
||||||
@@ -171,6 +177,8 @@ class VerilatedLockGuard {
|
|||||||
public:
|
public:
|
||||||
explicit VerilatedLockGuard(VerilatedMutex&) {}
|
explicit VerilatedLockGuard(VerilatedMutex&) {}
|
||||||
~VerilatedLockGuard() {}
|
~VerilatedLockGuard() {}
|
||||||
|
void lock() {}
|
||||||
|
void unlock() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VL_THREADED
|
#endif // VL_THREADED
|
||||||
@@ -218,13 +226,6 @@ public:
|
|||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Declare nets
|
// Declare nets
|
||||||
|
|
||||||
#ifndef VL_ST_SIG
|
|
||||||
# define VL_ST_SIG8(name, msb,lsb) CData name ///< Declare signal, 1-8 bits
|
|
||||||
# define VL_ST_SIG16(name, msb,lsb) SData name ///< Declare signal, 9-16 bits
|
|
||||||
# define VL_ST_SIG64(name, msb,lsb) QData name ///< Declare signal, 33-64 bits
|
|
||||||
# define VL_ST_SIG(name, msb,lsb) IData name ///< Declare signal, 17-32 bits
|
|
||||||
# define VL_ST_SIGW(name,msb,lsb,words) WData name[words] ///< Declare signal, 65+ bits
|
|
||||||
#endif
|
|
||||||
#ifndef VL_SIG
|
#ifndef VL_SIG
|
||||||
# define VL_SIG8(name, msb,lsb) CData name ///< Declare signal, 1-8 bits
|
# define VL_SIG8(name, msb,lsb) CData name ///< Declare signal, 1-8 bits
|
||||||
# define VL_SIG16(name, msb,lsb) SData name ///< Declare signal, 9-16 bits
|
# define VL_SIG16(name, msb,lsb) SData name ///< Declare signal, 9-16 bits
|
||||||
@@ -349,7 +350,7 @@ class Verilated {
|
|||||||
// Slow path variables
|
// Slow path variables
|
||||||
static VerilatedMutex m_mutex; ///< Mutex for s_s/s_ns members, when VL_THREADED
|
static VerilatedMutex m_mutex; ///< Mutex for s_s/s_ns members, when VL_THREADED
|
||||||
|
|
||||||
static VerilatedVoidCb s_flushCb; ///< Flush callback function
|
static VerilatedVoidCb s_flushCb; ///< Flush callback function
|
||||||
|
|
||||||
static struct Serialized { // All these members serialized/deserialized
|
static struct Serialized { // All these members serialized/deserialized
|
||||||
// Fast path
|
// Fast path
|
||||||
@@ -359,6 +360,8 @@ class Verilated {
|
|||||||
bool s_assertOn; ///< Assertions are enabled
|
bool s_assertOn; ///< Assertions are enabled
|
||||||
bool s_fatalOnVpiError; ///< Stop on vpi error/unsupported
|
bool s_fatalOnVpiError; ///< Stop on vpi error/unsupported
|
||||||
// Slow path
|
// Slow path
|
||||||
|
int s_errorCount; ///< Number of errors
|
||||||
|
int s_errorLimit; ///< Stop on error number
|
||||||
int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random
|
int s_randReset; ///< Random reset: 0=all 0s, 1=all 1s, 2=random
|
||||||
int s_randSeed; ///< Random seed: 0=random
|
int s_randSeed; ///< Random seed: 0=random
|
||||||
Serialized();
|
Serialized();
|
||||||
@@ -413,9 +416,9 @@ public:
|
|||||||
/// 1 = Set all bits to one
|
/// 1 = Set all bits to one
|
||||||
/// 2 = Randomize all bits
|
/// 2 = Randomize all bits
|
||||||
static void randReset(int val) VL_MT_SAFE;
|
static void randReset(int val) VL_MT_SAFE;
|
||||||
static int randReset() VL_MT_SAFE { return s_s.s_randReset; } ///< Return randReset value
|
static int randReset() VL_MT_SAFE { return s_s.s_randReset; } ///< Return randReset value
|
||||||
static void randSeed(int val) VL_MT_SAFE;
|
static void randSeed(int val) VL_MT_SAFE;
|
||||||
static int randSeed() VL_MT_SAFE { return s_s.s_randSeed; } ///< Return randSeed value
|
static int randSeed() VL_MT_SAFE { return s_s.s_randSeed; } ///< Return randSeed value
|
||||||
|
|
||||||
/// Enable debug of internal verilated code
|
/// Enable debug of internal verilated code
|
||||||
static void debug(int level) VL_MT_SAFE;
|
static void debug(int level) VL_MT_SAFE;
|
||||||
@@ -431,6 +434,13 @@ public:
|
|||||||
static void calcUnusedSigs(bool flag) VL_MT_SAFE;
|
static void calcUnusedSigs(bool flag) VL_MT_SAFE;
|
||||||
static bool calcUnusedSigs() VL_MT_SAFE { ///< Return calcUnusedSigs value
|
static bool calcUnusedSigs() VL_MT_SAFE { ///< Return calcUnusedSigs value
|
||||||
return s_s.s_calcUnusedSigs; }
|
return s_s.s_calcUnusedSigs; }
|
||||||
|
/// Current number of errors/assertions
|
||||||
|
static void errorCount(int val) VL_MT_SAFE;
|
||||||
|
static void errorCountInc() VL_MT_SAFE;
|
||||||
|
static int errorCount() VL_MT_SAFE { return s_s.s_errorCount; }
|
||||||
|
/// Set number of errors/assertions before stop
|
||||||
|
static void errorLimit(int val) VL_MT_SAFE;
|
||||||
|
static int errorLimit() VL_MT_SAFE { return s_s.s_errorLimit; }
|
||||||
/// Did the simulation $finish?
|
/// Did the simulation $finish?
|
||||||
static void gotFinish(bool flag) VL_MT_SAFE;
|
static void gotFinish(bool flag) VL_MT_SAFE;
|
||||||
static bool gotFinish() VL_MT_SAFE { return s_s.s_gotFinish; } ///< Return if got a $finish
|
static bool gotFinish() VL_MT_SAFE { return s_s.s_gotFinish; } ///< Return if got a $finish
|
||||||
@@ -491,7 +501,8 @@ public:
|
|||||||
public:
|
public:
|
||||||
// METHODS - INTERNAL USE ONLY (but public due to what uses it)
|
// METHODS - INTERNAL USE ONLY (but public due to what uses it)
|
||||||
// Internal: Create a new module name by concatenating two strings
|
// Internal: Create a new module name by concatenating two strings
|
||||||
static const char* catName(const char* n1, const char* n2); // Returns static data
|
static const char* catName(const char* n1, const char* n2,
|
||||||
|
const char* delimiter="."); // Returns static data
|
||||||
|
|
||||||
// Internal: Throw signal assertion
|
// Internal: Throw signal assertion
|
||||||
static void overWidthError(const char* signame) VL_MT_SAFE;
|
static void overWidthError(const char* signame) VL_MT_SAFE;
|
||||||
@@ -569,7 +580,8 @@ extern void vl_fatal(const char* filename, int linenum, const char* hier,
|
|||||||
/// Multithread safe wrapper for calls to $finish
|
/// Multithread safe wrapper for calls to $finish
|
||||||
extern void VL_FINISH_MT(const char* filename, int linenum, const char* hier) VL_MT_SAFE;
|
extern void VL_FINISH_MT(const char* filename, int linenum, const char* hier) VL_MT_SAFE;
|
||||||
/// Multithread safe wrapper for calls to $stop
|
/// Multithread safe wrapper for calls to $stop
|
||||||
extern void VL_STOP_MT(const char* filename, int linenum, const char* hier) VL_MT_SAFE;
|
extern void VL_STOP_MT(const char* filename, int linenum, const char* hier,
|
||||||
|
bool maybe = true) VL_MT_SAFE;
|
||||||
/// Multithread safe wrapper to call for a couple of fatal messages
|
/// Multithread safe wrapper to call for a couple of fatal messages
|
||||||
extern void VL_FATAL_MT(const char* filename, int linenum, const char* hier,
|
extern void VL_FATAL_MT(const char* filename, int linenum, const char* hier,
|
||||||
const char* msg) VL_MT_SAFE;
|
const char* msg) VL_MT_SAFE;
|
||||||
@@ -1513,11 +1525,11 @@ QData VL_POW_QQW(int obits, int, int rbits, QData lhs, WDataInP rwp);
|
|||||||
|
|
||||||
static inline IData VL_POWSS_III(int obits, int, int rbits,
|
static inline IData VL_POWSS_III(int obits, int, int rbits,
|
||||||
IData lhs, IData rhs, bool lsign, bool rsign) VL_MT_SAFE {
|
IData lhs, IData rhs, bool lsign, bool rsign) VL_MT_SAFE {
|
||||||
if (VL_UNLIKELY(rhs==0)) return 1;
|
if (VL_UNLIKELY(rhs == 0)) return 1;
|
||||||
if (rsign && VL_SIGN_I(rbits, rhs)) {
|
if (rsign && VL_SIGN_I(rbits, rhs)) {
|
||||||
if (lhs==0) return 0; // "X"
|
if (lhs == 0) return 0; // "X"
|
||||||
else if (lhs==1) return 1;
|
else if (lhs == 1) return 1;
|
||||||
else if (lsign && lhs==VL_MASK_I(obits)) { // -1
|
else if (lsign && lhs == VL_MASK_I(obits)) { // -1
|
||||||
if (rhs & 1) return VL_MASK_I(obits); // -1^odd=-1
|
if (rhs & 1) return VL_MASK_I(obits); // -1^odd=-1
|
||||||
else return 1; // -1^even=1
|
else return 1; // -1^even=1
|
||||||
}
|
}
|
||||||
@@ -1527,12 +1539,12 @@ static inline IData VL_POWSS_III(int obits, int, int rbits,
|
|||||||
}
|
}
|
||||||
static inline QData VL_POWSS_QQQ(int obits, int, int rbits,
|
static inline QData VL_POWSS_QQQ(int obits, int, int rbits,
|
||||||
QData lhs, QData rhs, bool lsign, bool rsign) VL_MT_SAFE {
|
QData lhs, QData rhs, bool lsign, bool rsign) VL_MT_SAFE {
|
||||||
if (VL_UNLIKELY(rhs==0)) return 1;
|
if (VL_UNLIKELY(rhs == 0)) return 1;
|
||||||
if (rsign && VL_SIGN_I(rbits, rhs)) {
|
if (rsign && VL_SIGN_Q(rbits, rhs)) {
|
||||||
if (lhs==0) return 0; // "X"
|
if (lhs == 0) return 0; // "X"
|
||||||
else if (lhs==1) return 1;
|
else if (lhs == 1) return 1;
|
||||||
else if (lsign && lhs==VL_MASK_I(obits)) { // -1
|
else if (lsign && lhs == VL_MASK_Q(obits)) { // -1
|
||||||
if (rhs & 1) return VL_MASK_I(obits); // -1^odd=-1
|
if (rhs & 1) return VL_MASK_Q(obits); // -1^odd=-1
|
||||||
else return 1; // -1^even=1
|
else return 1; // -1^even=1
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1654,7 +1666,7 @@ static inline IData VL_REPLICATE_III(int, int lbits, int, IData ld, IData rep) V
|
|||||||
returndata = returndata << lbits;
|
returndata = returndata << lbits;
|
||||||
returndata |= ld;
|
returndata |= ld;
|
||||||
}
|
}
|
||||||
return (returndata);
|
return returndata;
|
||||||
}
|
}
|
||||||
static inline QData VL_REPLICATE_QII(int, int lbits, int, IData ld, IData rep) VL_PURE {
|
static inline QData VL_REPLICATE_QII(int, int lbits, int, IData ld, IData rep) VL_PURE {
|
||||||
QData returndata = ld;
|
QData returndata = ld;
|
||||||
@@ -1662,7 +1674,7 @@ static inline QData VL_REPLICATE_QII(int, int lbits, int, IData ld, IData rep) V
|
|||||||
returndata = returndata << lbits;
|
returndata = returndata << lbits;
|
||||||
returndata |= static_cast<QData>(ld);
|
returndata |= static_cast<QData>(ld);
|
||||||
}
|
}
|
||||||
return (returndata);
|
return returndata;
|
||||||
}
|
}
|
||||||
static inline WDataOutP VL_REPLICATE_WII(int obits, int lbits, int,
|
static inline WDataOutP VL_REPLICATE_WII(int obits, int lbits, int,
|
||||||
WDataOutP owp, IData ld, IData rep) VL_MT_SAFE {
|
WDataOutP owp, IData ld, IData rep) VL_MT_SAFE {
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ CFG_LDLIBS_THREADS = @CFG_LDLIBS_THREADS@
|
|||||||
######################################################################
|
######################################################################
|
||||||
# Programs
|
# Programs
|
||||||
|
|
||||||
SP_INCLUDER = $(VERILATOR_INCLUDER)
|
|
||||||
VERILATOR_COVERAGE = $(PERL) $(VERILATOR_ROOT)/bin/verilator_coverage
|
VERILATOR_COVERAGE = $(PERL) $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||||
VERILATOR_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer
|
VERILATOR_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer
|
||||||
|
|
||||||
@@ -49,7 +48,6 @@ VK_CPPFLAGS_ALWAYS += \
|
|||||||
-MMD \
|
-MMD \
|
||||||
-I$(VERILATOR_ROOT)/include \
|
-I$(VERILATOR_ROOT)/include \
|
||||||
-I$(VERILATOR_ROOT)/include/vltstd \
|
-I$(VERILATOR_ROOT)/include/vltstd \
|
||||||
-DVL_PRINTF=printf \
|
|
||||||
-DVM_COVERAGE=$(VM_COVERAGE) \
|
-DVM_COVERAGE=$(VM_COVERAGE) \
|
||||||
-DVM_SC=$(VM_SC) \
|
-DVM_SC=$(VM_SC) \
|
||||||
-DVM_TRACE=$(VM_TRACE) \
|
-DVM_TRACE=$(VM_TRACE) \
|
||||||
@@ -173,8 +171,7 @@ else
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
$(VM_PREFIX)__ALL.a: $(VK_OBJS)
|
$(VM_PREFIX)__ALL.a: $(VK_OBJS)
|
||||||
@echo " Archiving" $@ ...
|
$(AR) -cr $@ $^
|
||||||
$(AR) r $@ $^
|
|
||||||
$(RANLIB) $@
|
$(RANLIB) $@
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Code available from: http://www.veripool.org/verilator
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
/// \file
|
/// \file
|
||||||
/// \brief Verilator: Auto version information include for all Verilated C files
|
/// \brief Verilator: Auto version information include for all Verilated C files
|
||||||
///
|
///
|
||||||
/// Code available from: http://www.veripool.org/verilator
|
/// Code available from: https://verilator.org
|
||||||
///
|
///
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@
|
|||||||
|
|
||||||
#define VL_COVER_INSERT(countp,args...) \
|
#define VL_COVER_INSERT(countp,args...) \
|
||||||
VL_IF_COVER(VerilatedCov::_inserti(countp); \
|
VL_IF_COVER(VerilatedCov::_inserti(countp); \
|
||||||
VerilatedCov::_insertf(__FILE__,__LINE__); \
|
VerilatedCov::_insertf(__FILE__, __LINE__); \
|
||||||
VerilatedCov::_insertp("hier", name(), args))
|
VerilatedCov::_insertp("hier", name(), args))
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
/// This file must be compiled and linked against all objects
|
/// This file must be compiled and linked against all objects
|
||||||
/// created from Verilator or called by Verilator that use the DPI.
|
/// created from Verilator or called by Verilator that use the DPI.
|
||||||
///
|
///
|
||||||
/// Code available from: http://www.veripool.org/verilator
|
/// Code available from: https://verilator.org
|
||||||
///
|
///
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
@@ -43,7 +43,8 @@
|
|||||||
|
|
||||||
// Not supported yet
|
// Not supported yet
|
||||||
#define _VL_SVDPI_UNIMP() \
|
#define _VL_SVDPI_UNIMP() \
|
||||||
VL_FATAL_MT(__FILE__,__LINE__,"",(std::string("%%Error: Unsupported DPI function: ")+VL_FUNC).c_str())
|
VL_FATAL_MT(__FILE__, __LINE__, "", \
|
||||||
|
(std::string("%%Error: Unsupported DPI function: ")+VL_FUNC).c_str())
|
||||||
|
|
||||||
#define _VL_SVDPI_WARN(message...) \
|
#define _VL_SVDPI_WARN(message...) \
|
||||||
VL_PRINTF_MT(message)
|
VL_PRINTF_MT(message)
|
||||||
|
|||||||
@@ -20,11 +20,10 @@
|
|||||||
/// all C++ files it generates where DPI is used. It contains
|
/// all C++ files it generates where DPI is used. It contains
|
||||||
/// DPI interface functions required by the Verilated code.
|
/// DPI interface functions required by the Verilated code.
|
||||||
///
|
///
|
||||||
/// Code available from: http://www.veripool.org/verilator
|
/// Code available from: https://verilator.org
|
||||||
///
|
///
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
|
|
||||||
#ifndef _VERILATED_DPI_H_
|
#ifndef _VERILATED_DPI_H_
|
||||||
#define _VERILATED_DPI_H_ 1 ///< Header Guard
|
#define _VERILATED_DPI_H_ 1 ///< Header Guard
|
||||||
|
|
||||||
|
|||||||
+20
-15
@@ -31,6 +31,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Include the GTKWave implementation directly
|
// Include the GTKWave implementation directly
|
||||||
|
#define FST_CONFIG_INCLUDE "fst_config.h"
|
||||||
#include "gtkwave/fastlz.c"
|
#include "gtkwave/fastlz.c"
|
||||||
#include "gtkwave/fstapi.c"
|
#include "gtkwave/fstapi.c"
|
||||||
#include "gtkwave/lz4.c"
|
#include "gtkwave/lz4.c"
|
||||||
@@ -73,7 +74,9 @@ protected:
|
|||||||
VerilatedFst::VerilatedFst(void* fst)
|
VerilatedFst::VerilatedFst(void* fst)
|
||||||
: m_fst(fst),
|
: m_fst(fst),
|
||||||
m_fullDump(true),
|
m_fullDump(true),
|
||||||
m_scopeEscape('.') {}
|
m_scopeEscape('.') {
|
||||||
|
m_valueStrBuffer.reserve(64+1); // Need enough room for quad
|
||||||
|
}
|
||||||
|
|
||||||
void VerilatedFst::open(const char* filename) VL_MT_UNSAFE {
|
void VerilatedFst::open(const char* filename) VL_MT_UNSAFE {
|
||||||
m_assertOne.check();
|
m_assertOne.check();
|
||||||
@@ -176,7 +179,7 @@ void VerilatedFst::addCallback(
|
|||||||
if (VL_UNLIKELY(isOpen())) {
|
if (VL_UNLIKELY(isOpen())) {
|
||||||
std::string msg = (std::string("Internal: ")+__FILE__+"::"+__FUNCTION__
|
std::string msg = (std::string("Internal: ")+__FILE__+"::"+__FUNCTION__
|
||||||
+" called with already open file");
|
+" called with already open file");
|
||||||
VL_FATAL_MT(__FILE__,__LINE__,"",msg.c_str());
|
VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str());
|
||||||
}
|
}
|
||||||
VerilatedFstCallInfo* vci = new VerilatedFstCallInfo(initcb, fullcb, changecb, userthis, 1);
|
VerilatedFstCallInfo* vci = new VerilatedFstCallInfo(initcb, fullcb, changecb, userthis, 1);
|
||||||
m_callbacks.push_back(vci);
|
m_callbacks.push_back(vci);
|
||||||
@@ -206,39 +209,41 @@ void VerilatedFst::dump(vluint64_t timeui) {
|
|||||||
// Helpers
|
// Helpers
|
||||||
|
|
||||||
char* VerilatedFst::word2Str(vluint32_t newval, int bits) {
|
char* VerilatedFst::word2Str(vluint32_t newval, int bits) {
|
||||||
m_valueStrBuffer.resize(bits+1);
|
// Constructor makes sure m_valueStrBuffer.reserve() > 32+1
|
||||||
char* s = m_valueStrBuffer.data();
|
char* s = m_valueStrBuffer.data();
|
||||||
for (int i = 0; i < bits; ++i) {
|
for (int i = 0; i < bits; ++i) {
|
||||||
*s = '0' + ((newval>>(bits-i-1))&1);
|
*s++ = '0' + ((newval>>(bits-i-1))&1);
|
||||||
++s;
|
|
||||||
}
|
}
|
||||||
*s = '\0';
|
*s = '\0';
|
||||||
return m_valueStrBuffer.data();
|
return m_valueStrBuffer.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
char* VerilatedFst::quad2Str(vluint64_t newval, int bits) {
|
char* VerilatedFst::quad2Str(vluint64_t newval, int bits) {
|
||||||
m_valueStrBuffer.resize(bits+1);
|
// Constructor makes sure m_valueStrBuffer.reserve() > 64+1
|
||||||
char* s = m_valueStrBuffer.data();
|
char* s = m_valueStrBuffer.data();
|
||||||
for (int i = 0; i < bits; ++i) {
|
for (int i = 0; i < bits; ++i) {
|
||||||
*s = '0' + ((newval>>(bits-i-1))&1);
|
*s++ = '0' + ((newval>>(bits-i-1))&1);
|
||||||
++s;
|
|
||||||
}
|
}
|
||||||
*s = '\0';
|
*s = '\0';
|
||||||
return m_valueStrBuffer.data();
|
return m_valueStrBuffer.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
char* VerilatedFst::array2Str(const vluint32_t* newval, int bits) {
|
char* VerilatedFst::array2Str(const vluint32_t* newval, int bits) {
|
||||||
int bq = bits/32, br = bits%32;
|
int bq = VL_BITWORD_I(bits), br = VL_BITBIT_I(bits);
|
||||||
m_valueStrBuffer.resize(bits+1);
|
m_valueStrBuffer.reserve(bits+1);
|
||||||
char* s = m_valueStrBuffer.data();
|
char* s = m_valueStrBuffer.data();
|
||||||
|
vluint32_t v = newval[bq];
|
||||||
for (int i = 0; i < br; ++i) {
|
for (int i = 0; i < br; ++i) {
|
||||||
*s = '0' + ((newval[bq]>>(br-i-1))&1);
|
*s++ = '0' + ((v>>(br-i-1))&1);
|
||||||
++s;
|
|
||||||
}
|
}
|
||||||
for (int w = bq-1; w >= 0; --w) {
|
for (int w = bq-1; w >= 0; --w) {
|
||||||
for (int i = 0; i < 32; ++i) {
|
v = newval[w];
|
||||||
*s = '0' + ((newval[w]>>(32-i-1))&1);
|
for (int i = 28; i >= 0; i-=4) {
|
||||||
++s;
|
s[0] = '0' + ((v>>(i+3))&1);
|
||||||
|
s[1] = '0' + ((v>>(i+2))&1);
|
||||||
|
s[2] = '0' + ((v>>(i+1))&1);
|
||||||
|
s[3] = '0' + ((v>>(i+0))&1);
|
||||||
|
s+=4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*s = '\0';
|
*s = '\0';
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ public:
|
|||||||
/// Change character that splits scopes. Note whitespace are ALWAYS escapes.
|
/// Change character that splits scopes. Note whitespace are ALWAYS escapes.
|
||||||
void scopeEscape(char flag) { m_scopeEscape = flag; }
|
void scopeEscape(char flag) { m_scopeEscape = flag; }
|
||||||
/// Is this an escape?
|
/// Is this an escape?
|
||||||
bool isScopeEscape(char c) { return isspace(c) || c==m_scopeEscape; }
|
bool isScopeEscape(char c) { return isspace(c) || c == m_scopeEscape; }
|
||||||
/// Inside dumping routines, called each cycle to make the dump
|
/// Inside dumping routines, called each cycle to make the dump
|
||||||
void dump(vluint64_t timeui);
|
void dump(vluint64_t timeui);
|
||||||
/// Inside dumping routines, declare callbacks for tracings
|
/// Inside dumping routines, declare callbacks for tracings
|
||||||
|
|||||||
+265
-5
@@ -21,18 +21,258 @@
|
|||||||
/// heavyweight types are required; these contents are not part of
|
/// heavyweight types are required; these contents are not part of
|
||||||
/// verilated.h to save compile time when such types aren't used.
|
/// verilated.h to save compile time when such types aren't used.
|
||||||
///
|
///
|
||||||
/// Code available from: http://www.veripool.org/verilator
|
/// Code available from: https://verilator.org
|
||||||
///
|
///
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
|
|
||||||
#ifndef _VERILATED_HEAVY_H_
|
#ifndef _VERILATED_HEAVY_H_
|
||||||
#define _VERILATED_HEAVY_H_ 1 ///< Header Guard
|
#define _VERILATED_HEAVY_H_ 1 ///< Header Guard
|
||||||
|
|
||||||
#include "verilated.h"
|
#include "verilated.h"
|
||||||
|
|
||||||
|
#include <deque>
|
||||||
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
// String formatters (required by below containers)
|
||||||
|
|
||||||
|
extern std::string VL_TO_STRING(CData obj);
|
||||||
|
extern std::string VL_TO_STRING(SData obj);
|
||||||
|
extern std::string VL_TO_STRING(IData obj);
|
||||||
|
extern std::string VL_TO_STRING(QData obj);
|
||||||
|
inline std::string VL_TO_STRING(const std::string& obj) { return "\""+obj+"\""; }
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
// Verilog array container
|
||||||
|
// Similar to std::array<WData, N>, but:
|
||||||
|
// 1. Doesn't require C++11
|
||||||
|
// 2. Lighter weight, only methods needed by Verilator, to help compile time.
|
||||||
|
//
|
||||||
|
// This is only used when we need an upper-level container and so can't
|
||||||
|
// simply use a C style array (which is just a pointer).
|
||||||
|
|
||||||
|
template <std::size_t T_Words> class VlWide {
|
||||||
|
WData m_storage[T_Words];
|
||||||
|
public:
|
||||||
|
// Default constructor/destructor/copy are fine
|
||||||
|
const WData& at(size_t index) const { return m_storage[index]; }
|
||||||
|
WData& at(size_t index) { return m_storage[index]; }
|
||||||
|
WData* data() { return &m_storage[0]; }
|
||||||
|
const WData* data() const { return &m_storage[0]; }
|
||||||
|
bool operator<(const VlWide<T_Words>& rhs) const {
|
||||||
|
return VL_LT_W(T_Words, data(), rhs.data());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Convert a C array to std::array reference by pointer magic, without copy.
|
||||||
|
// Data type (second argument) is so the function template can automatically generate.
|
||||||
|
template <std::size_t T_Words>
|
||||||
|
VlWide<T_Words>& VL_CVT_W_A(WDataInP inp, const VlWide<T_Words>&) {
|
||||||
|
return *((VlWide<T_Words>*)inp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
// Verilog associative array container
|
||||||
|
// There are no multithreaded locks on this; the base variable must
|
||||||
|
// be protected by other means
|
||||||
|
//
|
||||||
|
template <class T_Key, class T_Value> class VlAssocArray {
|
||||||
|
private:
|
||||||
|
// TYPES
|
||||||
|
typedef std::map<T_Key, T_Value> Map;
|
||||||
|
public:
|
||||||
|
typedef typename Map::const_iterator const_iterator;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// MEMBERS
|
||||||
|
Map m_map; // State of the assoc array
|
||||||
|
T_Value m_defaultValue; // Default value
|
||||||
|
|
||||||
|
public:
|
||||||
|
// CONSTRUCTORS
|
||||||
|
VlAssocArray() {
|
||||||
|
// m_defaultValue isn't defaulted. Caller's constructor must do it.
|
||||||
|
}
|
||||||
|
~VlAssocArray() {}
|
||||||
|
// Standard copy constructor works. Verilog: assoca = assocb
|
||||||
|
|
||||||
|
// METHODS
|
||||||
|
T_Value& atDefault() { return m_defaultValue; }
|
||||||
|
|
||||||
|
// Size of array. Verilog: function int size(), or int num()
|
||||||
|
int size() const { return m_map.size(); }
|
||||||
|
// Clear array. Verilog: function void delete([input index])
|
||||||
|
void clear() { m_map.clear(); }
|
||||||
|
void erase(const T_Key& index) { m_map.erase(index); }
|
||||||
|
// Return 0/1 if element exists. Verilog: function int exists(input index)
|
||||||
|
int exists(const T_Key& index) const { return m_map.find(index) != m_map.end(); }
|
||||||
|
// Return first element. Verilog: function int first(ref index);
|
||||||
|
int first(T_Key& indexr) const {
|
||||||
|
typename Map::const_iterator it = m_map.begin();
|
||||||
|
if (it == m_map.end()) return 0;
|
||||||
|
indexr = it->first;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// Return last element. Verilog: function int last(ref index)
|
||||||
|
int last(T_Key& indexr) const {
|
||||||
|
typename Map::const_reverse_iterator it = m_map.rbegin();
|
||||||
|
if (it == m_map.rend()) return 0;
|
||||||
|
indexr = it->first;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// Return next element. Verilog: function int next(ref index)
|
||||||
|
int next(T_Key& indexr) const {
|
||||||
|
typename Map::const_iterator it = m_map.find(indexr);
|
||||||
|
if (VL_UNLIKELY(it == m_map.end())) return 0;
|
||||||
|
it++;
|
||||||
|
if (VL_UNLIKELY(it == m_map.end())) return 0;
|
||||||
|
indexr = it->first;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// Return prev element. Verilog: function int prev(ref index)
|
||||||
|
int prev(T_Key& indexr) const {
|
||||||
|
typename Map::const_iterator it = m_map.find(indexr);
|
||||||
|
if (VL_UNLIKELY(it == m_map.end())) return 0;
|
||||||
|
if (VL_UNLIKELY(it == m_map.begin())) return 0;
|
||||||
|
--it;
|
||||||
|
indexr = it->first;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
// Setting. Verilog: assoc[index] = v
|
||||||
|
// Can't just overload operator[] or provide a "at" reference to set,
|
||||||
|
// because we need to be able to insert only when the value is set
|
||||||
|
T_Value& at(const T_Key& index) {
|
||||||
|
typename Map::iterator it = m_map.find(index);
|
||||||
|
if (it == m_map.end()) {
|
||||||
|
std::pair<typename Map::iterator, bool> pit
|
||||||
|
= m_map.insert(std::make_pair(index, m_defaultValue));
|
||||||
|
return pit.first->second;
|
||||||
|
}
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
// Accessing. Verilog: v = assoc[index]
|
||||||
|
const T_Value& at(const T_Key& index) const {
|
||||||
|
typename Map::iterator it = m_map.find(index);
|
||||||
|
if (it == m_map.end()) return m_defaultValue;
|
||||||
|
else return it->second;
|
||||||
|
}
|
||||||
|
// For save/restore
|
||||||
|
const_iterator begin() const { return m_map.begin(); }
|
||||||
|
const_iterator end() const { return m_map.end(); }
|
||||||
|
|
||||||
|
// Dumping. Verilog: str = $sformatf("%p", assoc)
|
||||||
|
std::string to_string() const {
|
||||||
|
std::string out = "'{";
|
||||||
|
std::string comma;
|
||||||
|
for (typename Map::const_iterator it = m_map.begin(); it != m_map.end(); ++it) {
|
||||||
|
out += comma + VL_TO_STRING(it->first) + ":" + VL_TO_STRING(it->second);
|
||||||
|
comma = ", ";
|
||||||
|
}
|
||||||
|
// Default not printed - maybe random init data
|
||||||
|
return out + "} ";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T_Key, class T_Value>
|
||||||
|
std::string VL_TO_STRING(const VlAssocArray<T_Key, T_Value>& obj) {
|
||||||
|
return obj.to_string();
|
||||||
|
}
|
||||||
|
|
||||||
|
//===================================================================
|
||||||
|
// Verilog queue container
|
||||||
|
// There are no multithreaded locks on this; the base variable must
|
||||||
|
// be protected by other means
|
||||||
|
//
|
||||||
|
template <class T_Value> class VlQueue {
|
||||||
|
private:
|
||||||
|
// TYPES
|
||||||
|
typedef std::deque<T_Value> Deque;
|
||||||
|
public:
|
||||||
|
typedef typename Deque::const_iterator const_iterator;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// MEMBERS
|
||||||
|
Deque m_deque; // State of the assoc array
|
||||||
|
T_Value m_defaultValue; // Default value
|
||||||
|
|
||||||
|
public:
|
||||||
|
// CONSTRUCTORS
|
||||||
|
VlQueue() {
|
||||||
|
// m_defaultValue isn't defaulted. Caller's constructor must do it.
|
||||||
|
}
|
||||||
|
~VlQueue() {}
|
||||||
|
// Standard copy constructor works. Verilog: assoca = assocb
|
||||||
|
|
||||||
|
// METHODS
|
||||||
|
T_Value& atDefault() { return m_defaultValue; }
|
||||||
|
|
||||||
|
// Size. Verilog: function int size(), or int num()
|
||||||
|
int size() const { return m_deque.size(); }
|
||||||
|
// Clear array. Verilog: function void delete([input index])
|
||||||
|
void clear() { m_deque.clear(); }
|
||||||
|
void erase(size_t index) { if (VL_LIKELY(index < m_deque.size())) m_deque.erase(index); }
|
||||||
|
|
||||||
|
// function void q.push_front(value)
|
||||||
|
void push_front(const T_Value& value) { m_deque.push_front(value); }
|
||||||
|
// function void q.push_back(value)
|
||||||
|
void push_back(const T_Value& value) { m_deque.push_back(value); }
|
||||||
|
// function value_t q.pop_front();
|
||||||
|
T_Value pop_front() {
|
||||||
|
if (m_deque.empty()) return m_defaultValue;
|
||||||
|
T_Value v = m_deque.front(); m_deque.pop_front(); return v;
|
||||||
|
}
|
||||||
|
// function value_t q.pop_back();
|
||||||
|
T_Value pop_back() {
|
||||||
|
if (m_deque.empty()) return m_defaultValue;
|
||||||
|
T_Value v = m_deque.back(); m_deque.pop_back(); return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setting. Verilog: assoc[index] = v
|
||||||
|
// Can't just overload operator[] or provide a "at" reference to set,
|
||||||
|
// because we need to be able to insert only when the value is set
|
||||||
|
T_Value& at(size_t index) {
|
||||||
|
static T_Value s_throwAway;
|
||||||
|
if (VL_UNLIKELY(index >= m_deque.size())) {
|
||||||
|
s_throwAway = atDefault();
|
||||||
|
return s_throwAway;
|
||||||
|
}
|
||||||
|
else return m_deque[index];
|
||||||
|
}
|
||||||
|
// Accessing. Verilog: v = assoc[index]
|
||||||
|
const T_Value& at(size_t index) const {
|
||||||
|
static T_Value s_throwAway;
|
||||||
|
if (VL_UNLIKELY(index >= m_deque.size())) return atDefault();
|
||||||
|
else return m_deque[index];
|
||||||
|
}
|
||||||
|
// function void q.insert(index, value);
|
||||||
|
void insert(size_t index, const T_Value& value) {
|
||||||
|
if (VL_UNLIKELY(index >= m_deque.size())) return;
|
||||||
|
m_deque[index] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For save/restore
|
||||||
|
const_iterator begin() const { return m_deque.begin(); }
|
||||||
|
const_iterator end() const { return m_deque.end(); }
|
||||||
|
|
||||||
|
// Dumping. Verilog: str = $sformatf("%p", assoc)
|
||||||
|
std::string to_string() const {
|
||||||
|
std::string out = "'{";
|
||||||
|
std::string comma;
|
||||||
|
for (typename Deque::const_iterator it = m_deque.begin(); it != m_deque.end(); ++it) {
|
||||||
|
out += comma + VL_TO_STRING(*it);
|
||||||
|
comma = ", ";
|
||||||
|
}
|
||||||
|
return out + "} ";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T_Value>
|
||||||
|
std::string VL_TO_STRING(const VlQueue<T_Value>& obj) {
|
||||||
|
return obj.to_string();
|
||||||
|
}
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// Conversion functions
|
// Conversion functions
|
||||||
|
|
||||||
@@ -49,7 +289,7 @@ inline std::string VL_CVT_PACK_STR_NI(IData lhs) VL_PURE {
|
|||||||
return VL_CVT_PACK_STR_NW(1, lw);
|
return VL_CVT_PACK_STR_NW(1, lw);
|
||||||
}
|
}
|
||||||
inline std::string VL_CONCATN_NNN(const std::string& lhs, const std::string& rhs) VL_PURE {
|
inline std::string VL_CONCATN_NNN(const std::string& lhs, const std::string& rhs) VL_PURE {
|
||||||
return lhs+rhs;
|
return lhs + rhs;
|
||||||
}
|
}
|
||||||
inline std::string VL_REPLICATEN_NNQ(int,int,int, const std::string& lhs, IData rep) VL_PURE {
|
inline std::string VL_REPLICATEN_NNQ(int,int,int, const std::string& lhs, IData rep) VL_PURE {
|
||||||
std::string out; out.reserve(lhs.length() * rep);
|
std::string out; out.reserve(lhs.length() * rep);
|
||||||
@@ -62,6 +302,8 @@ inline std::string VL_REPLICATEN_NNI(int obits,int lbits,int rbits,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline IData VL_LEN_IN(const std::string& ld) { return ld.length(); }
|
inline IData VL_LEN_IN(const std::string& ld) { return ld.length(); }
|
||||||
|
extern std::string VL_TOLOWER_NN(const std::string& ld);
|
||||||
|
extern std::string VL_TOUPPER_NN(const std::string& ld);
|
||||||
|
|
||||||
extern IData VL_FOPEN_NI(const std::string& filename, IData mode) VL_MT_SAFE;
|
extern IData VL_FOPEN_NI(const std::string& filename, IData mode) VL_MT_SAFE;
|
||||||
extern void VL_READMEM_N(bool hex, int width, int depth, int array_lsb,
|
extern void VL_READMEM_N(bool hex, int width, int depth, int array_lsb,
|
||||||
@@ -76,18 +318,36 @@ extern void VL_SFORMAT_X(int obits_ignored, std::string& output,
|
|||||||
const char* formatp, ...) VL_MT_SAFE;
|
const char* formatp, ...) VL_MT_SAFE;
|
||||||
extern std::string VL_SFORMATF_NX(const char* formatp, ...) VL_MT_SAFE;
|
extern std::string VL_SFORMATF_NX(const char* formatp, ...) VL_MT_SAFE;
|
||||||
extern IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) VL_MT_SAFE;
|
extern IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) VL_MT_SAFE;
|
||||||
inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, IData& rdr) VL_MT_SAFE {
|
inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, CData& rdr) VL_MT_SAFE {
|
||||||
WData rwp[2]; // WData must always be at least 2
|
WData rwp[2]; // WData must always be at least 2
|
||||||
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
|
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
|
||||||
if (got) rdr = rwp[0];
|
if (got) rdr = rwp[0];
|
||||||
return got;
|
return got;
|
||||||
}
|
}
|
||||||
|
inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, SData& rdr) VL_MT_SAFE {
|
||||||
|
WData rwp[2]; // WData must always be at least 2
|
||||||
|
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
|
||||||
|
if (got) rdr = rwp[0];
|
||||||
|
return got;
|
||||||
|
}
|
||||||
|
inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, IData& rdr) VL_MT_SAFE {
|
||||||
|
WData rwp[2]; // WData must always be at least 2
|
||||||
|
IData got = VL_VALUEPLUSARGS_INW(rbits, ld, rwp);
|
||||||
|
if (got) rdr = rwp[0];
|
||||||
|
return got;
|
||||||
|
}
|
||||||
inline IData VL_VALUEPLUSARGS_INQ(int rbits, const std::string& ld, QData& rdr) VL_MT_SAFE {
|
inline IData VL_VALUEPLUSARGS_INQ(int rbits, const std::string& ld, QData& rdr) VL_MT_SAFE {
|
||||||
WData rwp[2];
|
WData rwp[2];
|
||||||
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
|
IData got = VL_VALUEPLUSARGS_INW(rbits, ld, rwp);
|
||||||
if (got) rdr = VL_SET_QW(rwp);
|
if (got) rdr = VL_SET_QW(rwp);
|
||||||
return got;
|
return got;
|
||||||
}
|
}
|
||||||
|
inline IData VL_VALUEPLUSARGS_INQ(int rbits, const std::string& ld, double& rdr) VL_MT_SAFE {
|
||||||
|
WData rwp[2];
|
||||||
|
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
|
||||||
|
if (got) rdr = VL_CVT_D_Q(VL_SET_QW(rwp));
|
||||||
|
return got;
|
||||||
|
}
|
||||||
extern IData VL_VALUEPLUSARGS_INN(int, const std::string& ld, std::string& rdr) VL_MT_SAFE;
|
extern IData VL_VALUEPLUSARGS_INN(int, const std::string& ld, std::string& rdr) VL_MT_SAFE;
|
||||||
|
|
||||||
#endif // Guard
|
#endif // Guard
|
||||||
|
|||||||
+29
-26
@@ -16,11 +16,10 @@
|
|||||||
/// \file
|
/// \file
|
||||||
/// \brief Verilator: Implementation Header, only for verilated.cpp internals.
|
/// \brief Verilator: Implementation Header, only for verilated.cpp internals.
|
||||||
///
|
///
|
||||||
/// Code available from: http://www.veripool.org/verilator
|
/// Code available from: https://verilator.org
|
||||||
///
|
///
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
|
|
||||||
#ifndef _VERILATED_IMP_H_
|
#ifndef _VERILATED_IMP_H_
|
||||||
#define _VERILATED_IMP_H_ 1 ///< Header Guard
|
#define _VERILATED_IMP_H_ 1 ///< Header Guard
|
||||||
|
|
||||||
@@ -62,7 +61,8 @@ private:
|
|||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VerilatedMsg(const std::function<void()>& cb)
|
VerilatedMsg(const std::function<void()>& cb)
|
||||||
: m_mtaskId(Verilated::mtaskId()), m_cb(cb) {}
|
: m_mtaskId(Verilated::mtaskId())
|
||||||
|
, m_cb(cb) {}
|
||||||
~VerilatedMsg() {}
|
~VerilatedMsg() {}
|
||||||
// METHODS
|
// METHODS
|
||||||
vluint32_t mtaskId() const { return m_mtaskId; }
|
vluint32_t mtaskId() const { return m_mtaskId; }
|
||||||
@@ -73,7 +73,7 @@ public:
|
|||||||
/// Each thread has a queue it pushes to
|
/// Each thread has a queue it pushes to
|
||||||
/// This assumes no thread starts pushing the next tick until the previous has drained.
|
/// This assumes no thread starts pushing the next tick until the previous has drained.
|
||||||
/// If more aggressiveness is needed, a double-buffered scheme might work well.
|
/// If more aggressiveness is needed, a double-buffered scheme might work well.
|
||||||
class VerilatedEvalMsgQueue {
|
class VerilatedEvalMsgQueue {
|
||||||
typedef std::multiset<VerilatedMsg, VerilatedMsg::Cmp> VerilatedThreadQueue;
|
typedef std::multiset<VerilatedMsg, VerilatedMsg::Cmp> VerilatedThreadQueue;
|
||||||
|
|
||||||
std::atomic<vluint64_t> m_depth; ///< Current depth of queue (see comments below)
|
std::atomic<vluint64_t> m_depth; ///< Current depth of queue (see comments below)
|
||||||
@@ -82,10 +82,12 @@ class VerilatedEvalMsgQueue {
|
|||||||
VerilatedThreadQueue m_queue VL_GUARDED_BY(m_mutex); ///< Message queue
|
VerilatedThreadQueue m_queue VL_GUARDED_BY(m_mutex); ///< Message queue
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VerilatedEvalMsgQueue() : m_depth(0) {
|
VerilatedEvalMsgQueue()
|
||||||
|
: m_depth(0) {
|
||||||
assert(atomic_is_lock_free(&m_depth));
|
assert(atomic_is_lock_free(&m_depth));
|
||||||
}
|
}
|
||||||
~VerilatedEvalMsgQueue() { }
|
~VerilatedEvalMsgQueue() {}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VL_UNCOPYABLE(VerilatedEvalMsgQueue);
|
VL_UNCOPYABLE(VerilatedEvalMsgQueue);
|
||||||
public:
|
public:
|
||||||
@@ -122,11 +124,11 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// Each thread has a local queue to build up messages until the end of the eval() call
|
/// Each thread has a local queue to build up messages until the end of the eval() call
|
||||||
class VerilatedThreadMsgQueue {
|
class VerilatedThreadMsgQueue {
|
||||||
std::queue<VerilatedMsg> m_queue;
|
std::queue<VerilatedMsg> m_queue;
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VerilatedThreadMsgQueue() { }
|
VerilatedThreadMsgQueue() {}
|
||||||
~VerilatedThreadMsgQueue() {
|
~VerilatedThreadMsgQueue() {
|
||||||
// The only call of this with a non-empty queue is a fatal error.
|
// The only call of this with a non-empty queue is a fatal error.
|
||||||
// So this does not flush the queue, as the destination queue is not known to this class.
|
// So this does not flush the queue, as the destination queue is not known to this class.
|
||||||
@@ -170,8 +172,8 @@ class VerilatedImp {
|
|||||||
|
|
||||||
// TYPES
|
// TYPES
|
||||||
typedef std::vector<std::string> ArgVec;
|
typedef std::vector<std::string> ArgVec;
|
||||||
typedef std::map<std::pair<const void*,void*>,void*> UserMap;
|
typedef std::map<std::pair<const void*, void*>, void*> UserMap;
|
||||||
typedef std::map<const char*, int, VerilatedCStrCmp> ExportNameMap;
|
typedef std::map<const char*, int, VerilatedCStrCmp> ExportNameMap;
|
||||||
|
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
static VerilatedImp s_s; ///< Static Singleton; One and only static this
|
static VerilatedImp s_s; ///< Static Singleton; One and only static this
|
||||||
@@ -204,7 +206,8 @@ class VerilatedImp {
|
|||||||
public: // But only for verilated*.cpp
|
public: // But only for verilated*.cpp
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VerilatedImp()
|
VerilatedImp()
|
||||||
: m_argVecLoaded(false), m_exportNext(0) {
|
: m_argVecLoaded(false)
|
||||||
|
, m_exportNext(0) {
|
||||||
m_fdps.resize(3);
|
m_fdps.resize(3);
|
||||||
m_fdps[0] = stdin;
|
m_fdps[0] = stdin;
|
||||||
m_fdps[1] = stdout;
|
m_fdps[1] = stdout;
|
||||||
@@ -232,9 +235,9 @@ public:
|
|||||||
"%Error: Verilog called $test$plusargs or $value$plusargs without"
|
"%Error: Verilog called $test$plusargs or $value$plusargs without"
|
||||||
" testbench C first calling Verilated::commandArgs(argc,argv).");
|
" testbench C first calling Verilated::commandArgs(argc,argv).");
|
||||||
}
|
}
|
||||||
for (ArgVec::const_iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) {
|
for (ArgVec::const_iterator it = s_s.m_argVec.begin(); it != s_s.m_argVec.end(); ++it) {
|
||||||
if ((*it)[0]=='+') {
|
if ((*it)[0] == '+') {
|
||||||
if (0==strncmp(prefixp, it->c_str()+1, len)) return *it;
|
if (0 == strncmp(prefixp, it->c_str() + 1, len)) return *it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
@@ -252,7 +255,7 @@ public:
|
|||||||
// per map overhead * N scopes would take much more space and cache thrashing.
|
// per map overhead * N scopes would take much more space and cache thrashing.
|
||||||
static inline void userInsert(const void* scopep, void* userKey, void* userData) VL_MT_SAFE {
|
static inline void userInsert(const void* scopep, void* userKey, void* userData) VL_MT_SAFE {
|
||||||
VerilatedLockGuard lock(s_s.m_userMapMutex);
|
VerilatedLockGuard lock(s_s.m_userMapMutex);
|
||||||
UserMap::iterator it=s_s.m_userMap.find(std::make_pair(scopep, userKey));
|
UserMap::iterator it = s_s.m_userMap.find(std::make_pair(scopep, userKey));
|
||||||
if (it != s_s.m_userMap.end()) it->second = userData;
|
if (it != s_s.m_userMap.end()) it->second = userData;
|
||||||
// When we support VL_THREADs, we need a lock around this insert, as it's runtime
|
// When we support VL_THREADs, we need a lock around this insert, as it's runtime
|
||||||
else s_s.m_userMap.insert(it, std::make_pair(std::make_pair(scopep, userKey), userData));
|
else s_s.m_userMap.insert(it, std::make_pair(std::make_pair(scopep, userKey), userData));
|
||||||
@@ -268,7 +271,7 @@ private:
|
|||||||
static void userEraseScope(const VerilatedScope* scopep) VL_MT_SAFE {
|
static void userEraseScope(const VerilatedScope* scopep) VL_MT_SAFE {
|
||||||
// Slow ok - called once/scope on destruction, so we simply iterate.
|
// Slow ok - called once/scope on destruction, so we simply iterate.
|
||||||
VerilatedLockGuard lock(s_s.m_userMapMutex);
|
VerilatedLockGuard lock(s_s.m_userMapMutex);
|
||||||
for (UserMap::iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ) {
|
for (UserMap::iterator it = s_s.m_userMap.begin(); it != s_s.m_userMap.end();) {
|
||||||
if (it->first.first == scopep) {
|
if (it->first.first == scopep) {
|
||||||
s_s.m_userMap.erase(it++);
|
s_s.m_userMap.erase(it++);
|
||||||
} else {
|
} else {
|
||||||
@@ -291,7 +294,7 @@ public: // But only for verilated*.cpp
|
|||||||
static void scopeInsert(const VerilatedScope* scopep) VL_MT_SAFE {
|
static void scopeInsert(const VerilatedScope* scopep) VL_MT_SAFE {
|
||||||
// Slow ok - called once/scope at construction
|
// Slow ok - called once/scope at construction
|
||||||
VerilatedLockGuard lock(s_s.m_nameMutex);
|
VerilatedLockGuard lock(s_s.m_nameMutex);
|
||||||
VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
|
VerilatedScopeNameMap::iterator it = s_s.m_nameMap.find(scopep->name());
|
||||||
if (it == s_s.m_nameMap.end()) {
|
if (it == s_s.m_nameMap.end()) {
|
||||||
s_s.m_nameMap.insert(it, std::make_pair(scopep->name(), scopep));
|
s_s.m_nameMap.insert(it, std::make_pair(scopep->name(), scopep));
|
||||||
}
|
}
|
||||||
@@ -307,14 +310,14 @@ public: // But only for verilated*.cpp
|
|||||||
// Slow ok - called once/scope at destruction
|
// Slow ok - called once/scope at destruction
|
||||||
VerilatedLockGuard lock(s_s.m_nameMutex);
|
VerilatedLockGuard lock(s_s.m_nameMutex);
|
||||||
userEraseScope(scopep);
|
userEraseScope(scopep);
|
||||||
VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
|
VerilatedScopeNameMap::iterator it = s_s.m_nameMap.find(scopep->name());
|
||||||
if (it != s_s.m_nameMap.end()) s_s.m_nameMap.erase(it);
|
if (it != s_s.m_nameMap.end()) s_s.m_nameMap.erase(it);
|
||||||
}
|
}
|
||||||
static void scopesDump() VL_MT_SAFE {
|
static void scopesDump() VL_MT_SAFE {
|
||||||
VerilatedLockGuard lock(s_s.m_nameMutex);
|
VerilatedLockGuard lock(s_s.m_nameMutex);
|
||||||
VL_PRINTF_MT(" scopesDump:\n");
|
VL_PRINTF_MT(" scopesDump:\n");
|
||||||
for (VerilatedScopeNameMap::const_iterator it=s_s.m_nameMap.begin();
|
for (VerilatedScopeNameMap::const_iterator it = s_s.m_nameMap.begin();
|
||||||
it!=s_s.m_nameMap.end(); ++it) {
|
it != s_s.m_nameMap.end(); ++it) {
|
||||||
const VerilatedScope* scopep = it->second;
|
const VerilatedScope* scopep = it->second;
|
||||||
scopep->scopeDump();
|
scopep->scopeDump();
|
||||||
}
|
}
|
||||||
@@ -349,7 +352,7 @@ public: // But only for verilated*.cpp
|
|||||||
static int exportInsert(const char* namep) VL_MT_SAFE {
|
static int exportInsert(const char* namep) VL_MT_SAFE {
|
||||||
// Slow ok - called once/function at creation
|
// Slow ok - called once/function at creation
|
||||||
VerilatedLockGuard lock(s_s.m_exportMutex);
|
VerilatedLockGuard lock(s_s.m_exportMutex);
|
||||||
ExportNameMap::iterator it=s_s.m_exportMap.find(namep);
|
ExportNameMap::iterator it = s_s.m_exportMap.find(namep);
|
||||||
if (it == s_s.m_exportMap.end()) {
|
if (it == s_s.m_exportMap.end()) {
|
||||||
s_s.m_exportMap.insert(it, std::make_pair(namep, s_s.m_exportNext++));
|
s_s.m_exportMap.insert(it, std::make_pair(namep, s_s.m_exportNext++));
|
||||||
return s_s.m_exportNext++;
|
return s_s.m_exportNext++;
|
||||||
@@ -359,7 +362,7 @@ public: // But only for verilated*.cpp
|
|||||||
}
|
}
|
||||||
static int exportFind(const char* namep) VL_MT_SAFE {
|
static int exportFind(const char* namep) VL_MT_SAFE {
|
||||||
VerilatedLockGuard lock(s_s.m_exportMutex);
|
VerilatedLockGuard lock(s_s.m_exportMutex);
|
||||||
ExportNameMap::const_iterator it=s_s.m_exportMap.find(namep);
|
ExportNameMap::const_iterator it = s_s.m_exportMap.find(namep);
|
||||||
if (VL_LIKELY(it != s_s.m_exportMap.end())) return it->second;
|
if (VL_LIKELY(it != s_s.m_exportMap.end())) return it->second;
|
||||||
std::string msg = (std::string("%Error: Testbench C called ")+namep
|
std::string msg = (std::string("%Error: Testbench C called ")+namep
|
||||||
+" but no such DPI export function name exists in ANY model");
|
+" but no such DPI export function name exists in ANY model");
|
||||||
@@ -369,8 +372,8 @@ public: // But only for verilated*.cpp
|
|||||||
static const char* exportName(int funcnum) VL_MT_SAFE {
|
static const char* exportName(int funcnum) VL_MT_SAFE {
|
||||||
// Slowpath; find name for given export; errors only so no map to reverse-map it
|
// Slowpath; find name for given export; errors only so no map to reverse-map it
|
||||||
VerilatedLockGuard lock(s_s.m_exportMutex);
|
VerilatedLockGuard lock(s_s.m_exportMutex);
|
||||||
for (ExportNameMap::const_iterator it=s_s.m_exportMap.begin();
|
for (ExportNameMap::const_iterator it = s_s.m_exportMap.begin();
|
||||||
it!=s_s.m_exportMap.end(); ++it) {
|
it != s_s.m_exportMap.end(); ++it) {
|
||||||
if (it->second == funcnum) return it->first;
|
if (it->second == funcnum) return it->first;
|
||||||
}
|
}
|
||||||
return "*UNKNOWN*";
|
return "*UNKNOWN*";
|
||||||
@@ -406,7 +409,7 @@ public: // But only for verilated*.cpp
|
|||||||
static void fdDelete(IData fdi) VL_MT_SAFE {
|
static void fdDelete(IData fdi) VL_MT_SAFE {
|
||||||
IData idx = VL_MASK_I(31) & fdi;
|
IData idx = VL_MASK_I(31) & fdi;
|
||||||
VerilatedLockGuard lock(s_s.m_fdMutex);
|
VerilatedLockGuard lock(s_s.m_fdMutex);
|
||||||
if (VL_UNLIKELY(!(fdi & (1ULL<<31)) || idx >= s_s.m_fdps.size())) return;
|
if (VL_UNLIKELY(!(fdi & (VL_ULL(1) << 31)) || idx >= s_s.m_fdps.size())) return;
|
||||||
if (VL_UNLIKELY(!s_s.m_fdps[idx])) return; // Already free
|
if (VL_UNLIKELY(!s_s.m_fdps[idx])) return; // Already free
|
||||||
s_s.m_fdps[idx] = NULL;
|
s_s.m_fdps[idx] = NULL;
|
||||||
s_s.m_fdFree.push_back(idx);
|
s_s.m_fdFree.push_back(idx);
|
||||||
@@ -414,7 +417,7 @@ public: // But only for verilated*.cpp
|
|||||||
static inline FILE* fdToFp(IData fdi) VL_MT_SAFE {
|
static inline FILE* fdToFp(IData fdi) VL_MT_SAFE {
|
||||||
IData idx = VL_MASK_I(31) & fdi;
|
IData idx = VL_MASK_I(31) & fdi;
|
||||||
VerilatedLockGuard lock(s_s.m_fdMutex); // This might get slow, if it does we can cache it
|
VerilatedLockGuard lock(s_s.m_fdMutex); // This might get slow, if it does we can cache it
|
||||||
if (VL_UNLIKELY(!(fdi & (1ULL<<31)) || idx >= s_s.m_fdps.size())) return NULL;
|
if (VL_UNLIKELY(!(fdi & (VL_ULL(1) << 31)) || idx >= s_s.m_fdps.size())) return NULL;
|
||||||
return s_s.m_fdps[idx];
|
return s_s.m_fdps[idx];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#define _VERILATED_SAVE_C_H_ 1
|
#define _VERILATED_SAVE_C_H_ 1
|
||||||
|
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
|
#include "verilated_heavy.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
@@ -51,7 +52,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
VerilatedSerialize() {
|
VerilatedSerialize() {
|
||||||
m_isOpen = false;
|
m_isOpen = false;
|
||||||
m_bufp = new vluint8_t [bufferSize()];
|
m_bufp = new vluint8_t[bufferSize()];
|
||||||
m_cp = m_bufp;
|
m_cp = m_bufp;
|
||||||
}
|
}
|
||||||
virtual ~VerilatedSerialize() {
|
virtual ~VerilatedSerialize() {
|
||||||
@@ -112,7 +113,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
VerilatedDeserialize() {
|
VerilatedDeserialize() {
|
||||||
m_isOpen = false;
|
m_isOpen = false;
|
||||||
m_bufp = new vluint8_t [bufferSize()];
|
m_bufp = new vluint8_t[bufferSize()];
|
||||||
m_cp = m_bufp;
|
m_cp = m_bufp;
|
||||||
m_endp = NULL;
|
m_endp = NULL;
|
||||||
}
|
}
|
||||||
@@ -158,11 +159,11 @@ private:
|
|||||||
|
|
||||||
class VerilatedSave : public VerilatedSerialize {
|
class VerilatedSave : public VerilatedSerialize {
|
||||||
private:
|
private:
|
||||||
int m_fd; ///< File descriptor we're writing to
|
int m_fd; ///< File descriptor we're writing to
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VerilatedSave() { m_fd=-1; }
|
VerilatedSave() { m_fd = -1; }
|
||||||
virtual ~VerilatedSave() { close(); }
|
virtual ~VerilatedSave() { close(); }
|
||||||
// METHODS
|
// METHODS
|
||||||
void open(const char* filenamep) VL_MT_UNSAFE_ONE; ///< Open the file; call isOpen() to see if errors
|
void open(const char* filenamep) VL_MT_UNSAFE_ONE; ///< Open the file; call isOpen() to see if errors
|
||||||
@@ -177,11 +178,11 @@ public:
|
|||||||
|
|
||||||
class VerilatedRestore : public VerilatedDeserialize {
|
class VerilatedRestore : public VerilatedDeserialize {
|
||||||
private:
|
private:
|
||||||
int m_fd; ///< File descriptor we're writing to
|
int m_fd; ///< File descriptor we're writing to
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VerilatedRestore() { m_fd=-1; }
|
VerilatedRestore() { m_fd = -1; }
|
||||||
virtual ~VerilatedRestore() { close(); }
|
virtual ~VerilatedRestore() { close(); }
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
@@ -247,5 +248,33 @@ inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, std::string& r
|
|||||||
rhs.resize(len);
|
rhs.resize(len);
|
||||||
return os.read((void*)rhs.data(), len);
|
return os.read((void*)rhs.data(), len);
|
||||||
}
|
}
|
||||||
|
template <class T_Key, class T_Value>
|
||||||
|
VerilatedSerialize& operator<<(VerilatedSerialize& os, VlAssocArray<T_Key, T_Value>& rhs) {
|
||||||
|
os << rhs.atDefault();
|
||||||
|
vluint32_t len = rhs.size();
|
||||||
|
os << len;
|
||||||
|
for (typename VlAssocArray<T_Key, T_Value>::const_iterator it = rhs.begin();
|
||||||
|
it != rhs.end(); ++it) {
|
||||||
|
T_Key index = it->first; // Copy to get around const_iterator
|
||||||
|
T_Value value = it->second;
|
||||||
|
os << index << value;
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
template <class T_Key, class T_Value>
|
||||||
|
VerilatedDeserialize& operator>>(VerilatedDeserialize& os, VlAssocArray<T_Key, T_Value>& rhs) {
|
||||||
|
os >> rhs.atDefault();
|
||||||
|
vluint32_t len = 0;
|
||||||
|
os >> len;
|
||||||
|
rhs.clear();
|
||||||
|
for (vluint32_t i = 0; i < len; ++i) {
|
||||||
|
T_Key index;
|
||||||
|
T_Value value;
|
||||||
|
os >> index;
|
||||||
|
os >> value;
|
||||||
|
rhs.at(index) = value;
|
||||||
|
}
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // Guard
|
#endif // Guard
|
||||||
|
|||||||
@@ -19,11 +19,10 @@
|
|||||||
/// This file is included automatically by Verilator at the top of
|
/// This file is included automatically by Verilator at the top of
|
||||||
/// all SystemC files it generates.
|
/// all SystemC files it generates.
|
||||||
///
|
///
|
||||||
/// Code available from: http://www.veripool.org/verilator
|
/// Code available from: https://verilator.org
|
||||||
///
|
///
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
|
|
||||||
#ifndef _VERILATED_SC_H_
|
#ifndef _VERILATED_SC_H_
|
||||||
#define _VERILATED_SC_H_ 1 ///< Header Guard
|
#define _VERILATED_SC_H_ 1 ///< Header Guard
|
||||||
|
|
||||||
|
|||||||
@@ -24,11 +24,10 @@
|
|||||||
///
|
///
|
||||||
/// These classes are thread safe, and read only.
|
/// These classes are thread safe, and read only.
|
||||||
///
|
///
|
||||||
/// Code available from: http://www.veripool.org/verilator
|
/// Code available from: https://verilator.org
|
||||||
///
|
///
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
|
|
||||||
#ifndef _VERILATED_SYM_PROPS_H_
|
#ifndef _VERILATED_SYM_PROPS_H_
|
||||||
#define _VERILATED_SYM_PROPS_H_ 1 ///< Header Guard
|
#define _VERILATED_SYM_PROPS_H_ 1 ///< Header Guard
|
||||||
|
|
||||||
@@ -128,7 +127,7 @@ public:
|
|||||||
public:
|
public:
|
||||||
~VerilatedVarProps() {}
|
~VerilatedVarProps() {}
|
||||||
// METHODS
|
// METHODS
|
||||||
bool magicOk() const { return m_magic==MAGIC; }
|
bool magicOk() const { return m_magic == MAGIC; }
|
||||||
VerilatedVarType vltype() const { return m_vltype; }
|
VerilatedVarType vltype() const { return m_vltype; }
|
||||||
VerilatedVarFlags vldir() const {
|
VerilatedVarFlags vldir() const {
|
||||||
return static_cast<VerilatedVarFlags>(static_cast<int>(m_vlflags) & VLVF_MASK_DIR); }
|
return static_cast<VerilatedVarFlags>(static_cast<int>(m_vlflags) & VLVF_MASK_DIR); }
|
||||||
@@ -177,13 +176,15 @@ public:
|
|||||||
class VerilatedDpiOpenVar {
|
class VerilatedDpiOpenVar {
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
const VerilatedVarProps* m_propsp; // Variable properties
|
const VerilatedVarProps* m_propsp; // Variable properties
|
||||||
void* m_datap; // Location of data (local to thread always, so safe)
|
void* m_datap; // Location of data (local to thread always, so safe)
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VerilatedDpiOpenVar(const VerilatedVarProps* propsp, void* datap)
|
VerilatedDpiOpenVar(const VerilatedVarProps* propsp, void* datap)
|
||||||
: m_propsp(propsp), m_datap(datap) {}
|
: m_propsp(propsp)
|
||||||
|
, m_datap(datap) {}
|
||||||
VerilatedDpiOpenVar(const VerilatedVarProps* propsp, const void* datap)
|
VerilatedDpiOpenVar(const VerilatedVarProps* propsp, const void* datap)
|
||||||
: m_propsp(propsp), m_datap(const_cast<void*>(datap)) {}
|
: m_propsp(propsp)
|
||||||
|
, m_datap(const_cast<void*>(datap)) {}
|
||||||
~VerilatedDpiOpenVar() {}
|
~VerilatedDpiOpenVar() {}
|
||||||
// METHODS
|
// METHODS
|
||||||
void* datap() const { return m_datap; }
|
void* datap() const { return m_datap; }
|
||||||
@@ -211,7 +212,7 @@ public:
|
|||||||
|
|
||||||
class VerilatedVar : public VerilatedVarProps {
|
class VerilatedVar : public VerilatedVarProps {
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
void* m_datap; // Location of data
|
void* m_datap; // Location of data
|
||||||
const char* m_namep; // Name - slowpath
|
const char* m_namep; // Name - slowpath
|
||||||
protected:
|
protected:
|
||||||
friend class VerilatedScope;
|
friend class VerilatedScope;
|
||||||
|
|||||||
@@ -23,11 +23,10 @@
|
|||||||
/// These classes are thread safe and read only. It is constructed only
|
/// These classes are thread safe and read only. It is constructed only
|
||||||
/// when a model is built (from the main thread).
|
/// when a model is built (from the main thread).
|
||||||
///
|
///
|
||||||
/// Code available from: http://www.veripool.org/verilator
|
/// Code available from: https://verilator.org
|
||||||
///
|
///
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
|
|
||||||
#ifndef _VERILATED_SYMS_H_
|
#ifndef _VERILATED_SYMS_H_
|
||||||
#define _VERILATED_SYMS_H_ 1 ///< Header Guard
|
#define _VERILATED_SYMS_H_ 1 ///< Header Guard
|
||||||
|
|
||||||
@@ -43,7 +42,7 @@
|
|||||||
|
|
||||||
/// Class to sort maps keyed by const char*'s
|
/// Class to sort maps keyed by const char*'s
|
||||||
struct VerilatedCStrCmp {
|
struct VerilatedCStrCmp {
|
||||||
bool operator() (const char *a, const char *b) const {
|
bool operator() (const char* a, const char* b) const {
|
||||||
return std::strcmp(a, b) < 0;
|
return std::strcmp(a, b) < 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
std::atomic<vluint64_t> VlNotification::s_yields;
|
std::atomic<vluint64_t> VlMTaskVertex::s_yields;
|
||||||
|
|
||||||
VL_THREAD_LOCAL VlThreadPool::ProfileTrace* VlThreadPool::t_profilep = NULL;
|
VL_THREAD_LOCAL VlThreadPool::ProfileTrace* VlThreadPool::t_profilep = NULL;
|
||||||
|
|
||||||
@@ -41,7 +41,8 @@ VlMTaskVertex::VlMTaskVertex(vluint32_t upstreamDepCount)
|
|||||||
// VlWorkerThread
|
// VlWorkerThread
|
||||||
|
|
||||||
VlWorkerThread::VlWorkerThread(VlThreadPool* poolp, bool profiling)
|
VlWorkerThread::VlWorkerThread(VlThreadPool* poolp, bool profiling)
|
||||||
: m_poolp(poolp)
|
: m_ready_size(0)
|
||||||
|
, m_poolp(poolp)
|
||||||
, m_profiling(profiling)
|
, m_profiling(profiling)
|
||||||
, m_exiting(false)
|
, m_exiting(false)
|
||||||
// Must init this last -- after setting up fields that it might read:
|
// Must init this last -- after setting up fields that it might read:
|
||||||
@@ -49,12 +50,7 @@ VlWorkerThread::VlWorkerThread(VlThreadPool* poolp, bool profiling)
|
|||||||
|
|
||||||
VlWorkerThread::~VlWorkerThread() {
|
VlWorkerThread::~VlWorkerThread() {
|
||||||
m_exiting.store(true, std::memory_order_release);
|
m_exiting.store(true, std::memory_order_release);
|
||||||
{
|
wakeUp();
|
||||||
VerilatedLockGuard lk(m_mutex);
|
|
||||||
if (sleeping()) {
|
|
||||||
wakeUp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// The thread should exit; join it.
|
// The thread should exit; join it.
|
||||||
m_cthread.join();
|
m_cthread.join();
|
||||||
}
|
}
|
||||||
@@ -64,38 +60,18 @@ void VlWorkerThread::workerLoop() {
|
|||||||
m_poolp->setupProfilingClientThread();
|
m_poolp->setupProfilingClientThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
VlNotification alarm;
|
|
||||||
ExecRec work;
|
ExecRec work;
|
||||||
work.m_fnp = NULL;
|
work.m_fnp = NULL;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
bool sleep = false;
|
if (VL_LIKELY(!work.m_fnp)) {
|
||||||
if (VL_UNLIKELY(!work.m_fnp)) {
|
dequeWork(&work);
|
||||||
// Look for work
|
|
||||||
VerilatedLockGuard lk(m_mutex);
|
|
||||||
if (VL_LIKELY(!m_ready.empty())) {
|
|
||||||
dequeWork(&work);
|
|
||||||
} else {
|
|
||||||
// No work available, prepare to sleep. Pass alarm/work
|
|
||||||
// into m_sleepAlarm so wakeUp will tall this function.
|
|
||||||
//
|
|
||||||
// Must modify m_sleepAlarm in the same critical section as
|
|
||||||
// the check for ready work, otherwise we could race with
|
|
||||||
// another thread enqueueing work and never be awoken.
|
|
||||||
m_sleepAlarm.first = &alarm;
|
|
||||||
m_sleepAlarm.second = &work;
|
|
||||||
sleep = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do this here, not above, to avoid a race with the destructor.
|
// Do this here, not above, to avoid a race with the destructor.
|
||||||
if (VL_UNLIKELY(m_exiting.load(std::memory_order_acquire)))
|
if (VL_UNLIKELY(m_exiting.load(std::memory_order_acquire)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (VL_UNLIKELY(sleep)) {
|
|
||||||
alarm.waitForNotification(); // ZZZzzzzz
|
|
||||||
alarm.reset();
|
|
||||||
}
|
|
||||||
if (VL_LIKELY(work.m_fnp)) {
|
if (VL_LIKELY(work.m_fnp)) {
|
||||||
work.m_fnp(work.m_evenCycle, work.m_sym);
|
work.m_fnp(work.m_evenCycle, work.m_sym);
|
||||||
work.m_fnp = NULL;
|
work.m_fnp = NULL;
|
||||||
@@ -194,7 +170,7 @@ void VlThreadPool::profileDump(const char* filenamep, vluint64_t ticksElapsed) {
|
|||||||
fprintf(fp, "VLPROF arg +verilator+prof+threads+window+%u\n",
|
fprintf(fp, "VLPROF arg +verilator+prof+threads+window+%u\n",
|
||||||
Verilated::profThreadsWindow());
|
Verilated::profThreadsWindow());
|
||||||
fprintf(fp, "VLPROF stat yields %" VL_PRI64 "u\n",
|
fprintf(fp, "VLPROF stat yields %" VL_PRI64 "u\n",
|
||||||
VlNotification::yields());
|
VlMTaskVertex::yields());
|
||||||
|
|
||||||
vluint32_t thread_id = 0;
|
vluint32_t thread_id = 0;
|
||||||
for (ProfileSet::iterator pit = m_allProfiles.begin();
|
for (ProfileSet::iterator pit = m_allProfiles.begin();
|
||||||
|
|||||||
+45
-91
@@ -25,9 +25,12 @@
|
|||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
#include "verilated.h" // for VerilatedMutex and clang annotations
|
#include "verilated.h" // for VerilatedMutex and clang annotations
|
||||||
|
|
||||||
#include <sched.h> // For sched_getcpu()
|
#include <condition_variable>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#if defined(__linux)
|
||||||
|
#include <sched.h> // For sched_getcpu()
|
||||||
|
#endif
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
# include <cpuid.h> // For __cpuid_count()
|
# include <cpuid.h> // For __cpuid_count()
|
||||||
#endif
|
#endif
|
||||||
@@ -37,71 +40,12 @@
|
|||||||
// as a void* here.
|
// as a void* here.
|
||||||
typedef void* VlThrSymTab;
|
typedef void* VlThrSymTab;
|
||||||
|
|
||||||
class VlNotification {
|
|
||||||
// MEMBERS
|
|
||||||
std::atomic<bool> m_notified; // Notification pending
|
|
||||||
static std::atomic<vluint64_t> s_yields; // Statistics
|
|
||||||
|
|
||||||
public:
|
|
||||||
// CONSTRUCTORS
|
|
||||||
VlNotification()
|
|
||||||
: m_notified(false) {
|
|
||||||
assert(atomic_is_lock_free(&m_notified));
|
|
||||||
}
|
|
||||||
~VlNotification() {}
|
|
||||||
|
|
||||||
// METHODS
|
|
||||||
static vluint64_t yields() { return s_yields; }
|
|
||||||
static void yieldThread() {
|
|
||||||
++s_yields; // Statistics
|
|
||||||
std::this_thread::yield();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Block until notify() has occurred, then return.
|
|
||||||
// If notify() has already occurred, return immediately.
|
|
||||||
//
|
|
||||||
// This is logically const: the object will remain in notified state
|
|
||||||
// after WaitForNotification() returns, so you could notify more than
|
|
||||||
// one thread of the same event.
|
|
||||||
inline void waitForNotification() {
|
|
||||||
unsigned ct = 0;
|
|
||||||
while (VL_UNLIKELY(!notified())) {
|
|
||||||
VL_CPU_RELAX();
|
|
||||||
++ct;
|
|
||||||
if (VL_UNLIKELY(ct > VL_LOCK_SPINS)) {
|
|
||||||
ct = 0;
|
|
||||||
yieldThread();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The 'inline' keyword here means nothing to the compiler, it's
|
|
||||||
// implicit on methods defined within the class body anyway.
|
|
||||||
//
|
|
||||||
// 'inline' is attached the this method, and others in this file,
|
|
||||||
// to remind humans that some routines in this file are called many
|
|
||||||
// times per cycle in threaded mode. Such routines should be
|
|
||||||
// inlinable; that's why they're declared in the .h and not the .cpp.
|
|
||||||
inline bool notified() {
|
|
||||||
return m_notified.load(std::memory_order_acquire);
|
|
||||||
}
|
|
||||||
// Set notified state. If state is already notified,
|
|
||||||
// it remains so.
|
|
||||||
inline void notify() {
|
|
||||||
m_notified.store(true, std::memory_order_release);
|
|
||||||
}
|
|
||||||
// Reset the state to un-notified state, which is also the
|
|
||||||
// state of a new Notification object.
|
|
||||||
inline void reset() {
|
|
||||||
m_notified.store(false, std::memory_order_relaxed);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*VlExecFnp)(bool, VlThrSymTab);
|
typedef void (*VlExecFnp)(bool, VlThrSymTab);
|
||||||
|
|
||||||
/// Track dependencies for a single MTask.
|
/// Track dependencies for a single MTask.
|
||||||
class VlMTaskVertex {
|
class VlMTaskVertex {
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
|
static std::atomic<vluint64_t> s_yields; // Statistics
|
||||||
|
|
||||||
// On even cycles, _upstreamDepsDone increases as upstream
|
// On even cycles, _upstreamDepsDone increases as upstream
|
||||||
// dependencies complete. When it reaches _upstreamDepCount,
|
// dependencies complete. When it reaches _upstreamDepCount,
|
||||||
@@ -131,6 +75,12 @@ public:
|
|||||||
explicit VlMTaskVertex(vluint32_t upstreamDepCount);
|
explicit VlMTaskVertex(vluint32_t upstreamDepCount);
|
||||||
~VlMTaskVertex() {}
|
~VlMTaskVertex() {}
|
||||||
|
|
||||||
|
static vluint64_t yields() { return s_yields; }
|
||||||
|
static void yieldThread() {
|
||||||
|
++s_yields; // Statistics
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
|
|
||||||
// Upstream mtasks must call this when they complete.
|
// Upstream mtasks must call this when they complete.
|
||||||
// Returns true when the current MTaskVertex becomes ready to execute,
|
// Returns true when the current MTaskVertex becomes ready to execute,
|
||||||
// false while it's still waiting on more dependencies.
|
// false while it's still waiting on more dependencies.
|
||||||
@@ -158,7 +108,7 @@ public:
|
|||||||
++ct;
|
++ct;
|
||||||
if (VL_UNLIKELY(ct > VL_LOCK_SPINS)) {
|
if (VL_UNLIKELY(ct > VL_LOCK_SPINS)) {
|
||||||
ct = 0;
|
ct = 0;
|
||||||
VlNotification::yieldThread();
|
yieldThread();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -196,9 +146,7 @@ public:
|
|||||||
m_startTime = time;
|
m_startTime = time;
|
||||||
m_cpu = getcpu();
|
m_cpu = getcpu();
|
||||||
}
|
}
|
||||||
void endRecord(vluint64_t time) {
|
void endRecord(vluint64_t time) { m_endTime = time; }
|
||||||
m_endTime = time;
|
|
||||||
}
|
|
||||||
static int getcpu() { // Return current executing CPU
|
static int getcpu() { // Return current executing CPU
|
||||||
#if defined(__linux)
|
#if defined(__linux)
|
||||||
return sched_getcpu();
|
return sched_getcpu();
|
||||||
@@ -207,15 +155,16 @@ public:
|
|||||||
__cpuid_count(1, 0, info[0], info[1], info[2], info[3]);
|
__cpuid_count(1, 0, info[0], info[1], info[2], info[3]);
|
||||||
/* info[1] is EBX, bits 24-31 are APIC ID */
|
/* info[1] is EBX, bits 24-31 are APIC ID */
|
||||||
if ((info[3] & (1 << 9)) == 0) {
|
if ((info[3] & (1 << 9)) == 0) {
|
||||||
return -1; /* no APIC on chip */
|
return -1; // no APIC on chip
|
||||||
} else {
|
} else {
|
||||||
return (unsigned)info[1] >> 24;
|
return (unsigned)info[1] >> 24;
|
||||||
}
|
}
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
return GetCurrentProcessorNumber();
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class VlThreadPool;
|
class VlThreadPool;
|
||||||
@@ -234,19 +183,19 @@ private:
|
|||||||
|
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
VerilatedMutex m_mutex;
|
VerilatedMutex m_mutex;
|
||||||
|
std::condition_variable_any m_cv;
|
||||||
|
// Only notify the condition_variable if the worker is waiting
|
||||||
|
bool m_waiting VL_GUARDED_BY(m_mutex);
|
||||||
|
|
||||||
// Why a vector? We expect the pending list to be very short, typically
|
// Why a vector? We expect the pending list to be very short, typically
|
||||||
// 0 or 1 or 2, so popping from the front shouldn't be
|
// 0 or 1 or 2, so popping from the front shouldn't be
|
||||||
// expensive. Revisit if we ever have longer queues...
|
// expensive. Revisit if we ever have longer queues...
|
||||||
std::vector<ExecRec> m_ready VL_GUARDED_BY(m_mutex);
|
std::vector<ExecRec> m_ready VL_GUARDED_BY(m_mutex);
|
||||||
|
// Store the size atomically, so we can spin wait
|
||||||
|
std::atomic<size_t> m_ready_size;
|
||||||
|
|
||||||
VlThreadPool* m_poolp; // Our associated thread pool
|
VlThreadPool* m_poolp; // Our associated thread pool
|
||||||
|
|
||||||
// If values stored are non-NULL, the thread is asleep pending new
|
|
||||||
// work. If the thread is not asleep, both parts of m_sleepAlarm must
|
|
||||||
// be NULL.
|
|
||||||
std::pair<VlNotification*, ExecRec*> m_sleepAlarm VL_GUARDED_BY(m_mutex);
|
|
||||||
|
|
||||||
bool m_profiling; // Is profiling enabled?
|
bool m_profiling; // Is profiling enabled?
|
||||||
std::atomic<bool> m_exiting; // Worker thread should exit
|
std::atomic<bool> m_exiting; // Worker thread should exit
|
||||||
std::thread m_cthread; // Underlying C++ thread record
|
std::thread m_cthread; // Underlying C++ thread record
|
||||||
@@ -259,29 +208,36 @@ public:
|
|||||||
~VlWorkerThread();
|
~VlWorkerThread();
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
inline void dequeWork(ExecRec* workp) VL_REQUIRES(m_mutex) {
|
inline void dequeWork(ExecRec* workp) {
|
||||||
|
// Spin for a while, waiting for new data
|
||||||
|
for (int i = 0; i < VL_LOCK_SPINS; ++i) {
|
||||||
|
if (VL_LIKELY(m_ready_size.load(std::memory_order_relaxed))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
VL_CPU_RELAX();
|
||||||
|
}
|
||||||
|
VerilatedLockGuard lk(m_mutex);
|
||||||
|
while (m_ready.empty()) {
|
||||||
|
m_waiting = true;
|
||||||
|
m_cv.wait(lk);
|
||||||
|
}
|
||||||
|
m_waiting = false;
|
||||||
// As noted above this is inefficient if our ready list is ever
|
// As noted above this is inefficient if our ready list is ever
|
||||||
// long (but it shouldn't be)
|
// long (but it shouldn't be)
|
||||||
*workp = m_ready.front();
|
*workp = m_ready.front();
|
||||||
m_ready.erase(m_ready.begin());
|
m_ready.erase(m_ready.begin());
|
||||||
|
m_ready_size.fetch_sub(1, std::memory_order_relaxed);
|
||||||
}
|
}
|
||||||
inline void wakeUp() VL_REQUIRES(m_mutex) {
|
inline void wakeUp() { addTask(nullptr, false, nullptr); }
|
||||||
VlNotification* notifyp = m_sleepAlarm.first;
|
|
||||||
m_sleepAlarm.first = NULL; // NULL+NULL means wake
|
|
||||||
m_sleepAlarm.second = NULL;
|
|
||||||
notifyp->notify();
|
|
||||||
}
|
|
||||||
inline bool sleeping() VL_REQUIRES(m_mutex) {
|
|
||||||
return (m_sleepAlarm.first != NULL);
|
|
||||||
}
|
|
||||||
inline void addTask(VlExecFnp fnp, bool evenCycle, VlThrSymTab sym) {
|
inline void addTask(VlExecFnp fnp, bool evenCycle, VlThrSymTab sym) {
|
||||||
VerilatedLockGuard lk(m_mutex);
|
bool notify;
|
||||||
m_ready.emplace_back(fnp, evenCycle, sym);
|
{
|
||||||
if (VL_LIKELY(sleeping())) { // Generally queue is waiting for work
|
VerilatedLockGuard lk(m_mutex);
|
||||||
// Awaken thread
|
m_ready.emplace_back(fnp, evenCycle, sym);
|
||||||
dequeWork(m_sleepAlarm.second);
|
m_ready_size.fetch_add(1, std::memory_order_relaxed);
|
||||||
wakeUp();
|
notify = m_waiting;
|
||||||
}
|
}
|
||||||
|
if (notify) m_cv.notify_one();
|
||||||
}
|
}
|
||||||
void workerLoop();
|
void workerLoop();
|
||||||
static void startWorker(VlWorkerThread* workerp);
|
static void startWorker(VlWorkerThread* workerp);
|
||||||
@@ -315,9 +271,7 @@ public:
|
|||||||
~VlThreadPool();
|
~VlThreadPool();
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
inline int numThreads() const {
|
inline int numThreads() const { return m_workers.size(); }
|
||||||
return m_workers.size();
|
|
||||||
}
|
|
||||||
inline VlWorkerThread* workerp(int index) {
|
inline VlWorkerThread* workerp(int index) {
|
||||||
assert(index >= 0);
|
assert(index >= 0);
|
||||||
assert(index < m_workers.size());
|
assert(index < m_workers.size());
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
// DESCRIPTION: Verilator: pre-C++11 replacements for std::unordered_set
|
// DESCRIPTION: Verilator: pre-C++11 replacements for std::unordered_set
|
||||||
// and std::unordered_map.
|
// and std::unordered_map.
|
||||||
//
|
//
|
||||||
// Code available from: http://www.veripool.org/verilator
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -19,7 +19,6 @@
|
|||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
|
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
// This file has clones of the std::unordered_set and std::unordered_map
|
// This file has clones of the std::unordered_set and std::unordered_map
|
||||||
// hash table types. They are here so that Verilator can use hash tables
|
// hash table types. They are here so that Verilator can use hash tables
|
||||||
@@ -114,7 +113,7 @@ class vl_unordered_set {
|
|||||||
public:
|
public:
|
||||||
// TYPES
|
// TYPES
|
||||||
typedef std::list<T_Key> Bucket;
|
typedef std::list<T_Key> Bucket;
|
||||||
enum RehashType {GROW, SHRINK};
|
enum RehashType { GROW, SHRINK };
|
||||||
|
|
||||||
template <class KK, class VV,
|
template <class KK, class VV,
|
||||||
class HH, class EQ> friend class vl_unordered_map;
|
class HH, class EQ> friend class vl_unordered_map;
|
||||||
@@ -197,7 +196,7 @@ public:
|
|||||||
, m_log2Buckets(initLog2Buckets())
|
, m_log2Buckets(initLog2Buckets())
|
||||||
, m_bucketsp(NULL)
|
, m_bucketsp(NULL)
|
||||||
, m_hash()
|
, m_hash()
|
||||||
, m_equal() { }
|
, m_equal() {}
|
||||||
|
|
||||||
vl_unordered_set(const vl_unordered_set& other)
|
vl_unordered_set(const vl_unordered_set& other)
|
||||||
: m_numElements(other.m_numElements)
|
: m_numElements(other.m_numElements)
|
||||||
@@ -317,7 +316,7 @@ public:
|
|||||||
return find_internal(key, bucketIdx);
|
return find_internal(key, bucketIdx);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<iterator, bool> insert(const T_Key &val) {
|
std::pair<iterator, bool> insert(const T_Key& val) {
|
||||||
size_t bucketIdx;
|
size_t bucketIdx;
|
||||||
iterator existIt = find_internal(val, bucketIdx);
|
iterator existIt = find_internal(val, bucketIdx);
|
||||||
if (existIt != end()) {
|
if (existIt != end()) {
|
||||||
@@ -353,7 +352,7 @@ public:
|
|||||||
return next_it;
|
return next_it;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t erase(const T_Key &key) {
|
size_t erase(const T_Key& key) {
|
||||||
size_t bucketIdx;
|
size_t bucketIdx;
|
||||||
iterator it = find_internal(key, bucketIdx);
|
iterator it = find_internal(key, bucketIdx);
|
||||||
if (it != end()) {
|
if (it != end()) {
|
||||||
@@ -373,7 +372,7 @@ public:
|
|||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
if (m_bucketsp) {
|
if (m_bucketsp) {
|
||||||
delete [] m_bucketsp;
|
delete[] m_bucketsp;
|
||||||
m_bucketsp = NULL;
|
m_bucketsp = NULL;
|
||||||
}
|
}
|
||||||
m_numElements = 0;
|
m_numElements = 0;
|
||||||
@@ -417,7 +416,7 @@ private:
|
|||||||
size_t new_num_buckets = VL_ULL(1) << new_log2Buckets;
|
size_t new_num_buckets = VL_ULL(1) << new_log2Buckets;
|
||||||
Bucket* new_bucketsp = new Bucket[new_num_buckets];
|
Bucket* new_bucketsp = new Bucket[new_num_buckets];
|
||||||
|
|
||||||
for (size_t i=0; i<numBuckets(); i++) {
|
for (size_t i = 0; i < numBuckets(); i++) {
|
||||||
while (!m_bucketsp[i].empty()) {
|
while (!m_bucketsp[i].empty()) {
|
||||||
typename Bucket::iterator bit = m_bucketsp[i].begin();
|
typename Bucket::iterator bit = m_bucketsp[i].begin();
|
||||||
size_t hash = m_hash.operator()(*bit);
|
size_t hash = m_hash.operator()(*bit);
|
||||||
|
|||||||
@@ -708,9 +708,12 @@ void VerilatedVcd::flush_all() VL_MT_UNSAFE_ONE {
|
|||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
#ifdef VERILATED_VCD_TEST
|
#ifdef VERILATED_VCD_TEST
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
vluint32_t v1, v2, s1, s2[3];
|
vluint32_t v1, v2, s1, s2[3];
|
||||||
vluint32_t tri96[3];
|
vluint32_t tri96[3];
|
||||||
vluint32_t tri96__tri[3];
|
vluint32_t tri96__tri[3];
|
||||||
|
vluint64_t quad96[2];
|
||||||
vluint8_t ch;
|
vluint8_t ch;
|
||||||
vluint64_t timestamp = 1;
|
vluint64_t timestamp = 1;
|
||||||
double doub = 0;
|
double doub = 0;
|
||||||
@@ -734,6 +737,8 @@ void vcdInit(VerilatedVcd* vcdp, void* userthis, vluint32_t code) {
|
|||||||
// Note need to add 6 for next code.
|
// Note need to add 6 for next code.
|
||||||
vcdp->declDouble (0x1c, "doub",-1);
|
vcdp->declDouble (0x1c, "doub",-1);
|
||||||
// Note need to add 2 for next code.
|
// Note need to add 2 for next code.
|
||||||
|
vcdp->declArray(0x1e, "q2",-1, 95, 0);
|
||||||
|
// Note need to add 4 for next code.
|
||||||
}
|
}
|
||||||
|
|
||||||
void vcdFull(VerilatedVcd* vcdp, void* userthis, vluint32_t code) {
|
void vcdFull(VerilatedVcd* vcdp, void* userthis, vluint32_t code) {
|
||||||
@@ -746,6 +751,7 @@ void vcdFull(VerilatedVcd* vcdp, void* userthis, vluint32_t code) {
|
|||||||
vcdp->fullTriBus (0x12, tri96[0]&0x1f, tri96__tri[0]&0x1f, 5);
|
vcdp->fullTriBus (0x12, tri96[0]&0x1f, tri96__tri[0]&0x1f, 5);
|
||||||
vcdp->fullTriArray(0x16, tri96, tri96__tri, 96);
|
vcdp->fullTriArray(0x16, tri96, tri96__tri, 96);
|
||||||
vcdp->fullDouble(0x1c, doub);
|
vcdp->fullDouble(0x1c, doub);
|
||||||
|
vcdp->fullArray(0x1e, &quad96[0], 96);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vcdChange(VerilatedVcd* vcdp, void* userthis, vluint32_t code) {
|
void vcdChange(VerilatedVcd* vcdp, void* userthis, vluint32_t code) {
|
||||||
@@ -758,15 +764,17 @@ void vcdChange(VerilatedVcd* vcdp, void* userthis, vluint32_t code) {
|
|||||||
vcdp->chgTriBus (0x12, tri96[0]&0x1f, tri96__tri[0]&0x1f, 5);
|
vcdp->chgTriBus (0x12, tri96[0]&0x1f, tri96__tri[0]&0x1f, 5);
|
||||||
vcdp->chgTriArray (0x16, tri96, tri96__tri, 96);
|
vcdp->chgTriArray (0x16, tri96, tri96__tri, 96);
|
||||||
vcdp->chgDouble (0x1c, doub);
|
vcdp->chgDouble (0x1c, doub);
|
||||||
|
vcdp->chgArray(0x1e, &quad96[0], 96);
|
||||||
}
|
}
|
||||||
|
|
||||||
main() {
|
main() {
|
||||||
cout<<"test: O_LARGEFILE="<<O_LARGEFILE<<endl;
|
std::cout << "test: O_LARGEFILE=" << O_LARGEFILE << std::endl;
|
||||||
|
|
||||||
v1 = v2 = s1 = 0;
|
v1 = v2 = s1 = 0;
|
||||||
s2[0] = s2[1] = s2[2] = 0;
|
s2[0] = s2[1] = s2[2] = 0;
|
||||||
tri96[2] = tri96[1] = tri96[0] = 0;
|
tri96[2] = tri96[1] = tri96[0] = 0;
|
||||||
tri96__tri[2] = tri96__tri[1] = tri96__tri[0] = ~0;
|
tri96__tri[2] = tri96__tri[1] = tri96__tri[0] = ~0;
|
||||||
|
quad96[1] = quad96[0] = 0;
|
||||||
ch = 0;
|
ch = 0;
|
||||||
doub = 0;
|
doub = 0;
|
||||||
{
|
{
|
||||||
@@ -778,11 +786,13 @@ main() {
|
|||||||
v1 = 0xfff;
|
v1 = 0xfff;
|
||||||
tri96[2] = 4; tri96[1] = 2; tri96[0] = 1;
|
tri96[2] = 4; tri96[1] = 2; tri96[0] = 1;
|
||||||
tri96__tri[2] = tri96__tri[1] = tri96__tri[0] = ~0; // Still tri
|
tri96__tri[2] = tri96__tri[1] = tri96__tri[0] = ~0; // Still tri
|
||||||
|
quad96[1] = 0xffffffff ; quad96[0] = 0;
|
||||||
doub = 1.5;
|
doub = 1.5;
|
||||||
vcdp->dump(timestamp++);
|
vcdp->dump(timestamp++);
|
||||||
v2 = 0x1;
|
v2 = 0x1;
|
||||||
s2[1] = 2;
|
s2[1] = 2;
|
||||||
tri96__tri[2] = tri96__tri[1] = tri96__tri[0] = 0; // enable w/o data change
|
tri96__tri[2] = tri96__tri[1] = tri96__tri[0] = 0; // enable w/o data change
|
||||||
|
quad96[1] = 0 ; quad96[0] = ~0;
|
||||||
doub = -1.66e13;
|
doub = -1.66e13;
|
||||||
vcdp->dump(timestamp++);
|
vcdp->dump(timestamp++);
|
||||||
ch = 2;
|
ch = 2;
|
||||||
@@ -791,8 +801,8 @@ main() {
|
|||||||
vcdp->dump(timestamp++);
|
vcdp->dump(timestamp++);
|
||||||
vcdp->dump(timestamp++);
|
vcdp->dump(timestamp++);
|
||||||
# ifdef VERILATED_VCD_TEST_64BIT
|
# ifdef VERILATED_VCD_TEST_64BIT
|
||||||
vluint64_t bytesPerDump = 15ULL;
|
vluint64_t bytesPerDump = VL_ULL(15);
|
||||||
for (vluint64_t i=0; i<((1ULL<<32) / bytesPerDump); i++) {
|
for (vluint64_t i = 0; i < ((VL_ULL(1) << 32) / bytesPerDump); i++) {
|
||||||
v1 = i;
|
v1 = i;
|
||||||
vcdp->dump(timestamp++);
|
vcdp->dump(timestamp++);
|
||||||
}
|
}
|
||||||
@@ -804,5 +814,5 @@ main() {
|
|||||||
|
|
||||||
//********************************************************************
|
//********************************************************************
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
// compile-command: "mkdir -p ../test_dir && cd ../test_dir && c++ -DVERILATED_VCD_TEST ../src/verilated_vcd_c.cpp -o verilated_vcd_c && ./verilated_vcd_c && cat test.vcd"
|
// compile-command: "mkdir -p ../test_dir && cd ../test_dir && c++ -DVERILATED_VCD_TEST ../include/verilated_vcd_c.cpp -o verilated_vcd_c && ./verilated_vcd_c && cat test.vcd"
|
||||||
// End:
|
// End:
|
||||||
|
|||||||
+41
-23
@@ -112,9 +112,7 @@ private:
|
|||||||
inline void bufferCheck() {
|
inline void bufferCheck() {
|
||||||
// Flush the write buffer if there's not enough space left for new information
|
// Flush the write buffer if there's not enough space left for new information
|
||||||
// We only call this once per vector, so we need enough slop for a very wide "b###" line
|
// We only call this once per vector, so we need enough slop for a very wide "b###" line
|
||||||
if (VL_UNLIKELY(m_writep > m_wrFlushp)) {
|
if (VL_UNLIKELY(m_writep > m_wrFlushp)) { bufferFlush(); }
|
||||||
bufferFlush();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void closePrev();
|
void closePrev();
|
||||||
void closeErr();
|
void closeErr();
|
||||||
@@ -157,18 +155,18 @@ private:
|
|||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VL_UNCOPYABLE(VerilatedVcd);
|
VL_UNCOPYABLE(VerilatedVcd);
|
||||||
public:
|
public:
|
||||||
explicit VerilatedVcd(VerilatedVcdFile* filep=NULL);
|
explicit VerilatedVcd(VerilatedVcdFile* filep = NULL);
|
||||||
~VerilatedVcd();
|
~VerilatedVcd();
|
||||||
|
|
||||||
// ACCESSORS
|
// ACCESSORS
|
||||||
/// Set size in megabytes after which new file should be created
|
/// Set size in megabytes after which new file should be created
|
||||||
void rolloverMB(vluint64_t rolloverMB) { m_rolloverMB=rolloverMB; }
|
void rolloverMB(vluint64_t rolloverMB) { m_rolloverMB = rolloverMB; }
|
||||||
/// Is file open?
|
/// Is file open?
|
||||||
bool isOpen() const { return m_isOpen; }
|
bool isOpen() const { return m_isOpen; }
|
||||||
/// Change character that splits scopes. Note whitespace are ALWAYS escapes.
|
/// Change character that splits scopes. Note whitespace are ALWAYS escapes.
|
||||||
void scopeEscape(char flag) { m_scopeEscape = flag; }
|
void scopeEscape(char flag) { m_scopeEscape = flag; }
|
||||||
/// Is this an escape?
|
/// Is this an escape?
|
||||||
inline bool isScopeEscape(char c) { return isspace(c) || c==m_scopeEscape; }
|
inline bool isScopeEscape(char c) { return isspace(c) || c == m_scopeEscape; }
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
void open(const char* filename) VL_MT_UNSAFE_ONE; ///< Open the file; call isOpen() to see if errors
|
void open(const char* filename) VL_MT_UNSAFE_ONE; ///< Open the file; call isOpen() to see if errors
|
||||||
@@ -233,20 +231,31 @@ public:
|
|||||||
(*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) = newval;
|
(*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) = newval;
|
||||||
*m_writep++='b';
|
*m_writep++='b';
|
||||||
for (int bit=bits-1; bit>=0; --bit) {
|
for (int bit=bits-1; bit>=0; --bit) {
|
||||||
*m_writep++=((newval&(1ULL<<bit))?'1':'0');
|
*m_writep++ = ((newval & (VL_ULL(1) << bit)) ? '1' : '0');
|
||||||
}
|
}
|
||||||
*m_writep++=' '; printCode(code); *m_writep++='\n';
|
*m_writep++=' '; printCode(code); *m_writep++='\n';
|
||||||
bufferCheck();
|
bufferCheck();
|
||||||
}
|
}
|
||||||
void fullArray(vluint32_t code, const vluint32_t* newval, int bits) {
|
void fullArray(vluint32_t code, const vluint32_t* newval, int bits) {
|
||||||
for (int word=0; word<(((bits-1)/32)+1); ++word) {
|
for (int word = 0; word < (((bits - 1) / 32) + 1); ++word) {
|
||||||
m_sigs_oldvalp[code+word] = newval[word];
|
m_sigs_oldvalp[code + word] = newval[word];
|
||||||
}
|
}
|
||||||
*m_writep++='b';
|
*m_writep++ = 'b';
|
||||||
for (int bit=bits-1; bit>=0; --bit) {
|
for (int bit = bits - 1; bit >= 0; --bit) {
|
||||||
*m_writep++=((newval[(bit/32)]&(1L<<(bit&0x1f)))?'1':'0');
|
*m_writep++ = ((newval[(bit / 32)] & (1L << (bit & 0x1f))) ? '1' : '0');
|
||||||
}
|
}
|
||||||
*m_writep++=' '; printCode(code); *m_writep++='\n';
|
*m_writep ++= ' '; printCode(code); *m_writep ++= '\n';
|
||||||
|
bufferCheck();
|
||||||
|
}
|
||||||
|
void fullArray(vluint32_t code, const vluint64_t* newval, int bits) {
|
||||||
|
for (int word = 0; word < (((bits - 1) / 64) + 1); ++word) {
|
||||||
|
m_sigs_oldvalp[code + word] = newval[word];
|
||||||
|
}
|
||||||
|
*m_writep ++= 'b';
|
||||||
|
for (int bit = bits - 1; bit >= 0; --bit) {
|
||||||
|
*m_writep++ = ((newval[(bit / 64)] & (VL_ULL(1) << (bit & 0x3f))) ? '1' : '0');
|
||||||
|
}
|
||||||
|
*m_writep ++= ' '; printCode(code); *m_writep ++= '\n';
|
||||||
bufferCheck();
|
bufferCheck();
|
||||||
}
|
}
|
||||||
void fullTriBit(vluint32_t code, const vluint32_t newval, const vluint32_t newtri) {
|
void fullTriBit(vluint32_t code, const vluint32_t newval, const vluint32_t newtri) {
|
||||||
@@ -274,8 +283,8 @@ public:
|
|||||||
(*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code+1]))) = newtri;
|
(*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code+1]))) = newtri;
|
||||||
*m_writep++='b';
|
*m_writep++='b';
|
||||||
for (int bit=bits-1; bit>=0; --bit) {
|
for (int bit=bits-1; bit>=0; --bit) {
|
||||||
*m_writep++ = "01zz"[((newval >> bit)&1ULL)
|
*m_writep++ = "01zz"[((newval >> bit) & VL_ULL(1))
|
||||||
| (((newtri >> bit)&1ULL)<<1ULL)];
|
| (((newtri >> bit) & VL_ULL(1)) << VL_ULL(1))];
|
||||||
}
|
}
|
||||||
*m_writep++=' '; printCode(code); *m_writep++='\n';
|
*m_writep++=' '; printCode(code); *m_writep++='\n';
|
||||||
bufferCheck();
|
bufferCheck();
|
||||||
@@ -331,7 +340,7 @@ public:
|
|||||||
inline void chgBus(vluint32_t code, const vluint32_t newval, int bits) {
|
inline void chgBus(vluint32_t code, const vluint32_t newval, int bits) {
|
||||||
vluint32_t diff = m_sigs_oldvalp[code] ^ newval;
|
vluint32_t diff = m_sigs_oldvalp[code] ^ newval;
|
||||||
if (VL_UNLIKELY(diff)) {
|
if (VL_UNLIKELY(diff)) {
|
||||||
if (VL_UNLIKELY(bits==32 || (diff & ((1U<<bits)-1) ))) {
|
if (VL_UNLIKELY(bits == 32 || (diff & ((1U << bits) - 1)))) {
|
||||||
fullBus(code, newval, bits);
|
fullBus(code, newval, bits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,15 +348,23 @@ public:
|
|||||||
inline void chgQuad(vluint32_t code, const vluint64_t newval, int bits) {
|
inline void chgQuad(vluint32_t code, const vluint64_t newval, int bits) {
|
||||||
vluint64_t diff = (*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) ^ newval;
|
vluint64_t diff = (*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) ^ newval;
|
||||||
if (VL_UNLIKELY(diff)) {
|
if (VL_UNLIKELY(diff)) {
|
||||||
if (VL_UNLIKELY(bits==64 || (diff & ((1ULL<<bits)-1) ))) {
|
if (VL_UNLIKELY(bits == 64 || (diff & ((VL_ULL(1) << bits) - 1)))) {
|
||||||
fullQuad(code, newval, bits);
|
fullQuad(code, newval, bits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline void chgArray(vluint32_t code, const vluint32_t* newval, int bits) {
|
inline void chgArray(vluint32_t code, const vluint32_t* newval, int bits) {
|
||||||
for (int word=0; word<(((bits-1)/32)+1); ++word) {
|
for (int word = 0; word < (((bits - 1) / 32) + 1); ++word) {
|
||||||
if (VL_UNLIKELY(m_sigs_oldvalp[code+word] ^ newval[word])) {
|
if (VL_UNLIKELY(m_sigs_oldvalp[code + word] ^ newval[word])) {
|
||||||
fullArray(code,newval,bits);
|
fullArray(code, newval, bits);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline void chgArray(vluint32_t code, const vluint64_t* newval, int bits) {
|
||||||
|
for (int word = 0; word < (((bits - 1) / 64) + 1); ++word) {
|
||||||
|
if (VL_UNLIKELY(m_sigs_oldvalp[code + word] ^ newval[word])) {
|
||||||
|
fullArray(code, newval, bits);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,7 +396,7 @@ public:
|
|||||||
vluint64_t diff = ( ((*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) ^ newval)
|
vluint64_t diff = ( ((*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) ^ newval)
|
||||||
| ((*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code+1]))) ^ newtri));
|
| ((*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code+1]))) ^ newtri));
|
||||||
if (VL_UNLIKELY(diff)) {
|
if (VL_UNLIKELY(diff)) {
|
||||||
if (VL_UNLIKELY(bits==64 || (diff & ((1ULL<<bits)-1) ))) {
|
if (VL_UNLIKELY(bits == 64 || (diff & ((VL_ULL(1) << bits) - 1)))) {
|
||||||
fullTriQuad(code, newval, newtri, bits);
|
fullTriQuad(code, newval, newtri, bits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -424,7 +441,8 @@ class VerilatedVcdC {
|
|||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VL_UNCOPYABLE(VerilatedVcdC);
|
VL_UNCOPYABLE(VerilatedVcdC);
|
||||||
public:
|
public:
|
||||||
explicit VerilatedVcdC(VerilatedVcdFile* filep=NULL) : m_sptrace(filep) {}
|
explicit VerilatedVcdC(VerilatedVcdFile* filep = NULL)
|
||||||
|
: m_sptrace(filep) {}
|
||||||
~VerilatedVcdC() {}
|
~VerilatedVcdC() {}
|
||||||
public:
|
public:
|
||||||
// ACCESSORS
|
// ACCESSORS
|
||||||
@@ -438,7 +456,7 @@ public:
|
|||||||
/// Continue a VCD dump by rotating to a new file name
|
/// Continue a VCD dump by rotating to a new file name
|
||||||
/// The header is only in the first file created, this allows
|
/// The header is only in the first file created, this allows
|
||||||
/// "cat" to be used to combine the header plus any number of data files.
|
/// "cat" to be used to combine the header plus any number of data files.
|
||||||
void openNext(bool incFilename=true) VL_MT_UNSAFE_ONE { m_sptrace.openNext(incFilename); }
|
void openNext(bool incFilename = true) VL_MT_UNSAFE_ONE { m_sptrace.openNext(incFilename); }
|
||||||
/// Set size in megabytes after which new file should be created
|
/// Set size in megabytes after which new file should be created
|
||||||
void rolloverMB(size_t rolloverMB) { m_sptrace.rolloverMB(rolloverMB); }
|
void rolloverMB(size_t rolloverMB) { m_sptrace.rolloverMB(rolloverMB); }
|
||||||
/// Close dump
|
/// Close dump
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
// SystemC 2.1.v1
|
// SystemC 2.1.v1
|
||||||
// cppcheck-suppress unusedFunction
|
// cppcheck-suppress unusedFunction
|
||||||
void VerilatedVcdSc::write_comment(const std::string &) {}
|
void VerilatedVcdSc::write_comment(const std::string &) {}
|
||||||
void VerilatedVcdSc::trace(const unsigned int &, const std::string &, const char **) {}
|
void VerilatedVcdSc::trace(const unsigned int &, const std::string &, const char**) {}
|
||||||
|
|
||||||
# define DECL_TRACE_METHOD_A(tp) \
|
# define DECL_TRACE_METHOD_A(tp) \
|
||||||
void VerilatedVcdSc::trace( const tp& object, const std::string& name ) {}
|
void VerilatedVcdSc::trace( const tp& object, const std::string& name ) {}
|
||||||
@@ -82,7 +82,7 @@ void VerilatedVcdSc::trace(const unsigned int &, const std::string &, const char
|
|||||||
// SystemC 2.0.1
|
// SystemC 2.0.1
|
||||||
// cppcheck-suppress unusedFunction
|
// cppcheck-suppress unusedFunction
|
||||||
void VerilatedVcdSc::write_comment(const sc_string &) {}
|
void VerilatedVcdSc::write_comment(const sc_string &) {}
|
||||||
void VerilatedVcdSc::trace(const unsigned int &, const sc_string &, const char **) {}
|
void VerilatedVcdSc::trace(const unsigned int&, const sc_string&, const char**) {}
|
||||||
|
|
||||||
#define DECL_TRACE_METHOD_A(tp) \
|
#define DECL_TRACE_METHOD_A(tp) \
|
||||||
void VerilatedVcdSc::trace( const tp& object, const sc_string& name ) {}
|
void VerilatedVcdSc::trace( const tp& object, const sc_string& name ) {}
|
||||||
@@ -125,7 +125,7 @@ void VerilatedVcdSc::trace(const unsigned int &, const sc_string &, const char *
|
|||||||
// SystemC 1.2.1beta
|
// SystemC 1.2.1beta
|
||||||
// cppcheck-suppress unusedFunction
|
// cppcheck-suppress unusedFunction
|
||||||
void VerilatedVcdSc::write_comment(const sc_string &) {}
|
void VerilatedVcdSc::write_comment(const sc_string &) {}
|
||||||
void VerilatedVcdSc::trace(const unsigned int &, const sc_string &, const char **) {}
|
void VerilatedVcdSc::trace(const unsigned int&, const sc_string&, const char**) {}
|
||||||
|
|
||||||
#define DECL_TRACE_METHOD_A(tp) \
|
#define DECL_TRACE_METHOD_A(tp) \
|
||||||
void VerilatedVcdSc::trace( const tp& object, const sc_string& name ) {}
|
void VerilatedVcdSc::trace( const tp& object, const sc_string& name ) {}
|
||||||
|
|||||||
@@ -96,8 +96,8 @@ private:
|
|||||||
# define DECL_TRACE_METHOD_B(tp) \
|
# define DECL_TRACE_METHOD_B(tp) \
|
||||||
virtual void trace(const tp& object, const std::string& name, int width);
|
virtual void trace(const tp& object, const std::string& name, int width);
|
||||||
|
|
||||||
virtual void write_comment(const std::string &);
|
virtual void write_comment(const std::string&);
|
||||||
virtual void trace(const unsigned int &, const std::string &, const char **);
|
virtual void trace(const unsigned int&, const std::string&, const char**);
|
||||||
|
|
||||||
#if (SYSTEMC_VERSION>=20171012)
|
#if (SYSTEMC_VERSION>=20171012)
|
||||||
DECL_TRACE_METHOD_A( sc_event )
|
DECL_TRACE_METHOD_A( sc_event )
|
||||||
@@ -145,8 +145,8 @@ private:
|
|||||||
# define DECL_TRACE_METHOD_B(tp) \
|
# define DECL_TRACE_METHOD_B(tp) \
|
||||||
virtual void trace(const tp& object, const sc_string& name, int width);
|
virtual void trace(const tp& object, const sc_string& name, int width);
|
||||||
|
|
||||||
virtual void write_comment(const sc_string &);
|
virtual void write_comment(const sc_string&);
|
||||||
virtual void trace(const unsigned int &, const sc_string &, const char **);
|
virtual void trace(const unsigned int&, const sc_string&, const char**);
|
||||||
virtual void delta_cycles(bool) {}
|
virtual void delta_cycles(bool) {}
|
||||||
virtual void space(int n) {}
|
virtual void space(int n) {}
|
||||||
|
|
||||||
@@ -189,8 +189,8 @@ private:
|
|||||||
# define DECL_TRACE_METHOD_B(tp) \
|
# define DECL_TRACE_METHOD_B(tp) \
|
||||||
virtual void trace(const tp& object, const sc_string& name, int width);
|
virtual void trace(const tp& object, const sc_string& name, int width);
|
||||||
|
|
||||||
virtual void write_comment(const sc_string &);
|
virtual void write_comment(const sc_string&);
|
||||||
virtual void trace(const unsigned int &, const sc_string &, const char **);
|
virtual void trace(const unsigned int&, const sc_string&, const char**);
|
||||||
|
|
||||||
DECL_TRACE_METHOD_A( bool )
|
DECL_TRACE_METHOD_A( bool )
|
||||||
DECL_TRACE_METHOD_B( unsigned char )
|
DECL_TRACE_METHOD_B( unsigned char )
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
///
|
///
|
||||||
/// Use "verilator --vpi" to add this to the Makefile for the linker.
|
/// Use "verilator --vpi" to add this to the Makefile for the linker.
|
||||||
///
|
///
|
||||||
/// Code available from: http://www.veripool.org/verilator
|
/// Code available from: https://verilator.org
|
||||||
///
|
///
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
@@ -416,7 +416,9 @@ public:
|
|||||||
for (VpioTimedCbs::iterator it=s_s.m_timedCbs.begin(); it!=s_s.m_timedCbs.end(); ) {
|
for (VpioTimedCbs::iterator it=s_s.m_timedCbs.begin(); it!=s_s.m_timedCbs.end(); ) {
|
||||||
if (VL_UNLIKELY(it->first <= time)) {
|
if (VL_UNLIKELY(it->first <= time)) {
|
||||||
VerilatedVpioCb* vop = it->second;
|
VerilatedVpioCb* vop = it->second;
|
||||||
++it; // iterator may be deleted by callback
|
VpioTimedCbs::iterator last_it = it;
|
||||||
|
++it; // Timed callbacks are one-shot
|
||||||
|
s_s.m_timedCbs.erase(last_it);
|
||||||
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: timed_callback %p\n", vop););
|
VL_DEBUG_IF_PLI(VL_DBG_MSGF("- vpi: timed_callback %p\n", vop););
|
||||||
(vop->cb_rtnp()) (vop->cb_datap());
|
(vop->cb_rtnp()) (vop->cb_datap());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
/// This file must be compiled and linked against all objects
|
/// This file must be compiled and linked against all objects
|
||||||
/// created from Verilator or called by Verilator that use the VPI.
|
/// created from Verilator or called by Verilator that use the VPI.
|
||||||
///
|
///
|
||||||
/// Code available from: http://www.veripool.org/verilator
|
/// Code available from: https://verilator.org
|
||||||
///
|
///
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
|
|||||||
+15
-8
@@ -22,7 +22,7 @@
|
|||||||
/// config_build.h.in, code needed by Verilated code only goes into
|
/// config_build.h.in, code needed by Verilated code only goes into
|
||||||
/// verilated.h, and code needed by both goes here (verilatedos.h).
|
/// verilated.h, and code needed by both goes here (verilatedos.h).
|
||||||
///
|
///
|
||||||
/// Code available from: http://www.veripool.org/verilator
|
/// Code available from: https://verilator.org
|
||||||
///
|
///
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
@@ -122,7 +122,9 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
# ifdef __GNUC__
|
# if defined(_MSC_VER) && _MSC_VER >= 1900
|
||||||
|
# define VL_THREAD_LOCAL thread_local
|
||||||
|
# elif defined(__GNUC__)
|
||||||
# if (__cplusplus < 201103L) && !defined(VL_THREADED_NO_C11_WARNING)
|
# if (__cplusplus < 201103L) && !defined(VL_THREADED_NO_C11_WARNING)
|
||||||
# error "VL_THREADED/--threads support requires C++-11 or newer only; use newer compiler"
|
# error "VL_THREADED/--threads support requires C++-11 or newer only; use newer compiler"
|
||||||
# endif
|
# endif
|
||||||
@@ -160,7 +162,7 @@
|
|||||||
//=========================================================================
|
//=========================================================================
|
||||||
// C++-2011
|
// C++-2011
|
||||||
|
|
||||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(VL_CPPCHECK)
|
||||||
# define VL_EQ_DELETE = delete
|
# define VL_EQ_DELETE = delete
|
||||||
# define vl_unique_ptr std::unique_ptr
|
# define vl_unique_ptr std::unique_ptr
|
||||||
// By default we use std:: types in C++11.
|
// By default we use std:: types in C++11.
|
||||||
@@ -322,9 +324,9 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
|||||||
#define VL_WORDSIZE_LOG2 5 ///< log2(VL_WORDSIZE)
|
#define VL_WORDSIZE_LOG2 5 ///< log2(VL_WORDSIZE)
|
||||||
|
|
||||||
/// Bytes this number of bits needs (1 bit=1 byte)
|
/// Bytes this number of bits needs (1 bit=1 byte)
|
||||||
#define VL_BYTES_I(nbits) (((nbits)+(VL_BYTESIZE-1))/VL_BYTESIZE)
|
#define VL_BYTES_I(nbits) (((nbits) + (VL_BYTESIZE - 1)) / VL_BYTESIZE)
|
||||||
/// Words this number of bits needs (1 bit=1 word)
|
/// Words this number of bits needs (1 bit=1 word)
|
||||||
#define VL_WORDS_I(nbits) (((nbits)+(VL_WORDSIZE-1))/VL_WORDSIZE)
|
#define VL_WORDS_I(nbits) (((nbits) + (VL_WORDSIZE - 1)) / VL_WORDSIZE)
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Class definition helpers
|
// Class definition helpers
|
||||||
@@ -343,8 +345,8 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
|||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Base macros
|
// Base macros
|
||||||
|
|
||||||
#define VL_SIZEBITS_I (VL_WORDSIZE-1) ///< Bit mask for bits in a word
|
#define VL_SIZEBITS_I (VL_WORDSIZE - 1) ///< Bit mask for bits in a word
|
||||||
#define VL_SIZEBITS_Q (VL_QUADSIZE-1) ///< Bit mask for bits in a quad
|
#define VL_SIZEBITS_Q (VL_QUADSIZE - 1) ///< Bit mask for bits in a quad
|
||||||
|
|
||||||
/// Mask for words with 1's where relevant bits are (0=all bits)
|
/// Mask for words with 1's where relevant bits are (0=all bits)
|
||||||
#define VL_MASK_I(nbits) (((nbits) & VL_SIZEBITS_I) \
|
#define VL_MASK_I(nbits) (((nbits) & VL_SIZEBITS_I) \
|
||||||
@@ -390,7 +392,12 @@ typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
|||||||
// Threading related OS-specific functions
|
// Threading related OS-specific functions
|
||||||
|
|
||||||
#if VL_THREADED
|
#if VL_THREADED
|
||||||
# if defined(__i386__) || defined(__x86_64__)
|
# ifdef _WIN32
|
||||||
|
# define WIN32_LEAN_AND_MEAN
|
||||||
|
# define NOMINMAX
|
||||||
|
# include "Windows.h"
|
||||||
|
# define VL_CPU_RELAX() YieldProcessor()
|
||||||
|
# elif defined(__i386__) || defined(__x86_64__)
|
||||||
/// For more efficient busy waiting on SMT CPUs, let the processor know
|
/// For more efficient busy waiting on SMT CPUs, let the processor know
|
||||||
/// we're just waiting so it can let another thread run
|
/// we're just waiting so it can let another thread run
|
||||||
# define VL_CPU_RELAX() asm volatile("rep; nop" ::: "memory")
|
# define VL_CPU_RELAX() asm volatile("rep; nop" ::: "memory")
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user