mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 10:03:44 +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 | ||
|
|
dfcd412e5f | ||
|
|
307549e8a6 | ||
|
|
09b79a731a | ||
|
|
4544a2fd99 | ||
|
|
e09c918198 | ||
|
|
9bf6135f6d | ||
|
|
d472ef63e9 | ||
|
|
f1c04b5d25 | ||
|
|
1cf29c4d20 | ||
|
|
977a767477 | ||
|
|
771a301f66 | ||
|
|
a9954a71c3 | ||
|
|
967dc24fda | ||
|
|
e1e45cf13c | ||
|
|
bd89c71694 | ||
|
|
633131b984 | ||
|
|
99db18b6c3 | ||
|
|
961a8e190f | ||
|
|
045ff25f80 | ||
|
|
66209d1114 | ||
|
|
3f1fe2d18a | ||
|
|
8b6fb26272 | ||
|
|
881362bb04 | ||
|
|
239ef1ae6d | ||
|
|
9eaec3b5c1 | ||
|
|
dd4aa948ae | ||
|
|
12fa085b26 | ||
|
|
9d6b0d7dd6 | ||
|
|
a1405dac8e | ||
|
|
cb115e1a15 | ||
|
|
1c7eb89df5 | ||
|
|
6e91f82a7d | ||
|
|
17123cd0e0 | ||
|
|
3f0c5b7550 | ||
|
|
f6e0e9adec | ||
|
|
dea1531f40 | ||
|
|
edcfaa888d | ||
|
|
28b9db1903 | ||
|
|
9e64be71a7 | ||
|
|
99a8845a96 | ||
|
|
be4692772c | ||
|
|
4f315d9078 | ||
|
|
f133c4d0b3 | ||
|
|
8490046028 | ||
|
|
d6ac351dcb | ||
|
|
502bd6cbd6 | ||
|
|
d7b6b53c4d | ||
|
|
96725b3431 | ||
|
|
8686ed9b00 | ||
|
|
32e1207782 | ||
|
|
900115bb2d | ||
|
|
3469c78153 | ||
|
|
baa634343b | ||
|
|
1471f5691a | ||
|
|
e556269692 | ||
|
|
d1af69f91d | ||
|
|
fa904f386c | ||
|
|
a4daae66de | ||
|
|
c813026566 | ||
|
|
314cd92129 | ||
|
|
3bc260c55d | ||
|
|
4c0f95af10 | ||
|
|
35fe205fd6 | ||
|
|
70cf2582d6 | ||
|
|
ec620387af | ||
|
|
e1e4bde125 | ||
|
|
b947391662 | ||
|
|
edc0f442e4 | ||
|
|
562b9551bf | ||
|
|
f74af949da | ||
|
|
81e806e895 | ||
|
|
7d4958264a | ||
|
|
88b87429dc | ||
|
|
429f463032 | ||
|
|
af4a39603c | ||
|
|
a13d230d8c | ||
|
|
b7bd5956ea | ||
|
|
1a36e05cc6 | ||
|
|
71265a8ec9 | ||
|
|
3a720204c2 | ||
|
|
a95f58749f | ||
|
|
9e58ede480 | ||
|
|
cf2ac30f66 | ||
|
|
68b22a4a3d | ||
|
|
875dc9a27e | ||
|
|
1332446f2a | ||
|
|
6b798830c9 | ||
|
|
ffa23b59b8 | ||
|
|
7d27461054 | ||
|
|
b3f318d8ab | ||
|
|
4a14788c9b | ||
|
|
5560da2934 | ||
|
|
43ce048f9e | ||
|
|
b045111a67 | ||
|
|
654571bd1c | ||
|
|
a3fd105acb | ||
|
|
97561bf064 | ||
|
|
a4820fc700 | ||
|
|
ee469eedaf | ||
|
|
a49d819437 | ||
|
|
cbb9288cb1 | ||
|
|
173efbc829 | ||
|
|
0fef3b02ec | ||
|
|
d1ee6689c4 | ||
|
|
b3eab9d78a | ||
|
|
defd05bdd7 | ||
|
|
a7e5cccf33 | ||
|
|
0f857ce423 | ||
|
|
83cf1882de | ||
|
|
e17543d6d8 | ||
|
|
dacf45fea9 | ||
|
|
13a20c5ee9 | ||
|
|
58dfe9d071 | ||
|
|
6c5cc885a6 | ||
|
|
2c44ab61ac | ||
|
|
0847ea57ae | ||
|
|
9af84c71f5 | ||
|
|
4ce77d3e68 | ||
|
|
3c67791624 | ||
|
|
a281c00752 | ||
|
|
2ca418288d | ||
|
|
bea34d0ced | ||
|
|
a5f2ce0dad | ||
|
|
07ae7146e3 | ||
|
|
8548ecfdac | ||
|
|
7e54ff1b37 | ||
|
|
a4b9745e6e | ||
|
|
8612ba2b8d | ||
|
|
fea6e047e2 | ||
|
|
01ef7122e9 | ||
|
|
ac43e7322b | ||
|
|
02a3f2089f | ||
|
|
33ad834106 | ||
|
|
efe739c52f | ||
|
|
5cd531a5e0 | ||
|
|
0e8dfdbb71 | ||
|
|
ec32a9b976 | ||
|
|
1aae6df669 | ||
|
|
f7641d2ecc | ||
|
|
5f27c41ee3 | ||
|
|
51df77099a | ||
|
|
b8b7e5c978 | ||
|
|
dddcfeb482 | ||
|
|
8d63f83177 | ||
|
|
d43e9aa2c5 | ||
|
|
a2c1b7f827 | ||
|
|
2fff92fe78 | ||
|
|
ba9af4aabf | ||
|
|
ef02678305 | ||
|
|
6990db70fa | ||
|
|
af5616c077 | ||
|
|
009f053d6e | ||
|
|
6903c52ef7 | ||
|
|
aa65dfb1bc | ||
|
|
84a2cd0ec7 | ||
|
|
8e7559c6c9 | ||
|
|
951521320a | ||
|
|
abc0eb92a0 | ||
|
|
c514bb26e8 | ||
|
|
5cb6474cc6 | ||
|
|
b8eb6368e9 | ||
|
|
6239deb1df | ||
|
|
89c2a6070a | ||
|
|
c53ea10c75 | ||
|
|
8fa54b1c4d | ||
|
|
e5fae03364 | ||
|
|
081fd3b789 | ||
|
|
0edd3c9e95 | ||
|
|
659c7b78d5 | ||
|
|
34ef3c9c38 | ||
|
|
90af180ec1 | ||
|
|
0d71c1154d | ||
|
|
5da5e32e86 | ||
|
|
ea59a39661 | ||
|
|
f5ca1a04cc | ||
|
|
b6c905dffc | ||
|
|
e4a3f9b38c | ||
|
|
b3e2d26e35 | ||
|
|
79e9fbaeb7 | ||
|
|
f5f5cd522b | ||
|
|
e713c8ce57 | ||
|
|
94ed817897 | ||
|
|
ff360738b5 | ||
|
|
f7f73a0825 | ||
|
|
2cedd14d43 | ||
|
|
77c2d49d1a | ||
|
|
dd8d5ef687 | ||
|
|
cfb05cd70a | ||
|
|
6f2f668449 | ||
|
|
6ffbb7cabf | ||
|
|
6c1782e4de | ||
|
|
10e3cc6e3b | ||
|
|
34424e70d8 | ||
|
|
38ad8727af | ||
|
|
4e115d4b69 | ||
|
|
f6f8073058 | ||
|
|
902ba752a3 | ||
|
|
97d9de3dad | ||
|
|
97fef7c60b | ||
|
|
a58e7d94ec | ||
|
|
c0be8bcefb | ||
|
|
8846b365f4 | ||
|
|
72eb361131 | ||
|
|
b83b606267 | ||
|
|
59d7d9e8c3 | ||
|
|
3411279294 | ||
|
|
8d6bea8975 | ||
|
|
01725f662f | ||
|
|
d841e68f4f | ||
|
|
13ecb8e177 | ||
|
|
26436cf4dd | ||
|
|
96c70ea2df | ||
|
|
c8849094fc | ||
|
|
afea6d84e3 | ||
|
|
1fb0af7fba | ||
|
|
8ad1a68420 | ||
|
|
6ef7d5f0fd | ||
|
|
d0fbdfac07 | ||
|
|
16997d153f | ||
|
|
7777d10e9b | ||
|
|
00214f738f | ||
|
|
07e6bc17db | ||
|
|
afdfa4df87 | ||
|
|
1f714c6813 | ||
|
|
5df3032b11 | ||
|
|
eac3458647 | ||
|
|
00efa05b50 | ||
|
|
cc1d380864 | ||
|
|
f96942a526 | ||
|
|
b23fc06388 | ||
|
|
f818ddc71c | ||
|
|
37c8cc82b2 | ||
|
|
03ebd5554f | ||
|
|
a2a7021914 | ||
|
|
c6650f88e1 | ||
|
|
55a25674a2 | ||
|
|
05c3d520a6 | ||
|
|
6b3304320b | ||
|
|
8d15276625 | ||
|
|
354f107fed | ||
|
|
1ff55c20e0 | ||
|
|
9583f0d3cc | ||
|
|
3acb85a005 | ||
|
|
08d041cb93 | ||
|
|
274b2002c2 | ||
|
|
681e91f9d8 | ||
|
|
6e333bd9ab | ||
|
|
6a331e37fc | ||
|
|
d8a020905a | ||
|
|
efa6f4cd95 | ||
|
|
ca537dc3ed | ||
|
|
3b64f54cea | ||
|
|
32c1e38b84 |
+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/**'
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
*.v linguist-language=SystemVerilog
|
||||||
|
*.vh linguist-language=SystemVerilog
|
||||||
|
*.sv linguist-language=SystemVerilog
|
||||||
|
nodist linguist-detectable=false
|
||||||
@@ -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/*
|
||||||
|
|||||||
+176
@@ -0,0 +1,176 @@
|
|||||||
|
# DESCRIPTION: Travis-CI config
|
||||||
|
#
|
||||||
|
# Copyright 2003-2019 by Todd Strader. 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.
|
||||||
|
|
||||||
|
version: ~> 1.0
|
||||||
|
|
||||||
|
os: linux
|
||||||
|
language: cpp
|
||||||
|
cache: ccache
|
||||||
|
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
- VERILATOR_CACHE=$HOME/verilator_cache
|
||||||
|
- VERILATOR_ROOT=$PWD
|
||||||
|
- VERILATOR_NUM_JOBS=$(echo `nproc` + 1 | bc)
|
||||||
|
- VERILATOR_CONFIG_FLAGS="--enable-maintainer-mode --enable-longtests"
|
||||||
|
- OBJCACHE=ccache
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- $VERILATOR_CACHE
|
||||||
|
|
||||||
|
before_install:
|
||||||
|
# Perl modules needed for testing
|
||||||
|
- yes yes | sudo cpan -fi Unix::Processors Parallel::Forker Bit::Vector
|
||||||
|
- sudo apt-get install gdb gtkwave
|
||||||
|
before_script:
|
||||||
|
- bash -x ci/build_verilator.sh
|
||||||
|
after_script:
|
||||||
|
- 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]
|
||||||
@@ -1,674 +0,0 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The GNU General Public License is a free, copyleft license for
|
|
||||||
software and other kinds of works.
|
|
||||||
|
|
||||||
The licenses for most software and other practical works are designed
|
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
the GNU General Public License is intended to guarantee your freedom to
|
|
||||||
share and change all versions of a program--to make sure it remains free
|
|
||||||
software for all its users. We, the Free Software Foundation, use the
|
|
||||||
GNU General Public License for most of our software; it applies also to
|
|
||||||
any other work released this way by its authors. You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
|
||||||
free programs, and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
|
||||||
these rights or asking you to surrender the rights. Therefore, you have
|
|
||||||
certain responsibilities if you distribute copies of the software, or if
|
|
||||||
you modify it: responsibilities to respect the freedom of others.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
|
||||||
|
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
|
||||||
that there is no warranty for this free software. For both users' and
|
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
|
||||||
changed, so that their problems will not be attributed erroneously to
|
|
||||||
authors of previous versions.
|
|
||||||
|
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the manufacturer
|
|
||||||
can do so. This is fundamentally incompatible with the aim of
|
|
||||||
protecting users' freedom to change the software. The systematic
|
|
||||||
pattern of such abuse occurs in the area of products for individuals to
|
|
||||||
use, which is precisely where it is most unacceptable. Therefore, we
|
|
||||||
have designed this version of the GPL to prohibit the practice for those
|
|
||||||
products. If such problems arise substantially in other domains, we
|
|
||||||
stand ready to extend this provision to those domains in future versions
|
|
||||||
of the GPL, as needed to protect the freedom of users.
|
|
||||||
|
|
||||||
Finally, every program is threatened constantly by software patents.
|
|
||||||
States should not allow patents to restrict development and use of
|
|
||||||
software on general-purpose computers, but in those that do, we wish to
|
|
||||||
avoid the special danger that patents applied to a free program could
|
|
||||||
make it effectively proprietary. To prevent this, the GPL assures that
|
|
||||||
patents cannot be used to render the program non-free.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
0. Definitions.
|
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
|
||||||
works, such as semiconductor masks.
|
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
|
||||||
"recipients" may be individuals or organizations.
|
|
||||||
|
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
|
||||||
in a fashion requiring copyright permission, other than the making of an
|
|
||||||
exact copy. The resulting work is called a "modified version" of the
|
|
||||||
earlier work or a work "based on" the earlier work.
|
|
||||||
|
|
||||||
A "covered work" means either the unmodified Program or a work based
|
|
||||||
on the Program.
|
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
|
||||||
permission, would make you directly or secondarily liable for
|
|
||||||
infringement under applicable copyright law, except executing it on a
|
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
|
||||||
|
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user through
|
|
||||||
a computer network, with no transfer of a copy, is not conveying.
|
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices"
|
|
||||||
to the extent that it includes a convenient and prominently visible
|
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
|
||||||
tells the user that there is no warranty for the work (except to the
|
|
||||||
extent that warranties are provided), that licensees may convey the
|
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
|
||||||
menu, a prominent item in the list meets this criterion.
|
|
||||||
|
|
||||||
1. Source Code.
|
|
||||||
|
|
||||||
The "source code" for a work means the preferred form of the work
|
|
||||||
for making modifications to it. "Object code" means any non-source
|
|
||||||
form of a work.
|
|
||||||
|
|
||||||
A "Standard Interface" means an interface that either is an official
|
|
||||||
standard defined by a recognized standards body, or, in the case of
|
|
||||||
interfaces specified for a particular programming language, one that
|
|
||||||
is widely used among developers working in that language.
|
|
||||||
|
|
||||||
The "System Libraries" of an executable work include anything, other
|
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
|
||||||
Major Component, or to implement a Standard Interface for which an
|
|
||||||
implementation is available to the public in source code form. A
|
|
||||||
"Major Component", in this context, means a major essential component
|
|
||||||
(kernel, window system, and so on) of the specific operating system
|
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
|
||||||
The "Corresponding Source" for a work in object code form means all
|
|
||||||
the source code needed to generate, install, and (for an executable
|
|
||||||
work) run the object code and to modify the work, including scripts to
|
|
||||||
control those activities. However, it does not include the work's
|
|
||||||
System Libraries, or general-purpose tools or generally available free
|
|
||||||
programs which are used unmodified in performing those activities but
|
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
|
||||||
the work, and the source code for shared libraries and dynamically
|
|
||||||
linked subprograms that the work is specifically designed to require,
|
|
||||||
such as by intimate data communication or control flow between those
|
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
|
||||||
The Corresponding Source need not include anything that users
|
|
||||||
can regenerate automatically from other parts of the Corresponding
|
|
||||||
Source.
|
|
||||||
|
|
||||||
The Corresponding Source for a work in source code form is that
|
|
||||||
same work.
|
|
||||||
|
|
||||||
2. Basic Permissions.
|
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
|
||||||
permission to run the unmodified Program. The output from running a
|
|
||||||
covered work is covered by this License only if the output, given its
|
|
||||||
content, constitutes a covered work. This License acknowledges your
|
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
|
||||||
|
|
||||||
You may make, run and propagate covered works that you do not
|
|
||||||
convey, without conditions so long as your license otherwise remains
|
|
||||||
in force. You may convey covered works to others for the sole purpose
|
|
||||||
of having them make modifications exclusively for you, or provide you
|
|
||||||
with facilities for running those works, provided that you comply with
|
|
||||||
the terms of this License in conveying all material for which you do
|
|
||||||
not control copyright. Those thus making or running the covered works
|
|
||||||
for you must do so exclusively on your behalf, under your direction
|
|
||||||
and control, on terms that prohibit them from making any copies of
|
|
||||||
your copyrighted material outside their relationship with you.
|
|
||||||
|
|
||||||
Conveying under any other circumstances is permitted solely under
|
|
||||||
the conditions stated below. Sublicensing is not allowed; section 10
|
|
||||||
makes it unnecessary.
|
|
||||||
|
|
||||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such circumvention
|
|
||||||
is effected by exercising rights under this License with respect to
|
|
||||||
the covered work, and you disclaim any intention to limit operation or
|
|
||||||
modification of the work as a means of enforcing, against the work's
|
|
||||||
users, your or third parties' legal rights to forbid circumvention of
|
|
||||||
technological measures.
|
|
||||||
|
|
||||||
4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
|
|
||||||
b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under section
|
|
||||||
7. This requirement modifies the requirement in section 4 to
|
|
||||||
"keep intact all notices".
|
|
||||||
|
|
||||||
c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
|
|
||||||
d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms
|
|
||||||
of sections 4 and 5, provided that you also convey the
|
|
||||||
machine-readable Corresponding Source under the terms of this License,
|
|
||||||
in one of these ways:
|
|
||||||
|
|
||||||
a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
|
|
||||||
b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the
|
|
||||||
Corresponding Source from a network server at no charge.
|
|
||||||
|
|
||||||
c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
|
|
||||||
d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
|
|
||||||
e) Convey the object code using peer-to-peer transmission, provided
|
|
||||||
you inform other peers where the object code and Corresponding
|
|
||||||
Source of the work are being offered to the general public at no
|
|
||||||
charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal, family,
|
|
||||||
or household purposes, or (2) anything designed or sold for incorporation
|
|
||||||
into a dwelling. In determining whether a product is a consumer product,
|
|
||||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
|
||||||
product received by a particular user, "normally used" refers to a
|
|
||||||
typical or common use of that class of product, regardless of the status
|
|
||||||
of the particular user or of the way in which the particular user
|
|
||||||
actually uses, or expects or is expected to use, the product. A product
|
|
||||||
is a consumer product regardless of whether the product has substantial
|
|
||||||
commercial, industrial or non-consumer uses, unless such uses represent
|
|
||||||
the only significant mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to install
|
|
||||||
and execute modified versions of a covered work in that User Product from
|
|
||||||
a modified version of its Corresponding Source. The information must
|
|
||||||
suffice to ensure that the continued functioning of the modified object
|
|
||||||
code is in no case prevented or interfered with solely because
|
|
||||||
modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or updates
|
|
||||||
for a work that has been modified or installed by the recipient, or for
|
|
||||||
the User Product in which it has been modified or installed. Access to a
|
|
||||||
network may be denied when the modification itself materially and
|
|
||||||
adversely affects the operation of the network or violates the rules and
|
|
||||||
protocols for communication across the network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders of
|
|
||||||
that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
|
|
||||||
b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
|
|
||||||
c) Prohibiting misrepresentation of the origin of that material, or
|
|
||||||
requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
|
|
||||||
d) Limiting the use for publicity purposes of names of licensors or
|
|
||||||
authors of the material; or
|
|
||||||
|
|
||||||
e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
|
|
||||||
f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions of
|
|
||||||
it) with contractual assumptions of liability to the recipient, for
|
|
||||||
any liability that these contractual assumptions directly impose on
|
|
||||||
those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions;
|
|
||||||
the above requirements apply either way.
|
|
||||||
|
|
||||||
8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your
|
|
||||||
license from a particular copyright holder is reinstated (a)
|
|
||||||
provisionally, unless and until the copyright holder explicitly and
|
|
||||||
finally terminates your license, and (b) permanently, if the copyright
|
|
||||||
holder fails to notify you of the violation by some reasonable means
|
|
||||||
prior to 60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or
|
|
||||||
run a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims
|
|
||||||
owned or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within
|
|
||||||
the scope of its coverage, prohibits the exercise of, or is
|
|
||||||
conditioned on the non-exercise of one or more of the rights that are
|
|
||||||
specifically granted under this License. You may not convey a covered
|
|
||||||
work if you are a party to an arrangement with a third party that is
|
|
||||||
in the business of distributing software, under which you make payment
|
|
||||||
to the third party based on the extent of your activity of conveying
|
|
||||||
the work, and under which the third party grants, to any of the
|
|
||||||
parties who would receive the covered work from you, a discriminatory
|
|
||||||
patent license (a) in connection with copies of the covered work
|
|
||||||
conveyed by you (or copies made from those copies), or (b) primarily
|
|
||||||
for and in connection with specific products or compilations that
|
|
||||||
contain the covered work, unless you entered into that arrangement,
|
|
||||||
or that patent license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you may
|
|
||||||
not convey it at all. For example, if you agree to terms that obligate you
|
|
||||||
to collect a royalty for further conveying from those to whom you convey
|
|
||||||
the Program, the only way you could satisfy both those terms and this
|
|
||||||
License would be to refrain entirely from conveying the Program.
|
|
||||||
|
|
||||||
13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
|
||||||
the GNU General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Program specifies that a certain numbered version of the GNU General
|
|
||||||
Public License "or any later version" applies to it, you have the
|
|
||||||
option of following the terms and conditions either of that numbered
|
|
||||||
version or of any later version published by the Free Software
|
|
||||||
Foundation. If the Program does not specify a version number of the
|
|
||||||
GNU General Public License, you may choose any version ever published
|
|
||||||
by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
|
||||||
versions of the GNU General Public License can be used, that proxy's
|
|
||||||
public statement of acceptance of a version permanently authorizes you
|
|
||||||
to choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
|
||||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
|
||||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
|
||||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
|
||||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
|
||||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
|
||||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
||||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
|
||||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGES.
|
|
||||||
|
|
||||||
17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
|
||||||
@@ -2,6 +2,209 @@ 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
|
||||||
|
|
||||||
|
*** Support $fseek, $ftell, $frewind, bug1496. [Howard Su]
|
||||||
|
|
||||||
|
*** Add --public-flat-rw, bug1511. [Stefan Wallentowitz]
|
||||||
|
|
||||||
|
*** Support vpiModule, bug1469. [Stefan Wallentowitz]
|
||||||
|
|
||||||
|
**** Make Syms file honor --output-split-cfuncs, bug1499. [Todd Strader]
|
||||||
|
|
||||||
|
**** Fix make test with no VERILATOR_ROOT, bug1494. [Ahmed El-Mahmoudy]
|
||||||
|
|
||||||
|
**** Fix error on multidimensional cells, bug1505. [Anderson Ignacio Da Silva]
|
||||||
|
|
||||||
|
**** Fix config_rev revision detection on old versions.
|
||||||
|
|
||||||
|
**** Fix false warning on backward indexing, bug1507. [Hao Shi]
|
||||||
|
|
||||||
|
**** Fix vpiType accessor, bug1509, bug1510. [Stefan Wallentowitz]
|
||||||
|
|
||||||
|
**** Fix ugly error on interface misuse, bug1525. [Bogdan Vukobratovic]
|
||||||
|
|
||||||
|
**** Fix misc bad-syntax crashes, bug1529-bug1533. [Eric Rippey]
|
||||||
|
|
||||||
|
**** Fix case statements with strings, bug1536. [Philipp Wagner]
|
||||||
|
|
||||||
|
|
||||||
|
* Verilator 4.018 2019-08-29
|
||||||
|
|
||||||
|
** When showing an error, show source code and offer suggestions of replacements.
|
||||||
|
|
||||||
|
** When showing an error, show the instance location, bug1305. [Todd Strader]
|
||||||
|
|
||||||
|
*** Add --rr, bug1481. [Todd Strader]
|
||||||
|
|
||||||
|
*** Change MULTITOP to warning to help linting, see manual.
|
||||||
|
|
||||||
|
*** Add XSim support to driver.pl, bug1493. [Todd Strader]
|
||||||
|
|
||||||
|
**** Show included-from filenames in warnings, bug1439. [Todd Strader]
|
||||||
|
|
||||||
|
**** Fix elaboration time errors, bug1429. [Udi Finkelstein]
|
||||||
|
|
||||||
|
**** Fix not reporting some duplicate signals/ports, bug1462. [Peter Gerst]
|
||||||
|
|
||||||
|
**** Fix not in array context on non-power-of-two slices, msg2946. [Yu Sheng Lin]
|
||||||
|
|
||||||
|
**** Fix system compile flags injection. [Gianfranco Costamagna]
|
||||||
|
|
||||||
|
**** Fix enum values not being sized based on parent, bug1442. [Dan Petrisko]
|
||||||
|
|
||||||
|
**** Fix internal error on gate optimization of assign, bug1475. [Oyvind Harboe]
|
||||||
|
|
||||||
|
**** Add --dpi-hdr-only, bug1491. [Todd Strader]
|
||||||
|
|
||||||
|
|
||||||
|
* Verilator 4.016 2019-06-16
|
||||||
|
|
||||||
|
*** Add --quiet-exit, bug1436. [Todd Strader]
|
||||||
|
|
||||||
|
**** Error continuation lines no longer have %Error prefix.
|
||||||
|
|
||||||
|
**** Support logical equivalence operator <->.
|
||||||
|
|
||||||
|
**** Support VerilatedFstC set_time_unit, bug1433. [Pieter Kapsenberg]
|
||||||
|
|
||||||
|
**** Support deferred assertions, bug1449. [Charles Eddleston]
|
||||||
|
|
||||||
|
**** Mark infrequently called functions with GCC cold attribute.
|
||||||
|
|
||||||
|
**** Fix sign-compare warning in verilated.cpp, bug1437. [Sergey Kvachonok]
|
||||||
|
|
||||||
|
**** Fix fault on $realtime with %t, bug1443. [Julien Margetts]
|
||||||
|
|
||||||
|
**** Fix $display with string without %s, bug1441. [Denis Rystsov]
|
||||||
|
|
||||||
|
**** Fix parameter function string returns, bug1441. [Denis Rystsov]
|
||||||
|
|
||||||
|
**** Fix invalid XML output due to special chars, bug1444. [Kanad Kanhere]
|
||||||
|
|
||||||
|
**** Fix performance when mulithreaded on 1 CPU, bug1455. [Stefan Wallentowitz]
|
||||||
|
|
||||||
|
**** Fix type and real parameter issues, bug1427, bug1456, bug1458. [Todd Strader]
|
||||||
|
|
||||||
|
**** Fix build error on MinGW, bug1460. [Richard Myers]
|
||||||
|
|
||||||
|
**** Fix not reporting some duplicate signals, bug1462. [Peter Gerst]
|
||||||
|
|
||||||
|
**** Fix --savable invalid C++ on packed arrays, bug1465. [Alex Chadwick]
|
||||||
|
|
||||||
|
**** Fix constant function return of function var, bug1467. [Roman Popov]
|
||||||
|
|
||||||
|
|
||||||
|
* Verilator 4.014 2019-05-08
|
||||||
|
|
||||||
|
*** Add --trace-fst-thread.
|
||||||
|
|
||||||
|
**** Support '#' comments in $readmem, bug1411. [Frederick Requin]
|
||||||
|
|
||||||
|
**** Support "'dx" constants, bug1423. [Udi Finkelstein]
|
||||||
|
|
||||||
|
**** For FST tracing use LZ4 compression. [Tony Bybell]
|
||||||
|
|
||||||
|
**** Add error when use parameters without value, bug1424. [Peter Gerst]
|
||||||
|
|
||||||
|
**** Auto-extend and WIDTH warn on unsized X/Zs, bug1423. [Udi Finkelstein]
|
||||||
|
|
||||||
|
**** Fix missing VL_SHIFTL_ errors, bug1412, bug1415. [Larry Lee]
|
||||||
|
|
||||||
|
**** Fix MinGW GCC 6 printf formats, bug1413. [Sergey Kvachonok]
|
||||||
|
|
||||||
|
**** Fix test problems when missing fst2vcd, bug1417. [Todd Strader]
|
||||||
|
|
||||||
|
**** Fix GTKWave register warning, bug1421. [Pieter Kapsenberg]
|
||||||
|
|
||||||
|
**** Fix FST enums not displaying, bug1426. [Danilo Ramos]
|
||||||
|
|
||||||
|
**** Fix table compile error with multiinterfaces, bug1431. [Bogdan Vukobratovic]
|
||||||
|
|
||||||
|
|
||||||
* Verilator 4.012 2019-3-23
|
* Verilator 4.012 2019-3-23
|
||||||
|
|
||||||
*** Add +verilator+seed, bug1396. [Stan Sokorac]
|
*** Add +verilator+seed, bug1396. [Stan Sokorac]
|
||||||
@@ -3218,7 +3421,7 @@ of input ports exists for tracing.
|
|||||||
* Verilator 0.0 1994/7/8
|
* Verilator 0.0 1994/7/8
|
||||||
|
|
||||||
**** First code written.
|
**** First code written.
|
||||||
|
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
This uses outline mode in Emacs. See C-h m [M-x describe-mode].
|
This uses outline mode in Emacs. See C-h m [M-x describe-mode].
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
GNU LESSER GENERAL PUBLIC LICENSE
|
GNU LESSER GENERAL PUBLIC LICENSE
|
||||||
Version 3, 29 June 2007
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
+15
-2
@@ -1,5 +1,7 @@
|
|||||||
|
\.clang-format
|
||||||
\.clang-tidy
|
\.clang-tidy
|
||||||
\.git/
|
\.git/
|
||||||
|
\.git$
|
||||||
\.svn/
|
\.svn/
|
||||||
\.(bak|old)/
|
\.(bak|old)/
|
||||||
\.(bak|old)$
|
\.(bak|old)$
|
||||||
@@ -13,6 +15,9 @@
|
|||||||
.*\.key
|
.*\.key
|
||||||
.*\.vcd
|
.*\.vcd
|
||||||
.*\.1
|
.*\.1
|
||||||
|
\.codacy\.yml
|
||||||
|
\.travis\.yml
|
||||||
|
/build/
|
||||||
/obj_dir/
|
/obj_dir/
|
||||||
/obj_dbg/
|
/obj_dbg/
|
||||||
/obj_nc/
|
/obj_nc/
|
||||||
@@ -25,8 +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/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$
|
||||||
@@ -35,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.*
|
||||||
@@ -42,11 +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/
|
||||||
doxygen-doc/.*
|
obj_dir.*
|
||||||
obj_dir/.*
|
|
||||||
TAGS
|
TAGS
|
||||||
.*~
|
.*~
|
||||||
|
|||||||
+90
-89
@@ -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
|
||||||
#
|
#
|
||||||
#*****************************************************************************
|
#*****************************************************************************
|
||||||
#
|
#
|
||||||
@@ -83,7 +83,7 @@ infodir = @infodir@
|
|||||||
pkgdatadir = @pkgdatadir@
|
pkgdatadir = @pkgdatadir@
|
||||||
|
|
||||||
# Directory in which to install pkgconfig file
|
# Directory in which to install pkgconfig file
|
||||||
# Generall ${prefix}/share/pkgconfig
|
# Generally ${prefix}/share/pkgconfig
|
||||||
pkgconfigdir = @pkgconfigdir@
|
pkgconfigdir = @pkgconfigdir@
|
||||||
|
|
||||||
# Directory in which to install data across multiple architectures
|
# Directory in which to install data across multiple architectures
|
||||||
@@ -104,27 +104,49 @@ 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 internals.txt internals.html \
|
INFOS = verilator.txt verilator.html verilator.pdf
|
||||||
internals.pdf verilator.txt verilator.html verilator.pdf \
|
|
||||||
$(VL_INST_MAN_FILES)
|
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
|
||||||
|
|
||||||
DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
|
DISTFILES_INC = $(INFOS) .gitignore \
|
||||||
*.in *.ac \
|
*.in *.ac \
|
||||||
Changes TODO \
|
Artistic \
|
||||||
|
Changes \
|
||||||
|
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 \
|
||||||
bin/verilator_gantt \
|
bin/verilator_gantt \
|
||||||
bin/verilator_includer \
|
bin/verilator_includer \
|
||||||
bin/verilator_profcfunc \
|
bin/verilator_profcfunc \
|
||||||
doxygen-mainpage doxygen.config verilator_logo.png \
|
docs/.gitignore \
|
||||||
|
docs/CONTRIBUTING.adoc \
|
||||||
|
docs/CONTRIBUTORS \
|
||||||
|
docs/Makefile.in \
|
||||||
|
docs/TODO \
|
||||||
|
docs/doxygen-mainpage \
|
||||||
|
docs/doxygen.config \
|
||||||
|
docs/install.adoc \
|
||||||
|
docs/internals.adoc \
|
||||||
|
docs/verilator_logo.png \
|
||||||
install-sh configure *.pod \
|
install-sh configure *.pod \
|
||||||
include/*.[chv]* \
|
include/*.[chv]* \
|
||||||
include/*.in \
|
include/*.in \
|
||||||
@@ -138,9 +160,15 @@ DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
|
|||||||
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* \
|
||||||
@@ -172,12 +200,21 @@ INST_PROJ_BIN_FILES = \
|
|||||||
|
|
||||||
DISTFILES := $(DISTFILES_INC)
|
DISTFILES := $(DISTFILES_INC)
|
||||||
|
|
||||||
|
EXAMPLES_FIRST = \
|
||||||
|
examples/make_hello_c \
|
||||||
|
examples/make_hello_sc \
|
||||||
|
|
||||||
|
EXAMPLES = $(EXAMPLES_FIRST) $(filter-out $(EXAMPLES_FIRST), $(sort $(wildcard examples/*)))
|
||||||
|
|
||||||
ifeq ($(OBJCACHE_JOBS),)
|
ifeq ($(OBJCACHE_JOBS),)
|
||||||
ifneq ($(OBJCACHE_HOSTS),)
|
ifneq ($(OBJCACHE_HOSTS),)
|
||||||
export OBJCACHE_JOBS := -j $(shell objcache --jobs "$(OBJCACHE_HOSTS)")
|
export OBJCACHE_JOBS := -j $(shell objcache --jobs "$(OBJCACHE_HOSTS)")
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
|
||||||
|
VL_INST_MAN_FILES = verilator.1 verilator_coverage.1 verilator_gantt.1 verilator_profcfunc.1
|
||||||
|
|
||||||
default: all
|
default: all
|
||||||
all: all_nomsg msg_test
|
all: all_nomsg msg_test
|
||||||
all_nomsg: verilator_exe $(VL_INST_MAN_FILES)
|
all_nomsg: verilator_exe $(VL_INST_MAN_FILES)
|
||||||
@@ -200,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
|
||||||
@@ -211,20 +250,22 @@ 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
|
||||||
|
|
||||||
examples: all_nomsg
|
examples: all_nomsg
|
||||||
for p in examples/* ; do \
|
for p in $(EXAMPLES) ; do \
|
||||||
$(MAKE) -C $$p VERILATOR_ROOT=`pwd` || exit 10; \
|
$(MAKE) -C $$p VERILATOR_ROOT=`pwd` || exit 10; \
|
||||||
done
|
done
|
||||||
|
|
||||||
|
.PHONY: docs
|
||||||
|
docs: info
|
||||||
|
|
||||||
info: $(INFOS)
|
info: $(INFOS)
|
||||||
|
|
||||||
# Use --no-split to avoid creating filenames > 14 chars.
|
|
||||||
%.1: ${srcdir}/bin/%
|
%.1: ${srcdir}/bin/%
|
||||||
pod2man $< $@
|
pod2man $< $@
|
||||||
|
|
||||||
@@ -243,47 +284,12 @@ 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
|
|
||||||
|
|
||||||
internals.txt: internals.pod
|
|
||||||
-rm -f $@
|
|
||||||
$(POD2TEXT) --loose $< > $@
|
|
||||||
|
|
||||||
internals.html: internals.pod
|
|
||||||
pod2html $< >$@
|
|
||||||
|
|
||||||
# PDF needs DIST variables; but having configure.ac as dependency isn't detected
|
|
||||||
internals.pdf: internals.pod Makefile $(POD2LATEXFIX)
|
|
||||||
pod2latex --full --out internals.tex $<
|
|
||||||
$(PERL) $(POD2LATEXFIX) "$(DISTTITLE) Internals Manual" "${DISTDATE}" < internals.tex > internals2.tex
|
|
||||||
mv internals2.tex internals.tex
|
|
||||||
pdflatex internals.tex
|
|
||||||
pdflatex internals.tex
|
|
||||||
-rm -f internals.toc internals.aux internals.idx internals.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
|
||||||
# Some scripts go into both the search path and pkgdatadir,
|
# Some scripts go into both the search path and pkgdatadir,
|
||||||
# so they can be found by the user, and under $VERILATOR_ROOT.
|
# so they can be found by the user, and under $VERILATOR_ROOT.
|
||||||
|
|
||||||
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
|
|
||||||
VL_INST_MAN_FILES = verilator.1 verilator_coverage.1 verilator_gantt.1 verilator_profcfunc.1
|
|
||||||
|
|
||||||
VL_INST_INC_BLDDIR_FILES = \
|
VL_INST_INC_BLDDIR_FILES = \
|
||||||
include/verilated_config.h \
|
include/verilated_config.h \
|
||||||
include/verilated.mk \
|
include/verilated.mk \
|
||||||
@@ -296,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)
|
||||||
@@ -327,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:
|
||||||
@@ -347,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)
|
||||||
|
|
||||||
@@ -367,34 +391,9 @@ install-here: installman ftp
|
|||||||
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
|
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
|
||||||
DISTNAMEREV = $(shell sed -e '/DTVERSION/!d' -e 's/.*verilator_\([^"]*\).*/\1/' -e q ${srcdir}/src/config_rev.h)
|
DISTNAMEREV = $(shell sed -e '/DTVERSION/!d' -e 's/.*verilator_\([^"]*\).*/\1/' -e q ${srcdir}/src/config_rev.h)
|
||||||
|
|
||||||
DIRPROJECT := $(shell project_dir --project)
|
|
||||||
VERILATOR_CAD_DIR = $(CAD_DIR)/verilator/$(DISTNAMEREV)/$(DIRPROJECT_ARCH)
|
VERILATOR_CAD_DIR = $(CAD_DIR)/verilator/$(DISTNAMEREV)/$(DIRPROJECT_ARCH)
|
||||||
INST_PROJ_CVS = cp_if_cvs_diff
|
INST_PROJ_CVS = cp_if_cvs_diff
|
||||||
|
|
||||||
install-project: dist
|
|
||||||
@echo "Install-project to $(DIRPROJECT)"
|
|
||||||
strip bin/verilator_bin*
|
|
||||||
strip bin/verilator_coverage_bin*
|
|
||||||
$(MAKE) install-project-quick
|
|
||||||
for p in $(VL_INST_MAN_FILES) ; do \
|
|
||||||
$(INSTALL_DATA) $$p $(DIRPROJECT_PREFIX)/man/man1/$$p; \
|
|
||||||
done
|
|
||||||
$(INST_PROJ_CVS) $(DISTNAME).tgz $(DIRPROJECT)/hw/utils/verilator/verilator.tgz
|
|
||||||
rm $(DISTNAME).tgz
|
|
||||||
|
|
||||||
install-project-quick:
|
|
||||||
ifeq ($(CFG_WITH_DEFENV),yes)
|
|
||||||
@echo "%Error: Reconfigure with './configure --disable-defenv' to avoid hardcoded paths."
|
|
||||||
false
|
|
||||||
endif
|
|
||||||
@echo "Install-project-quick (no strip) to $(DIRPROJECT)"
|
|
||||||
for p in $(INST_PROJ_FILES) ; do \
|
|
||||||
$(INST_PROJ_CVS) $$p $(DIRPROJECT)/hw/utils/verilator/$$p; \
|
|
||||||
done
|
|
||||||
for p in $(INST_PROJ_BIN_FILES) ; do \
|
|
||||||
$(INST_PROJ_CVS) $$p $(DIRPROJECT)/hw/utils/verilator/$$p-$(DIRPROJECT_ARCH); \
|
|
||||||
done
|
|
||||||
|
|
||||||
install-cadtools: dist
|
install-cadtools: dist
|
||||||
@echo "Install-project to $(CAD_DIR)"
|
@echo "Install-project to $(CAD_DIR)"
|
||||||
strip bin/verilator_bin*
|
strip bin/verilator_bin*
|
||||||
@@ -435,7 +434,8 @@ CPPCHECK_H = $(wildcard \
|
|||||||
$(srcdir)/src/*.h )
|
$(srcdir)/src/*.h )
|
||||||
CPPCHECK = src/cppcheck_filtered
|
CPPCHECK = src/cppcheck_filtered
|
||||||
CPPCHECK_FLAGS = --enable=all --inline-suppr \
|
CPPCHECK_FLAGS = --enable=all --inline-suppr \
|
||||||
--suppress=unusedScopedObject --suppress=cstyleCast --suppress=useInitializationList
|
--suppress=unusedScopedObject --suppress=cstyleCast --suppress=useInitializationList \
|
||||||
|
--suppress=nullPointerRedundantCheck
|
||||||
CPPCHECK_FLAGS += --xml
|
CPPCHECK_FLAGS += --xml
|
||||||
CPPCHECK_DEP = $(subst .cpp,.cppcheck,$(CPPCHECK_CPP))
|
CPPCHECK_DEP = $(subst .cpp,.cppcheck,$(CPPCHECK_CPP))
|
||||||
CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/src/obj_dbg -I$(srcdir)/src
|
CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/src/obj_dbg -I$(srcdir)/src
|
||||||
@@ -472,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
|
||||||
@@ -511,11 +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 test_*/obj_dir
|
rm -rf test_*/obj_dir
|
||||||
rm -rf examples/*/obj_dir examples/*/logs
|
rm -rf nodist/obj_dir
|
||||||
|
|
||||||
distclean maintainer-clean::
|
distclean maintainer-clean::
|
||||||
rm -f *.info* *.1 $(INFOS)
|
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*
|
||||||
@@ -530,7 +531,7 @@ TAGS: $(TAGFILES)
|
|||||||
.PHONY: doxygen
|
.PHONY: doxygen
|
||||||
|
|
||||||
doxygen:
|
doxygen:
|
||||||
$(DOXYGEN) doxygen.config
|
$(MAKE) -C docs doxygen
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
# Test targets
|
# Test targets
|
||||||
|
|||||||
+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.)
|
||||||
-211
@@ -1,211 +0,0 @@
|
|||||||
# DESCRIPTION: DOCUMENT source run through perl to produce README file
|
|
||||||
# Use 'make README' to produce the output file
|
|
||||||
|
|
||||||
=pod
|
|
||||||
|
|
||||||
=head1 NAME
|
|
||||||
|
|
||||||
This is the Verilator package README file.
|
|
||||||
|
|
||||||
=head1 DISTRIBUTION
|
|
||||||
|
|
||||||
http://www.veripool.org/verilator
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
=head1 DESCRIPTION
|
|
||||||
|
|
||||||
Verilator converts synthesizable (generally not behavioral) Verilog code
|
|
||||||
into C++ or SystemC code. It is not a complete simulator, just a
|
|
||||||
translator.
|
|
||||||
|
|
||||||
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 Linix-ish platform. Verilator also works on
|
|
||||||
Windows under Cygwin, and Windows under MinGW (gcc -mno-cygwin). Verilated
|
|
||||||
output (not Verilator itself) compiles under MSVC++ 2008 and newer.
|
|
||||||
|
|
||||||
=head1 INSTALLATION
|
|
||||||
|
|
||||||
For more details see
|
|
||||||
L<http://www.veripool.org/projects/verilator/wiki/Installing>.
|
|
||||||
|
|
||||||
If you will be modifying Verilator, you should use the "git" method as it
|
|
||||||
will let you track changes.
|
|
||||||
|
|
||||||
=over 4
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
The latest version is available at L<http://www.veripool.org/verilator>.
|
|
||||||
|
|
||||||
Download the latest package from that site, and decompress.
|
|
||||||
|
|
||||||
tar xvzf verilator_version.tgz
|
|
||||||
|
|
||||||
=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 you will need the C<perl>, C<make> (or C<gmake>), and
|
|
||||||
C<g++> (or C<clang>) packages.
|
|
||||||
|
|
||||||
To use Verilator FST tracing you will need the C<gtkwave> and C<libgz> (on
|
|
||||||
Ubuntu C<zlibc> C<zlib1g> C<zlib1g-dev>) packages installed.
|
|
||||||
|
|
||||||
To compile Verilator in addition to the above you need the C<flex>,
|
|
||||||
C<bison> and C<texi2html> packages installed.
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
C<cd> to the Verilator directory containing this README.
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
You now 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 the kit directory.
|
|
||||||
This allows the easiest experimentation and upgrading. It's also how most
|
|
||||||
EDA tools operate; to run you point to the tarball, no install is needed.
|
|
||||||
|
|
||||||
export VERILATOR_ROOT=`pwd` # if your shell is bash
|
|
||||||
setenv VERILATOR_ROOT `pwd` # if your shell is csh
|
|
||||||
./configure
|
|
||||||
|
|
||||||
=item 2.
|
|
||||||
|
|
||||||
To install globally onto a "cad" disk with multiple versions of every tool,
|
|
||||||
and add it to path using Modules/modulecmd:
|
|
||||||
|
|
||||||
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_//"`
|
|
||||||
|
|
||||||
After installing 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 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
|
|
||||||
|
|
||||||
=item 4.
|
|
||||||
|
|
||||||
Alternatively you can configure a prefix that install will populate, 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 you will need to add /opt/verilator-VERSION/bin to
|
|
||||||
PATH.
|
|
||||||
|
|
||||||
=back
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
Type C<make> to compile Verilator.
|
|
||||||
|
|
||||||
Type C<make test> to check the compilation.
|
|
||||||
|
|
||||||
Configure with C<--enable-longtests> for more complete developer tests.
|
|
||||||
Additional packages may be required for these tests.
|
|
||||||
|
|
||||||
You may get a error about a typedef conflict for uint32_t. Edit
|
|
||||||
verilated.h to change the typedef to work, probably to @samp{typedef
|
|
||||||
unsigned long uint32_t;}.
|
|
||||||
|
|
||||||
=item
|
|
||||||
|
|
||||||
If you used the VERILATOR_ROOT scheme you're done. Programs should set the
|
|
||||||
environment variable VERILATOR_ROOT to point to this distribution, then
|
|
||||||
execute $VERILATOR_ROOT/bin/verilator, which will find the path to all
|
|
||||||
needed files.
|
|
||||||
|
|
||||||
If you used the prefix scheme, now do a C<make install>. To run verilator,
|
|
||||||
have the verilator binary directory in your PATH (this should already be
|
|
||||||
true if using the default configure), and make sure VERILATOR_ROOT is not
|
|
||||||
set.
|
|
||||||
|
|
||||||
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.txt in the same directory as this README.
|
|
||||||
|
|
||||||
=head1 DIRECTORY STRUCTURE
|
|
||||||
|
|
||||||
The directories in the kit after de-taring are as follows:
|
|
||||||
|
|
||||||
bin/verilator => Compiler Wrapper invoked to Verilate code
|
|
||||||
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.v => Stub defines for linting
|
|
||||||
include/verilated.mk => Common makefile
|
|
||||||
src/ => Translator source code
|
|
||||||
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
|
|
||||||
test_regress => Internal tests
|
|
||||||
|
|
||||||
=head1 LIMITATIONS
|
|
||||||
|
|
||||||
See verilator.txt (or execute C<bin/verilator --help>) for limitations.
|
|
||||||
+655
-254
File diff suppressed because it is too large
Load Diff
+43
-45
@@ -17,13 +17,6 @@ eval 'exec perl -wS $0 ${1+"$@"}'
|
|||||||
|
|
||||||
require 5.006_001;
|
require 5.006_001;
|
||||||
use warnings;
|
use warnings;
|
||||||
BEGIN {
|
|
||||||
if ($ENV{DIRPROJECT} && $ENV{DIRPROJECT_PERL_BOOT}) {
|
|
||||||
# Magic to allow author testing of perl packages in local directory
|
|
||||||
require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
use Getopt::Long;
|
use Getopt::Long;
|
||||||
use FindBin qw($RealBin $RealScript);
|
use FindBin qw($RealBin $RealScript);
|
||||||
use IO::File;
|
use IO::File;
|
||||||
@@ -56,12 +49,12 @@ foreach my $sw (@ARGV) {
|
|||||||
|
|
||||||
Getopt::Long::config("no_auto_abbrev","pass_through");
|
Getopt::Long::config("no_auto_abbrev","pass_through");
|
||||||
if (! GetOptions (
|
if (! GetOptions (
|
||||||
# Major operating modes
|
# Major operating modes
|
||||||
"help" => \&usage,
|
"help" => \&usage,
|
||||||
"debug:s" => \&debug,
|
"debug:s" => \&debug,
|
||||||
# "version!" => \&version, # Also passthru'ed
|
# "version!" => \&version, # Also passthru'ed
|
||||||
# Additional parameters
|
# Additional parameters
|
||||||
"<>" => sub {}, # Ignored
|
"<>" => sub {}, # Ignored
|
||||||
)) {
|
)) {
|
||||||
pod2usage(-exitstatus=>2, -verbose=>0);
|
pod2usage(-exitstatus=>2, -verbose=>0);
|
||||||
}
|
}
|
||||||
@@ -73,7 +66,7 @@ run(verilator_coverage_bin()
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
sub usage {
|
sub usage {
|
||||||
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
pod2usage(-verbose=>2, -exitval=>0, -output=>\*STDOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub debug {
|
sub debug {
|
||||||
@@ -90,25 +83,25 @@ sub verilator_coverage_bin {
|
|||||||
my $bin = "";
|
my $bin = "";
|
||||||
# Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
|
# Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
|
||||||
my $basename = ($ENV{VERILATOR_COVERAGE_BIN}
|
my $basename = ($ENV{VERILATOR_COVERAGE_BIN}
|
||||||
|| "verilator_coverage_bin_dbg");
|
|| "verilator_coverage_bin_dbg");
|
||||||
if (defined($ENV{VERILATOR_ROOT})) {
|
if (defined($ENV{VERILATOR_ROOT})) {
|
||||||
my $dir = $ENV{VERILATOR_ROOT};
|
my $dir = $ENV{VERILATOR_ROOT};
|
||||||
if (-x "$dir/bin/$basename"
|
if (-x "$dir/bin/$basename"
|
||||||
|| -x "$dir/bin/$basename.exe") { # From a "make install" into VERILATOR_ROOT
|
|| -x "$dir/bin/$basename.exe") { # From a "make install" into VERILATOR_ROOT
|
||||||
$bin = "$dir/bin/$basename";
|
$bin = "$dir/bin/$basename";
|
||||||
} else {
|
} else {
|
||||||
$bin = "$dir/$basename"; # From pointing to kit directory
|
$bin = "$dir/$basename"; # From pointing to kit directory
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (-x "$RealBin/$basename"
|
if (-x "$RealBin/$basename"
|
||||||
|| -x "$RealBin/$basename.exe") {
|
|| -x "$RealBin/$basename.exe") {
|
||||||
$bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
|
$bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
|
||||||
} else {
|
} else {
|
||||||
$bin = $basename; # Find in PATH
|
$bin = $basename; # Find in PATH
|
||||||
}
|
}
|
||||||
# Note we don't look under bin/$basename which would be right if running
|
# Note we don't look under bin/$basename which would be right if running
|
||||||
# in the kit dir. Running that would likely break, since
|
# in the kit dir. Running that would likely break, since
|
||||||
# VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
|
# VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
|
||||||
}
|
}
|
||||||
return $bin;
|
return $bin;
|
||||||
}
|
}
|
||||||
@@ -125,23 +118,28 @@ sub run {
|
|||||||
system($command);
|
system($command);
|
||||||
my $status = $?;
|
my $status = $?;
|
||||||
if ($status) {
|
if ($status) {
|
||||||
if ($! =~ /no such file or directory/i) {
|
if ($! =~ /no such file or directory/i) {
|
||||||
warn "%Error: verilator_coverage: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
|
warn "%Error: verilator_coverage: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
|
||||||
}
|
}
|
||||||
if ($Debug) { # For easy rerunning
|
if ($Debug) { # For easy rerunning
|
||||||
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
|
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
|
||||||
warn "%Error: $command\n";
|
warn "%Error: $command\n";
|
||||||
}
|
}
|
||||||
if ($status & 127) {
|
if ($status & 127) {
|
||||||
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
|
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
|
||||||
warn "%Error: Verilator_coverage internal fault, sorry.\n" if !$Debug;
|
warn "%Error: Verilator_coverage internal fault, sorry.\n" if !$Debug;
|
||||||
} elsif (($status & 127) == 6) { # SIGABRT
|
} elsif (($status & 127) == 6) { # SIGABRT
|
||||||
warn "%Error: Verilator_coverage aborted.\n" if !$Debug;
|
warn "%Error: Verilator_coverage aborted.\n" if !$Debug;
|
||||||
} else {
|
} else {
|
||||||
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -271,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
|
||||||
|
|||||||
+55
-55
@@ -38,11 +38,11 @@ my $Opt_Lineno = 1;
|
|||||||
autoflush STDOUT 1;
|
autoflush STDOUT 1;
|
||||||
autoflush STDERR 1;
|
autoflush STDERR 1;
|
||||||
Getopt::Long::config("no_auto_abbrev");
|
Getopt::Long::config("no_auto_abbrev");
|
||||||
if (! GetOptions (
|
if (! GetOptions(
|
||||||
"help" => \&usage,
|
"help" => \&usage,
|
||||||
"debug" => \&debug,
|
"debug" => \&debug,
|
||||||
"<>" => \¶meter,
|
"<>" => \¶meter,
|
||||||
"lineno!" => \$Opt_Lineno,
|
"lineno!" => \$Opt_Lineno,
|
||||||
)) {
|
)) {
|
||||||
die "%Error: Bad usage, try 'verilator_difftree --help'\n";
|
die "%Error: Bad usage, try 'verilator_difftree --help'\n";
|
||||||
}
|
}
|
||||||
@@ -68,22 +68,22 @@ sub diff_dir {
|
|||||||
my %files;
|
my %files;
|
||||||
|
|
||||||
foreach my $fn (glob("$a/*.tree")) {
|
foreach my $fn (glob("$a/*.tree")) {
|
||||||
(my $base = $fn) =~ s!.*/!!;
|
(my $base = $fn) =~ s!.*/!!;
|
||||||
$files{$base}{a} = $fn;
|
$files{$base}{a} = $fn;
|
||||||
}
|
}
|
||||||
foreach my $fn (glob("$b/*.tree")) {
|
foreach my $fn (glob("$b/*.tree")) {
|
||||||
(my $base = $fn) =~ s!.*/!!;
|
(my $base = $fn) =~ s!.*/!!;
|
||||||
$files{$base}{b} = $fn;
|
$files{$base}{b} = $fn;
|
||||||
}
|
}
|
||||||
my $any;
|
my $any;
|
||||||
foreach my $base (sort (keys %files)) {
|
foreach my $base (sort (keys %files)) {
|
||||||
my $a = $files{$base}{a};
|
my $a = $files{$base}{a};
|
||||||
my $b = $files{$base}{b};
|
my $b = $files{$base}{b};
|
||||||
next if !$a || !$b;
|
next if !$a || !$b;
|
||||||
print "="x70,"\n";
|
print "="x70,"\n";
|
||||||
print "= $a <-> $b\n";
|
print "= $a <-> $b\n";
|
||||||
diff_file($a,$b);
|
diff_file($a,$b);
|
||||||
$any = 1;
|
$any = 1;
|
||||||
}
|
}
|
||||||
$any or warn("%Warning: No .tree files found that have similar base names:\n "
|
$any or warn("%Warning: No .tree files found that have similar base names:\n "
|
||||||
.join("\n ", sort keys %files),"\n");
|
.join("\n ", sort keys %files),"\n");
|
||||||
@@ -101,7 +101,7 @@ sub diff_file {
|
|||||||
my $vera = version_from($a);
|
my $vera = version_from($a);
|
||||||
my $verb = version_from($b);
|
my $verb = version_from($b);
|
||||||
my $verCvt = (($vera < 0x3900 && $verb >= 0x3900)
|
my $verCvt = (($vera < 0x3900 && $verb >= 0x3900)
|
||||||
|| ($vera >= 0x3900 && $verb < 0x3900));
|
|| ($vera >= 0x3900 && $verb < 0x3900));
|
||||||
|
|
||||||
filter($a, $tmp_a, $verCvt);
|
filter($a, $tmp_a, $verCvt);
|
||||||
filter($b, $tmp_b, $verCvt);
|
filter($b, $tmp_b, $verCvt);
|
||||||
@@ -115,8 +115,8 @@ sub version_from {
|
|||||||
# Return dump format
|
# Return dump format
|
||||||
my $f1 = IO::File->new ($fn) or die "%Error: $! $fn,";
|
my $f1 = IO::File->new ($fn) or die "%Error: $! $fn,";
|
||||||
while (defined (my $line=$f1->getline())) {
|
while (defined (my $line=$f1->getline())) {
|
||||||
last if $. > 10;
|
last if $. > 10;
|
||||||
return hex $1 if $line =~ /\(format (0x[0-9.]+)\)/;
|
return hex $1 if $line =~ /\(format (0x[0-9.]+)\)/;
|
||||||
}
|
}
|
||||||
return 1.0;
|
return 1.0;
|
||||||
}
|
}
|
||||||
@@ -130,36 +130,36 @@ sub filter {
|
|||||||
my $f2 = IO::File->new ($fn2,"w") or die "%Error: $! $fn2,";
|
my $f2 = IO::File->new ($fn2,"w") or die "%Error: $! $fn2,";
|
||||||
while (defined (my $line=$f1->getline())) {
|
while (defined (my $line=$f1->getline())) {
|
||||||
same_line:
|
same_line:
|
||||||
next if $line =~ / This=/;
|
next if $line =~ / This=/;
|
||||||
$line =~ s/0x[a-f0-9]+/0x/g;
|
$line =~ s/0x[a-f0-9]+/0x/g;
|
||||||
$line =~ s/<e[0-9]+\#?>/<e>/g;
|
$line =~ s/<e[0-9]+\#?>/<e>/g;
|
||||||
$line =~ s/{[a-z]*\d+}/{}/g if !$Opt_Lineno;
|
$line =~ s/{[a-z]*\d+}/{}/g if !$Opt_Lineno;
|
||||||
if ($verCvt) {
|
if ($verCvt) {
|
||||||
next if $line =~ /^ NETLIST/;
|
next if $line =~ /^ NETLIST/;
|
||||||
$line =~ s!\@dt=0x\(G?/?([^)]+)\)!$1!g; # NEW: @dt -> OLD: non @dt format
|
$line =~ s!\@dt=0x\(G?/?([^)]+)\)!$1!g; # NEW: @dt -> OLD: non @dt format
|
||||||
# # Below Ver1_Non_Dtyped may replace above further
|
# # Below Ver1_Non_Dtyped may replace above further
|
||||||
if ($line =~ /: ([A-Z]+) /) {
|
if ($line =~ /: ([A-Z]+) /) {
|
||||||
my $type = $1;
|
my $type = $1;
|
||||||
next if $type =~ 'DTYPE';
|
next if $type =~ 'DTYPE';
|
||||||
if ($type eq 'TYPETABLE' || $type eq 'RANGE') {
|
if ($type eq 'TYPETABLE' || $type eq 'RANGE') {
|
||||||
$line =~ /^(\s+\S+:) /; my $prefix = $1;
|
$line =~ /^(\s+\S+:) /; my $prefix = $1;
|
||||||
while (defined ($line=$f1->getline())) {
|
while (defined ($line=$f1->getline())) {
|
||||||
next if $line =~ /^\s+[a-z]/; # Table body
|
next if $line =~ /^\s+[a-z]/; # Table body
|
||||||
next if $line =~ /^${prefix}[0-9]:/;
|
next if $line =~ /^${prefix}[0-9]:/;
|
||||||
goto same_line;
|
goto same_line;
|
||||||
}
|
}
|
||||||
next;
|
next;
|
||||||
}
|
}
|
||||||
if ($Ver1_Non_Dtyped{$type}) {
|
if ($Ver1_Non_Dtyped{$type}) {
|
||||||
$line =~ s! w[0-9]+!!g;
|
$line =~ s! w[0-9]+!!g;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$line =~ s!\@dt=0$!NoW!g; # NEW: dt=null -> common format
|
$line =~ s!\@dt=0$!NoW!g; # NEW: dt=null -> common format
|
||||||
$line =~ s!\@dt=0 !NoW !g; # NEW: dt=null -> common format
|
$line =~ s!\@dt=0 !NoW !g; # NEW: dt=null -> common format
|
||||||
$line =~ s! s?w0$! NoW!g; # OLD: no width -> common format
|
$line =~ s! s?w0$! NoW!g; # OLD: no width -> common format
|
||||||
$line =~ s! s?w0 ! NoW !g; # OLD: no width -> common format
|
$line =~ s! s?w0 ! NoW !g; # OLD: no width -> common format
|
||||||
}
|
}
|
||||||
print $f2 $line;
|
print $f2 $line;
|
||||||
}
|
}
|
||||||
$f1->close;
|
$f1->close;
|
||||||
$f2->close;
|
$f2->close;
|
||||||
@@ -168,8 +168,8 @@ sub filter {
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
sub usage {
|
sub usage {
|
||||||
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
pod2usage(-verbose=>2, -exitval=>0, -output=>\*STDOUT);
|
||||||
exit(1);
|
exit(1); # Unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
sub debug {
|
sub debug {
|
||||||
@@ -179,11 +179,11 @@ sub debug {
|
|||||||
sub parameter {
|
sub parameter {
|
||||||
my $param = shift;
|
my $param = shift;
|
||||||
if (!defined $Opt_A) {
|
if (!defined $Opt_A) {
|
||||||
$Opt_A = $param;
|
$Opt_A = $param;
|
||||||
} elsif (!defined $Opt_B) {
|
} elsif (!defined $Opt_B) {
|
||||||
$Opt_B = $param;
|
$Opt_B = $param;
|
||||||
} else {
|
} else {
|
||||||
die "%Error: Unknown parameter: $param\n";
|
die "%Error: Unknown parameter: $param\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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
|
||||||
|
|||||||
+3
-3
@@ -43,8 +43,8 @@ exit(0);
|
|||||||
#######################################################################
|
#######################################################################
|
||||||
|
|
||||||
sub usage {
|
sub usage {
|
||||||
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
pod2usage(-verbose=>2, -exitval=>0, -output=>\*STDOUT);
|
||||||
exit(1);
|
exit(1); # Unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
sub parameter {
|
sub parameter {
|
||||||
@@ -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
|
||||||
|
|||||||
+88
-88
@@ -24,11 +24,11 @@ my $Opt_File;
|
|||||||
autoflush STDOUT 1;
|
autoflush STDOUT 1;
|
||||||
autoflush STDERR 1;
|
autoflush STDERR 1;
|
||||||
Getopt::Long::config("no_auto_abbrev");
|
Getopt::Long::config("no_auto_abbrev");
|
||||||
if (! GetOptions (
|
if (! GetOptions(
|
||||||
"help" => \&usage,
|
"help" => \&usage,
|
||||||
"debug" => \&debug,
|
"debug" => \&debug,
|
||||||
"<>" => \¶meter,
|
"<>" => \¶meter,
|
||||||
)) {
|
)) {
|
||||||
die "%Error: Bad usage, try 'verilator_profcfunc --help'\n";
|
die "%Error: Bad usage, try 'verilator_profcfunc --help'\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,8 +39,8 @@ profcfunc($Opt_File);
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
sub usage {
|
sub usage {
|
||||||
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
pod2usage(-verbose=>2, -exitval=>0, -output=>\*STDOUT);
|
||||||
exit(1);
|
exit(1); # Unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
sub debug {
|
sub debug {
|
||||||
@@ -50,9 +50,9 @@ sub debug {
|
|||||||
sub parameter {
|
sub parameter {
|
||||||
my $param = shift;
|
my $param = shift;
|
||||||
if (!defined $Opt_File) {
|
if (!defined $Opt_File) {
|
||||||
$Opt_File = $param;
|
$Opt_File = $param;
|
||||||
} else {
|
} else {
|
||||||
die "%Error: Unknown parameter: $param\n";
|
die "%Error: Unknown parameter: $param\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,13 +66,13 @@ sub profcfunc {
|
|||||||
my %funcs;
|
my %funcs;
|
||||||
|
|
||||||
while (defined (my $line=$fh->getline())) {
|
while (defined (my $line=$fh->getline())) {
|
||||||
# %time cumesec selfsec calls {stuff} name
|
# %time cumesec selfsec calls {stuff} name
|
||||||
if ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$/) {
|
if ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$/) {
|
||||||
my $pct=$1; my $sec=$2; my $calls=$3; my $func=$4;
|
my $pct=$1; my $sec=$2; my $calls=$3; my $func=$4;
|
||||||
$funcs{$func}{pct} += $pct;
|
$funcs{$func}{pct} += $pct;
|
||||||
$funcs{$func}{sec} += $sec;
|
$funcs{$func}{sec} += $sec;
|
||||||
$funcs{$func}{calls} += $calls;
|
$funcs{$func}{calls} += $calls;
|
||||||
}
|
}
|
||||||
# Older gprofs have no call column for single-call functions
|
# Older gprofs have no call column for single-call functions
|
||||||
# %time cumesec selfsec {stuff} name
|
# %time cumesec selfsec {stuff} name
|
||||||
elsif ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$/) {
|
elsif ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$/) {
|
||||||
@@ -88,10 +88,10 @@ sub profcfunc {
|
|||||||
my %pointer_mods;
|
my %pointer_mods;
|
||||||
my %verilated_mods;
|
my %verilated_mods;
|
||||||
foreach my $func (keys %funcs) {
|
foreach my $func (keys %funcs) {
|
||||||
if ($func =~ /(.*)::_eval\(([a-zA-Z_0-9]+__Syms).*\)$/) {
|
if ($func =~ /(.*)::_eval\(([a-zA-Z_0-9]+__Syms).*\)$/) {
|
||||||
$verilated_mods{$1} = qr/^$1/;
|
$verilated_mods{$1} = qr/^$1/;
|
||||||
$pointer_mods{$2} = $1;
|
$pointer_mods{$2} = $1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#print Dumper(\%pointer_mods, \%verilated_mods);
|
#print Dumper(\%pointer_mods, \%verilated_mods);
|
||||||
|
|
||||||
@@ -99,72 +99,72 @@ sub profcfunc {
|
|||||||
my %vfuncs;
|
my %vfuncs;
|
||||||
my %groups;
|
my %groups;
|
||||||
foreach my $func (keys %funcs) {
|
foreach my $func (keys %funcs) {
|
||||||
my $pct = $funcs{$func}{pct};
|
my $pct = $funcs{$func}{pct};
|
||||||
my $vfunc = $func;
|
my $vfunc = $func;
|
||||||
my $design;
|
my $design;
|
||||||
|
|
||||||
if ($func =~ /\(([a-zA-Z_0-9]+__Syms)/) {
|
if ($func =~ /\(([a-zA-Z_0-9]+__Syms)/) {
|
||||||
$design = $pointer_mods{$1};
|
$design = $pointer_mods{$1};
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach my $vde (keys %verilated_mods) {
|
foreach my $vde (keys %verilated_mods) {
|
||||||
last if $design;
|
last if $design;
|
||||||
if ($func =~ /$verilated_mods{$vde}/) {
|
if ($func =~ /$verilated_mods{$vde}/) {
|
||||||
$design=$vde;
|
$design=$vde;
|
||||||
last;
|
last;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($vfunc =~ /__PROF__([a-zA-Z_0-9]+)__l?([0-9]+)\(/) {
|
if ($vfunc =~ /__PROF__([a-zA-Z_0-9]+)__l?([0-9]+)\(/) {
|
||||||
$vfunc = sprintf("VBlock %s:%d", $1, $2);
|
$vfunc = sprintf("VBlock %s:%d", $1, $2);
|
||||||
$groups{type}{"Verilog Blocks under $design"} += $pct;
|
$groups{type}{"Verilog Blocks under $design"} += $pct;
|
||||||
$groups{design}{$design} += $pct;
|
$groups{design}{$design} += $pct;
|
||||||
$groups{module}{$1} += $pct;
|
$groups{module}{$1} += $pct;
|
||||||
} else {
|
} else {
|
||||||
if ($design) {
|
if ($design) {
|
||||||
$vfunc = sprintf("VCommon %s", $func);
|
$vfunc = sprintf("VCommon %s", $func);
|
||||||
$groups{type}{"Common code under $design"} += $pct;
|
$groups{type}{"Common code under $design"} += $pct;
|
||||||
$groups{design}{$design} += $pct;
|
$groups{design}{$design} += $pct;
|
||||||
$groups{module}{$design." common code"} += $pct;
|
$groups{module}{$design." common code"} += $pct;
|
||||||
} elsif ($func =~ /^VL_[A-Z0-9_]+/
|
} elsif ($func =~ /^VL_[A-Z0-9_]+/
|
||||||
|| $func =~ /^_?vl_[a-zA-Z0-9_]+/
|
|| $func =~ /^_?vl_[a-zA-Z0-9_]+/
|
||||||
|| $func =~ /^verilated/i) {
|
|| $func =~ /^verilated/i) {
|
||||||
$vfunc = sprintf("VLib %s", $func);
|
$vfunc = sprintf("VLib %s", $func);
|
||||||
$groups{type}{'VLib'} += $pct;
|
$groups{type}{'VLib'} += $pct;
|
||||||
$groups{design}{'VLib'} += $pct;
|
$groups{design}{'VLib'} += $pct;
|
||||||
$groups{module}{'VLib'} += $pct;
|
$groups{module}{'VLib'} += $pct;
|
||||||
} elsif ($func =~ /^_mcount_private/) {
|
} elsif ($func =~ /^_mcount_private/) {
|
||||||
$vfunc = sprintf("Prof %s", $func);
|
$vfunc = sprintf("Prof %s", $func);
|
||||||
$groups{type}{'Prof'} += $pct;
|
$groups{type}{'Prof'} += $pct;
|
||||||
$groups{design}{'Prof'} += $pct;
|
$groups{design}{'Prof'} += $pct;
|
||||||
$groups{module}{'Prof'} += $pct;
|
$groups{module}{'Prof'} += $pct;
|
||||||
} else {
|
} else {
|
||||||
$vfunc = sprintf("C++ %s", $func);
|
$vfunc = sprintf("C++ %s", $func);
|
||||||
$groups{type}{'C++'} += $pct;
|
$groups{type}{'C++'} += $pct;
|
||||||
$groups{design}{'C++'} += $pct;
|
$groups{design}{'C++'} += $pct;
|
||||||
$groups{module}{'C++'} += $pct;
|
$groups{module}{'C++'} += $pct;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$vfuncs{$vfunc} = $funcs{$func};
|
$vfuncs{$vfunc} = $funcs{$func};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
foreach my $type (qw(type design module)) {
|
foreach my $type (qw(type design module)) {
|
||||||
my $missing = 100;
|
my $missing = 100;
|
||||||
foreach (sort (keys %{$groups{$type}})) {
|
foreach (sort (keys %{$groups{$type}})) {
|
||||||
$missing -= $groups{$type}{$_};
|
$missing -= $groups{$type}{$_};
|
||||||
}
|
}
|
||||||
if ($missing) {
|
if ($missing) {
|
||||||
$groups{$type}{"\377Unaccounted for/rounding error"} = $missing;
|
$groups{$type}{"\377Unaccounted for/rounding error"} = $missing;
|
||||||
}
|
}
|
||||||
|
|
||||||
print("Overall summary by $type:\n");
|
print("Overall summary by $type:\n");
|
||||||
printf(" %-6s %s\n","% time",$type);
|
printf(" %-6s %s\n","% time",$type);
|
||||||
foreach my $what (sort (keys %{$groups{$type}})) {
|
foreach my $what (sort (keys %{$groups{$type}})) {
|
||||||
(my $pwhat = $what) =~ s/^\377//; # Just used to establish sort order
|
(my $pwhat = $what) =~ s/^\377//; # Just used to establish sort order
|
||||||
printf(" %6.2f %s\n", $groups{$type}{$what}, $pwhat);
|
printf(" %6.2f %s\n", $groups{$type}{$what}, $pwhat);
|
||||||
}
|
}
|
||||||
print("\n");
|
print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
print("Verilog code profile:\n");
|
print("Verilog code profile:\n");
|
||||||
@@ -181,14 +181,14 @@ sub profcfunc {
|
|||||||
|
|
||||||
my $cume = 0;
|
my $cume = 0;
|
||||||
foreach my $func (sort {$vfuncs{$b}{sec} <=> $vfuncs{$a}{sec}
|
foreach my $func (sort {$vfuncs{$b}{sec} <=> $vfuncs{$a}{sec}
|
||||||
|| $a cmp $b}
|
|| $a cmp $b}
|
||||||
(keys %vfuncs)) {
|
(keys %vfuncs)) {
|
||||||
$cume += $vfuncs{$func}{sec};
|
$cume += $vfuncs{$func}{sec};
|
||||||
printf +("%6.2f %9.2f %8.2f %8d %s\n",
|
printf +("%6.2f %9.2f %8.2f %8d %s\n",
|
||||||
$vfuncs{$func}{pct},
|
$vfuncs{$func}{pct},
|
||||||
$cume, $vfuncs{$func}{sec},
|
$cume, $vfuncs{$func}{sec},
|
||||||
$vfuncs{$func}{calls},
|
$vfuncs{$func}{calls},
|
||||||
$func);
|
$func);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,7 +212,7 @@ verilator_profcfunc - Read gprof report created with --prof-cfuncs
|
|||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
Verilator_profcfunc reads a profile report created by gprof. The names of
|
Verilator_profcfunc reads a profile report created by gprof. The names of
|
||||||
the functions are then transformed, assuming the user used verilator's
|
the functions are then transformed, assuming the user used Verilator's
|
||||||
--prof-cfuncs, and a report printed showing the percentage of time, etc,
|
--prof-cfuncs, and a report printed showing the percentage of time, etc,
|
||||||
in each Verilog block.
|
in each Verilog block.
|
||||||
|
|
||||||
@@ -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
|
||||||
+40
-23
@@ -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.012 2019-03-23],
|
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 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])
|
||||||
|
|
||||||
@@ -91,10 +91,10 @@ AC_SUBST(CFG_WITH_PREC11)
|
|||||||
AC_MSG_RESULT($CFG_WITH_PREC11)
|
AC_MSG_RESULT($CFG_WITH_PREC11)
|
||||||
|
|
||||||
# Compiler flags
|
# Compiler flags
|
||||||
CFLAGS=-I${includedir}
|
CFLAGS+=" -I${includedir}"
|
||||||
CPPFLAGS=-I${includedir}
|
CPPFLAGS+=" -I${includedir}"
|
||||||
CXXFLAGS=-I${includedir}
|
CXXFLAGS+=" -I${includedir}"
|
||||||
LDFLAGS=-L${libdir}
|
LDFLAGS+=" -L${libdir}"
|
||||||
|
|
||||||
# Checks for programs.
|
# Checks for programs.
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
@@ -273,25 +273,42 @@ AC_SUBST(CFG_CXXFLAGS_PARSER)
|
|||||||
# without this flag, even though there's a conditional to prevent the divide.
|
# without this flag, even though there's a conditional to prevent the divide.
|
||||||
# We still don't add no-div-by-zero as it throws message to stdout, though doesn't die.
|
# We still don't add no-div-by-zero as it throws message to stdout, though doesn't die.
|
||||||
#_MY_CXX_CHECK_OPT(-Wno-div-by-zero)
|
#_MY_CXX_CHECK_OPT(-Wno-div-by-zero)
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-faligned-new)
|
# For some reason -faligned-new does not work under Travis w/ clang but the
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-fbracket-depth=4096)
|
# configure test doesn't catch this either
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Qunused-arguments)
|
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,-Wno-bool-operation)
|
CFG_CXX_FLAGS_CMAKE="-faligned-new"
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-parentheses-equality)
|
m4_foreach([cflag],[
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-sign-compare)
|
[-fbracket-depth=4096],
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-uninitialized)
|
[-fcf-protection=none],
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-but-set-variable)
|
[-mno-cet],
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-parameter)
|
[-Qunused-arguments],
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-variable)
|
[-Wno-bool-operation],
|
||||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-shadow)
|
[-Wno-parentheses-equality],
|
||||||
|
[-Wno-sign-compare],
|
||||||
|
[-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)
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
*.1
|
||||||
|
*.html
|
||||||
|
*.pdf
|
||||||
|
Makefile
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
= How to contribute to Verilator
|
||||||
|
|
||||||
|
Thanks for using Verilator! We welcome your contributions in whatever form.
|
||||||
|
|
||||||
|
This contributing document contains some suggestions that may make
|
||||||
|
contributions flow more efficiently.
|
||||||
|
|
||||||
|
==== Did you find a bug?
|
||||||
|
|
||||||
|
* Please **Ensure the bug was not already reported** by searching
|
||||||
|
https://verilator.org/issues[Verilator Issues].
|
||||||
|
|
||||||
|
* If you're unable to find an open issue addressing the problem,
|
||||||
|
https://verilator.org/issues/new[open a new issue].
|
||||||
|
|
||||||
|
** Be sure to include a **code sample** or an **executable test case**
|
||||||
|
demonstrating the bug and expected behavior that is not occurring.
|
||||||
|
|
||||||
|
** The ideal example works against other simulators, and is in the
|
||||||
|
test_regress/t test format, as described in
|
||||||
|
link:internals.adoc[docs/internals].
|
||||||
|
|
||||||
|
==== Did you write a patch that fixes a bug?
|
||||||
|
|
||||||
|
* Please https://verilator.org/issues/new[Open a new issue].
|
||||||
|
|
||||||
|
* You may attach a patch to the issue, or (preferred) may point to a GitHub
|
||||||
|
repository branch within your GitHub account.
|
||||||
|
|
||||||
|
** Verilator uses Travis CI to provide continuous integration. You may
|
||||||
|
want to setup Travis CI on your GitHub branch to ensure your changes
|
||||||
|
keep the tests passing. See link:internals.adoc[docs/internals].
|
||||||
|
|
||||||
|
* Your source-code contributions must be certified as open source, under
|
||||||
|
the https://developercertificate.org/[Developer Certificate of
|
||||||
|
Origin]. On your first contribution, you must either:
|
||||||
|
|
||||||
|
** Have your patch include the addition of your name to
|
||||||
|
link:CONTRIBUTORS[docs/CONTRIBUTORS] (preferred).
|
||||||
|
|
||||||
|
** Use "git -s" as part of your commit. This adds a "signed-of-by"
|
||||||
|
attribute which will certify your contribution as described in the
|
||||||
|
https://github.com/wking/signed-off-by/blob/master/Documentation/SubmittingPatches[Signed-of-By
|
||||||
|
convention].
|
||||||
|
|
||||||
|
** Email, or post in an issue a statement that you certify your
|
||||||
|
contributions.
|
||||||
|
|
||||||
|
** In any of these cases your name will be added to
|
||||||
|
link:CONTRIBUTORS[docs/CONTRIBUTORS] and you are agreeing all future
|
||||||
|
contributions are also certified.
|
||||||
|
|
||||||
|
** We occasionally accept contributions where people do not want their
|
||||||
|
name published. Please email us; you must still certify your
|
||||||
|
contribution using email.
|
||||||
|
|
||||||
|
* Your test contributions are generally considered released into the public
|
||||||
|
domain, unless you request otherwise or put a GNU/Artistic license on
|
||||||
|
your test file.
|
||||||
|
|
||||||
|
* Most important is we get your patch. If you'd like to clean up
|
||||||
|
indentation and related issues ahead of our feedback, that is
|
||||||
|
appreciated; please see the coding conventions in
|
||||||
|
link:internals.adoc[docs/internals].
|
||||||
|
|
||||||
|
==== Do you have questions?
|
||||||
|
|
||||||
|
* Please see FAQ section and rest of the
|
||||||
|
https://verilator.org/verilator_doc.html[Verilator manual],
|
||||||
|
or https://verilator.org/verilator_doc.pdf[Verilator manual (PDF)].
|
||||||
|
|
||||||
|
* Ask any question in the
|
||||||
|
https://verilator.org/forum[Verilator forum].
|
||||||
|
|
||||||
|
==== Code of Conduct
|
||||||
|
|
||||||
|
* Our contributors and participants pledge to make participation in our
|
||||||
|
project and our community a positive experience for everyone. We follow
|
||||||
|
the https://www.contributor-covenant.org/version/1/4/code-of-conduct.html[Contributor
|
||||||
|
Covenant version 1.4].
|
||||||
|
|
||||||
|
Thanks!
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
The contributors listed below have certified their Verilator contributions
|
||||||
|
under the Developer Certificate of Origin
|
||||||
|
(https://developercertificate.org/).
|
||||||
|
|
||||||
|
Please see the Verilator manual for 200+ additional contributors. Thanks to
|
||||||
|
all.
|
||||||
|
|
||||||
|
Ahmed El-Mahmoudy
|
||||||
|
Alex Chadwick
|
||||||
|
Chris Randall
|
||||||
|
Driss Hafdi
|
||||||
|
Eric Rippey
|
||||||
|
Garrett Smith
|
||||||
|
Gianfranco Costamagna
|
||||||
|
Howard Su
|
||||||
|
Iztok Jeras
|
||||||
|
Jeremy Bennett
|
||||||
|
John Coiner
|
||||||
|
Julien Margetts
|
||||||
|
Kanad Kanhere
|
||||||
|
Kevin Kiningham
|
||||||
|
Lukasz Dalek
|
||||||
|
Maarten De Braekeleer
|
||||||
|
Matthew Ballance
|
||||||
|
Mike Popoloski
|
||||||
|
Patrick Stewart
|
||||||
|
Philipp Wagner
|
||||||
|
Richard Myers
|
||||||
|
Sebastien Van Cauwenberghe
|
||||||
|
Stefan Wallentowitz
|
||||||
|
Todd Strader
|
||||||
|
Wilson Snyder
|
||||||
|
Yves Mathieu
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
#*****************************************************************************
|
||||||
|
# DESCRIPTION: Verilator documentation: Makefile pre-configure version
|
||||||
|
#
|
||||||
|
# This file is part of Verilator.
|
||||||
|
#
|
||||||
|
# Code available from: https://verilator.org
|
||||||
|
#
|
||||||
|
#*****************************************************************************
|
||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
# Verilator 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.
|
||||||
|
#
|
||||||
|
#****************************************************************************/
|
||||||
|
#
|
||||||
|
# This file is intended only to be called from the top-level Verilator Makefile.
|
||||||
|
|
||||||
|
#### Start of system configuration section. ####
|
||||||
|
|
||||||
|
ASCIIDOCTOR = asciidoctor
|
||||||
|
DOXYGEN = doxygen
|
||||||
|
|
||||||
|
#### End of system configuration section. ####
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
|
||||||
|
default:
|
||||||
|
@echo "error: make not supported here, run 'make docs' from Verilator top-level"
|
||||||
|
|
||||||
|
%.html: %.adoc
|
||||||
|
$(ASCIIDOCTOR) $< -n -o $@
|
||||||
|
|
||||||
|
clean mostlyclean distclean maintainer-clean::
|
||||||
|
rm -f $(SCRIPTS) *.tmp
|
||||||
|
rm -f *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.kys *.log
|
||||||
|
rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs *.idx
|
||||||
|
rm -f *.ev *.evs *.ov *.ovs *.cv *.cvs *.ma *.mas
|
||||||
|
rm -f *.tex
|
||||||
|
|
||||||
|
distclean maintainer-clean::
|
||||||
|
rm -f *.info* *.1 *.html *.pdf $(INFOS)
|
||||||
|
rm -f Makefile
|
||||||
|
|
||||||
|
.PHONY: doxygen
|
||||||
|
|
||||||
|
doxygen:
|
||||||
|
$(DOXYGEN) doxygen.config
|
||||||
Executable → Regular
@@ -45,7 +45,7 @@ PROJECT_BRIEF = "Verilog to C translator"
|
|||||||
# exceed 55 pixels and the maximum width should not exceed 200 pixels.
|
# exceed 55 pixels and the maximum width should not exceed 200 pixels.
|
||||||
# Doxygen will copy the logo to the output directory.
|
# Doxygen will copy the logo to the output directory.
|
||||||
|
|
||||||
PROJECT_LOGO = veripool-logo.png
|
PROJECT_LOGO = verilator_logo.png
|
||||||
|
|
||||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||||
# base path where the generated documentation will be put.
|
# base path where the generated documentation will be put.
|
||||||
@@ -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.
|
||||||
@@ -0,0 +1,978 @@
|
|||||||
|
= Verilator Internals Documentation
|
||||||
|
: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 file discusses internal and programming details for Verilator. It's a
|
||||||
|
reference for developers and debugging problems.
|
||||||
|
|
||||||
|
See also the Verilator internals presentation at https://www.veripool.org.
|
||||||
|
|
||||||
|
== Code Flows
|
||||||
|
|
||||||
|
=== Verilator Flow
|
||||||
|
|
||||||
|
The main flow of Verilator can be followed by reading the Verilator.cpp
|
||||||
|
`process()` function:
|
||||||
|
|
||||||
|
. First, the files specified on the command line are read. Reading
|
||||||
|
involves preprocessing, then lexical analysis with Flex and parsing with
|
||||||
|
Bison. This produces an abstract syntax tree (AST) representation of the
|
||||||
|
design, which is what is visible in the .tree files described below.
|
||||||
|
|
||||||
|
. Verilator then makes a series of passes over the AST, progressively
|
||||||
|
refining and optimizing it.
|
||||||
|
|
||||||
|
. Cells in the AST first linked, which will read and parse additional files
|
||||||
|
as above.
|
||||||
|
|
||||||
|
. Functions, variable and other references are linked to their definitions.
|
||||||
|
|
||||||
|
. Parameters are resolved and the design is elaborated.
|
||||||
|
|
||||||
|
. Verilator then performs many additional edits and optimizations on the
|
||||||
|
hierarchical design. This includes coverage, assertions, X elimination,
|
||||||
|
inlining, constant propagation, and dead code elimination.
|
||||||
|
|
||||||
|
. References in the design are then pseudo-flattened. Each module's
|
||||||
|
variables and functions get "Scope" references. A scope reference is an
|
||||||
|
occurrence of that un-flattened variable in the flattened hierarchy. A
|
||||||
|
module that occurs only once in the hierarchy will have a single scope and
|
||||||
|
single VarScope for each variable. A module that occurs twice will have a
|
||||||
|
scope for each occurrence, and two VarScopes for each variable. This
|
||||||
|
allows optimizations to proceed across the flattened design, while still
|
||||||
|
preserving the hierarchy.
|
||||||
|
|
||||||
|
. Additional edits and optimizations proceed on the pseudo-flat design.
|
||||||
|
These include module references, function inlining, loop unrolling,
|
||||||
|
variable lifetime analysis, lookup table creation, always splitting, and
|
||||||
|
logic gate simplifications (pushing inverters, etc).
|
||||||
|
|
||||||
|
. Verilator orders the code. Best case, this results in a single "eval"
|
||||||
|
function which has all always statements flowing from top to bottom with no
|
||||||
|
loops.
|
||||||
|
|
||||||
|
. Verilator mostly removes the flattening, so that code may be shared
|
||||||
|
between multiple invocations of the same module. It localizes variables,
|
||||||
|
combines identical functions, expands macros to C primitives, adds branch
|
||||||
|
prediction hints, and performs additional constant propagation.
|
||||||
|
|
||||||
|
. Verilator finally writes the C++ modules.
|
||||||
|
|
||||||
|
=== Key Classes Used in the Verilator Flow
|
||||||
|
|
||||||
|
==== `AstNode`
|
||||||
|
|
||||||
|
The AST is represented at the top level by the class `AstNode`. This
|
||||||
|
abstract class has derived classes for the individual components
|
||||||
|
(e.g. `AstGenerate` for a generate block) or groups of components
|
||||||
|
(e.g. `AstNodeFTask` for functions and tasks, which in turn has `AstFunc`
|
||||||
|
and `AstTask` as derived classes).
|
||||||
|
|
||||||
|
Each `AstNode` has pointers to up to four children, accessed by the `op1p`
|
||||||
|
through `op4p` methods. These methods are then abstracted in a specific
|
||||||
|
Ast* node class to a more specific name. For example with the `AstIf` node
|
||||||
|
(for `if` statements), `ifsp` calls `op2p` to give the pointer to the AST
|
||||||
|
for the "then" block, while `elsesp` calls `op3p` to give the pointer to
|
||||||
|
the AST for the "else" block, or NULL if there is not one.
|
||||||
|
|
||||||
|
`AstNode` has the concept of a next and previous AST - for example the next
|
||||||
|
and previous statements in a block. Pointers to the AST for these
|
||||||
|
statements (if they exist) can be obtained using the `back` and `next`
|
||||||
|
methods.
|
||||||
|
|
||||||
|
It is useful to remember that the derived class `AstNetlist` is at the top
|
||||||
|
of the tree, so checking for this class is the standard way to see if you
|
||||||
|
are at the top of the tree.
|
||||||
|
|
||||||
|
By convention, each function/method uses the variable `nodep` as a pointer
|
||||||
|
to the `AstNode` currently being processed.
|
||||||
|
|
||||||
|
==== `AstNVisitor`
|
||||||
|
|
||||||
|
The passes are implemented by AST visitor classes. These are implemented
|
||||||
|
by subclasses of the abstract class, `AstNVisitor`. Each pass creates an
|
||||||
|
instance of the visitor class, which in turn implements a method to perform
|
||||||
|
the pass.
|
||||||
|
|
||||||
|
==== `V3Graph`
|
||||||
|
|
||||||
|
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 manipulate the graphs and to output them in
|
||||||
|
https://www.graphviz.org[GraphViz] dot format. `V3Graph.h` provides
|
||||||
|
documentation of this class.
|
||||||
|
|
||||||
|
==== `V3GraphVertex`
|
||||||
|
|
||||||
|
`V3GraphVertex` is the base class for vertices in a graph. Vertices have
|
||||||
|
an associated `fanout`, `color` and `rank`, which may be used in algorithms
|
||||||
|
for ordering the graph. A generic `user`/`userp` member variable is also
|
||||||
|
provided.
|
||||||
|
|
||||||
|
Virtual methods are provided to specify the name, color, shape and style to
|
||||||
|
be used in dot output. Typically users provide derived classes from
|
||||||
|
`V3GraphVertex` which will reimplement these methods.
|
||||||
|
|
||||||
|
Iterators are provided to access in and out edges. Typically these are used
|
||||||
|
in the form:
|
||||||
|
|
||||||
|
for (V3GraphEdge *edgep = vertexp->inBeginp();
|
||||||
|
edgep;
|
||||||
|
edgep = edgep->inNextp()) {
|
||||||
|
|
||||||
|
==== `V3GraphEdge`
|
||||||
|
|
||||||
|
`V3GraphEdge` is the base class for directed edges between pairs of
|
||||||
|
vertices. Edges have an associated `weight` and may also be made
|
||||||
|
`cutable`. A generic `user`/`userp` member variable is also provided.
|
||||||
|
|
||||||
|
Accessors, `fromp` and `top` return the "from" and "to" vertices
|
||||||
|
respectively.
|
||||||
|
|
||||||
|
Virtual methods are provided to specify the label, color and style to be
|
||||||
|
used in dot output. Typically users provided derived classes from
|
||||||
|
`V3GraphEdge` which will reimplement these methods.
|
||||||
|
|
||||||
|
==== `V3GraphAlg`
|
||||||
|
|
||||||
|
This is the base class for graph algorithms. It implements a `bool` method,
|
||||||
|
`followEdge` which algorithms can use to decide whether an edge is
|
||||||
|
followed. This method returns true if the graph edge has weight greater
|
||||||
|
than one and a user function, `edgeFuncp` (supplied in the constructor)
|
||||||
|
returns `true`.
|
||||||
|
|
||||||
|
A number of predefined derived algorithm classes and access methods are
|
||||||
|
provided and documented in `V3GraphAlg.cpp`.
|
||||||
|
|
||||||
|
=== Multithreaded Mode
|
||||||
|
|
||||||
|
In `--threads` mode, the frontend of the Verilator pipeline is the same as
|
||||||
|
serial mode, up until V3Order.
|
||||||
|
|
||||||
|
`V3Order` builds a fine-grained, statement-level dependency graph that
|
||||||
|
governs the ordering of code within a single `eval()` call. In serial mode,
|
||||||
|
that dependency graph is used to order all statements into a total serial
|
||||||
|
order. In parallel mode, the same dependency graph is the starting point
|
||||||
|
for a partitioner (`V3Partition`).
|
||||||
|
|
||||||
|
The partitioner's goal is to coarsen the fine-grained graph into a coarser
|
||||||
|
graph, while maintaining as much available parallelism as possible. Often
|
||||||
|
the partitioner can transform an input graph with millions of nodes into a
|
||||||
|
coarsened execution graph with a few dozen nodes, while maintaining enough
|
||||||
|
parallelism to take advantage of a modern multicore CPU. Runtime
|
||||||
|
synchronization cost is not prohibitive with so few nodes.
|
||||||
|
|
||||||
|
==== Partitioning
|
||||||
|
|
||||||
|
Our partitioner is similar to the one Vivek Sarkar described in his 1989
|
||||||
|
paper _Partitioning and Scheduling Parallel Programs for Multiprocessors_.
|
||||||
|
|
||||||
|
Let's define some terms:
|
||||||
|
|
||||||
|
==== Par Factor
|
||||||
|
|
||||||
|
The available parallelism or "par-factor" of a DAG is the total cost to
|
||||||
|
execute all nodes, divided by the cost to execute the longest critical path
|
||||||
|
through the graph. This is the speedup you would get from running the graph
|
||||||
|
in parallel, if given infinite CPU cores available and communication and
|
||||||
|
synchronization are zero.
|
||||||
|
|
||||||
|
==== Macro Task
|
||||||
|
|
||||||
|
When the partitioner coarsens the graph, it combines nodes together. Each
|
||||||
|
fine-grained node represents an atomic "task"; combined nodes in the
|
||||||
|
coarsened graph are "macro-tasks". This term comes from Sarkar. Each
|
||||||
|
macro-task executes from start to end on one processor, without any
|
||||||
|
synchronization to any other macro-task during its
|
||||||
|
execution. (Synchronization only happens before the macro-task begins or
|
||||||
|
after it ends.)
|
||||||
|
|
||||||
|
==== Edge Contraction
|
||||||
|
|
||||||
|
Verilator's partitioner, like Sarkar's, primarily relies on "edge
|
||||||
|
contraction" to coarsen the graph. It starts with one macro-task per atomic
|
||||||
|
task and iteratively combines pairs of edge-connected macro-tasks.
|
||||||
|
|
||||||
|
==== Local Critical Path
|
||||||
|
|
||||||
|
Each node in the graph has a "local" critical path. That's the critical
|
||||||
|
path from the start of the graph to the start of the node, plus the node's
|
||||||
|
cost, plus the critical path from the end of the node to the end of the
|
||||||
|
graph.
|
||||||
|
|
||||||
|
Sarkar calls out an important trade-off: coarsening the graph reduces
|
||||||
|
runtime synchronization overhead among the macro-tasks, but it tends to
|
||||||
|
increase the critical path through the graph and thus reduces par-factor.
|
||||||
|
|
||||||
|
Sarkar's partitioner, and ours, chooses pairs of macro-tasks to merge such
|
||||||
|
that the growth in critical path is minimized. Each candidate merge would
|
||||||
|
result in a new node, which would have some local critical path. We choose
|
||||||
|
the candidate that would produce the shortest local critical path. Repeat
|
||||||
|
until par-factor falls to a target threshold. It's a greedy algorithm, and
|
||||||
|
it's not guaranteed to produce the best partition (which Sarkar proves is
|
||||||
|
NP-hard).
|
||||||
|
|
||||||
|
==== Estimating Logic Costs
|
||||||
|
|
||||||
|
To compute the cost of any given path through the graph, Verilator
|
||||||
|
estimates an execution cost for each task. Each macro-task has an execution
|
||||||
|
cost which is simply the sum of its tasks' costs. We assume that
|
||||||
|
communication overhead and synchronization overhead are zero, so the cost
|
||||||
|
of any given path through the graph is simply the sum of macro-task
|
||||||
|
execution costs. Sarkar does almost the same thing, except that he has
|
||||||
|
nonzero estimates for synchronization costs.
|
||||||
|
|
||||||
|
Verilator's cost estimates are assigned by `InstrCountCostVisitor`. This
|
||||||
|
class is perhaps the most fragile piece of the multithread implementation.
|
||||||
|
It's easy to have a bug where you count something cheap (eg. accessing one
|
||||||
|
element of a huge array) as if it were expensive (eg. by counting it as if
|
||||||
|
it were an access to the entire array.) Even without such gross bugs, the
|
||||||
|
estimates this produce are only loosely predictive of actual runtime cost.
|
||||||
|
Multithread performance would be better with better runtime costs
|
||||||
|
estimates. This is an area to improve.
|
||||||
|
|
||||||
|
==== Scheduling Macro-Tasks at Runtime
|
||||||
|
|
||||||
|
After coarsening the graph, we must schedule the macro-tasks for runtime.
|
||||||
|
Sarkar describes two options: you can dynamically schedule tasks at
|
||||||
|
runtime, with a runtime graph follower. Sarkar calls this the
|
||||||
|
"macro-dataflow model." Verilator does not support this; early experiments
|
||||||
|
with this approach had poor performance.
|
||||||
|
|
||||||
|
The other option is to statically assign macro-tasks to threads, with each
|
||||||
|
thread running its macro-tasks in a static order. Sarkar describes this in
|
||||||
|
Chapter 5. Verilator takes this static approach. The only dynamic aspect is
|
||||||
|
that each macro task may block before starting, to wait until its
|
||||||
|
prerequisites on other threads have finished.
|
||||||
|
|
||||||
|
The synchronization cost is cheap if the prereqs are done. If they're not,
|
||||||
|
fragmentation (idle CPU cores waiting) is possible. This is the major
|
||||||
|
source of overhead in this approach. The `--prof-threads` switch and the
|
||||||
|
`verilator_gantt` script can visualize the time lost to such fragmentation.
|
||||||
|
|
||||||
|
==== Locating Variables for Best Spatial Locality
|
||||||
|
|
||||||
|
After scheduling all code, we attempt to locate variables in memory such
|
||||||
|
that variables accessed by a single macro-task are close together in
|
||||||
|
memory. This provides "spatial locality" -- when we pull in a 64-byte
|
||||||
|
cache line to access a 2-byte variable, we want the other 62 bytes to be
|
||||||
|
ones we'll also likely access soon, for best cache performance.
|
||||||
|
|
||||||
|
This turns out to be critical for performance. It should allow Verilator to
|
||||||
|
scale to very large models. We don't rely on our working set fitting in any
|
||||||
|
CPU cache; instead we essentially "stream" data into caches from
|
||||||
|
memory. It's not literally streaming, where the address increases
|
||||||
|
monotonically, but it should have similar performance characteristics, so
|
||||||
|
long as each macro-task's dataset fits in one core's local caches.
|
||||||
|
|
||||||
|
To achieve spatial locality, we tag each variable with the set of
|
||||||
|
macro-tasks that access it. Let's call this set the "footprint" of that
|
||||||
|
variable. The variables in a given module have a set of footprints. We can
|
||||||
|
order those footprints to minimize the distance between them (distance is
|
||||||
|
the number of macro-tasks that are different across any two footprints) and
|
||||||
|
then emit all variables into the struct in ordered-footprint order.
|
||||||
|
|
||||||
|
The footprint ordering is literally the traveling salesman problem, and we
|
||||||
|
use a TSP-approximation algorithm to get close to an optimal sort.
|
||||||
|
|
||||||
|
This is an old idea. Simulators designed at DEC in the early 1990s used
|
||||||
|
similar techniques to optimize both single-thread and multi-thread modes.
|
||||||
|
(Verilator does not optimize variable placement for spatial locality in
|
||||||
|
serial mode; that is a possible area for improvement.)
|
||||||
|
|
||||||
|
==== Improving Multithreaded Performance Further (a TODO list)
|
||||||
|
|
||||||
|
===== Wave Scheduling
|
||||||
|
|
||||||
|
To allow the Verilated model to run in parallel with the testbench, it
|
||||||
|
might be nice to support "wave" scheduling, in which work on a cycle begins
|
||||||
|
before `eval()` is called or continues after `eval()` returns. For now all
|
||||||
|
work on a cycle happens during the `eval()` call, leaving Verilator's
|
||||||
|
threads idle while the testbench (everything outside `eval()`) is
|
||||||
|
working. This would involve fundamental changes within the partitioner,
|
||||||
|
however, it's probably the best bet for hiding testbench latency.
|
||||||
|
|
||||||
|
===== Efficient Dynamic Scheduling
|
||||||
|
|
||||||
|
To scale to more than a few threads, we may revisit a fully dynamic
|
||||||
|
scheduler. For large (>16 core) systems it might make sense to dedicate an
|
||||||
|
entire core to scheduling, so that scheduler data structures would fit in
|
||||||
|
its L1 cache and thus the cost of traversing priority-ordered ready lists
|
||||||
|
would not be prohibitive.
|
||||||
|
|
||||||
|
===== Static Scheduling with Runtime Repack
|
||||||
|
|
||||||
|
We could modify the static scheduling approach by gathering actual
|
||||||
|
macro-task execution times at run time, and dynamically re-packing the
|
||||||
|
macro-tasks into the threads also at run time. Say, re-pack once every
|
||||||
|
10,000 cycles or something. This has the potential to do better than our
|
||||||
|
static estimates about macro-task run times. It could potentially react to
|
||||||
|
CPU cores that aren't performing equally, due to NUMA or thermal throttling
|
||||||
|
or nonuniform competing memory traffic or whatever.
|
||||||
|
|
||||||
|
===== Clock Domain Balancing
|
||||||
|
|
||||||
|
Right now Verilator makes no attempt to balance clock domains across
|
||||||
|
macro-tasks. For a multi-domain model, that could lead to bad gantt chart
|
||||||
|
fragmentation. This could be improved if it's a real problem in practice.
|
||||||
|
|
||||||
|
===== Other Forms of MTask Balancing
|
||||||
|
|
||||||
|
The largest source of runtime overhead is idle CPUs, which happens due to
|
||||||
|
variance between our predicted runtime for each MTask and its actual
|
||||||
|
runtime. That variance is magnified if MTasks are homogeneous, containing
|
||||||
|
similar repeating logic which was generally close together in source code
|
||||||
|
and which is still packed together even after going through Verilator's
|
||||||
|
digestive tract.
|
||||||
|
|
||||||
|
If Verilator could avoid doing that, and instead would take source logic
|
||||||
|
that was close together and distribute it across MTasks, that would
|
||||||
|
increase the diversity of any given MTask, and this should reduce variance
|
||||||
|
in the cost estimates.
|
||||||
|
|
||||||
|
One way to do that might be to make various "tie breaker" comparison
|
||||||
|
routines in the sources to rely more heavily on randomness, and generally
|
||||||
|
try harder not to keep input nodes together when we have the option to
|
||||||
|
scramble things.
|
||||||
|
|
||||||
|
===== Performance Regression
|
||||||
|
|
||||||
|
It would be nice if we had a regression of large designs, with some
|
||||||
|
diversity of design styles, to test on both single- and multi-threaded
|
||||||
|
modes. This would help to avoid performance regressions, and also to
|
||||||
|
evaluate the optimizations while minimizing the impact of parasitic noise.
|
||||||
|
|
||||||
|
===== Per-Instance Classes
|
||||||
|
|
||||||
|
If we have multiple instances of the same module, and they partition
|
||||||
|
differently (likely; we make no attempt to partition them the same) then
|
||||||
|
the variable sort will be suboptimal for either instance. A possible
|
||||||
|
improvement would be to emit a unique class for each instance of a module,
|
||||||
|
and sort its variables optimally for that instance's code stream.
|
||||||
|
|
||||||
|
=== Verilated Flow
|
||||||
|
|
||||||
|
The evaluation loop outputted by Verilator is designed to allow a single
|
||||||
|
function to perform evaluation under most situations.
|
||||||
|
|
||||||
|
On the first evaluation, the Verilated code calls initial blocks, and then
|
||||||
|
"settles" the modules, by evaluating functions (from always statements)
|
||||||
|
until all signals are stable.
|
||||||
|
|
||||||
|
On other evaluations, the Verilated code detects what input signals have
|
||||||
|
changes. If any are clocks, it calls the appropriate sequential functions
|
||||||
|
(from `always @ posedge` statements). Interspersed with sequential functions
|
||||||
|
it calls combo functions (from `always @*`). After this is complete, it
|
||||||
|
detects any changes due to combo loops or internally generated clocks, and
|
||||||
|
if one is found must reevaluate the model again.
|
||||||
|
|
||||||
|
For SystemC code, the `eval()` function is wrapped in a SystemC
|
||||||
|
`SC_METHOD`, sensitive to all inputs. (Ideally it would only be sensitive
|
||||||
|
to clocks and combo inputs, but tracing requires all signals to cause
|
||||||
|
evaluation, and the performance difference is small.)
|
||||||
|
|
||||||
|
If tracing is enabled, a callback examines all variables in the design for
|
||||||
|
changes, and writes the trace for each change. To accelerate this process
|
||||||
|
the evaluation process records a bitmask of variables that might have
|
||||||
|
changed; if clear, checking those signals for changes may be skipped.
|
||||||
|
|
||||||
|
== Coding Conventions
|
||||||
|
|
||||||
|
=== Indentation and Naming Style
|
||||||
|
|
||||||
|
We will work with contributors to fix up indentation style issues, but it
|
||||||
|
is appreciated if you could match our style:
|
||||||
|
|
||||||
|
* All files should contain the magic header to insure standard indentation:
|
||||||
|
+
|
||||||
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||||
|
+
|
||||||
|
This sets indentation to the `cc-mode` defaults. (Verilator predates a
|
||||||
|
CC-mode change of several years ago which overrides the defaults with GNU
|
||||||
|
style indentation; the `c-set-style` undoes that.)
|
||||||
|
|
||||||
|
* Use 4 spaces per level, and no tabs.
|
||||||
|
|
||||||
|
* Use 2 spaces between the end of source and the beginning of a comment.
|
||||||
|
|
||||||
|
* 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.
|
||||||
|
|
||||||
|
=== The `astgen` Script
|
||||||
|
|
||||||
|
Some of the code implementing passes is extremely repetitive, and must be
|
||||||
|
implemented for each sub-class of `AstNode`. However, while repetitive,
|
||||||
|
there is more variability than can be handled in C++ macros.
|
||||||
|
|
||||||
|
In Verilator this is implemented by using a Perl script, `astgen` to
|
||||||
|
pre-process the C++ code. For example in `V3Const.cpp` this is used to
|
||||||
|
implement the `visit()` functions for each binary operation using the
|
||||||
|
`TREEOP` macro.
|
||||||
|
|
||||||
|
The original C++ source code is transformed into C++ code in the `obj_opt`
|
||||||
|
and `obj_dbg` sub-directories (the former for the optimized version of
|
||||||
|
Verilator, the latter for the debug version). So for example `V3Const.cpp`
|
||||||
|
into `V3Const__gen.cpp`.
|
||||||
|
|
||||||
|
=== Visitor Functions
|
||||||
|
|
||||||
|
Verilator uses the "Visitor" design pattern to implement its refinement and
|
||||||
|
optimization passes. This allows separation of the pass algorithm from the
|
||||||
|
AST on which it operates. Wikipedia provides an introduction to the concept
|
||||||
|
at https://en.wikipedia.org/wiki/Visitor_pattern.
|
||||||
|
|
||||||
|
As noted above, all visitors are derived classes of `AstNVisitor`. All
|
||||||
|
derived classes of `AstNode` implement the `accept` method, which takes as
|
||||||
|
argument a reference to an instance or a `AstNVisitor` derived class and
|
||||||
|
applies the visit method of the `AstNVisitor` to the invoking AstNode
|
||||||
|
instance (i.e. `this`).
|
||||||
|
|
||||||
|
One possible difficulty is that a call to `accept` may perform an edit
|
||||||
|
which destroys the node it receives as argument. The
|
||||||
|
`acceptSubtreeReturnEdits` method of `AstNode` is provided to apply
|
||||||
|
`accept` and return the resulting node, even if the original node is
|
||||||
|
destroyed (if it is not destroyed it will just return the original node).
|
||||||
|
|
||||||
|
The behavior of the visitor classes is achieved by overloading the `visit`
|
||||||
|
function for the different `AstNode` derived classes. If a specific
|
||||||
|
implementation is not found, the system will look in turn for overloaded
|
||||||
|
implementations up the inheritance hierarchy. For example calling `accept`
|
||||||
|
on `AstIf` will look in turn for:
|
||||||
|
|
||||||
|
void visit(AstIf* nodep)
|
||||||
|
void visit(AstNodeIf* nodep)
|
||||||
|
void visit(AstNodeStmt* nodep)
|
||||||
|
void visit(AstNode* nodep)
|
||||||
|
|
||||||
|
There are three ways data is passed between visitor functions.
|
||||||
|
|
||||||
|
1. A visitor-class member variable. This is generally for passing "parent"
|
||||||
|
information down to children. `m_modp` is a common example. It's set to
|
||||||
|
NULL in the constructor, where that node (`AstModule` visitor) sets it,
|
||||||
|
then the children are iterated, then it's cleared. Children under an
|
||||||
|
`AstModule` will see it set, while nodes elsewhere will see it clear. If
|
||||||
|
there can be nested items (for example an `AstFor` under an `AstFor`) the
|
||||||
|
variable needs to be save-set-restored in the `AstFor` visitor, otherwise
|
||||||
|
exiting the lower for will lose the upper for's setting.
|
||||||
|
|
||||||
|
2. User attributes. Each `AstNode` (*Note.* The AST node, not the visitor)
|
||||||
|
has five user attributes, which may be accessed as an integer using the
|
||||||
|
`user1()` through `user5()` methods, or as a pointer (of type `AstNUser`)
|
||||||
|
using the `user1p()` through `user5p()` methods (a common technique lifted
|
||||||
|
from graph traversal packages).
|
||||||
|
+
|
||||||
|
A visitor first clears the one it wants to use by calling
|
||||||
|
`AstNode::user#ClearTree()`, then it can mark any node's `user#()` with whatever
|
||||||
|
data it wants. Readers just call `nodep->user()`, but may need to cast
|
||||||
|
appropriately, so you'll often see `VN_CAST(nodep->userp(), SOMETYPE)`.
|
||||||
|
At the top of each visitor are comments describing how the `user()` stuff
|
||||||
|
applies to that visitor class. For example:
|
||||||
|
+
|
||||||
|
// NODE STATE
|
||||||
|
// Cleared entire netlist
|
||||||
|
// AstModule::user1p() // bool. True to inline this module
|
||||||
|
+
|
||||||
|
This says that at the `AstNetlist` `user1ClearTree()` is called. Each
|
||||||
|
`AstModule`'s `user1()` is used to indicate if we're going to inline it.
|
||||||
|
+
|
||||||
|
These comments are important to make sure a `user#()` on a given `AstNode`
|
||||||
|
type is never being used for two different purposes.
|
||||||
|
+
|
||||||
|
Note that calling `user#ClearTree` is fast, it doesn't walk the tree, so
|
||||||
|
it's ok to call fairly often. For example, it's commonly called on every
|
||||||
|
module.
|
||||||
|
|
||||||
|
3. Parameters can be passed between the visitors in close to the "normal"
|
||||||
|
function caller to callee way. This is the second `vup` parameter of type
|
||||||
|
`AstNUser` that is ignored on most of the visitor functions. V3Width does
|
||||||
|
this, but it proved more messy than the above and is deprecated. (V3Width
|
||||||
|
was nearly the first module written. Someday this scheme may be removed,
|
||||||
|
as it slows the program down to have to pass vup everywhere.)
|
||||||
|
|
||||||
|
=== Iterators
|
||||||
|
|
||||||
|
`AstNVisitor` provides a set of iterators to facilitate walking over the
|
||||||
|
tree. Each operates on the current `AstNVisitor` class (as this) and takes
|
||||||
|
an argument type `AstNode*`.
|
||||||
|
|
||||||
|
`iterate`::
|
||||||
|
|
||||||
|
Applies the `accept` method of the `AstNode` to the visitor function.
|
||||||
|
|
||||||
|
`iterateAndNextIgnoreEdit`::
|
||||||
|
|
||||||
|
Applies the `accept` method of each `AstNode` in a list (i.e. connected by
|
||||||
|
`nextp` and `backp` pointers).
|
||||||
|
|
||||||
|
`iterateAndNextNull`::
|
||||||
|
|
||||||
|
Applies the `accept` method of each `AstNode` in a list, only if the
|
||||||
|
provided node is non-NULL. If a node is edited by the call to `accept`,
|
||||||
|
apply `accept` again, until the node does not change.
|
||||||
|
|
||||||
|
`iterateListBackwards`::
|
||||||
|
|
||||||
|
Applies the `accept` method of each `AstNode` in a list, starting with the
|
||||||
|
last one.
|
||||||
|
|
||||||
|
`iterateChildren`::
|
||||||
|
|
||||||
|
Applies the `iterateAndNextNull` method on each child `op1p` through `op4p`
|
||||||
|
in turn.
|
||||||
|
|
||||||
|
`iterateChildrenBackwards`::
|
||||||
|
|
||||||
|
Applies the `iterateListBackwards` method on each child `op1p` through
|
||||||
|
`op4p` in turn.
|
||||||
|
|
||||||
|
==== Caution on Using Iterators When Child Changes
|
||||||
|
|
||||||
|
Visitors often replace one node with another node; V3Width and V3Const are
|
||||||
|
major examples. A visitor which is the parent of such a replacement needs
|
||||||
|
to be aware that calling iteration may cause the children to change. For
|
||||||
|
example:
|
||||||
|
|
||||||
|
// nodep->lhsp() is 0x1234000
|
||||||
|
iterateAndNextNull(nodep->lhsp()); // and under covers nodep->lhsp() changes
|
||||||
|
// nodep->lhsp() is 0x5678400
|
||||||
|
iterateAndNextNull(nodep->lhsp());
|
||||||
|
|
||||||
|
Will work fine, as even if the first iterate causes a new node to take the
|
||||||
|
place of the `lhsp()`, that edit will update `nodep->lhsp()` and the second
|
||||||
|
call will correctly see the change. Alternatively:
|
||||||
|
|
||||||
|
lp = nodep->lhsp();
|
||||||
|
// nodep->lhsp() is 0x1234000, lp is 0x1234000
|
||||||
|
iterateAndNextNull(lp); **lhsp=NULL;** // and under covers nodep->lhsp() changes
|
||||||
|
// nodep->lhsp() is 0x5678400, lp is 0x1234000
|
||||||
|
iterateAndNextNull(lp);
|
||||||
|
|
||||||
|
This will cause bugs or a core dump, as lp is a dangling pointer. Thus it
|
||||||
|
is advisable to set lhsp=NULL shown in the *'s above to make sure these
|
||||||
|
dangles are avoided. Another alternative used in special cases mostly in
|
||||||
|
V3Width is to use acceptSubtreeReturnEdits, which operates on a single node
|
||||||
|
and returns the new pointer if any. Note acceptSubtreeReturnEdits does not
|
||||||
|
follow `nextp()` links.
|
||||||
|
|
||||||
|
lp = acceptSubtreeReturnEdits(lp)
|
||||||
|
|
||||||
|
=== Identifying Derived Classes
|
||||||
|
|
||||||
|
A common requirement is to identify the specific `AstNode` class we are
|
||||||
|
dealing with. For example a visitor might not implement separate `visit`
|
||||||
|
methods for `AstIf` and `AstGenIf`, but just a single method for the base
|
||||||
|
class:
|
||||||
|
|
||||||
|
void visit (AstNodeIf* nodep)
|
||||||
|
|
||||||
|
However that method might want to specify additional code if it is called
|
||||||
|
for `AstGenIf`. Verilator does this by providing a `VN_IS` method for each
|
||||||
|
possible node type, which returns true if the node is of that type (or
|
||||||
|
derived from that type). So our `visit` method could use:
|
||||||
|
|
||||||
|
if (VN_IS(nodep, AstGenIf) {
|
||||||
|
<code specific to AstGenIf>
|
||||||
|
}
|
||||||
|
|
||||||
|
Additionally the `VN_CAST` method converts pointers similar to C++
|
||||||
|
`dynamic_cast`. This either returns a pointer to the object cast to that
|
||||||
|
type (if it is of class `SOMETYPE`, or a derived class of `SOMETYPE`) or
|
||||||
|
else NULL. (However, for true/false tests use `VN_IS` as that is faster.)
|
||||||
|
|
||||||
|
== Testing
|
||||||
|
|
||||||
|
For an overview of how to write a test see the BUGS section of the
|
||||||
|
Verilator primary manual.
|
||||||
|
|
||||||
|
It is important to add tests for failures as well as success (for example
|
||||||
|
to check that an error message is correctly triggered).
|
||||||
|
|
||||||
|
Tests that fail should by convention have the suffix `_bad` in their name,
|
||||||
|
and include `fails = 1` in either their `compile` or `execute` step as
|
||||||
|
appropriate.
|
||||||
|
|
||||||
|
=== Preparing to Run Tests
|
||||||
|
|
||||||
|
For all tests to pass you must install the following packages:
|
||||||
|
|
||||||
|
* SystemC to compile the SystemC outputs, see http://systemc.org
|
||||||
|
|
||||||
|
* Parallel::Forker from CPAN to run tests in parallel, you can install this
|
||||||
|
with e.g. "sudo cpan install Parallel::Forker".
|
||||||
|
|
||||||
|
* vcddiff to find differences in VCD outputs. See the readme at
|
||||||
|
https://github.com/veripool/vcddiff
|
||||||
|
|
||||||
|
=== Controlling the Test Driver
|
||||||
|
|
||||||
|
Test drivers are written in PERL. All invoke the main test driver script,
|
||||||
|
which can provide detailed help on all the features available when writing
|
||||||
|
a test driver.
|
||||||
|
|
||||||
|
test_regress/t/driver.pl --help
|
||||||
|
|
||||||
|
For convenience, a summary of the most commonly used features is provided
|
||||||
|
here. All drivers require a call to `compile` subroutine to compile the
|
||||||
|
test. For run-time tests, this is followed by a call to the `execute`
|
||||||
|
subroutine. Both of these functions can optionally be provided with a hash
|
||||||
|
table as argument specifying additional options.
|
||||||
|
|
||||||
|
The test driver assumes by default that the source Verilog file name
|
||||||
|
matches the PERL driver name. So a test whose driver is `t/t_mytest.pl`
|
||||||
|
will expect a Verilog source file `t/t_mytest.v`. This can be changed
|
||||||
|
using the `top_filename` subroutine, for example
|
||||||
|
|
||||||
|
top_filename("t/t_myothertest.v");
|
||||||
|
|
||||||
|
By default all tests will run with major simulators (Icarus Verilog, NC,
|
||||||
|
VCS, ModelSim, etc) as well as Verilator, to allow results to be
|
||||||
|
compared. However if you wish a test only to be used with Verilator, you
|
||||||
|
can use the following:
|
||||||
|
|
||||||
|
scenarios(vlt => 1);
|
||||||
|
|
||||||
|
Of the many options that can be set through arguments to `compiler` and
|
||||||
|
`execute`, the following are particularly useful:
|
||||||
|
|
||||||
|
`verilator_flags2`::
|
||||||
|
|
||||||
|
A list of flags to be passed to verilator when compiling.
|
||||||
|
|
||||||
|
`fails`::
|
||||||
|
|
||||||
|
Set to 1 to indicate that the compilation or execution is intended to fail.
|
||||||
|
|
||||||
|
For example the following would specify that compilation requires two
|
||||||
|
defines and is expected to fail.
|
||||||
|
|
||||||
|
compile (
|
||||||
|
verilator_flags2 => ["-DSMALL_CLOCK -DGATED_COMMENT"],
|
||||||
|
fails => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
=== Regression Testing for Developers
|
||||||
|
|
||||||
|
Developers will also want to call ./configure with two extra flags:
|
||||||
|
|
||||||
|
`--enable-ccwarn`::
|
||||||
|
|
||||||
|
Causes the build to stop on warnings as well as errors. A good way to
|
||||||
|
ensure no sloppy code gets added, however it can be painful when it comes
|
||||||
|
to testing, since third party code used in the tests (e.g. SystemC) may not
|
||||||
|
be warning free.
|
||||||
|
|
||||||
|
`--enable-longtests`::
|
||||||
|
|
||||||
|
In addition to the standard C, SystemC examples, also run the tests in the
|
||||||
|
`test_regress` directory when using _make test_'. This is disabled by
|
||||||
|
default as SystemC installation problems would otherwise falsely indicate a
|
||||||
|
Verilator problem.
|
||||||
|
|
||||||
|
When enabling the long tests, some additional PERL modules are needed,
|
||||||
|
which you can install using cpan.
|
||||||
|
|
||||||
|
cpan install Unix::Processors
|
||||||
|
|
||||||
|
There are some traps to avoid when running regression tests
|
||||||
|
|
||||||
|
* When checking the MANIFEST, the test will barf on unexpected code in the
|
||||||
|
Verilator tree. So make sure to keep any such code outside the tree.
|
||||||
|
|
||||||
|
* Not all Linux systems install Perldoc by default. This is needed for the
|
||||||
|
`--help_' option to Verilator, and also for regression testing. This can be
|
||||||
|
installed using cpan:
|
||||||
|
+
|
||||||
|
cpan install Pod::Perldoc
|
||||||
|
+
|
||||||
|
Many Linux systems also offer a standard package for this. Red
|
||||||
|
Hat/Fedora/Centos offer _perl-Pod-Perldoc_', while Debian/Ubuntu/Linux Mint
|
||||||
|
offer `perl-doc'.
|
||||||
|
|
||||||
|
* Running regression may exhaust resources on some Linux systems,
|
||||||
|
particularly file handles and user processes. Increase these to
|
||||||
|
respectively 16,384 and 4,096. The method of doing this is system
|
||||||
|
dependent, but on Fedora Linux it would require editing the
|
||||||
|
`/etc/security/limits.conf` file as root.
|
||||||
|
|
||||||
|
=== Continuous Integration
|
||||||
|
|
||||||
|
Verilator has a https://travis-ci.com/verilator/verilator[Travis CI environment]
|
||||||
|
which automatically tests the master branch for test failures on new commits. It
|
||||||
|
also runs a daily cron job to validate all of the tests against different OS and
|
||||||
|
compiler versions.
|
||||||
|
|
||||||
|
Developers can connect Travis CI to their GitHub account so that the CI
|
||||||
|
environment can check their branches too by doing the following:
|
||||||
|
|
||||||
|
* Go to https://github.com/marketplace/travis-ci and follow the prompts
|
||||||
|
|
||||||
|
* Only the Open Source (FREE) version of Travis CI is required
|
||||||
|
|
||||||
|
* Under a Travis CI project click More options > Settings in order to set up a
|
||||||
|
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
|
||||||
|
|
||||||
|
=== --debug
|
||||||
|
|
||||||
|
When you run with `--debug` there are two primary output file types placed
|
||||||
|
into the obj_dir, .tree and .dot files.
|
||||||
|
|
||||||
|
=== .dot Output
|
||||||
|
|
||||||
|
Dot files are dumps of internal graphs in
|
||||||
|
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
|
||||||
|
output, for example:
|
||||||
|
|
||||||
|
dot -Tps -o ~/a.ps obj_dir/Vtop_foo.dot
|
||||||
|
|
||||||
|
You can then print a.ps. You may prefer gif format, which doesn't get
|
||||||
|
scaled so can be more useful with large graphs.
|
||||||
|
|
||||||
|
For dynamic graph viewing consider
|
||||||
|
http://zvtm.sourceforge.net/zgrviewer.html[ZGRViewer]. If you know of
|
||||||
|
better viewers let us know; ZGRViewer isn't great for large graphs.
|
||||||
|
|
||||||
|
=== .tree Output
|
||||||
|
|
||||||
|
Tree files are dumps of the AST Tree and are produced between every major
|
||||||
|
algorithmic stage. An example:
|
||||||
|
|
||||||
|
NETLIST 0x90fb00 <e1> {a0}
|
||||||
|
1: MODULE 0x912b20 <e8822> {a8} top L2 [P]
|
||||||
|
*1:2: VAR 0x91a780 <e74#> {a22} @dt=0xa2e640(w32) out_wide [O] WIRE
|
||||||
|
1:2:1: BASICDTYPE 0xa2e640 <e2149> {e24} @dt=this(sw32) integer kwd=integer range=[31:0]
|
||||||
|
|
||||||
|
The following summarizes the above example dump, with more detail on each
|
||||||
|
field in the section below.
|
||||||
|
|
||||||
|
[cols="20%,80%"]
|
||||||
|
|===
|
||||||
|
|
||||||
|
|`1:2:` | indicates the hierarchy of the `VAR` is the `op2p` pointer under
|
||||||
|
the `MODULE`, which in turn is the `op1p` pointer under the `NETLIST`
|
||||||
|
|
||||||
|
|`VAR` | is the AstNodeType.
|
||||||
|
|
||||||
|
| `0x91a780` | is the address of this node.
|
||||||
|
|
||||||
|
| `<e74>` | means the 74th edit to the netlist was the last modification to
|
||||||
|
this node.
|
||||||
|
|
||||||
|
| `{a22}` | indicates this node is related to line 22 in the source filename
|
||||||
|
"a", where "a" is the first file read, "z" the 26th, and "aa" the 27th.
|
||||||
|
|
||||||
|
| `@dt=0x...` | indicates the address of the data type this node contains.
|
||||||
|
|
||||||
|
| `w32` | indicates the width is 32 bits.
|
||||||
|
|
||||||
|
| `out_wide` | is the name of the node, in this case the name of the variable.
|
||||||
|
|
||||||
|
| `[O]` | are flags which vary with the type of node, in this case it means the
|
||||||
|
variable is an output.
|
||||||
|
|
||||||
|
|===
|
||||||
|
|
||||||
|
In more detail the following fields are dumped common to all nodes. They
|
||||||
|
are produced by the `AstNode::dump()` method:
|
||||||
|
|
||||||
|
Tree Hierarchy::
|
||||||
|
|
||||||
|
The dump lines begin with numbers and colons to indicate the child node
|
||||||
|
hierarchy. As noted above, `AstNode` has lists of items at the same level
|
||||||
|
in the AST, connected by the `nextp()` and `prevp()` pointers. These appear
|
||||||
|
as nodes at the same level. For example after inlining:
|
||||||
|
|
||||||
|
NETLIST 0x929c1c8 <e1> {a0} w0
|
||||||
|
1: MODULE 0x92bac80 <e3144> {e14} w0 TOP_t L1 [P]
|
||||||
|
1:1: CELLINLINE 0x92bab18 <e3686#> {e14} w0 v -> t
|
||||||
|
1:1: CELLINLINE 0x92bc1d8 <e3688#> {e24} w0 v__DOT__i_test_gen -> test_gen
|
||||||
|
...
|
||||||
|
1: MODULE 0x92b9bb0 <e503> {e47} w0 test_gen L3
|
||||||
|
...
|
||||||
|
|
||||||
|
AstNode type::
|
||||||
|
|
||||||
|
The textual name of this node AST type (always in capitals). Many of these
|
||||||
|
correspond directly to Verilog entities (for example `MODULE` and
|
||||||
|
`TASK`), but others are internal to Verilator (for example `NETLIST` and
|
||||||
|
`BASICDTYPE`).
|
||||||
|
|
||||||
|
Address of the node::
|
||||||
|
|
||||||
|
A hexadecimal address of the node in memory. Useful for examining with the
|
||||||
|
debugger.
|
||||||
|
|
||||||
|
Last edit number::
|
||||||
|
|
||||||
|
Of the form `<ennnn>` or `<ennnn#>` , where `nnnn` is the number
|
||||||
|
of the last edit to modify this node. The trailing `#` indicates the node
|
||||||
|
has been edited since the last tree dump (which typically means in the last
|
||||||
|
refinement or optimization pass). GDB can watch for this, see << /Debugging >>.
|
||||||
|
|
||||||
|
Source file and line::
|
||||||
|
|
||||||
|
Of the form `{xxnnnn}`, where C{xx} is the filename letter (or
|
||||||
|
letters) and `nnnn` is the line number within that file. The first file is
|
||||||
|
`a`, the 26th is `z`, the 27th is `aa` and so on.
|
||||||
|
|
||||||
|
User pointers::
|
||||||
|
|
||||||
|
Shows the value of the node's user1p...user5p, if non-NULL.
|
||||||
|
|
||||||
|
Data type::
|
||||||
|
|
||||||
|
Many nodes have an explicit data type. "@dt=0x..." indicates the address
|
||||||
|
of the data type (AstNodeDType) this node uses.
|
||||||
|
+
|
||||||
|
If a data type is present and is numeric, it then prints the width of the
|
||||||
|
item. This field is a sequence of flag characters and width data as follows:
|
||||||
|
+
|
||||||
|
* `s` if the node is signed.
|
||||||
|
* `d` if the node is a double (i.e a floating point entity).
|
||||||
|
* `w` always present, indicating this is the width field.
|
||||||
|
* `u` if the node is unsized.
|
||||||
|
* `/nnnn` if the node is unsized, where `nnnn` is the minimum width.
|
||||||
|
|
||||||
|
Name of the entity represented by the node if it exists::
|
||||||
|
|
||||||
|
For example for a `VAR` it is the name of the variable.
|
||||||
|
|
||||||
|
Many nodes follow these fields with additional node specific
|
||||||
|
information. Thus the `VARREF` node will print either `[LV]` or `[RV]`
|
||||||
|
to indicate a left value or right value, followed by the node of the
|
||||||
|
variable being referred to. For example:
|
||||||
|
|
||||||
|
1:2:1:1: VARREF 0x92c2598 <e509> {e24} w0 clk [RV] <- VAR 0x92a2e90 <e79> {e18} w0 clk [I] INPUT
|
||||||
|
|
||||||
|
In general, examine the `dump()` method in `V3AstNodes.cpp` of the node
|
||||||
|
type in question to determine additional fields that may be printed.
|
||||||
|
|
||||||
|
The `MODULE` has a list of `CELLINLINE` nodes referred to by its
|
||||||
|
`op1p()` pointer, connected by `nextp()` and `prevp()` pointers.
|
||||||
|
|
||||||
|
Similarly the `NETLIST` has a list of modules referred to by its `op1p()`
|
||||||
|
pointer.
|
||||||
|
|
||||||
|
=== Debugging with GDB
|
||||||
|
|
||||||
|
The test_regress/driver.pl script accepts `--debug --gdb` to start
|
||||||
|
Verilator under gdb and break when an error is hit or the program is about
|
||||||
|
to exit. You can also use `--debug --gdbbt` to just backtrace and then
|
||||||
|
exit gdb. To debug the Verilated executable, use `--gdbsim`.
|
||||||
|
|
||||||
|
If you wish to start Verilator under GDB (or another debugger), then you
|
||||||
|
can use `--debug` and look at the underlying invocation of
|
||||||
|
`verilator_dbg`. For example
|
||||||
|
|
||||||
|
t/t_alw_dly.pl --debug
|
||||||
|
|
||||||
|
shows it invokes the command:
|
||||||
|
|
||||||
|
../verilator_bin_dbg --prefix Vt_alw_dly --x-assign unique --debug
|
||||||
|
-cc -Mdir obj_dir/t_alw_dly --debug-check -f input.vc t/t_alw_dly.v
|
||||||
|
|
||||||
|
Start GDB, then `start` with the remaining arguments.
|
||||||
|
|
||||||
|
gdb ../verilator_bin_dbg
|
||||||
|
...
|
||||||
|
(gdb) start --prefix Vt_alw_dly --x-assign unique --debug -cc -Mdir
|
||||||
|
obj_dir/t_alw_dly --debug-check -f input.vc t/t_alw_dly.v
|
||||||
|
> obj_dir/t_alw_dly/vlt_compile.log
|
||||||
|
...
|
||||||
|
Temporary breakpoint 1, main (argc=13, argv=0xbfffefa4, env=0xbfffefdc)
|
||||||
|
at ../Verilator.cpp:615
|
||||||
|
615 ios::sync_with_stdio();
|
||||||
|
(gdb)
|
||||||
|
|
||||||
|
You can then continue execution with breakpoints as required.
|
||||||
|
|
||||||
|
To break at a specific edit number which changed a node (presumably to find
|
||||||
|
what made a <e####> line in the tree dumps):
|
||||||
|
|
||||||
|
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:
|
||||||
|
|
||||||
|
pn nodep
|
||||||
|
# or: call nodep->dumpGdb() # aliased to "pn" in src/.gdbinit
|
||||||
|
pnt nodep
|
||||||
|
# or: call nodep->dumpTreeGdb() # aliased to "pnt" in src/.gdbinit
|
||||||
|
|
||||||
|
When GDB halts, it is useful to understand that the backtrace will commonly
|
||||||
|
show the iterator functions between each invocation of `visit` in the
|
||||||
|
backtrace. You will typically see a frame sequence something like
|
||||||
|
|
||||||
|
...
|
||||||
|
visit()
|
||||||
|
iterateChildren()
|
||||||
|
iterateAndNext()
|
||||||
|
accept()
|
||||||
|
visit()
|
||||||
|
...
|
||||||
|
|
||||||
|
== Adding a New Feature
|
||||||
|
|
||||||
|
Generally what would you do to add a new feature?
|
||||||
|
|
||||||
|
. File an issue (if there isn't already) so others know what you're working on.
|
||||||
|
|
||||||
|
. Make a testcase in the test_regress/t/t_EXAMPLE format, see << /TESTING >>.
|
||||||
|
|
||||||
|
. If grammar changes are needed, look at the git version of VerilogPerl's
|
||||||
|
src/VParseGrammar.y, as this grammar supports the full SystemVerilog
|
||||||
|
language and has a lot of back-and-forth with Verilator's grammar. Copy
|
||||||
|
the appropriate rules to src/verilog.y and modify the productions.
|
||||||
|
|
||||||
|
. If a new Ast type is needed, add it to V3AstNodes.h.
|
||||||
|
|
||||||
|
. Now you can run "test_regress/t/t_{new testcase}.pl --debug" and it'll
|
||||||
|
probably fail but you'll see a test_regress/obj_dir/t_{newtestcase}/*.tree
|
||||||
|
file which you can examine to see if the parsing worked. See also the
|
||||||
|
sections above on debugging.
|
||||||
|
|
||||||
|
. Modify the later visitor functions to process the new feature as needed.
|
||||||
|
|
||||||
|
=== Adding a New Pass
|
||||||
|
|
||||||
|
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
|
||||||
|
pass. You'll need to add a call into your pass from the `process()`
|
||||||
|
function in `src/verilator.cpp`.
|
||||||
|
|
||||||
|
To get your pass to build you'll need to add its binary filename to the
|
||||||
|
list in `src/Makefile_obj.in` and reconfigure.
|
||||||
|
|
||||||
|
== Distribution
|
||||||
|
|
||||||
|
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.
|
||||||
|
Before Width: | Height: | Size: 9.9 KiB After Width: | Height: | Size: 9.9 KiB |
@@ -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,10 +21,10 @@ 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 inatall, and verilator is in your path. Otherwise find the
|
# package install, and verilator is in your path. Otherwise find the
|
||||||
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||||
ifeq ($(VERILATOR_ROOT),)
|
ifeq ($(VERILATOR_ROOT),)
|
||||||
VERILATOR = verilator
|
VERILATOR = verilator
|
||||||
@@ -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,10 +21,10 @@ 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 inatall, and verilator is in your path. Otherwise find the
|
# package install, and verilator is in your path. Otherwise find the
|
||||||
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||||
ifeq ($(VERILATOR_ROOT),)
|
ifeq ($(VERILATOR_ROOT),)
|
||||||
VERILATOR = verilator
|
VERILATOR = verilator
|
||||||
@@ -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
|
||||||
@@ -21,7 +21,7 @@ endif
|
|||||||
# Set up variables
|
# Set up variables
|
||||||
|
|
||||||
# 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 inatall, and verilator is in your path. Otherwise find the
|
# package install, and verilator is in your path. Otherwise find the
|
||||||
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||||
ifeq ($(VERILATOR_ROOT),)
|
ifeq ($(VERILATOR_ROOT),)
|
||||||
VERILATOR = verilator
|
VERILATOR = verilator
|
||||||
@@ -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) {}
|
||||||
@@ -41,7 +41,7 @@ int main(int argc, char** argv, char** env) {
|
|||||||
Verilated::commandArgs(argc, argv);
|
Verilated::commandArgs(argc, argv);
|
||||||
|
|
||||||
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
|
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
|
||||||
Vtop* top = new Vtop; // Or use a const unique_ptr, or the VL_UNIQUE_PTR wrapper
|
Vtop* top = new Vtop; // Or use a const unique_ptr, or the VL_UNIQUE_PTR wrapper
|
||||||
|
|
||||||
#if VM_TRACE
|
#if VM_TRACE
|
||||||
// If verilator was invoked with --trace argument,
|
// If verilator was invoked with --trace argument,
|
||||||
@@ -94,14 +94,14 @@ int main(int argc, char** argv, char** env) {
|
|||||||
|
|
||||||
#if VM_TRACE
|
#if VM_TRACE
|
||||||
// Dump trace data for this cycle
|
// Dump trace data for this cycle
|
||||||
if (tfp) tfp->dump (main_time);
|
if (tfp) tfp->dump(main_time);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Read outputs
|
// Read outputs
|
||||||
VL_PRINTF ("[%" VL_PRI64 "d] clk=%x rstl=%x iquad=%" VL_PRI64 "x"
|
VL_PRINTF("[%" VL_PRI64 "d] clk=%x rstl=%x iquad=%" VL_PRI64 "x"
|
||||||
" -> oquad=%" VL_PRI64"x owide=%x_%08x_%08x\n",
|
" -> oquad=%" VL_PRI64"x owide=%x_%08x_%08x\n",
|
||||||
main_time, top->clk, top->reset_l, top->in_quad,
|
main_time, top->clk, top->reset_l, top->in_quad,
|
||||||
top->out_quad, top->out_wide[2], top->out_wide[1], top->out_wide[0]);
|
top->out_quad, top->out_wide[2], top->out_wide[1], top->out_wide[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final model cleanup
|
// Final model cleanup
|
||||||
@@ -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
|
||||||
(
|
(
|
||||||
@@ -14,18 +14,18 @@ module top
|
|||||||
input fastclk,
|
input fastclk,
|
||||||
input reset_l,
|
input reset_l,
|
||||||
|
|
||||||
output [1:0] out_small,
|
output wire [1:0] out_small,
|
||||||
output [39:0] out_quad,
|
output wire [39:0] out_quad,
|
||||||
output [69:0] out_wide,
|
output wire [69:0] out_wide,
|
||||||
input [1:0] in_small,
|
input [1:0] in_small,
|
||||||
input [39:0] in_quad,
|
input [39:0] in_quad,
|
||||||
input [69:0] in_wide
|
input [69:0] in_wide
|
||||||
);
|
);
|
||||||
|
|
||||||
// Connect up the outputs, using some trivial logic
|
// Connect up the outputs, using some trivial logic
|
||||||
wire [1:0] out_small = ~reset_l ? '0 : (in_small + 2'b1);
|
assign out_small = ~reset_l ? '0 : (in_small + 2'b1);
|
||||||
wire [39:0] out_quad = ~reset_l ? '0 : (in_quad + 40'b1);
|
assign out_quad = ~reset_l ? '0 : (in_quad + 40'b1);
|
||||||
wire [69:0] out_wide = ~reset_l ? '0 : (in_wide + 70'b1);
|
assign out_wide = ~reset_l ? '0 : (in_wide + 70'b1);
|
||||||
|
|
||||||
// And an example sub module. The submodule will print stuff.
|
// And an example sub module. The submodule will print stuff.
|
||||||
sub sub (/*AUTOINST*/
|
sub sub (/*AUTOINST*/
|
||||||
@@ -21,7 +21,7 @@ endif
|
|||||||
# Set up variables
|
# Set up variables
|
||||||
|
|
||||||
# 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 inatall, and verilator is in your path. Otherwise find the
|
# package install, and verilator is in your path. Otherwise find the
|
||||||
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||||
ifeq ($(VERILATOR_ROOT),)
|
ifeq ($(VERILATOR_ROOT),)
|
||||||
VERILATOR = verilator
|
VERILATOR = verilator
|
||||||
@@ -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) {}
|
||||||
@@ -115,9 +115,9 @@ int sc_main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
// Apply inputs
|
// Apply inputs
|
||||||
if (VL_TIME_Q() > 1 && VL_TIME_Q() < 10) {
|
if (VL_TIME_Q() > 1 && VL_TIME_Q() < 10) {
|
||||||
reset_l = !1; // Assert reset
|
reset_l = !1; // Assert reset
|
||||||
} else if (VL_TIME_Q() > 1) {
|
} else if (VL_TIME_Q() > 1) {
|
||||||
reset_l = !0; // Deassert reset
|
reset_l = !0; // Deassert reset
|
||||||
}
|
}
|
||||||
|
|
||||||
// Simulate 1ns
|
// Simulate 1ns
|
||||||
@@ -49,7 +49,7 @@ module sub
|
|||||||
|
|
||||||
// An example assertion
|
// An example assertion
|
||||||
always_ff @ (posedge clk) begin
|
always_ff @ (posedge clk) begin
|
||||||
AssertionExample: assert (!reset_l || count_c<100);
|
AssertionExample: assert(!reset_l || count_c<100);
|
||||||
end
|
end
|
||||||
|
|
||||||
// And example coverage analysis
|
// And example coverage analysis
|
||||||
@@ -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
|
||||||
(
|
(
|
||||||
@@ -14,18 +14,18 @@ module top
|
|||||||
input fastclk,
|
input fastclk,
|
||||||
input reset_l,
|
input reset_l,
|
||||||
|
|
||||||
output [1:0] out_small,
|
output wire [1:0] out_small,
|
||||||
output [39:0] out_quad,
|
output wire [39:0] out_quad,
|
||||||
output [69:0] out_wide,
|
output wire [69:0] out_wide,
|
||||||
input [1:0] in_small,
|
input [1:0] in_small,
|
||||||
input [39:0] in_quad,
|
input [39:0] in_quad,
|
||||||
input [69:0] in_wide
|
input [69:0] in_wide
|
||||||
);
|
);
|
||||||
|
|
||||||
// Connect up the outputs, using some trivial logic
|
// Connect up the outputs, using some trivial logic
|
||||||
wire [1:0] out_small = ~reset_l ? '0 : (in_small + 2'b1);
|
assign out_small = ~reset_l ? '0 : (in_small + 2'b1);
|
||||||
wire [39:0] out_quad = ~reset_l ? '0 : (in_quad + 40'b1);
|
assign out_quad = ~reset_l ? '0 : (in_quad + 40'b1);
|
||||||
wire [69:0] out_wide = ~reset_l ? '0 : (in_wide + 70'b1);
|
assign out_wide = ~reset_l ? '0 : (in_wide + 70'b1);
|
||||||
|
|
||||||
// And an example sub module. The submodule will print stuff.
|
// And an example sub module. The submodule will print stuff.
|
||||||
sub sub (/*AUTOINST*/
|
sub sub (/*AUTOINST*/
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
+73
-24
@@ -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 | "
|
||||||
|
|
||||||
/***********************/
|
/***********************/
|
||||||
@@ -663,6 +675,7 @@ return(rc);
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef FST_DYNAMIC_ALIAS2_DISABLE
|
||||||
static int fstWriterSVarint(FILE *handle, int64_t v)
|
static int fstWriterSVarint(FILE *handle, int64_t v)
|
||||||
{
|
{
|
||||||
unsigned char buf[15]; /* ceil(64/7) = 10 + sign byte padded way up */
|
unsigned char buf[15]; /* ceil(64/7) = 10 + sign byte padded way up */
|
||||||
@@ -688,6 +701,7 @@ len = pnt-buf;
|
|||||||
fstFwrite(buf, len, 1, handle);
|
fstFwrite(buf, len, 1, handle);
|
||||||
return(len);
|
return(len);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/***********************/
|
/***********************/
|
||||||
@@ -952,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);
|
||||||
@@ -974,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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1682,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;
|
||||||
@@ -1874,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 */
|
||||||
@@ -1890,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;
|
||||||
|
|
||||||
@@ -1912,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;
|
||||||
@@ -2020,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);
|
||||||
|
|
||||||
@@ -2843,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);
|
||||||
@@ -2858,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);
|
||||||
@@ -2959,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);
|
||||||
@@ -2974,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);
|
||||||
@@ -3004,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 */
|
||||||
{
|
{
|
||||||
@@ -4810,6 +4855,7 @@ uint32_t cur_blackout = 0;
|
|||||||
int packtype;
|
int packtype;
|
||||||
unsigned char *mc_mem = NULL;
|
unsigned char *mc_mem = NULL;
|
||||||
uint32_t mc_mem_len; /* corresponds to largest value encountered in chain_table_lengths[i] */
|
uint32_t mc_mem_len; /* corresponds to largest value encountered in chain_table_lengths[i] */
|
||||||
|
int dumpvars_state = 0;
|
||||||
|
|
||||||
if(!xc) return(0);
|
if(!xc) return(0);
|
||||||
|
|
||||||
@@ -4819,7 +4865,6 @@ length_remaining = (uint32_t *)calloc(xc->maxhandle, sizeof(uint32_t));
|
|||||||
|
|
||||||
if(fv)
|
if(fv)
|
||||||
{
|
{
|
||||||
fprintf(fv, "$dumpvars\n");
|
|
||||||
#ifndef FST_WRITEX_DISABLE
|
#ifndef FST_WRITEX_DISABLE
|
||||||
fflush(fv);
|
fflush(fv);
|
||||||
setvbuf(fv, (char *) NULL, _IONBF, 0); /* even buffered IO is slow so disable it and use our own routines that don't need seeking */
|
setvbuf(fv, (char *) NULL, _IONBF, 0); /* even buffered IO is slow so disable it and use our own routines that don't need seeking */
|
||||||
@@ -4966,8 +5011,10 @@ for(;;)
|
|||||||
|
|
||||||
if(beg_tim)
|
if(beg_tim)
|
||||||
{
|
{
|
||||||
|
if(dumpvars_state == 1) { wx_len = sprintf(wx_buf, "$end\n"); fstWritex(xc, wx_buf, wx_len); dumpvars_state = 2; }
|
||||||
wx_len = sprintf(wx_buf, "#%" PRIu64 "\n", beg_tim);
|
wx_len = sprintf(wx_buf, "#%" PRIu64 "\n", beg_tim);
|
||||||
fstWritex(xc, wx_buf, wx_len);
|
fstWritex(xc, wx_buf, wx_len);
|
||||||
|
if(!dumpvars_state) { wx_len = sprintf(wx_buf, "$dumpvars\n"); fstWritex(xc, wx_buf, wx_len); dumpvars_state = 1; }
|
||||||
}
|
}
|
||||||
if((xc->num_blackouts)&&(cur_blackout != xc->num_blackouts))
|
if((xc->num_blackouts)&&(cur_blackout != xc->num_blackouts))
|
||||||
{
|
{
|
||||||
@@ -5400,8 +5447,10 @@ for(;;)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(dumpvars_state == 1) { wx_len = sprintf(wx_buf, "$end\n"); fstWritex(xc, wx_buf, wx_len); dumpvars_state = 2; }
|
||||||
wx_len = sprintf(wx_buf, "#%" PRIu64 "\n", time_table[i]);
|
wx_len = sprintf(wx_buf, "#%" PRIu64 "\n", time_table[i]);
|
||||||
fstWritex(xc, wx_buf, wx_len);
|
fstWritex(xc, wx_buf, wx_len);
|
||||||
|
if(!dumpvars_state) { wx_len = sprintf(wx_buf, "$dumpvars\n"); fstWritex(xc, wx_buf, wx_len); dumpvars_state = 1; }
|
||||||
|
|
||||||
if((xc->num_blackouts)&&(cur_blackout != xc->num_blackouts))
|
if((xc->num_blackouts)&&(cur_blackout != xc->num_blackouts))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ static const int LZ4_minLength = (MFLIMIT+1);
|
|||||||
/**************************************
|
/**************************************
|
||||||
* Common functions
|
* Common functions
|
||||||
**************************************/
|
**************************************/
|
||||||
static unsigned LZ4_NbCommonBytes (register size_t val)
|
static unsigned LZ4_NbCommonBytes (size_t val)
|
||||||
{
|
{
|
||||||
if (LZ4_isLittleEndian())
|
if (LZ4_isLittleEndian())
|
||||||
{
|
{
|
||||||
|
|||||||
+665
-513
File diff suppressed because it is too large
Load Diff
+548
-489
File diff suppressed because it is too large
Load Diff
+16
-5
@@ -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) \
|
||||||
@@ -116,8 +114,22 @@ endif
|
|||||||
|
|
||||||
ifneq ($(VM_THREADS),0)
|
ifneq ($(VM_THREADS),0)
|
||||||
ifneq ($(VM_THREADS),)
|
ifneq ($(VM_THREADS),)
|
||||||
|
CPPFLAGS += -DVL_THREADED
|
||||||
|
VK_LIBS_THREADED=1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(VM_TRACE_THREADED),0)
|
||||||
|
ifneq ($(VM_TRACE_THREADED),)
|
||||||
|
CPPFLAGS += -DVL_TRACE_THREADED
|
||||||
|
VK_LIBS_THREADED=1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifneq ($(VK_LIBS_THREADED),0)
|
||||||
|
ifneq ($(VK_LIBS_THREADED),)
|
||||||
# Need C++11 at least, so always default to newest
|
# Need C++11 at least, so always default to newest
|
||||||
CPPFLAGS += -DVL_THREADED $(CFG_CXXFLAGS_STD_NEWEST)
|
CPPFLAGS += $(CFG_CXXFLAGS_STD_NEWEST)
|
||||||
LDLIBS += $(CFG_LDLIBS_THREADS)
|
LDLIBS += $(CFG_LDLIBS_THREADS)
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
@@ -159,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) $@
|
||||||
|
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
// Code available from: http://www.veripool.org/verilator
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
//
|
//
|
||||||
@@ -17,7 +17,7 @@
|
|||||||
//=========================================================================
|
//=========================================================================
|
||||||
//
|
//
|
||||||
// DESCRIPTION: Verilator: Include in verilog files to hide verilator defines
|
// DESCRIPTION: Verilator: Include in verilog files to hide verilator defines
|
||||||
|
|
||||||
`ifdef _VERILATED_V_ `else
|
`ifdef _VERILATED_V_ `else
|
||||||
`define _VERILATED_V_ 1
|
`define _VERILATED_V_ 1
|
||||||
|
|
||||||
|
|||||||
@@ -16,10 +16,10 @@
|
|||||||
/// \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
|
||||||
///
|
///
|
||||||
//*************************************************************************
|
//*************************************************************************
|
||||||
|
|
||||||
|
|
||||||
///**** Product and Version name
|
///**** Product and Version name
|
||||||
|
|
||||||
|
|||||||
+238
-236
@@ -50,10 +50,10 @@ public: // But only local to this file
|
|||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
// Derived classes should call zero() in their constructor
|
// Derived classes should call zero() in their constructor
|
||||||
VerilatedCovImpItem() {
|
VerilatedCovImpItem() {
|
||||||
for (int i=0; i<MAX_KEYS; ++i) {
|
for (int i=0; i<MAX_KEYS; ++i) {
|
||||||
m_keys[i]=KEY_UNDEF;
|
m_keys[i] = KEY_UNDEF;
|
||||||
m_vals[i]=0;
|
m_vals[i] = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual ~VerilatedCovImpItem() {}
|
virtual ~VerilatedCovImpItem() {}
|
||||||
virtual vluint64_t count() const = 0;
|
virtual vluint64_t count() const = 0;
|
||||||
@@ -96,7 +96,7 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
VerilatedMutex m_mutex; ///< Protects all members, when VL_THREADED. Wrapper deals with setting it.
|
VerilatedMutex m_mutex; ///< Protects all members, when VL_THREADED. Wrapper deals with setting it.
|
||||||
ValueIndexMap m_valueIndexes VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value
|
ValueIndexMap m_valueIndexes VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value
|
||||||
IndexValueMap m_indexValues VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value
|
IndexValueMap m_indexValues VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value
|
||||||
ItemList m_items VL_GUARDED_BY(m_mutex); ///< List of all items
|
ItemList m_items VL_GUARDED_BY(m_mutex); ///< List of all items
|
||||||
@@ -107,294 +107,296 @@ private:
|
|||||||
|
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VerilatedCovImp() {
|
VerilatedCovImp() {
|
||||||
m_insertp = NULL;
|
m_insertp = NULL;
|
||||||
m_insertFilenamep = NULL;
|
m_insertFilenamep = NULL;
|
||||||
m_insertLineno = 0;
|
m_insertLineno = 0;
|
||||||
}
|
}
|
||||||
VL_UNCOPYABLE(VerilatedCovImp);
|
VL_UNCOPYABLE(VerilatedCovImp);
|
||||||
public:
|
public:
|
||||||
~VerilatedCovImp() { clearGuts(); }
|
~VerilatedCovImp() { clearGuts(); }
|
||||||
static VerilatedCovImp& imp() VL_MT_SAFE {
|
static VerilatedCovImp& imp() VL_MT_SAFE {
|
||||||
static VerilatedCovImp s_singleton;
|
static VerilatedCovImp s_singleton;
|
||||||
return s_singleton;
|
return s_singleton;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// PRIVATE METHODS
|
// PRIVATE METHODS
|
||||||
int valueIndex(const std::string& value) VL_REQUIRES(m_mutex) {
|
int valueIndex(const std::string& value) VL_REQUIRES(m_mutex) {
|
||||||
static int nextIndex = KEY_UNDEF+1;
|
static int nextIndex = KEY_UNDEF+1;
|
||||||
ValueIndexMap::iterator iter = m_valueIndexes.find(value);
|
ValueIndexMap::iterator iter = m_valueIndexes.find(value);
|
||||||
if (iter != m_valueIndexes.end()) return iter->second;
|
if (iter != m_valueIndexes.end()) return iter->second;
|
||||||
nextIndex++; assert(nextIndex>0);
|
nextIndex++; assert(nextIndex>0);
|
||||||
m_valueIndexes.insert(std::make_pair(value, nextIndex));
|
m_valueIndexes.insert(std::make_pair(value, nextIndex));
|
||||||
m_indexValues.insert(std::make_pair(nextIndex, value));
|
m_indexValues.insert(std::make_pair(nextIndex, value));
|
||||||
return nextIndex;
|
return nextIndex;
|
||||||
}
|
}
|
||||||
static std::string dequote(const std::string& text) VL_PURE {
|
static std::string dequote(const std::string& text) VL_PURE {
|
||||||
// Quote any special characters
|
// Quote any special characters
|
||||||
std::string rtn;
|
std::string rtn;
|
||||||
for (const char* pos = text.c_str(); *pos; ++pos) {
|
for (const char* pos = text.c_str(); *pos; ++pos) {
|
||||||
if (!isprint(*pos) || *pos=='%' || *pos=='"') {
|
if (!isprint(*pos) || *pos=='%' || *pos=='"') {
|
||||||
char hex[10]; sprintf(hex,"%%%02X",pos[0]);
|
char hex[10]; sprintf(hex, "%%%02X", pos[0]);
|
||||||
rtn += hex;
|
rtn += hex;
|
||||||
} else {
|
} else {
|
||||||
rtn += *pos;
|
rtn += *pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rtn;
|
return rtn;
|
||||||
}
|
}
|
||||||
static bool legalKey(const std::string& key) VL_PURE {
|
static bool legalKey(const std::string& key) VL_PURE {
|
||||||
// Because we compress long keys to a single letter, and
|
// Because we compress long keys to a single letter, and
|
||||||
// don't want applications to either get confused if they use
|
// don't want applications to either get confused if they use
|
||||||
// a letter differently, nor want them to rely on our compression...
|
// a letter differently, nor want them to rely on our compression...
|
||||||
// (Considered using numeric keys, but will remain back compatible.)
|
// (Considered using numeric keys, but will remain back compatible.)
|
||||||
if (key.length()<2) return false;
|
if (key.length()<2) return false;
|
||||||
if (key.length()==2 && isdigit(key[1])) return false;
|
if (key.length()==2 && isdigit(key[1])) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
static std::string keyValueFormatter(const std::string& key, const std::string& value) VL_PURE {
|
static std::string keyValueFormatter(const std::string& key, const std::string& value) VL_PURE {
|
||||||
std::string name;
|
std::string name;
|
||||||
if (key.length()==1 && isalpha(key[0])) {
|
if (key.length()==1 && isalpha(key[0])) {
|
||||||
name += std::string("\001")+key;
|
name += std::string("\001")+key;
|
||||||
} else {
|
} else {
|
||||||
name += std::string("\001")+dequote(key);
|
name += std::string("\001")+dequote(key);
|
||||||
}
|
}
|
||||||
name += std::string("\002")+dequote(value);
|
name += std::string("\002")+dequote(value);
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
static std::string combineHier(const std::string& old, const std::string& add) VL_PURE {
|
static std::string combineHier(const std::string& old, const std::string& add) VL_PURE {
|
||||||
// (foo.a.x, foo.b.x) => foo.*.x
|
// (foo.a.x, foo.b.x) => foo.*.x
|
||||||
// (foo.a.x, foo.b.y) => foo.*
|
// (foo.a.x, foo.b.y) => foo.*
|
||||||
// (foo.a.x, foo.b) => foo.*
|
// (foo.a.x, foo.b) => foo.*
|
||||||
if (old == add) return add;
|
if (old == add) return add;
|
||||||
if (old.empty()) return add;
|
if (old.empty()) return add;
|
||||||
if (add.empty()) return old;
|
if (add.empty()) return old;
|
||||||
|
|
||||||
const char* a = old.c_str();
|
const char* a = old.c_str();
|
||||||
const char* b = add.c_str();
|
const char* b = add.c_str();
|
||||||
|
|
||||||
// Scan forward to first mismatch
|
// Scan forward to first mismatch
|
||||||
const char* apre = a;
|
const char* apre = a;
|
||||||
const char* bpre = b;
|
const char* bpre = b;
|
||||||
while (*apre == *bpre) { apre++; bpre++; }
|
while (*apre == *bpre) { apre++; bpre++; }
|
||||||
|
|
||||||
// We used to backup and split on only .'s but it seems better to be verbose
|
// We used to backup and split on only .'s but it seems better to be verbose
|
||||||
// and not assume . is the separator
|
// and not assume . is the separator
|
||||||
std::string prefix = std::string(a,apre-a);
|
std::string prefix = std::string(a, apre-a);
|
||||||
|
|
||||||
// Scan backward to last mismatch
|
// Scan backward to last mismatch
|
||||||
const char* apost = a+strlen(a)-1;
|
const char* apost = a+strlen(a)-1;
|
||||||
const char* bpost = b+strlen(b)-1;
|
const char* bpost = b+strlen(b)-1;
|
||||||
while (*apost == *bpost
|
while (*apost == *bpost
|
||||||
&& apost>apre && bpost>bpre) { apost--; bpost--; }
|
&& apost>apre && bpost>bpre) { apost--; bpost--; }
|
||||||
|
|
||||||
// Forward to . so we have a whole word
|
// Forward to . so we have a whole word
|
||||||
std::string suffix = *bpost ? std::string(bpost+1) : "";
|
std::string suffix = *bpost ? std::string(bpost+1) : "";
|
||||||
|
|
||||||
std::string out = prefix+"*"+suffix;
|
std::string out = prefix+"*"+suffix;
|
||||||
|
|
||||||
//cout << "\nch pre="<<prefix<<" s="<<suffix<<"\nch a="<<old<<"\nch b="<<add<<"\nch o="<<out<<endl;
|
//cout << "\nch pre="<<prefix<<" s="<<suffix<<"\nch a="<<old<<"\nch b="<<add<<"\nch o="<<out<<endl;
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
bool itemMatchesString(VerilatedCovImpItem* itemp, const std::string& match) VL_REQUIRES(m_mutex) {
|
bool itemMatchesString(VerilatedCovImpItem* itemp, const std::string& match) VL_REQUIRES(m_mutex) {
|
||||||
for (int i=0; i<MAX_KEYS; ++i) {
|
for (int i=0; i<MAX_KEYS; ++i) {
|
||||||
if (itemp->m_keys[i] != KEY_UNDEF) {
|
if (itemp->m_keys[i] != KEY_UNDEF) {
|
||||||
// We don't compare keys, only values
|
// We don't compare keys, only values
|
||||||
std::string val = m_indexValues[itemp->m_vals[i]];
|
std::string val = m_indexValues[itemp->m_vals[i]];
|
||||||
if (std::string::npos != val.find(match)) { // Found
|
if (std::string::npos != val.find(match)) { // Found
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
static void selftest() VL_MT_SAFE {
|
static void selftest() VL_MT_SAFE {
|
||||||
// Little selftest
|
// Little selftest
|
||||||
if (combineHier ("a.b.c","a.b.c") !="a.b.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("a.b.c","a.b.c") !="a.b.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
if (combineHier ("a.b.c","a.b") !="a.b*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("a.b.c","a.b") !="a.b*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
if (combineHier ("a.x.c","a.y.c") !="a.*.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("a.x.c","a.y.c") !="a.*.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
if (combineHier ("a.z.z.z.c","a.b.c") !="a.*.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("a.z.z.z.c","a.b.c") !="a.*.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
if (combineHier ("z","a") !="*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("z","a") !="*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
if (combineHier ("q.a","q.b") !="q.*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("q.a","q.b") !="q.*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
if (combineHier ("q.za","q.zb") !="q.z*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("q.za","q.zb") !="q.z*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
if (combineHier ("1.2.3.a","9.8.7.a") !="*.a") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
if (combineHier("1.2.3.a","9.8.7.a") !="*.a") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||||
}
|
}
|
||||||
void clearGuts() VL_REQUIRES(m_mutex) {
|
void clearGuts() VL_REQUIRES(m_mutex) {
|
||||||
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||||
VerilatedCovImpItem* itemp = *(it);
|
VerilatedCovImpItem* itemp = *(it);
|
||||||
delete itemp;
|
delete itemp;
|
||||||
}
|
}
|
||||||
m_items.clear();
|
m_items.clear();
|
||||||
m_indexValues.clear();
|
m_indexValues.clear();
|
||||||
m_valueIndexes.clear();
|
m_valueIndexes.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// PUBLIC METHODS
|
// PUBLIC METHODS
|
||||||
void clear() VL_EXCLUDES(m_mutex) {
|
void clear() VL_EXCLUDES(m_mutex) {
|
||||||
Verilated::quiesce();
|
Verilated::quiesce();
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
clearGuts();
|
clearGuts();
|
||||||
}
|
}
|
||||||
void clearNonMatch(const char* matchp) VL_EXCLUDES(m_mutex) {
|
void clearNonMatch(const char* matchp) VL_EXCLUDES(m_mutex) {
|
||||||
Verilated::quiesce();
|
Verilated::quiesce();
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
if (matchp && matchp[0]) {
|
if (matchp && matchp[0]) {
|
||||||
ItemList newlist;
|
ItemList newlist;
|
||||||
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||||
VerilatedCovImpItem* itemp = *(it);
|
VerilatedCovImpItem* itemp = *(it);
|
||||||
if (!itemMatchesString(itemp, matchp)) {
|
if (!itemMatchesString(itemp, matchp)) {
|
||||||
delete itemp;
|
delete itemp;
|
||||||
} else {
|
} else {
|
||||||
newlist.push_back(itemp);
|
newlist.push_back(itemp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_items = newlist;
|
m_items = newlist;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void zero() VL_EXCLUDES(m_mutex) {
|
void zero() VL_EXCLUDES(m_mutex) {
|
||||||
Verilated::quiesce();
|
Verilated::quiesce();
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||||
(*it)->zero();
|
(*it)->zero();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We assume there's always call to i/f/p in that order
|
// We assume there's always call to i/f/p in that order
|
||||||
void inserti(VerilatedCovImpItem* itemp) VL_EXCLUDES(m_mutex) {
|
void inserti(VerilatedCovImpItem* itemp) VL_EXCLUDES(m_mutex) {
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
assert(!m_insertp);
|
assert(!m_insertp);
|
||||||
m_insertp = itemp;
|
m_insertp = itemp;
|
||||||
}
|
}
|
||||||
void insertf(const char* filenamep, int lineno) VL_EXCLUDES(m_mutex) {
|
void insertf(const char* filenamep, int lineno) VL_EXCLUDES(m_mutex) {
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
m_insertFilenamep = filenamep;
|
m_insertFilenamep = filenamep;
|
||||||
m_insertLineno = lineno;
|
m_insertLineno = lineno;
|
||||||
}
|
}
|
||||||
void insertp(const char* ckeyps[MAX_KEYS],
|
void insertp(const char* ckeyps[MAX_KEYS],
|
||||||
const char* valps[MAX_KEYS]) VL_EXCLUDES(m_mutex) {
|
const char* valps[MAX_KEYS]) VL_EXCLUDES(m_mutex) {
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
assert(m_insertp);
|
assert(m_insertp);
|
||||||
// First two key/vals are filename
|
// First two key/vals are filename
|
||||||
ckeyps[0]="filename"; valps[0]=m_insertFilenamep;
|
ckeyps[0]="filename"; valps[0]=m_insertFilenamep;
|
||||||
std::string linestr = vlCovCvtToStr(m_insertLineno);
|
std::string linestr = vlCovCvtToStr(m_insertLineno);
|
||||||
ckeyps[1]="lineno"; valps[1]=linestr.c_str();
|
ckeyps[1]="lineno"; valps[1]=linestr.c_str();
|
||||||
// Default page if not specified
|
// Default page if not specified
|
||||||
const char* fnstartp = m_insertFilenamep;
|
const char* fnstartp = m_insertFilenamep;
|
||||||
while (const char* foundp = strchr(fnstartp,'/')) fnstartp=foundp+1;
|
while (const char* foundp = strchr(fnstartp,'/')) fnstartp = foundp+1;
|
||||||
const char* fnendp = fnstartp;
|
const char* fnendp = fnstartp;
|
||||||
while (*fnendp && *fnendp!='.') fnendp++;
|
while (*fnendp && *fnendp!='.') fnendp++;
|
||||||
std::string page_default = "sp_user/"+std::string(fnstartp,fnendp-fnstartp);
|
std::string page_default = "sp_user/"+std::string(fnstartp, fnendp-fnstartp);
|
||||||
ckeyps[2]="page"; valps[2]=page_default.c_str();
|
ckeyps[2]="page"; valps[2]=page_default.c_str();
|
||||||
|
|
||||||
// Keys -> strings
|
// Keys -> strings
|
||||||
std::string keys[MAX_KEYS];
|
std::string keys[MAX_KEYS];
|
||||||
for (int i=0; i<MAX_KEYS; ++i) {
|
for (int i=0; i<MAX_KEYS; ++i) {
|
||||||
if (ckeyps[i] && ckeyps[i][0]) {
|
if (ckeyps[i] && ckeyps[i][0]) {
|
||||||
keys[i] = ckeyps[i];
|
keys[i] = ckeyps[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Ignore empty keys
|
// Ignore empty keys
|
||||||
for (int i=0; i<MAX_KEYS; ++i) {
|
for (int i=0; i<MAX_KEYS; ++i) {
|
||||||
if (!keys[i].empty()) {
|
if (!keys[i].empty()) {
|
||||||
for (int j=i+1; j<MAX_KEYS; ++j) {
|
for (int j=i+1; j<MAX_KEYS; ++j) {
|
||||||
if (keys[i] == keys[j]) { // Duplicate key. Keep the last one
|
if (keys[i] == keys[j]) { // Duplicate key. Keep the last one
|
||||||
keys[i] = "";
|
keys[i] = "";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Insert the values
|
// Insert the values
|
||||||
int addKeynum=0;
|
int addKeynum = 0;
|
||||||
for (int i=0; i<MAX_KEYS; ++i) {
|
for (int i=0; i<MAX_KEYS; ++i) {
|
||||||
const std::string key = keys[i];
|
const std::string key = keys[i];
|
||||||
if (!keys[i].empty()) {
|
if (!keys[i].empty()) {
|
||||||
const std::string val = valps[i];
|
const std::string val = valps[i];
|
||||||
//cout<<" "<<__FUNCTION__<<" "<<key<<" = "<<val<<endl;
|
//cout<<" "<<__FUNCTION__<<" "<<key<<" = "<<val<<endl;
|
||||||
m_insertp->m_keys[addKeynum] = valueIndex(key);
|
m_insertp->m_keys[addKeynum] = valueIndex(key);
|
||||||
m_insertp->m_vals[addKeynum] = valueIndex(val);
|
m_insertp->m_vals[addKeynum] = valueIndex(val);
|
||||||
addKeynum++;
|
addKeynum++;
|
||||||
if (!legalKey(key)) {
|
if (!legalKey(key)) {
|
||||||
std::string msg = "%Error: Coverage keys of one character, or letter+digit are illegal: "+key;
|
std::string msg
|
||||||
VL_FATAL_MT("",0,"",msg.c_str());
|
= ("%Error: Coverage keys of one character, or letter+digit are illegal: "
|
||||||
}
|
+key);
|
||||||
}
|
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||||
}
|
}
|
||||||
m_items.push_back(m_insertp);
|
}
|
||||||
// Prepare for next
|
}
|
||||||
m_insertp = NULL;
|
m_items.push_back(m_insertp);
|
||||||
|
// Prepare for next
|
||||||
|
m_insertp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void write(const char* filename) VL_EXCLUDES(m_mutex) {
|
void write(const char* filename) VL_EXCLUDES(m_mutex) {
|
||||||
Verilated::quiesce();
|
Verilated::quiesce();
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
#ifndef VM_COVERAGE
|
#ifndef VM_COVERAGE
|
||||||
VL_FATAL_MT("",0,"","%Error: Called VerilatedCov::write when VM_COVERAGE disabled\n");
|
VL_FATAL_MT("", 0, "", "%Error: Called VerilatedCov::write when VM_COVERAGE disabled\n");
|
||||||
#endif
|
#endif
|
||||||
selftest();
|
selftest();
|
||||||
|
|
||||||
std::ofstream os(filename);
|
std::ofstream os(filename);
|
||||||
if (os.fail()) {
|
if (os.fail()) {
|
||||||
std::string msg = std::string("%Error: Can't write '")+filename+"'";
|
std::string msg = std::string("%Error: Can't write '")+filename+"'";
|
||||||
VL_FATAL_MT("",0,"",msg.c_str());
|
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
os << "# SystemC::Coverage-3\n";
|
os << "# SystemC::Coverage-3\n";
|
||||||
|
|
||||||
// Build list of events; totalize if collapsing hierarchy
|
// Build list of events; totalize if collapsing hierarchy
|
||||||
typedef std::map<std::string,std::pair<std::string,vluint64_t> > EventMap;
|
typedef std::map<std::string,std::pair<std::string,vluint64_t> > EventMap;
|
||||||
EventMap eventCounts;
|
EventMap eventCounts;
|
||||||
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||||
VerilatedCovImpItem* itemp = *(it);
|
VerilatedCovImpItem* itemp = *(it);
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string hier;
|
std::string hier;
|
||||||
bool per_instance = false;
|
bool per_instance = false;
|
||||||
|
|
||||||
for (int i=0; i<MAX_KEYS; ++i) {
|
for (int i=0; i<MAX_KEYS; ++i) {
|
||||||
if (itemp->m_keys[i] != KEY_UNDEF) {
|
if (itemp->m_keys[i] != KEY_UNDEF) {
|
||||||
std::string key = VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]);
|
std::string key = VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]);
|
||||||
std::string val = m_indexValues[itemp->m_vals[i]];
|
std::string val = m_indexValues[itemp->m_vals[i]];
|
||||||
if (key == VL_CIK_PER_INSTANCE) {
|
if (key == VL_CIK_PER_INSTANCE) {
|
||||||
if (val != "0") per_instance = true;
|
if (val != "0") per_instance = true;
|
||||||
}
|
}
|
||||||
if (key == VL_CIK_HIER) {
|
if (key == VL_CIK_HIER) {
|
||||||
hier = val;
|
hier = val;
|
||||||
} else {
|
} else {
|
||||||
// Print it
|
// Print it
|
||||||
name += keyValueFormatter(key,val);
|
name += keyValueFormatter(key, val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (per_instance) { // Not collapsing hierarchies
|
if (per_instance) { // Not collapsing hierarchies
|
||||||
name += keyValueFormatter(VL_CIK_HIER,hier);
|
name += keyValueFormatter(VL_CIK_HIER, hier);
|
||||||
hier = "";
|
hier = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group versus point labels don't matter here, downstream
|
// Group versus point labels don't matter here, downstream
|
||||||
// deals with it. Seems bad for sizing though and doesn't
|
// deals with it. Seems bad for sizing though and doesn't
|
||||||
// allow easy addition of new group codes (would be
|
// allow easy addition of new group codes (would be
|
||||||
// inefficient)
|
// inefficient)
|
||||||
|
|
||||||
// Find or insert the named event
|
// Find or insert the named event
|
||||||
EventMap::iterator cit = eventCounts.find(name);
|
EventMap::iterator cit = eventCounts.find(name);
|
||||||
if (cit != eventCounts.end()) {
|
if (cit != eventCounts.end()) {
|
||||||
const std::string& oldhier = cit->second.first;
|
const std::string& oldhier = cit->second.first;
|
||||||
cit->second.second += itemp->count();
|
cit->second.second += itemp->count();
|
||||||
cit->second.first = combineHier(oldhier, hier);
|
cit->second.first = combineHier(oldhier, hier);
|
||||||
} else {
|
} else {
|
||||||
eventCounts.insert(std::make_pair(name, make_pair(hier,itemp->count())));
|
eventCounts.insert(std::make_pair(name, make_pair(hier, itemp->count())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output body
|
// Output body
|
||||||
for (EventMap::const_iterator it=eventCounts.begin(); it!=eventCounts.end(); ++it) {
|
for (EventMap::const_iterator it=eventCounts.begin(); it!=eventCounts.end(); ++it) {
|
||||||
os<<"C '"<<std::dec;
|
os<<"C '"<<std::dec;
|
||||||
os<<it->first;
|
os<<it->first;
|
||||||
if (!it->second.first.empty()) os<<keyValueFormatter(VL_CIK_HIER,it->second.first);
|
if (!it->second.first.empty()) os<<keyValueFormatter(VL_CIK_HIER, it->second.first);
|
||||||
os<<"' "<<it->second.second;
|
os<<"' "<<it->second.second;
|
||||||
os<<std::endl;
|
os<<std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -420,7 +422,7 @@ void VerilatedCov::_inserti(vluint64_t* itemp) VL_MT_SAFE {
|
|||||||
VerilatedCovImp::imp().inserti(new VerilatedCoverItemSpec<vluint64_t>(itemp));
|
VerilatedCovImp::imp().inserti(new VerilatedCoverItemSpec<vluint64_t>(itemp));
|
||||||
}
|
}
|
||||||
void VerilatedCov::_insertf(const char* filename, int lineno) VL_MT_SAFE {
|
void VerilatedCov::_insertf(const char* filename, int lineno) VL_MT_SAFE {
|
||||||
VerilatedCovImp::imp().insertf(filename,lineno);
|
VerilatedCovImp::imp().insertf(filename, lineno);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define K(n) const char* key ## n
|
#define K(n) const char* key ## n
|
||||||
@@ -446,14 +448,14 @@ void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
|
|||||||
// And versions with fewer arguments (oh for a language with named parameters!)
|
// And versions with fewer arguments (oh for a language with named parameters!)
|
||||||
void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)) VL_MT_SAFE {
|
void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)) VL_MT_SAFE {
|
||||||
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
|
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
|
||||||
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
|
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
|
||||||
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
||||||
}
|
}
|
||||||
void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
|
void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
|
||||||
A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)) VL_MT_SAFE {
|
A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)) VL_MT_SAFE {
|
||||||
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
|
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
|
||||||
C(10),C(11),C(12),C(13),C(14),C(15),C(16),C(17),C(18),C(19),
|
C(10),C(11),C(12),C(13),C(14),C(15),C(16),C(17),C(18),C(19),
|
||||||
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
||||||
}
|
}
|
||||||
// Backward compatibility for Verilator
|
// Backward compatibility for Verilator
|
||||||
void VerilatedCov::_insertp(A(0), A(1), K(2),int val2, K(3),int val3,
|
void VerilatedCov::_insertp(A(0), A(1), K(2),int val2, K(3),int val3,
|
||||||
@@ -461,10 +463,10 @@ void VerilatedCov::_insertp(A(0), A(1), K(2),int val2, K(3),int val3,
|
|||||||
std::string val2str = vlCovCvtToStr(val2);
|
std::string val2str = vlCovCvtToStr(val2);
|
||||||
std::string val3str = vlCovCvtToStr(val3);
|
std::string val3str = vlCovCvtToStr(val3);
|
||||||
_insertp(C(0),C(1),
|
_insertp(C(0),C(1),
|
||||||
key2,val2str.c_str(), key3,val3str.c_str(), key4, val4.c_str(),
|
key2,val2str.c_str(), key3,val3str.c_str(), key4, val4.c_str(),
|
||||||
C(5),C(6),N(7),N(8),N(9),
|
C(5),C(6),N(7),N(8),N(9),
|
||||||
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
|
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
|
||||||
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
||||||
}
|
}
|
||||||
#undef A
|
#undef A
|
||||||
#undef C
|
#undef C
|
||||||
|
|||||||
+19
-19
@@ -44,31 +44,31 @@
|
|||||||
/// The value may be a string, or another type which will be auto-converted to a string.
|
/// The value may be a string, or another type which will be auto-converted to a string.
|
||||||
///
|
///
|
||||||
/// Some typical keys:
|
/// Some typical keys:
|
||||||
/// filename File the recording occurs in. Defaults to __FILE__
|
/// filename File the recording occurs in. Defaults to __FILE__
|
||||||
/// lineno Line number the recording occurs in. Defaults to __LINE__
|
/// lineno Line number the recording occurs in. Defaults to __LINE__
|
||||||
/// column Column number (or occurrence# for dup file/lines). Defaults to undef.
|
/// column Column number (or occurrence# for dup file/lines). Defaults to undef.
|
||||||
/// hier Hierarchical name. Defaults to name()
|
/// hier Hierarchical name. Defaults to name()
|
||||||
/// type Type of coverage. Defaults to "user"
|
/// type Type of coverage. Defaults to "user"
|
||||||
/// Other types are 'block', 'fsm', 'toggle'.
|
/// Other types are 'block', 'fsm', 'toggle'.
|
||||||
/// comment Description of the coverage event. Should be set by the user.
|
/// comment Description of the coverage event. Should be set by the user.
|
||||||
/// Comments for type==block: 'if', 'else', 'elsif', 'case'
|
/// Comments for type==block: 'if', 'else', 'elsif', 'case'
|
||||||
/// thresh Threshold to consider fully covered.
|
/// thresh Threshold to consider fully covered.
|
||||||
/// If unspecified, downstream tools will determine it.
|
/// If unspecified, downstream tools will determine it.
|
||||||
///
|
///
|
||||||
/// Examples:
|
/// Examples:
|
||||||
///
|
///
|
||||||
/// vluint32_t m_cases[10];
|
/// vluint32_t m_cases[10];
|
||||||
/// constructor {
|
/// constructor {
|
||||||
/// for (int i=0; i<10; ++i) { m_cases[i]=0; }
|
/// for (int i=0; i<10; ++i) { m_cases[i]=0; }
|
||||||
|
/// }
|
||||||
|
/// for (int i=0; i<10; ++i) {
|
||||||
|
/// VL_COVER_INSERT(&m_cases[i], "comment", "Coverage Case", "i", cvtToNumStr(i));
|
||||||
/// }
|
/// }
|
||||||
/// for (int i=0; i<10; ++i) {
|
|
||||||
/// VL_COVER_INSERT(&m_cases[i], "comment", "Coverage Case", "i", cvtToNumStr(i));
|
|
||||||
/// }
|
|
||||||
|
|
||||||
#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))
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/// Convert VL_COVER_INSERT value arguments to strings
|
/// Convert VL_COVER_INSERT value arguments to strings
|
||||||
|
|||||||
@@ -19,10 +19,10 @@
|
|||||||
/// 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
|
||||||
///
|
///
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
|
|
||||||
#define _VERILATED_DPI_CPP_
|
#define _VERILATED_DPI_CPP_
|
||||||
|
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
@@ -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)
|
||||||
@@ -320,7 +321,8 @@ static void _vl_svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
|
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
|
||||||
|
varp->vltype());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -348,7 +350,8 @@ static void _vl_svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandl
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
|
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
|
||||||
|
varp->vltype());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -370,7 +373,8 @@ static void _vl_svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecV
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
|
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n",
|
||||||
|
varp->vltype());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -707,11 +711,13 @@ void svPutLogicArrElem1(const svOpenArrayHandle d, svLogic value, int indx1) {
|
|||||||
// Verilator doesn't support X/Z so can just call Bit version
|
// Verilator doesn't support X/Z so can just call Bit version
|
||||||
svPutBitArrElem1(d, value, indx1);
|
svPutBitArrElem1(d, value, indx1);
|
||||||
}
|
}
|
||||||
void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value, int indx1, int indx2) {
|
void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value,
|
||||||
|
int indx1, int indx2) {
|
||||||
// Verilator doesn't support X/Z so can just call Bit version
|
// Verilator doesn't support X/Z so can just call Bit version
|
||||||
svPutBitArrElem2(d, value, indx1, indx2);
|
svPutBitArrElem2(d, value, indx1, indx2);
|
||||||
}
|
}
|
||||||
void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value, int indx1, int indx2, int indx3) {
|
void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value,
|
||||||
|
int indx1, int indx2, int indx3) {
|
||||||
// Verilator doesn't support X/Z so can just call Bit version
|
// Verilator doesn't support X/Z so can just call Bit version
|
||||||
svPutBitArrElem3(d, value, indx1, indx2, indx3);
|
svPutBitArrElem3(d, value, indx1, indx2, indx3);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,10 +20,9 @@
|
|||||||
/// 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
|
||||||
|
|||||||
+33
-17
@@ -24,7 +24,14 @@
|
|||||||
#include "verilated.h"
|
#include "verilated.h"
|
||||||
#include "verilated_fst_c.h"
|
#include "verilated_fst_c.h"
|
||||||
|
|
||||||
|
// GTKWave configuration
|
||||||
|
#ifdef VL_TRACE_THREADED
|
||||||
|
# define HAVE_LIBPTHREAD
|
||||||
|
# define FST_WRITER_PARALLEL
|
||||||
|
#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"
|
||||||
@@ -57,7 +64,7 @@ protected:
|
|||||||
VerilatedFstCallInfo(VerilatedFstCallback_t icb, VerilatedFstCallback_t fcb,
|
VerilatedFstCallInfo(VerilatedFstCallback_t icb, VerilatedFstCallback_t fcb,
|
||||||
VerilatedFstCallback_t changecb,
|
VerilatedFstCallback_t changecb,
|
||||||
void* ut, vluint32_t code)
|
void* ut, vluint32_t code)
|
||||||
: m_initcb(icb), m_fullcb(fcb), m_changecb(changecb), m_userthis(ut), m_code(code) {};
|
: m_initcb(icb), m_fullcb(fcb), m_changecb(changecb), m_userthis(ut), m_code(code) {}
|
||||||
~VerilatedFstCallInfo() {}
|
~VerilatedFstCallInfo() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -67,11 +74,17 @@ 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();
|
||||||
m_fst = fstWriterCreate(filename, 1);
|
m_fst = fstWriterCreate(filename, 1);
|
||||||
|
fstWriterSetPackType(m_fst, FST_WR_PT_LZ4);
|
||||||
|
#ifdef VL_TRACE_THREADED
|
||||||
|
fstWriterSetParallelMode(m_fst, 1);
|
||||||
|
#endif
|
||||||
m_curScope.clear();
|
m_curScope.clear();
|
||||||
|
|
||||||
for (vluint32_t ent = 0; ent< m_callbacks.size(); ++ent) {
|
for (vluint32_t ent = 0; ent< m_callbacks.size(); ++ent) {
|
||||||
@@ -164,8 +177,9 @@ void VerilatedFst::addCallback(
|
|||||||
VerilatedFstCallback_t changecb, void* userthis) VL_MT_UNSAFE_ONE {
|
VerilatedFstCallback_t changecb, void* userthis) VL_MT_UNSAFE_ONE {
|
||||||
m_assertOne.check();
|
m_assertOne.check();
|
||||||
if (VL_UNLIKELY(isOpen())) {
|
if (VL_UNLIKELY(isOpen())) {
|
||||||
std::string msg = std::string("Internal: ")+__FILE__+"::"+__FUNCTION__+" called with already open file";
|
std::string msg = (std::string("Internal: ")+__FILE__+"::"+__FUNCTION__
|
||||||
VL_FATAL_MT(__FILE__,__LINE__,"",msg.c_str());
|
+" called with already open file");
|
||||||
|
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);
|
||||||
@@ -195,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';
|
||||||
|
|||||||
+19
-13
@@ -77,11 +77,11 @@ public:
|
|||||||
fstWriterClose(m_fst);
|
fstWriterClose(m_fst);
|
||||||
m_fst = NULL;
|
m_fst = NULL;
|
||||||
}
|
}
|
||||||
// void set_time_unit(const char* unitp); ///< Set time units (s/ms, defaults to ns)
|
void set_time_unit(const char* unitp) { fstWriterSetTimescaleFromString(m_fst, unitp); }
|
||||||
// void set_time_unit(const std::string& unit) { set_time_unit(unit.c_str()); }
|
void set_time_unit(const std::string& unit) { set_time_unit(unit.c_str()); }
|
||||||
|
|
||||||
// void set_time_resolution(const char* unitp); ///< Set time resolution (s/ms, defaults to ns)
|
void set_time_resolution(const char* unitp) { if (unitp) {} }
|
||||||
// void set_time_resolution(const std::string& unit) { set_time_resolution(unit.c_str()); }
|
void set_time_resolution(const std::string& unit) { set_time_resolution(unit.c_str()); }
|
||||||
|
|
||||||
// double timescaleToDouble(const char* unitp);
|
// double timescaleToDouble(const char* unitp);
|
||||||
// std::string doubleToTimescale(double value);
|
// std::string doubleToTimescale(double value);
|
||||||
@@ -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
|
||||||
@@ -157,12 +157,18 @@ public:
|
|||||||
fstWriterEmitValueChange(m_fst, m_code2symbol[code], array2Str(newval, bits));
|
fstWriterEmitValueChange(m_fst, m_code2symbol[code], array2Str(newval, bits));
|
||||||
}
|
}
|
||||||
|
|
||||||
void fullBit(vluint32_t code, const vluint32_t newval) { chgBit(code, newval); }
|
void fullBit(vluint32_t code, const vluint32_t newval) {
|
||||||
void fullBus(vluint32_t code, const vluint32_t newval, int bits) { chgBus(code, newval, bits); }
|
chgBit(code, newval); }
|
||||||
void fullDouble(vluint32_t code, const double newval) { chgDouble(code, newval); }
|
void fullBus(vluint32_t code, const vluint32_t newval, int bits) {
|
||||||
void fullFloat(vluint32_t code, const float newval) { chgFloat(code, newval); }
|
chgBus(code, newval, bits); }
|
||||||
void fullQuad(vluint32_t code, const vluint64_t newval, int bits) { chgQuad(code, newval, bits); }
|
void fullDouble(vluint32_t code, const double newval) {
|
||||||
void fullArray(vluint32_t code, const vluint32_t* newval, int bits) { chgArray(code, newval, bits); }
|
chgDouble(code, newval); }
|
||||||
|
void fullFloat(vluint32_t code, const float newval) {
|
||||||
|
chgFloat(code, newval); }
|
||||||
|
void fullQuad(vluint32_t code, const vluint64_t newval, int bits) {
|
||||||
|
chgQuad(code, newval, bits); }
|
||||||
|
void fullArray(vluint32_t code, const vluint32_t* newval, int bits) {
|
||||||
|
chgArray(code, newval, bits); }
|
||||||
|
|
||||||
void declTriBit (vluint32_t code, const char* name, int arraynum);
|
void declTriBit (vluint32_t code, const char* name, int arraynum);
|
||||||
void declTriBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
|
void declTriBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
|
||||||
@@ -216,11 +222,11 @@ public:
|
|||||||
void dump(int timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
|
void dump(int timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
|
||||||
/// Set time units (s/ms, defaults to ns)
|
/// Set time units (s/ms, defaults to ns)
|
||||||
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
|
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
|
||||||
void set_time_unit(const char* unit) { /* TODO */ }
|
void set_time_unit(const char* unitp) { m_sptrace.set_time_unit(unitp); }
|
||||||
void set_time_unit(const std::string& unit) { set_time_unit(unit.c_str()); }
|
void set_time_unit(const std::string& unit) { set_time_unit(unit.c_str()); }
|
||||||
/// Set time resolution (s/ms, defaults to ns)
|
/// Set time resolution (s/ms, defaults to ns)
|
||||||
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
|
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
|
||||||
void set_time_resolution(const char* unit) { /* TODO */ }
|
void set_time_resolution(const char* unitp) { m_sptrace.set_time_resolution(unitp); }
|
||||||
void set_time_resolution(const std::string& unit) { set_time_resolution(unit.c_str()); }
|
void set_time_resolution(const std::string& unit) { set_time_resolution(unit.c_str()); }
|
||||||
|
|
||||||
/// Internal class access
|
/// Internal class access
|
||||||
|
|||||||
+269
-7
@@ -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,
|
||||||
@@ -70,22 +312,42 @@ extern void VL_READMEM_N(bool hex, int width, int depth, int array_lsb,
|
|||||||
extern void VL_WRITEMEM_N(bool hex, int width, int depth, int array_lsb,
|
extern void VL_WRITEMEM_N(bool hex, int width, int depth, int array_lsb,
|
||||||
const std::string& filename,
|
const std::string& filename,
|
||||||
const void* memp, IData start, IData end) VL_MT_SAFE;
|
const void* memp, IData start, IData end) VL_MT_SAFE;
|
||||||
extern IData VL_SSCANF_INX(int lbits, const std::string& ld, const char* formatp, ...) VL_MT_SAFE;
|
extern IData VL_SSCANF_INX(int lbits, const std::string& ld,
|
||||||
extern void VL_SFORMAT_X(int obits_ignored, std::string& output, const char* formatp, ...) VL_MT_SAFE;
|
const char* formatp, ...) VL_MT_SAFE;
|
||||||
|
extern void VL_SFORMAT_X(int obits_ignored, std::string& output,
|
||||||
|
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
|
||||||
|
|||||||
+179
-156
@@ -16,15 +16,14 @@
|
|||||||
/// \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
|
||||||
|
|
||||||
#if !defined(_VERILATED_CPP_) && !defined(_VERILATED_DPI_CPP_)
|
#if !defined(_VERILATED_CPP_) && !defined(_VERILATED_DPI_CPP_) && !defined(_VERILATED_VPI_CPP_)
|
||||||
# error "verilated_imp.h only to be included by verilated*.cpp internals"
|
# error "verilated_imp.h only to be included by verilated*.cpp internals"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -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,61 +82,63 @@ 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:
|
||||||
// METHODS
|
// METHODS
|
||||||
//// Add message to queue (called by producer)
|
//// Add message to queue (called by producer)
|
||||||
void post(const VerilatedMsg& msg) VL_EXCLUDES(m_mutex) {
|
void post(const VerilatedMsg& msg) VL_EXCLUDES(m_mutex) {
|
||||||
VerilatedLockGuard lock(m_mutex);
|
VerilatedLockGuard lock(m_mutex);
|
||||||
m_queue.insert(msg); // Pass by value to copy the message into queue
|
m_queue.insert(msg); // Pass by value to copy the message into queue
|
||||||
++m_depth;
|
++m_depth;
|
||||||
}
|
}
|
||||||
/// Service queue until completion (called by consumer)
|
/// Service queue until completion (called by consumer)
|
||||||
void process() VL_EXCLUDES(m_mutex) {
|
void process() VL_EXCLUDES(m_mutex) {
|
||||||
// Tracking m_depth is redundant to e.g. getting the mutex and looking at queue size,
|
// Tracking m_depth is redundant to e.g. getting the mutex and looking at queue size,
|
||||||
// but on the reader side it's 4x faster to test an atomic then getting a mutex
|
// but on the reader side it's 4x faster to test an atomic then getting a mutex
|
||||||
while (m_depth) {
|
while (m_depth) {
|
||||||
// Wait for a message to be added to the queue
|
// Wait for a message to be added to the queue
|
||||||
// We don't use unique_lock as want to unlock with the message copy still in scope
|
// We don't use unique_lock as want to unlock with the message copy still in scope
|
||||||
m_mutex.lock();
|
m_mutex.lock();
|
||||||
assert(!m_queue.empty()); // Otherwise m_depth is wrong
|
assert(!m_queue.empty()); // Otherwise m_depth is wrong
|
||||||
// Unfortunately to release the lock we need to copy the message
|
// Unfortunately to release the lock we need to copy the message
|
||||||
// (Or have the message be a pointer, but then new/delete cost on each message)
|
// (Or have the message be a pointer, but then new/delete cost on each message)
|
||||||
// We assume messages are small, so copy
|
// We assume messages are small, so copy
|
||||||
auto it = m_queue.begin();
|
auto it = m_queue.begin();
|
||||||
const VerilatedMsg msg = *(it);
|
const VerilatedMsg msg = *(it);
|
||||||
m_queue.erase(it);
|
m_queue.erase(it);
|
||||||
m_mutex.unlock();
|
m_mutex.unlock();
|
||||||
m_depth--; // Ok if outside critical section as only this code checks the value
|
m_depth--; // Ok if outside critical section as only this code checks the value
|
||||||
{
|
{
|
||||||
VL_DEBUG_IF(VL_DBG_MSGF("Executing callback from mtaskId=%d\n", msg.mtaskId()););
|
VL_DEBUG_IF(VL_DBG_MSGF("Executing callback from mtaskId=%d\n", msg.mtaskId()););
|
||||||
msg.run();
|
msg.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// 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.
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
VL_UNCOPYABLE(VerilatedThreadMsgQueue);
|
VL_UNCOPYABLE(VerilatedThreadMsgQueue);
|
||||||
// METHODS
|
// METHODS
|
||||||
static VerilatedThreadMsgQueue& threadton() {
|
static VerilatedThreadMsgQueue& threadton() {
|
||||||
static VL_THREAD_LOCAL VerilatedThreadMsgQueue t_s;
|
static VL_THREAD_LOCAL VerilatedThreadMsgQueue t_s;
|
||||||
return t_s;
|
return t_s;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
/// Add message to queue, called by producer
|
/// Add message to queue, called by producer
|
||||||
@@ -153,11 +155,11 @@ public:
|
|||||||
}
|
}
|
||||||
/// Push all messages to the eval's queue
|
/// Push all messages to the eval's queue
|
||||||
static void flush(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
|
static void flush(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
|
||||||
while (!threadton().m_queue.empty()) {
|
while (!threadton().m_queue.empty()) {
|
||||||
evalMsgQp->post(threadton().m_queue.front());
|
evalMsgQp->post(threadton().m_queue.front());
|
||||||
threadton().m_queue.pop();
|
threadton().m_queue.pop();
|
||||||
Verilated::endOfEvalReqdDec();
|
Verilated::endOfEvalReqdDec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#endif // VL_THREADED
|
#endif // VL_THREADED
|
||||||
@@ -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
|
||||||
@@ -187,6 +189,10 @@ class VerilatedImp {
|
|||||||
|
|
||||||
VerilatedMutex m_nameMutex; ///< Protect m_nameMap
|
VerilatedMutex m_nameMutex; ///< Protect m_nameMap
|
||||||
VerilatedScopeNameMap m_nameMap VL_GUARDED_BY(m_nameMutex); ///< Map of <scope_name, scope pointer>
|
VerilatedScopeNameMap m_nameMap VL_GUARDED_BY(m_nameMutex); ///< Map of <scope_name, scope pointer>
|
||||||
|
|
||||||
|
VerilatedMutex m_hierMapMutex; ///< Protect m_hierMap
|
||||||
|
VerilatedHierarchyMap m_hierMap VL_GUARDED_BY(m_hierMapMutex); ///< Map the represents scope hierarchy
|
||||||
|
|
||||||
// Slow - somewhat static:
|
// Slow - somewhat static:
|
||||||
VerilatedMutex m_exportMutex; ///< Protect m_nameMap
|
VerilatedMutex m_exportMutex; ///< Protect m_nameMap
|
||||||
ExportNameMap m_exportMap VL_GUARDED_BY(m_exportMutex); ///< Map of <export_func_proto, func number>
|
ExportNameMap m_exportMap VL_GUARDED_BY(m_exportMutex); ///< Map of <export_func_proto, func number>
|
||||||
@@ -200,11 +206,12 @@ 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_fdps.resize(3);
|
, m_exportNext(0) {
|
||||||
m_fdps[0] = stdin;
|
m_fdps.resize(3);
|
||||||
m_fdps[1] = stdout;
|
m_fdps[0] = stdin;
|
||||||
m_fdps[2] = stderr;
|
m_fdps[1] = stdout;
|
||||||
|
m_fdps[2] = stderr;
|
||||||
}
|
}
|
||||||
~VerilatedImp() {}
|
~VerilatedImp() {}
|
||||||
private:
|
private:
|
||||||
@@ -219,21 +226,21 @@ public:
|
|||||||
static void commandArgs(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex);
|
static void commandArgs(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex);
|
||||||
static void commandArgsAdd(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex);
|
static void commandArgsAdd(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex);
|
||||||
static std::string argPlusMatch(const char* prefixp) VL_EXCLUDES(s_s.m_argMutex) {
|
static std::string argPlusMatch(const char* prefixp) VL_EXCLUDES(s_s.m_argMutex) {
|
||||||
VerilatedLockGuard lock(s_s.m_argMutex);
|
VerilatedLockGuard lock(s_s.m_argMutex);
|
||||||
// Note prefixp does not include the leading "+"
|
// Note prefixp does not include the leading "+"
|
||||||
size_t len = strlen(prefixp);
|
size_t len = strlen(prefixp);
|
||||||
if (VL_UNLIKELY(!s_s.m_argVecLoaded)) {
|
if (VL_UNLIKELY(!s_s.m_argVecLoaded)) {
|
||||||
s_s.m_argVecLoaded = true; // Complain only once
|
s_s.m_argVecLoaded = true; // Complain only once
|
||||||
VL_FATAL_MT("unknown",0,"",
|
VL_FATAL_MT("unknown", 0, "",
|
||||||
"%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 "";
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
static void commandArgsAddGuts(int argc, const char** argv) VL_REQUIRES(s_s.m_argMutex);
|
static void commandArgsAddGuts(int argc, const char** argv) VL_REQUIRES(s_s.m_argMutex);
|
||||||
@@ -247,78 +254,92 @@ public:
|
|||||||
// There's often many more scopes than userdata's and thus having a ~48byte
|
// There's often many more scopes than userdata's and thus having a ~48byte
|
||||||
// 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));
|
||||||
}
|
}
|
||||||
static inline void* userFind(const void* scopep, void* userKey) VL_MT_SAFE {
|
static inline void* userFind(const void* scopep, void* userKey) VL_MT_SAFE {
|
||||||
VerilatedLockGuard lock(s_s.m_userMapMutex);
|
VerilatedLockGuard lock(s_s.m_userMapMutex);
|
||||||
UserMap::const_iterator it=s_s.m_userMap.find(std::make_pair(scopep,userKey));
|
UserMap::const_iterator it=s_s.m_userMap.find(std::make_pair(scopep, userKey));
|
||||||
if (VL_LIKELY(it != s_s.m_userMap.end())) return it->second;
|
if (VL_LIKELY(it != s_s.m_userMap.end())) return it->second;
|
||||||
else return NULL;
|
else return NULL;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
/// Symbol table destruction cleans up the entries for each scope.
|
/// Symbol table destruction cleans up the entries for each scope.
|
||||||
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 {
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static void userDump() VL_MT_SAFE {
|
static void userDump() VL_MT_SAFE {
|
||||||
VerilatedLockGuard lock(s_s.m_userMapMutex); // Avoid it changing in middle of dump
|
VerilatedLockGuard lock(s_s.m_userMapMutex); // Avoid it changing in middle of dump
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (UserMap::const_iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ++it) {
|
for (UserMap::const_iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ++it) {
|
||||||
if (first) { VL_PRINTF_MT(" userDump:\n"); first=false; }
|
if (first) { VL_PRINTF_MT(" userDump:\n"); first=false; }
|
||||||
VL_PRINTF_MT(" DPI_USER_DATA scope %p key %p: %p\n",
|
VL_PRINTF_MT(" DPI_USER_DATA scope %p key %p: %p\n",
|
||||||
it->first.first, it->first.second, it->second);
|
it->first.first, it->first.second, it->second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public: // But only for verilated*.cpp
|
public: // But only for verilated*.cpp
|
||||||
// METHODS - scope name
|
// METHODS - scope name
|
||||||
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static inline const VerilatedScope* scopeFind(const char* namep) VL_MT_SAFE {
|
static inline const VerilatedScope* scopeFind(const char* namep) VL_MT_SAFE {
|
||||||
VerilatedLockGuard lock(s_s.m_nameMutex); // If too slow, can assume this is only VL_MT_SAFE_POSINIT
|
VerilatedLockGuard lock(s_s.m_nameMutex);
|
||||||
VerilatedScopeNameMap::const_iterator it=s_s.m_nameMap.find(namep);
|
// If too slow, can assume this is only VL_MT_SAFE_POSINIT
|
||||||
if (VL_LIKELY(it != s_s.m_nameMap.end())) return it->second;
|
VerilatedScopeNameMap::const_iterator it=s_s.m_nameMap.find(namep);
|
||||||
else return NULL;
|
if (VL_LIKELY(it != s_s.m_nameMap.end())) return it->second;
|
||||||
|
else return NULL;
|
||||||
}
|
}
|
||||||
static void scopeErase(const VerilatedScope* scopep) VL_MT_SAFE {
|
static void scopeErase(const VerilatedScope* scopep) VL_MT_SAFE {
|
||||||
// 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(); it!=s_s.m_nameMap.end(); ++it) {
|
for (VerilatedScopeNameMap::const_iterator it = s_s.m_nameMap.begin();
|
||||||
const VerilatedScope* scopep = it->second;
|
it != s_s.m_nameMap.end(); ++it) {
|
||||||
scopep->scopeDump();
|
const VerilatedScope* scopep = it->second;
|
||||||
}
|
scopep->scopeDump();
|
||||||
VL_PRINTF_MT("\n");
|
}
|
||||||
|
VL_PRINTF_MT("\n");
|
||||||
}
|
}
|
||||||
static const VerilatedScopeNameMap* scopeNameMap() VL_MT_SAFE_POSTINIT {
|
static const VerilatedScopeNameMap* scopeNameMap() VL_MT_SAFE_POSTINIT {
|
||||||
// Thread save only assuming this is called only after model construction completed
|
// Thread save only assuming this is called only after model construction completed
|
||||||
return &s_s.m_nameMap;
|
return &s_s.m_nameMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public: // But only for verilated*.cpp
|
||||||
|
// METHODS - hierarchy
|
||||||
|
static void hierarchyAdd(const VerilatedScope* fromp, const VerilatedScope* top) VL_MT_SAFE {
|
||||||
|
// Slow ok - called at construction for VPI accessible elements
|
||||||
|
VerilatedLockGuard lock(s_s.m_hierMapMutex);
|
||||||
|
s_s.m_hierMap[fromp].push_back(top);
|
||||||
|
}
|
||||||
|
static const VerilatedHierarchyMap* hierarchyMap() VL_MT_SAFE_POSTINIT {
|
||||||
|
// Thread save only assuming this is called only after model construction completed
|
||||||
|
return &s_s.m_hierMap;
|
||||||
|
}
|
||||||
|
|
||||||
public: // But only for verilated*.cpp
|
public: // But only for verilated*.cpp
|
||||||
// METHODS - export names
|
// METHODS - export names
|
||||||
|
|
||||||
@@ -329,40 +350,42 @@ public: // But only for verilated*.cpp
|
|||||||
// Rather than a 2D map, the integer scheme saves 500ish ns on a likely
|
// Rather than a 2D map, the integer scheme saves 500ish ns on a likely
|
||||||
// miss at the cost of a multiply, and all lookups move to slowpath.
|
// miss at the cost of a multiply, and all lookups move to slowpath.
|
||||||
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++;
|
||||||
} else {
|
} else {
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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");
|
||||||
VL_FATAL_MT("unknown",0,"", msg.c_str());
|
VL_FATAL_MT("unknown", 0, "", msg.c_str());
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
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(); it!=s_s.m_exportMap.end(); ++it) {
|
for (ExportNameMap::const_iterator it = s_s.m_exportMap.begin();
|
||||||
if (it->second == funcnum) return it->first;
|
it != s_s.m_exportMap.end(); ++it) {
|
||||||
}
|
if (it->second == funcnum) return it->first;
|
||||||
return "*UNKNOWN*";
|
}
|
||||||
|
return "*UNKNOWN*";
|
||||||
}
|
}
|
||||||
static void exportsDump() VL_MT_SAFE {
|
static void exportsDump() VL_MT_SAFE {
|
||||||
VerilatedLockGuard lock(s_s.m_exportMutex);
|
VerilatedLockGuard lock(s_s.m_exportMutex);
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (ExportNameMap::const_iterator it=s_s.m_exportMap.begin(); it!=s_s.m_exportMap.end(); ++it) {
|
for (ExportNameMap::const_iterator it=s_s.m_exportMap.begin();
|
||||||
if (first) { VL_PRINTF_MT(" exportDump:\n"); first=false; }
|
it!=s_s.m_exportMap.end(); ++it) {
|
||||||
VL_PRINTF_MT(" DPI_EXPORT_NAME %05d: %s\n", it->second, it->first);
|
if (first) { VL_PRINTF_MT(" exportDump:\n"); first=false; }
|
||||||
}
|
VL_PRINTF_MT(" DPI_EXPORT_NAME %05d: %s\n", it->second, it->first);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// We don't free up m_exportMap until the end, because we can't be sure
|
// We don't free up m_exportMap until the end, because we can't be sure
|
||||||
// what other models are using the assigned funcnum's.
|
// what other models are using the assigned funcnum's.
|
||||||
@@ -370,32 +393,32 @@ public: // But only for verilated*.cpp
|
|||||||
public: // But only for verilated*.cpp
|
public: // But only for verilated*.cpp
|
||||||
// METHODS - file IO
|
// METHODS - file IO
|
||||||
static IData fdNew(FILE* fp) VL_MT_SAFE {
|
static IData fdNew(FILE* fp) VL_MT_SAFE {
|
||||||
if (VL_UNLIKELY(!fp)) return 0;
|
if (VL_UNLIKELY(!fp)) return 0;
|
||||||
// Bit 31 indicates it's a descriptor not a MCD
|
// Bit 31 indicates it's a descriptor not a MCD
|
||||||
VerilatedLockGuard lock(s_s.m_fdMutex);
|
VerilatedLockGuard lock(s_s.m_fdMutex);
|
||||||
if (s_s.m_fdFree.empty()) {
|
if (s_s.m_fdFree.empty()) {
|
||||||
// Need to create more space in m_fdps and m_fdFree
|
// Need to create more space in m_fdps and m_fdFree
|
||||||
size_t start = s_s.m_fdps.size();
|
size_t start = s_s.m_fdps.size();
|
||||||
s_s.m_fdps.resize(start*2);
|
s_s.m_fdps.resize(start*2);
|
||||||
for (size_t i=start; i<start*2; ++i) s_s.m_fdFree.push_back(static_cast<IData>(i));
|
for (size_t i=start; i<start*2; ++i) s_s.m_fdFree.push_back(static_cast<IData>(i));
|
||||||
}
|
}
|
||||||
IData idx = s_s.m_fdFree.back(); s_s.m_fdFree.pop_back();
|
IData idx = s_s.m_fdFree.back(); s_s.m_fdFree.pop_back();
|
||||||
s_s.m_fdps[idx] = fp;
|
s_s.m_fdps[idx] = fp;
|
||||||
return (idx | (1UL<<31)); // bit 31 indicates not MCD
|
return (idx | (1UL<<31)); // bit 31 indicates not MCD
|
||||||
}
|
}
|
||||||
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);
|
||||||
}
|
}
|
||||||
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];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+62
-60
@@ -56,17 +56,19 @@ bool VerilatedDeserialize::readDiffers(const void* __restrict datap, size_t size
|
|||||||
const vluint8_t* __restrict dp = static_cast<const vluint8_t* __restrict>(datap);
|
const vluint8_t* __restrict dp = static_cast<const vluint8_t* __restrict>(datap);
|
||||||
vluint8_t miss = 0;
|
vluint8_t miss = 0;
|
||||||
while (size--) {
|
while (size--) {
|
||||||
miss |= (*dp++ ^ *m_cp++);
|
miss |= (*dp++ ^ *m_cp++);
|
||||||
}
|
}
|
||||||
return (miss!=0);
|
return (miss!=0);
|
||||||
}
|
}
|
||||||
|
|
||||||
VerilatedDeserialize& VerilatedDeserialize::readAssert(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
VerilatedDeserialize& VerilatedDeserialize::readAssert(const void* __restrict datap,
|
||||||
if (VL_UNLIKELY(readDiffers(datap,size))) {
|
size_t size) VL_MT_UNSAFE_ONE {
|
||||||
std::string fn = filename();
|
if (VL_UNLIKELY(readDiffers(datap, size))) {
|
||||||
std::string msg = std::string("Can't deserialize save-restore file as was made from different model");
|
std::string fn = filename();
|
||||||
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
std::string msg = "Can't deserialize save-restore file as was made from different model:"
|
||||||
close();
|
+filename();
|
||||||
|
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
||||||
|
close();
|
||||||
}
|
}
|
||||||
return *this; // For function chaining
|
return *this; // For function chaining
|
||||||
}
|
}
|
||||||
@@ -84,10 +86,11 @@ void VerilatedSerialize::header() VL_MT_UNSAFE_ONE {
|
|||||||
void VerilatedDeserialize::header() VL_MT_UNSAFE_ONE {
|
void VerilatedDeserialize::header() VL_MT_UNSAFE_ONE {
|
||||||
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
|
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
|
||||||
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR)))) {
|
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR)))) {
|
||||||
std::string fn = filename();
|
std::string fn = filename();
|
||||||
std::string msg = std::string("Can't deserialize; file has wrong header signature");
|
std::string msg = std::string("Can't deserialize; file has wrong header signature: ")
|
||||||
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
+filename();
|
||||||
close();
|
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
||||||
|
close();
|
||||||
}
|
}
|
||||||
os.read(Verilated::serializedPtr(), Verilated::serializedSize());
|
os.read(Verilated::serializedPtr(), Verilated::serializedSize());
|
||||||
}
|
}
|
||||||
@@ -101,10 +104,11 @@ void VerilatedSerialize::trailer() VL_MT_UNSAFE_ONE {
|
|||||||
void VerilatedDeserialize::trailer() VL_MT_UNSAFE_ONE {
|
void VerilatedDeserialize::trailer() VL_MT_UNSAFE_ONE {
|
||||||
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
|
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
|
||||||
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR)))) {
|
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR)))) {
|
||||||
std::string fn = filename();
|
std::string fn = filename();
|
||||||
std::string msg = std::string("Can't deserialize; file has wrong end-of-file signature");
|
std::string msg = std::string("Can't deserialize; file has wrong end-of-file signature: ")
|
||||||
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
+filename();
|
||||||
close();
|
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
||||||
|
close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,19 +120,19 @@ void VerilatedDeserialize::trailer() VL_MT_UNSAFE_ONE {
|
|||||||
void VerilatedSave::open(const char* filenamep) VL_MT_UNSAFE_ONE {
|
void VerilatedSave::open(const char* filenamep) VL_MT_UNSAFE_ONE {
|
||||||
m_assertOne.check();
|
m_assertOne.check();
|
||||||
if (isOpen()) return;
|
if (isOpen()) return;
|
||||||
VL_DEBUG_IF(VL_DBG_MSGF("- save: opening save file %s\n",filenamep););
|
VL_DEBUG_IF(VL_DBG_MSGF("- save: opening save file %s\n", filenamep););
|
||||||
|
|
||||||
if (filenamep[0]=='|') {
|
if (filenamep[0]=='|') {
|
||||||
assert(0); // Not supported yet.
|
assert(0); // Not supported yet.
|
||||||
} else {
|
} else {
|
||||||
// cppcheck-suppress duplicateExpression
|
// cppcheck-suppress duplicateExpression
|
||||||
m_fd = ::open(filenamep, O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK|O_CLOEXEC
|
m_fd = ::open(filenamep, O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK|O_CLOEXEC
|
||||||
, 0666);
|
, 0666);
|
||||||
if (m_fd<0) {
|
if (m_fd<0) {
|
||||||
// User code can check isOpen()
|
// User code can check isOpen()
|
||||||
m_isOpen = false;
|
m_isOpen = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_isOpen = true;
|
m_isOpen = true;
|
||||||
m_filename = filenamep;
|
m_filename = filenamep;
|
||||||
@@ -139,19 +143,19 @@ void VerilatedSave::open(const char* filenamep) VL_MT_UNSAFE_ONE {
|
|||||||
void VerilatedRestore::open(const char* filenamep) VL_MT_UNSAFE_ONE {
|
void VerilatedRestore::open(const char* filenamep) VL_MT_UNSAFE_ONE {
|
||||||
m_assertOne.check();
|
m_assertOne.check();
|
||||||
if (isOpen()) return;
|
if (isOpen()) return;
|
||||||
VL_DEBUG_IF(VL_DBG_MSGF("- restore: opening restore file %s\n",filenamep););
|
VL_DEBUG_IF(VL_DBG_MSGF("- restore: opening restore file %s\n", filenamep););
|
||||||
|
|
||||||
if (filenamep[0]=='|') {
|
if (filenamep[0]=='|') {
|
||||||
assert(0); // Not supported yet.
|
assert(0); // Not supported yet.
|
||||||
} else {
|
} else {
|
||||||
// cppcheck-suppress duplicateExpression
|
// cppcheck-suppress duplicateExpression
|
||||||
m_fd = ::open(filenamep, O_CREAT|O_RDONLY|O_LARGEFILE|O_CLOEXEC
|
m_fd = ::open(filenamep, O_CREAT|O_RDONLY|O_LARGEFILE|O_CLOEXEC
|
||||||
, 0666);
|
, 0666);
|
||||||
if (m_fd<0) {
|
if (m_fd<0) {
|
||||||
// User code can check isOpen()
|
// User code can check isOpen()
|
||||||
m_isOpen = false;
|
m_isOpen = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_isOpen = true;
|
m_isOpen = true;
|
||||||
m_filename = filenamep;
|
m_filename = filenamep;
|
||||||
@@ -184,21 +188,21 @@ void VerilatedSave::flush() VL_MT_UNSAFE_ONE {
|
|||||||
if (VL_UNLIKELY(!isOpen())) return;
|
if (VL_UNLIKELY(!isOpen())) return;
|
||||||
vluint8_t* wp = m_bufp;
|
vluint8_t* wp = m_bufp;
|
||||||
while (1) {
|
while (1) {
|
||||||
ssize_t remaining = (m_cp - wp);
|
ssize_t remaining = (m_cp - wp);
|
||||||
if (remaining==0) break;
|
if (remaining==0) break;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
ssize_t got = ::write(m_fd, wp, remaining);
|
ssize_t got = ::write(m_fd, wp, remaining);
|
||||||
if (got>0) {
|
if (got>0) {
|
||||||
wp += got;
|
wp += got;
|
||||||
} else if (got < 0) {
|
} else if (got < 0) {
|
||||||
if (errno != EAGAIN && errno != EINTR) {
|
if (errno != EAGAIN && errno != EINTR) {
|
||||||
// write failed, presume error (perhaps out of disk space)
|
// write failed, presume error (perhaps out of disk space)
|
||||||
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
|
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
|
||||||
VL_FATAL_MT("",0,"",msg.c_str());
|
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||||
close();
|
close();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_cp = m_bufp; // Reset buffer
|
m_cp = m_bufp; // Reset buffer
|
||||||
}
|
}
|
||||||
@@ -213,30 +217,28 @@ void VerilatedRestore::fill() VL_MT_UNSAFE_ONE {
|
|||||||
m_cp = m_bufp; // Reset buffer
|
m_cp = m_bufp; // Reset buffer
|
||||||
// Read into buffer starting at m_endp
|
// Read into buffer starting at m_endp
|
||||||
while (1) {
|
while (1) {
|
||||||
ssize_t remaining = (m_bufp+bufferSize() - m_endp);
|
ssize_t remaining = (m_bufp+bufferSize() - m_endp);
|
||||||
if (remaining==0) break;
|
if (remaining==0) break;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
ssize_t got = ::read(m_fd, m_endp, remaining);
|
ssize_t got = ::read(m_fd, m_endp, remaining);
|
||||||
if (got>0) {
|
if (got>0) {
|
||||||
m_endp += got;
|
m_endp += got;
|
||||||
} else if (got < 0) {
|
} else if (got < 0) {
|
||||||
if (errno != EAGAIN && errno != EINTR) {
|
if (errno != EAGAIN && errno != EINTR) {
|
||||||
// write failed, presume error (perhaps out of disk space)
|
// write failed, presume error (perhaps out of disk space)
|
||||||
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
|
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
|
||||||
VL_FATAL_MT("",0,"",msg.c_str());
|
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||||
close();
|
close();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else { // got==0, EOF
|
} else { // got==0, EOF
|
||||||
// Fill buffer from here to end with NULLs so reader's don't
|
// Fill buffer from here to end with NULLs so reader's don't
|
||||||
// need to check eof each character.
|
// need to check eof each character.
|
||||||
while (m_endp < m_bufp+bufferSize()) *m_endp++ = '\0';
|
while (m_endp < m_bufp+bufferSize()) *m_endp++ = '\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Serialization of types
|
// Serialization of types
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+86
-57
@@ -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>
|
||||||
|
|
||||||
@@ -34,10 +35,10 @@ class VerilatedSerialize {
|
|||||||
protected:
|
protected:
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
// For speed, keep m_cp as the first member of this structure
|
// For speed, keep m_cp as the first member of this structure
|
||||||
vluint8_t* m_cp; ///< Current pointer into m_bufp buffer
|
vluint8_t* m_cp; ///< Current pointer into m_bufp buffer
|
||||||
vluint8_t* m_bufp; ///< Output buffer
|
vluint8_t* m_bufp; ///< Output buffer
|
||||||
bool m_isOpen; ///< True indicates open file/stream
|
bool m_isOpen; ///< True indicates open file/stream
|
||||||
std::string m_filename; ///< Filename, for error messages
|
std::string m_filename; ///< Filename, for error messages
|
||||||
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
|
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
|
||||||
|
|
||||||
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
|
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
|
||||||
@@ -50,13 +51,13 @@ protected:
|
|||||||
VL_UNCOPYABLE(VerilatedSerialize);
|
VL_UNCOPYABLE(VerilatedSerialize);
|
||||||
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() {
|
||||||
close();
|
close();
|
||||||
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
|
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
|
||||||
}
|
}
|
||||||
// METHODS
|
// METHODS
|
||||||
bool isOpen() const { return m_isOpen; }
|
bool isOpen() const { return m_isOpen; }
|
||||||
@@ -64,24 +65,24 @@ public:
|
|||||||
virtual void close() VL_MT_UNSAFE_ONE { flush(); }
|
virtual void close() VL_MT_UNSAFE_ONE { flush(); }
|
||||||
virtual void flush() VL_MT_UNSAFE_ONE {}
|
virtual void flush() VL_MT_UNSAFE_ONE {}
|
||||||
inline VerilatedSerialize& write(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
inline VerilatedSerialize& write(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
||||||
const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap;
|
const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap;
|
||||||
while (size) {
|
while (size) {
|
||||||
bufferCheck();
|
bufferCheck();
|
||||||
size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize();
|
size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize();
|
||||||
const vluint8_t* __restrict maxp = dp + blk;
|
const vluint8_t* __restrict maxp = dp + blk;
|
||||||
while (dp < maxp) *m_cp++ = *dp++;
|
while (dp < maxp) *m_cp++ = *dp++;
|
||||||
size -= blk;
|
size -= blk;
|
||||||
}
|
}
|
||||||
return *this; // For function chaining
|
return *this; // For function chaining
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
VerilatedSerialize& bufferCheck() VL_MT_UNSAFE_ONE {
|
VerilatedSerialize& bufferCheck() VL_MT_UNSAFE_ONE {
|
||||||
// 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_cp > (m_bufp+(bufferSize()-bufferInsertSize())))) {
|
if (VL_UNLIKELY(m_cp > (m_bufp+(bufferSize()-bufferInsertSize())))) {
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
return *this; // For function chaining
|
return *this; // For function chaining
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -93,12 +94,12 @@ class VerilatedDeserialize {
|
|||||||
protected:
|
protected:
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
// For speed, keep m_cp as the first member of this structure
|
// For speed, keep m_cp as the first member of this structure
|
||||||
vluint8_t* m_cp; ///< Current pointer into m_bufp buffer
|
vluint8_t* m_cp; ///< Current pointer into m_bufp buffer
|
||||||
vluint8_t* m_bufp; ///< Output buffer
|
vluint8_t* m_bufp; ///< Output buffer
|
||||||
vluint8_t* m_endp; ///< Last valid byte in m_bufp buffer
|
vluint8_t* m_endp; ///< Last valid byte in m_bufp buffer
|
||||||
bool m_isOpen; ///< True indicates open file/stream
|
bool m_isOpen; ///< True indicates open file/stream
|
||||||
std::string m_filename; ///< Filename, for error messages
|
std::string m_filename; ///< Filename, for error messages
|
||||||
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
|
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
|
||||||
|
|
||||||
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
|
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
|
||||||
inline static size_t bufferInsertSize() { return 16*1024; }
|
inline static size_t bufferInsertSize() { return 16*1024; }
|
||||||
@@ -111,14 +112,14 @@ protected:
|
|||||||
VL_UNCOPYABLE(VerilatedDeserialize);
|
VL_UNCOPYABLE(VerilatedDeserialize);
|
||||||
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;
|
||||||
}
|
}
|
||||||
virtual ~VerilatedDeserialize() {
|
virtual ~VerilatedDeserialize() {
|
||||||
close();
|
close();
|
||||||
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
|
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
|
||||||
}
|
}
|
||||||
// METHODS
|
// METHODS
|
||||||
bool isOpen() const { return m_isOpen; }
|
bool isOpen() const { return m_isOpen; }
|
||||||
@@ -126,15 +127,15 @@ public:
|
|||||||
virtual void close() VL_MT_UNSAFE_ONE { flush(); }
|
virtual void close() VL_MT_UNSAFE_ONE { flush(); }
|
||||||
virtual void flush() VL_MT_UNSAFE_ONE {}
|
virtual void flush() VL_MT_UNSAFE_ONE {}
|
||||||
inline VerilatedDeserialize& read(void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
inline VerilatedDeserialize& read(void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
||||||
vluint8_t* __restrict dp = (vluint8_t* __restrict)datap;
|
vluint8_t* __restrict dp = (vluint8_t* __restrict)datap;
|
||||||
while (size) {
|
while (size) {
|
||||||
bufferCheck();
|
bufferCheck();
|
||||||
size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize();
|
size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize();
|
||||||
const vluint8_t* __restrict maxp = dp + blk;
|
const vluint8_t* __restrict maxp = dp + blk;
|
||||||
while (dp < maxp) *dp++ = *m_cp++;
|
while (dp < maxp) *dp++ = *m_cp++;
|
||||||
size -= blk;
|
size -= blk;
|
||||||
}
|
}
|
||||||
return *this; // For function chaining
|
return *this; // For function chaining
|
||||||
}
|
}
|
||||||
// Read a datum and compare with expected value
|
// Read a datum and compare with expected value
|
||||||
VerilatedDeserialize& readAssert(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE;
|
VerilatedDeserialize& readAssert(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE;
|
||||||
@@ -143,12 +144,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
bool readDiffers(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE;
|
bool readDiffers(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE;
|
||||||
VerilatedDeserialize& bufferCheck() VL_MT_UNSAFE_ONE {
|
VerilatedDeserialize& bufferCheck() VL_MT_UNSAFE_ONE {
|
||||||
// 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_cp+bufferInsertSize()) > m_endp)) {
|
if (VL_UNLIKELY((m_cp+bufferInsertSize()) > m_endp)) {
|
||||||
fill();
|
fill();
|
||||||
}
|
}
|
||||||
return *this; // For function chaining
|
return *this; // For function chaining
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -237,15 +238,43 @@ inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, float& rhs) {
|
|||||||
return os.read(&rhs, sizeof(rhs));
|
return os.read(&rhs, sizeof(rhs));
|
||||||
}
|
}
|
||||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, std::string& rhs) {
|
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, std::string& rhs) {
|
||||||
vluint32_t len=rhs.length();
|
vluint32_t len = rhs.length();
|
||||||
os<<len;
|
os<<len;
|
||||||
return os.write(rhs.data(), len);
|
return os.write(rhs.data(), len);
|
||||||
}
|
}
|
||||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, std::string& rhs) {
|
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, std::string& rhs) {
|
||||||
vluint32_t len=0;
|
vluint32_t len = 0;
|
||||||
os>>len;
|
os>>len;
|
||||||
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,10 +19,9 @@
|
|||||||
/// 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,10 +24,9 @@
|
|||||||
///
|
///
|
||||||
/// 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); }
|
||||||
@@ -142,22 +141,28 @@ public:
|
|||||||
const VerilatedRange& unpacked() const { return m_unpacked[0]; }
|
const VerilatedRange& unpacked() const { return m_unpacked[0]; }
|
||||||
// DPI accessors
|
// DPI accessors
|
||||||
int left(int dim) const {
|
int left(int dim) const {
|
||||||
return dim==0 ? m_packed.left() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].left() : 0;
|
return dim==0 ? m_packed.left()
|
||||||
|
: VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].left() : 0;
|
||||||
}
|
}
|
||||||
int right(int dim) const {
|
int right(int dim) const {
|
||||||
return dim==0 ? m_packed.right() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].right() : 0;
|
return dim==0 ? m_packed.right()
|
||||||
|
: VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].right() : 0;
|
||||||
}
|
}
|
||||||
int low(int dim) const {
|
int low(int dim) const {
|
||||||
return dim==0 ? m_packed.low() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].low() : 0;
|
return dim==0 ? m_packed.low()
|
||||||
|
: VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].low() : 0;
|
||||||
}
|
}
|
||||||
int high(int dim) const {
|
int high(int dim) const {
|
||||||
return dim==0 ? m_packed.high() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].high() : 0;
|
return dim==0 ? m_packed.high()
|
||||||
|
: VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].high() : 0;
|
||||||
}
|
}
|
||||||
int increment(int dim) const {
|
int increment(int dim) const {
|
||||||
return dim==0 ? m_packed.increment() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].increment() : 0;
|
return dim==0 ? m_packed.increment()
|
||||||
|
: VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].increment() : 0;
|
||||||
}
|
}
|
||||||
int elements(int dim) const {
|
int elements(int dim) const {
|
||||||
return dim==0 ? m_packed.elements() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].elements() : 0;
|
return dim==0 ? m_packed.elements()
|
||||||
|
: VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].elements() : 0;
|
||||||
}
|
}
|
||||||
/// Total size in bytes (note DPI limited to 4GB)
|
/// Total size in bytes (note DPI limited to 4GB)
|
||||||
size_t totalSize() const;
|
size_t totalSize() const;
|
||||||
@@ -171,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; }
|
||||||
@@ -205,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,10 +23,9 @@
|
|||||||
/// 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
|
||||||
@@ -36,13 +35,14 @@
|
|||||||
#include "verilated_sym_props.h"
|
#include "verilated_sym_props.h"
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
/// Types
|
/// Types
|
||||||
|
|
||||||
/// 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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -63,4 +63,13 @@ public:
|
|||||||
~VerilatedVarNameMap() {}
|
~VerilatedVarNameMap() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef std::vector<const VerilatedScope*> VerilatedScopeVector;
|
||||||
|
|
||||||
|
class VerilatedHierarchyMap
|
||||||
|
: public std::map<const VerilatedScope*, VerilatedScopeVector> {
|
||||||
|
public:
|
||||||
|
VerilatedHierarchyMap() {}
|
||||||
|
~VerilatedHierarchyMap() {}
|
||||||
|
};
|
||||||
|
|
||||||
#endif // Guard
|
#endif // Guard
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -119,8 +95,11 @@ VlThreadPool::VlThreadPool(int nThreads, bool profiling)
|
|||||||
// --threads N passes nThreads=N-1, as the "main" threads counts as 1
|
// --threads N passes nThreads=N-1, as the "main" threads counts as 1
|
||||||
unsigned cpus = std::thread::hardware_concurrency();
|
unsigned cpus = std::thread::hardware_concurrency();
|
||||||
if (cpus < nThreads+1) {
|
if (cpus < nThreads+1) {
|
||||||
VL_PRINTF_MT("%%Warning: System has %u CPUs but model Verilated with"
|
static int warnedOnce = 0;
|
||||||
" --threads %d; may run slow.\n", cpus, nThreads+1);
|
if (!warnedOnce++) {
|
||||||
|
VL_PRINTF_MT("%%Warning: System has %u CPUs but model Verilated with"
|
||||||
|
" --threads %d; may run slow.\n", cpus, nThreads+1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Create'em
|
// Create'em
|
||||||
for (int i=0; i<nThreads; ++i) {
|
for (int i=0; i<nThreads; ++i) {
|
||||||
@@ -191,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();
|
||||||
@@ -218,8 +197,7 @@ void VlThreadPool::profileDump(const char* filenamep, vluint64_t ticksElapsed) {
|
|||||||
eit->m_cpu,
|
eit->m_cpu,
|
||||||
thread_id);
|
thread_id);
|
||||||
break;
|
break;
|
||||||
default: assert(false);
|
default: assert(false); break; // LCOV_EXCL_LINE
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user