mirror of
https://github.com/verilator/verilator.git
synced 2026-10-06 01:54:01 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
746c7ea8f7 | ||
|
|
5ed882faf2 | ||
|
|
fa4b10b4d9 | ||
|
|
f25a9a4c80 | ||
|
|
a999c73ce0 | ||
|
|
75a70bee6d | ||
|
|
1b1907af49 | ||
|
|
1b18eee5dc | ||
|
|
4931e48016 | ||
|
|
f96454adcc | ||
|
|
9a20a258f5 | ||
|
|
10796457d2 | ||
|
|
78e659a142 | ||
|
|
2f50642ecb | ||
|
|
050060b139 | ||
|
|
63c694f65f | ||
|
|
12093e6939 | ||
|
|
9949a6cd17 | ||
|
|
ce03293128 | ||
|
|
0a8cfb8d2c | ||
|
|
0b07679ff2 | ||
|
|
5df14627fd | ||
|
|
fc3ce29845 | ||
|
|
bba800f2d6 | ||
|
|
fe2a1e1749 | ||
|
|
fc4ffd454e | ||
|
|
8dae4ad93a | ||
|
|
8da261f302 | ||
|
|
7d88e63bab | ||
|
|
79be097e34 | ||
|
|
11b0d36ba2 | ||
|
|
80b73859a2 | ||
|
|
a548a77f26 | ||
|
|
d6bfb37e6a | ||
|
|
38a8d7fb2e | ||
|
|
0c70a0dcbf | ||
|
|
d16619fe86 | ||
|
|
2dc85a5acd | ||
|
|
dbe1348b4c | ||
|
|
d74536a4dc | ||
|
|
da20da264b | ||
|
|
22b9dfb9c9 | ||
|
|
e43c089ab8 | ||
|
|
d85b909054 | ||
|
|
75fd71d7e5 | ||
|
|
9efd64ab98 | ||
|
|
7aa01625d8 | ||
|
|
a3c58d7b70 | ||
|
|
ae466b1703 | ||
|
|
2564484429 | ||
|
|
93a044f587 | ||
|
|
81fe35ee2e | ||
|
|
08b6bdddf9 | ||
|
|
4d49db48a3 | ||
|
|
9b2266f68c | ||
|
|
752f425025 | ||
|
|
47262cd4ec | ||
|
|
47e64535d6 | ||
|
|
45d622e4bc | ||
|
|
249feaae7c | ||
|
|
9a27004ae5 | ||
|
|
42283150d7 | ||
|
|
5a1bcf9794 | ||
|
|
361cef4633 | ||
|
|
e94cdcf29c | ||
|
|
1af046986d | ||
|
|
1c9263a25b | ||
|
|
6b6790fc50 | ||
|
|
fb931087ab | ||
|
|
937e893b6d | ||
|
|
d42a2d6494 | ||
|
|
8e8f4b1e5c | ||
|
|
2ba39b25f1 | ||
|
|
5c828b7e60 | ||
|
|
8d0c06e570 | ||
|
|
5b2fbf4f37 | ||
|
|
592dab2bdb | ||
|
|
51daa64e9a | ||
|
|
2136afde6b | ||
|
|
ea55db7286 | ||
|
|
6a5f77b278 | ||
|
|
8658a0d7dc | ||
|
|
c335aad25f | ||
|
|
9d9d647c1f | ||
|
|
d47a37fb76 | ||
|
|
0a3a15a66e | ||
|
|
2358ced061 | ||
|
|
5869fdf7f6 | ||
|
|
1a1d2ecfd9 | ||
|
|
9ac64d0b92 | ||
|
|
c6607724cb | ||
|
|
90dc04cf93 | ||
|
|
4d81eb021d | ||
|
|
83475008d9 | ||
|
|
03ac7ad730 | ||
|
|
cd50949a7e | ||
|
|
f0040c7b9a | ||
|
|
f8a0389e73 | ||
|
|
b436794773 | ||
|
|
90d22cbec6 | ||
|
|
33e2acfe61 | ||
|
|
db5fdfb0ee | ||
|
|
951cd73fe0 | ||
|
|
0eeb40b975 | ||
|
|
93272c13fd | ||
|
|
43abaeb055 | ||
|
|
18b9e661c9 | ||
|
|
f435d96241 | ||
|
|
d32e3f042f | ||
|
|
df5f95a5bd | ||
|
|
b0c475205b | ||
|
|
1e2219347e | ||
|
|
cbe1b8e266 | ||
|
|
2b12fe5773 | ||
|
|
d20f22beb1 | ||
|
|
f4fe10844b | ||
|
|
122e89ffde | ||
|
|
96a4b3e5a5 | ||
|
|
fac8e76923 | ||
|
|
b864f5f5ba | ||
|
|
f9f66d787e | ||
|
|
bd211c87aa | ||
|
|
6c33e6e889 | ||
|
|
cfb6fd8b34 | ||
|
|
cb60663d49 | ||
|
|
0d2bf23d82 | ||
|
|
682a60e325 | ||
|
|
2ab6272cc7 | ||
|
|
152a6cd886 | ||
|
|
f91793e931 | ||
|
|
a2d26b45bb | ||
|
|
dce8f3d25d | ||
|
|
38e5b6c1ad | ||
|
|
b9d7819faa | ||
|
|
1f9323d086 | ||
|
|
574dbfded1 | ||
|
|
2a87387eb3 | ||
|
|
a5ddd10e31 | ||
|
|
e871cd8a44 | ||
|
|
7b431b37c7 | ||
|
|
eeef5ab4de | ||
|
|
ac4ec87942 | ||
|
|
290c2e0388 | ||
|
|
89924bda51 | ||
|
|
60eab3eb8c | ||
|
|
e0b61ceabd | ||
|
|
30e3edb81d | ||
|
|
542e324869 | ||
|
|
1c5e5704f5 | ||
|
|
1d400dd98c | ||
|
|
a4ed3c2086 | ||
|
|
efb5caad22 | ||
|
|
3a002b6cf2 | ||
|
|
f8b7981be4 | ||
|
|
b55ee79d86 | ||
|
|
af70db88db | ||
|
|
7ef033f876 | ||
|
|
db59c07f27 | ||
|
|
9085e34d70 | ||
|
|
0dfa7d3af5 | ||
|
|
b0e796ca83 | ||
|
|
3bd830eacf | ||
|
|
f4efcbde5c | ||
|
|
658819bb71 | ||
|
|
3fc8249429 | ||
|
|
e0a38ce2c2 | ||
|
|
178e1789b5 | ||
|
|
108c900387 | ||
|
|
63507e8e29 | ||
|
|
87f1e06c41 | ||
|
|
7e8bafd217 | ||
|
|
457ad07ade | ||
|
|
79c901c220 | ||
|
|
b61d819fcb | ||
|
|
f4038e3674 | ||
|
|
8377514127 | ||
|
|
d8ea989eda | ||
|
|
5f3316d3dc | ||
|
|
a4fddb3fbe | ||
|
|
3d71716a8a | ||
|
|
9f37cef1bb | ||
|
|
0de1bbc85b | ||
|
|
3aa8624658 | ||
|
|
42b711b862 | ||
|
|
2873dbe154 | ||
|
|
31a83cb0d8 | ||
|
|
383e384739 | ||
|
|
1bb6433649 | ||
|
|
ced39d0982 | ||
|
|
fc4d6a62af | ||
|
|
fa99cbbc73 | ||
|
|
49455721a3 | ||
|
|
11032b1936 | ||
|
|
f2fba51fe2 | ||
|
|
7c79f0d431 | ||
|
|
41b9b30b9b | ||
|
|
1fa82ffb7b | ||
|
|
4f93ac6477 | ||
|
|
f7533010c6 | ||
|
|
47b650d821 | ||
|
|
0c2c097377 | ||
|
|
d721f70690 | ||
|
|
ea8aaa21e8 | ||
|
|
660d1059b0 | ||
|
|
e7dc2de14b | ||
|
|
32100a3c91 | ||
|
|
67f7432dd7 | ||
|
|
59dc2853e3 | ||
|
|
ada58465b2 | ||
|
|
173f57c636 | ||
|
|
1f3e8640f7 | ||
|
|
6039e9dcc3 | ||
|
|
d64f979f99 | ||
|
|
0c53d19113 | ||
|
|
c64a07fd09 | ||
|
|
694919b9d1 | ||
|
|
606b35853b | ||
|
|
26b7452178 | ||
|
|
b51f887567 | ||
|
|
c4b8675d77 | ||
|
|
a7cd7a1ed9 | ||
|
|
a48c779367 | ||
|
|
cf1eccc24f | ||
|
|
d45caca011 | ||
|
|
0722f47539 | ||
|
|
a372e010bd | ||
|
|
530817191e | ||
|
|
1282548a1c | ||
|
|
c7610ed044 | ||
|
|
ffc1c51526 | ||
|
|
b130a8cfeb | ||
|
|
551bd284dd | ||
|
|
9edccfdffa | ||
|
|
1a056f6db9 | ||
|
|
e018eb7bac | ||
|
|
0a91ddf38a | ||
|
|
67bb2c640e | ||
|
|
561eaa311d | ||
|
|
3f7a248ed4 | ||
|
|
ecaa07a72a | ||
|
|
99bdc27be3 | ||
|
|
c3c46967dc | ||
|
|
7f1a9239ab | ||
|
|
c8102c8ffe | ||
|
|
5aa12e9b51 | ||
|
|
829437b20b | ||
|
|
3c4131d45d | ||
|
|
ae8d8ee1ac | ||
|
|
89ec3d16dc | ||
|
|
7602c983c5 | ||
|
|
560efb2c9e | ||
|
|
c2328ef46a | ||
|
|
f6035447ae | ||
|
|
38438b3373 | ||
|
|
71dedccbbe | ||
|
|
cddbe4642f | ||
|
|
bdfdc737a0 | ||
|
|
3d045c3aee | ||
|
|
9583f152ee | ||
|
|
5b2755d28d | ||
|
|
9378259779 | ||
|
|
3d762282b9 | ||
|
|
30783e6a79 | ||
|
|
aa86c777f4 | ||
|
|
a2792785fe | ||
|
|
267315e7d4 | ||
|
|
99d39cb6ff | ||
|
|
915ceb2d04 | ||
|
|
49c90ecbce | ||
|
|
8395004d25 | ||
|
|
5de1c619c8 | ||
|
|
a6d678d41d | ||
|
|
2b91d764b5 | ||
|
|
62337bb6ac | ||
|
|
9abab2c366 | ||
|
|
b22e368b25 | ||
|
|
a9cd2998e5 | ||
|
|
f1ea30f257 | ||
|
|
0b74e9b354 | ||
|
|
8189416d0c | ||
|
|
5f0e1fae7f | ||
|
|
880a9be3b1 | ||
|
|
7bfc1a00a7 | ||
|
|
baff64a43d | ||
|
|
b7f2bb0e80 | ||
|
|
08e0a397d3 | ||
|
|
5f333be947 | ||
|
|
f5f4e15ce2 | ||
|
|
fbd568dc47 | ||
|
|
c79ea88576 | ||
|
|
9be4e7b576 | ||
|
|
33105f017c | ||
|
|
e02f97854c | ||
|
|
960d0de361 | ||
|
|
31ce1fdfd3 | ||
|
|
9821381059 | ||
|
|
3f7bf3d2dc | ||
|
|
f9e69984ff | ||
|
|
b1b5b5dfe2 | ||
|
|
c7440b250f | ||
|
|
bab8462789 | ||
|
|
4eaa6fdd06 | ||
|
|
38b2845e2a | ||
|
|
14d24213a8 | ||
|
|
c61258c0d0 | ||
|
|
47226236f4 | ||
|
|
e744c21f56 | ||
|
|
89a0632ecc | ||
|
|
dcc05db7f1 | ||
|
|
90fb2e5487 | ||
|
|
b5ce7d5982 | ||
|
|
f211616a4c | ||
|
|
a9cb9bac21 | ||
|
|
ae005434e4 | ||
|
|
ef87d057fc | ||
|
|
181b9a5795 | ||
|
|
9baf9c55c2 | ||
|
|
e29132377e | ||
|
|
999751c422 | ||
|
|
22656d6fdd | ||
|
|
ef0c5fd772 | ||
|
|
90c61c79d6 | ||
|
|
4ba3bff87f | ||
|
|
c3dd6f5344 | ||
|
|
321880f5a6 | ||
|
|
3737d209f6 | ||
|
|
29c4b0a141 | ||
|
|
956f64c6ba | ||
|
|
c2d18d8ae4 | ||
|
|
5b9806ae6d | ||
|
|
665fa140a8 | ||
|
|
32f843a214 | ||
|
|
72a3c756ad | ||
|
|
47069dfe52 | ||
|
|
43a84d7ad8 | ||
|
|
b6ca2a42f2 | ||
|
|
e52a4ac74f | ||
|
|
decfa6bd7a | ||
|
|
8931bd37e2 | ||
|
|
4b79d23d00 | ||
|
|
77fe7c426e | ||
|
|
331c2244fc | ||
|
|
5a3eab634a | ||
|
|
77e68acf54 | ||
|
|
7a355d448a | ||
|
|
3b7ad1820d | ||
|
|
d3b63b2653 | ||
|
|
046896e60a | ||
|
|
fb9119ff49 | ||
|
|
818aaa8b89 | ||
|
|
26bdfc3474 | ||
|
|
0e91d8a10e | ||
|
|
434c3c3ef3 | ||
|
|
21e05c43dd | ||
|
|
0e154b35ef | ||
|
|
e6554e061c | ||
|
|
0f004c8e7b | ||
|
|
f5b1a5cd58 | ||
|
|
48a098b041 | ||
|
|
f8c0169e82 | ||
|
|
539c9d4c63 | ||
|
|
b4d8220cbb | ||
|
|
5eded789aa | ||
|
|
e931c6230a | ||
|
|
64a6e1ac8b | ||
|
|
50094ca296 | ||
|
|
15b32dc140 | ||
|
|
441ecfedc9 | ||
|
|
78147ee8d7 | ||
|
|
8c58612a3b | ||
|
|
56f9d244de | ||
|
|
2ba9eb4228 | ||
|
|
9a8c878f2d | ||
|
|
41a563bdc8 | ||
|
|
4e5f30858b | ||
|
|
b989ac6db5 | ||
|
|
4d1f4bbf49 | ||
|
|
e9ad665d32 | ||
|
|
78052f87bd | ||
|
|
ebf5c11e03 | ||
|
|
7e355e211c | ||
|
|
f36461e696 | ||
|
|
88d7ca01b0 | ||
|
|
2e2b82c052 | ||
|
|
f1bb0544be | ||
|
|
3b1371124e | ||
|
|
e6857df5c6 | ||
|
|
73374a0303 | ||
|
|
e334740dd6 | ||
|
|
84ee833ea7 | ||
|
|
b7ad1e6d61 | ||
|
|
340efe3a3a | ||
|
|
2342549caf | ||
|
|
028737cde8 | ||
|
|
bf972963f4 | ||
|
|
9bda91b3bf | ||
|
|
e4c5eb5e69 | ||
|
|
2e8cc22c54 | ||
|
|
655910d486 | ||
|
|
2a0ec88379 | ||
|
|
80859a609a | ||
|
|
d679d50eca | ||
|
|
65de118e51 | ||
|
|
4cd56b1fb9 | ||
|
|
f3945e7c02 | ||
|
|
5ef982b4b5 | ||
|
|
f96d336b97 | ||
|
|
a68a4fc888 | ||
|
|
0c3ffa1841 | ||
|
|
24a0d2a0c9 | ||
|
|
ca42be982c | ||
|
|
ffc31e2efa | ||
|
|
8952aa59ff | ||
|
|
2966f03042 | ||
|
|
d15e9e2b7a | ||
|
|
fd45be3def | ||
|
|
0658a7654f | ||
|
|
7526151670 | ||
|
|
560b59f97f | ||
|
|
b2ca89c185 | ||
|
|
1de2de4bde | ||
|
|
4135867e53 | ||
|
|
ff425369ac | ||
|
|
30ccccdb67 | ||
|
|
5e3016f34a | ||
|
|
f775feb7f0 | ||
|
|
0a94ea5386 | ||
|
|
aa8423ba46 | ||
|
|
d753f36ebc | ||
|
|
55976dbc25 | ||
|
|
77c005835d | ||
|
|
6b0601fd54 | ||
|
|
c1652979d5 | ||
|
|
740fee660e | ||
|
|
984ee624ed | ||
|
|
00ef0519f5 | ||
|
|
59d170c6f8 | ||
|
|
9a722ccf62 | ||
|
|
748fa4cb80 | ||
|
|
694cf371f9 | ||
|
|
8696e38e6f | ||
|
|
706162ecc6 | ||
|
|
c3f17ce2c4 | ||
|
|
41f29d2ce3 | ||
|
|
7b119a594f | ||
|
|
b7d20b102b | ||
|
|
ac05a779ae |
+21
-10
@@ -17,7 +17,7 @@ AllowShortLoopsOnASingleLine: true
|
|||||||
AlwaysBreakAfterDefinitionReturnType: None
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
AlwaysBreakAfterReturnType: None
|
AlwaysBreakAfterReturnType: None
|
||||||
AlwaysBreakBeforeMultilineStrings: false
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
AlwaysBreakTemplateDeclarations: false
|
AlwaysBreakTemplateDeclarations: true
|
||||||
BinPackArguments: true
|
BinPackArguments: true
|
||||||
BinPackParameters: true
|
BinPackParameters: true
|
||||||
BraceWrapping:
|
BraceWrapping:
|
||||||
@@ -59,15 +59,27 @@ ForEachMacros:
|
|||||||
- foreach
|
- foreach
|
||||||
- Q_FOREACH
|
- Q_FOREACH
|
||||||
- BOOST_FOREACH
|
- BOOST_FOREACH
|
||||||
IncludeBlocks: Preserve
|
|
||||||
|
# Include grouping/sorting
|
||||||
|
SortIncludes: true
|
||||||
|
IncludeBlocks: Regroup
|
||||||
IncludeCategories:
|
IncludeCategories:
|
||||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
- Regex: '"(config_build|verilated_config|verilatedos)\.h"'
|
||||||
Priority: 2
|
Priority: -1 # Sepecials before main header
|
||||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
- Regex: '(<|")verilated.*'
|
||||||
Priority: 3
|
Priority: 1 # Runtime headers
|
||||||
- Regex: '.*'
|
- Regex: '"V3.*__gen.*\.h"'
|
||||||
Priority: 1
|
Priority: 3 # Generated internal headers separately
|
||||||
IncludeIsMainRegex: '(Test)?$'
|
- Regex: '"V3.*"'
|
||||||
|
Priority: 2 # Internal header
|
||||||
|
- Regex: '".*"'
|
||||||
|
Priority: 4 # Other non-system headers
|
||||||
|
- Regex: '<[[:alnum:]_.]+>'
|
||||||
|
Priority: 5 # Simple system headers next
|
||||||
|
- Regex: '<.*>'
|
||||||
|
Priority: 6 # Other system headers next
|
||||||
|
IncludeIsMainRegex: '$'
|
||||||
|
|
||||||
IndentCaseLabels: false
|
IndentCaseLabels: false
|
||||||
IndentPPDirectives: None
|
IndentPPDirectives: None
|
||||||
IndentWidth: 4
|
IndentWidth: 4
|
||||||
@@ -91,7 +103,6 @@ PenaltyExcessCharacter: 1000000
|
|||||||
PenaltyReturnTypeOnItsOwnLine: 60
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
PointerAlignment: Left
|
PointerAlignment: Left
|
||||||
ReflowComments: true
|
ReflowComments: true
|
||||||
SortIncludes: false
|
|
||||||
SortUsingDeclarations: true
|
SortUsingDeclarations: true
|
||||||
SpaceAfterCStyleCast: false
|
SpaceAfterCStyleCast: false
|
||||||
SpaceAfterTemplateKeyword: true
|
SpaceAfterTemplateKeyword: true
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: Bug report
|
name: Bug report
|
||||||
about: Something isn't working as expected, and it isn't "Unsupported." (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.rst)
|
about: Use this to report that something isn't working as expected, and it isn't "Unsupported." (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.rst)
|
||||||
title: ''
|
title: ''
|
||||||
labels: new
|
labels: new
|
||||||
assignees: ''
|
assignees: ''
|
||||||
@@ -15,4 +15,4 @@ What 'verilator --version' are you using? Did you try it with the git master ve
|
|||||||
|
|
||||||
What OS and distribution are you using?
|
What OS and distribution are you using?
|
||||||
|
|
||||||
Would you be willing to try to fix Verilator yourself with assistance?
|
May we assist you in trying to fix this in Verilator yourself?
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: Feature Request
|
name: Feature Request
|
||||||
about: Request something should be supported, or a new feature added. (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.rst)
|
about: Use this to request something should be supported, or a new feature added. (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.rst)
|
||||||
title: ''
|
title: ''
|
||||||
labels: new
|
labels: new
|
||||||
assignees: ''
|
assignees: ''
|
||||||
@@ -13,4 +13,4 @@ What would you like added/supported?
|
|||||||
|
|
||||||
Can you attach an example that runs on other simulators? (Must be openly licensed, ideally in test_regress format.)
|
Can you attach an example that runs on other simulators? (Must be openly licensed, ideally in test_regress format.)
|
||||||
|
|
||||||
May we assist you in trying to fix this yourself?
|
May we assist you in trying to fix this in Verilator yourself?
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: Q and A, or Other
|
name: Q and A, or Other
|
||||||
about: Ask a question, not related to a specific bug or feature request. (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.rst)
|
about: Use this to ask a question, not related to a specific bug nor feature request. (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.rst)
|
||||||
title: ''
|
title: ''
|
||||||
labels: new
|
labels: new
|
||||||
assignees: ''
|
assignees: ''
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-20.04, ubuntu-18.04]
|
os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04]
|
||||||
compiler:
|
compiler:
|
||||||
- { cc: clang, cxx: clang++ }
|
- { cc: clang, cxx: clang++ }
|
||||||
- { cc: gcc, cxx: g++ }
|
- { cc: gcc, cxx: g++ }
|
||||||
@@ -37,9 +37,16 @@ jobs:
|
|||||||
exclude:
|
exclude:
|
||||||
# Build pull requests only with ubuntu-20.04 and without m32
|
# Build pull requests only with ubuntu-20.04 and without m32
|
||||||
- os: ${{ github.event_name == 'pull_request' && 'ubuntu-18.04' || 'do-not-exclude' }}
|
- os: ${{ github.event_name == 'pull_request' && 'ubuntu-18.04' || 'do-not-exclude' }}
|
||||||
|
- os: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'do-not-exclude' }}
|
||||||
- m32: ${{ github.event_name == 'pull_request' && 1 || 'do-not-exclude' }}
|
- m32: ${{ github.event_name == 'pull_request' && 1 || 'do-not-exclude' }}
|
||||||
# Build -m32 only on ubuntu-20.04
|
# Build -m32 only on ubuntu-20.04
|
||||||
- {os: ubuntu-18.04, m32: 1}
|
- {os: ubuntu-18.04, m32: 1}
|
||||||
|
- {os: ubuntu-22.04, m32: 1}
|
||||||
|
include:
|
||||||
|
# Build GCC 10 on ubuntu-20.04
|
||||||
|
- os: ubuntu-20.04
|
||||||
|
compiler: { cc: gcc-10, cxx: g++-10 }
|
||||||
|
m32: 0
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
name: Build | ${{ matrix.os }} | ${{ matrix.compiler.cc }} ${{ matrix.m32 && '| -m32' || '' }}
|
name: Build | ${{ matrix.os }} | ${{ matrix.compiler.cc }} ${{ matrix.m32 && '| -m32' || '' }}
|
||||||
env:
|
env:
|
||||||
@@ -90,7 +97,7 @@ jobs:
|
|||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-20.04, ubuntu-18.04]
|
os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04]
|
||||||
compiler:
|
compiler:
|
||||||
- { cc: clang, cxx: clang++ }
|
- { cc: clang, cxx: clang++ }
|
||||||
- { cc: gcc, cxx: g++ }
|
- { cc: gcc, cxx: g++ }
|
||||||
@@ -99,9 +106,18 @@ jobs:
|
|||||||
exclude:
|
exclude:
|
||||||
# Build pull requests only with ubuntu-20.04 and without m32
|
# Build pull requests only with ubuntu-20.04 and without m32
|
||||||
- os: ${{ github.event_name == 'pull_request' && 'ubuntu-18.04' || 'do-not-exclude' }}
|
- os: ${{ github.event_name == 'pull_request' && 'ubuntu-18.04' || 'do-not-exclude' }}
|
||||||
|
- os: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'do-not-exclude' }}
|
||||||
- m32: ${{ github.event_name == 'pull_request' && 1 || 'do-not-exclude' }}
|
- m32: ${{ github.event_name == 'pull_request' && 1 || 'do-not-exclude' }}
|
||||||
# Build -m32 only on ubuntu-20.04
|
# Build -m32 only on ubuntu-20.04
|
||||||
- {os: ubuntu-18.04, m32: 1}
|
- {os: ubuntu-18.04, m32: 1}
|
||||||
|
- {os: ubuntu-22.04, m32: 1}
|
||||||
|
include:
|
||||||
|
# Test with GCC 10 on ubuntu-20.04 without m32
|
||||||
|
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, m32: 0, suite: dist-vlt-0}
|
||||||
|
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, m32: 0, suite: dist-vlt-1}
|
||||||
|
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, m32: 0, suite: dist-vlt-2}
|
||||||
|
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, m32: 0, suite: vltmt-0}
|
||||||
|
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, m32: 0, suite: vltmt-1}
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
name: Test | ${{ matrix.os }} | ${{ matrix.compiler.cc }} | ${{ matrix.suite }} ${{ matrix.m32 && '| -m32' || '' }}
|
name: Test | ${{ matrix.os }} | ${{ matrix.compiler.cc }} | ${{ matrix.suite }} ${{ matrix.m32 && '| -m32' || '' }}
|
||||||
env:
|
env:
|
||||||
@@ -110,7 +126,7 @@ jobs:
|
|||||||
CI_M32: ${{ matrix.m32 }}
|
CI_M32: ${{ matrix.m32 }}
|
||||||
CC: ${{ matrix.compiler.cc }}
|
CC: ${{ matrix.compiler.cc }}
|
||||||
CXX: ${{ matrix.compiler.cxx }}
|
CXX: ${{ matrix.compiler.cxx }}
|
||||||
CACHE_BASE_KEY: test-${{ matrix.os }}-${{ matrix.compiler.cc }}-m32=${{ matrix.m32 }}-${ matrix.suite }}
|
CACHE_BASE_KEY: test-${{ matrix.os }}-${{ matrix.compiler.cc }}-m32=${{ matrix.m32 }}-${{ matrix.suite }}
|
||||||
CCACHE_MAXSIZE: 64M # Per build matrix entry (2160M in total)
|
CCACHE_MAXSIZE: 64M # Per build matrix entry (2160M in total)
|
||||||
VERILATOR_ARCHIVE: verilator-${{ github.sha }}-${{ matrix.os }}-${{ matrix.compiler.cc }}${{ matrix.m32 && '-m32' || '' }}.tar.gz
|
VERILATOR_ARCHIVE: verilator-${{ github.sha }}-${{ matrix.os }}-${{ matrix.compiler.cc }}${{ matrix.m32 && '-m32' || '' }}.tar.gz
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
Test:
|
Test:
|
||||||
name: "'docs/CONTRIBUTORS' was signed"
|
name: "'docs/CONTRIBUTORS' was signed"
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
- run: test_regress/t/t_dist_contributors.pl
|
- run: test_regress/t/t_dist_contributors.pl
|
||||||
|
|||||||
@@ -10,11 +10,11 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
format:
|
format:
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-22.04
|
||||||
name: Ubuntu 20.04 | format
|
name: Ubuntu 22.04 | format
|
||||||
env:
|
env:
|
||||||
CI_OS_NAME: linux
|
CI_OS_NAME: linux
|
||||||
CI_RUNS_ON: ubuntu-20.04
|
CI_RUNS_ON: ubuntu-22.04
|
||||||
CI_COMMIT: ${{ github.sha }}
|
CI_COMMIT: ${{ github.sha }}
|
||||||
CI_M32: 0
|
CI_M32: 0
|
||||||
steps:
|
steps:
|
||||||
@@ -27,14 +27,14 @@ jobs:
|
|||||||
CI_BUILD_STAGE_NAME: build
|
CI_BUILD_STAGE_NAME: build
|
||||||
run: |
|
run: |
|
||||||
bash ci/ci-install.bash &&
|
bash ci/ci-install.bash &&
|
||||||
sudo apt-get install clang-format-11 yapf3 &&
|
sudo apt-get install clang-format-14 yapf3 &&
|
||||||
git config --global user.email "[email protected]" &&
|
git config --global user.email "[email protected]" &&
|
||||||
git config --global user.name "github action"
|
git config --global user.name "github action"
|
||||||
- name: Format code
|
- name: Format code
|
||||||
run: |
|
run: |
|
||||||
autoconf &&
|
autoconf &&
|
||||||
./configure &&
|
./configure &&
|
||||||
make -j 2 format CLANGFORMAT=clang-format-11 &&
|
make -j 2 format CLANGFORMAT=clang-format-14 &&
|
||||||
git status
|
git status
|
||||||
- name: Push
|
- name: Push
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
\#*
|
\#*
|
||||||
.#*
|
.#*
|
||||||
|
.gdb_history
|
||||||
.nfs*
|
.nfs*
|
||||||
*~
|
*~
|
||||||
*.tidy
|
*.tidy
|
||||||
|
|||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
set noparent
|
||||||
|
linelength=100
|
||||||
|
filter=-build/c++11
|
||||||
|
filter=-build/header_guard
|
||||||
|
filter=-build/include_order
|
||||||
|
filter=-build/include_subdir
|
||||||
|
filter=-readability/inheritance
|
||||||
|
filter=-readability/nolint
|
||||||
|
filter=-readability/todo
|
||||||
|
filter=-runtime/references
|
||||||
|
filter=-whitespace/blank_line
|
||||||
|
filter=-whitespace/empty_if_body
|
||||||
|
filter=-whitespace/indent
|
||||||
|
filter=-whitespace/newline
|
||||||
|
filter=-whitespace/braces
|
||||||
|
filter=-whitespace/parens
|
||||||
|
filter=-whitespace/todo
|
||||||
@@ -8,6 +8,185 @@ The changes in each Verilator version are described below. The
|
|||||||
contributors that suggested a given feature are shown in []. Thanks!
|
contributors that suggested a given feature are shown in []. Thanks!
|
||||||
|
|
||||||
|
|
||||||
|
Verilator 4.228 2022-10-01
|
||||||
|
==========================
|
||||||
|
|
||||||
|
**Announcement:**
|
||||||
|
|
||||||
|
* The next release is anticipated primere Verilator Version 5. Please
|
||||||
|
consider beta-testing the github 'develop-v5' branch, which will soon
|
||||||
|
merge into the github 'master' branch (#3383).
|
||||||
|
|
||||||
|
**Minor:**
|
||||||
|
|
||||||
|
* Support some IEEE signal strengths (#3601) (#3629). [Ryszard Rozak/Antmicro]
|
||||||
|
* Add --main to generate main() C++ (previously was experimental only).
|
||||||
|
* Add --build-jobs, and rework arguments for -j (#3623). [Kamil Rakoczy]
|
||||||
|
* Rename --bin to --build-dep-bin.
|
||||||
|
* Rename debug flags --dumpi-tree, --dumpi-graph, etc. [Geza Lore]
|
||||||
|
* Fix thread saftey in SystemC VL_ASSIGN_SBW/WSB (#3494) (#3513). [Mladen Slijepcevic]
|
||||||
|
* Fix crash in gate optimization of circular logic (#3543). [Bill Flynn]
|
||||||
|
* Fix arguments in non-static method call (#3547) (#3582). [Gustav Svensk]
|
||||||
|
* Fix default --mod-prefix when --prefix is repeated (#3603). [Geza Lore]
|
||||||
|
* Fix calling trace() after open() segfault (#3610) (#3627). [Yu-Sheng Lin]
|
||||||
|
* Fix typedef'ed class conversion to boolean (#3616). [Aleksander Kiryk]
|
||||||
|
* Fix Verilation speed when disabled warnings (#3632). [Kamil Rakoczy/Antmicro]
|
||||||
|
|
||||||
|
|
||||||
|
Verilator 4.226 2022-08-31
|
||||||
|
==========================
|
||||||
|
|
||||||
|
**Minor:**
|
||||||
|
|
||||||
|
* Add --future0 and --future1 options.
|
||||||
|
* Support class parameters (#2231) (#3541). [Arkadiusz Kozdra/Antmicro]
|
||||||
|
* Support wildcard index associative arrays (#3501). [Arkadiusz Kozdra/Antmicro]
|
||||||
|
* Support negated properties (#3572). [Aleksander Kiryk]
|
||||||
|
* Support $test$plusargs(expr) (#3489).
|
||||||
|
* Rename trace rolloverSize() (#3570).
|
||||||
|
* Improve Verilation speed with --threads on large designs. [Geza Lore]
|
||||||
|
* Improve Verilation memory by reducing V3Number (#3521). [Mariusz Glebocki/Antmicro]
|
||||||
|
* Fix struct pattern assignment (#2328) (#3517). [Mostafa Gamal]
|
||||||
|
* Fix public combo propagation issues (#2905). [Todd Strader]
|
||||||
|
* Fix incorrect tristate logic (#3399) [shareefj, Vighnesh Iyer]
|
||||||
|
* Fix incorrect bit op tree optimization (#3470). [algrobman]
|
||||||
|
* Fix bisonpre for MSYS2 (#3471).
|
||||||
|
* Fix max memory usage (#3483). [Kamil Rakoczy/Antmicro]
|
||||||
|
* Fix empty string arguments to display (#3484). [Grulfen]
|
||||||
|
* Fix table misoptimizing away display (#3488). [Stefan Post]
|
||||||
|
* Fix unique_ptr memory header for MinGW64 (#3493).
|
||||||
|
* Fix $dump systemtask with --output-split-cfuncs (#3495) (#3497). [Varun Koyyalagunta]
|
||||||
|
* Fix wrong bit op tree optimization (#3509). [Nathan Graybeal]
|
||||||
|
* Fix nested default assignment for struct pattern (#3511) (#3524). [Mostafa Gamal]
|
||||||
|
* Fix sformat string incorrectly cleared (#3515) (#3519). [Gustav Svensk]
|
||||||
|
* Fix segfault exporting non-existant package (#3535).
|
||||||
|
* Fix void-cast queue pop_front or pop_back (#3542) (#3364). [Drew Ranck]
|
||||||
|
* Fix case statement comparing string literal (#3544). [Gustav Svensk]
|
||||||
|
* Fix === with some tristate constants (#3551). [Ryszard Rozak/Antmicro]
|
||||||
|
* Fix converting subclasses to string (#3552). [Arkadiusz Kozdra/Antmicro]
|
||||||
|
* Fix --hierarchical with order-based pin connections (#3583) (#3585). [Kelin9298]
|
||||||
|
|
||||||
|
|
||||||
|
Verilator 4.224 2022-06-19
|
||||||
|
==========================
|
||||||
|
|
||||||
|
**Major:**
|
||||||
|
|
||||||
|
* VCD tracing is now parallelized with --threads (#3449). [Geza Lore, Shunyao CAD]
|
||||||
|
|
||||||
|
**Minor:**
|
||||||
|
|
||||||
|
* Add -f<optimization> options to replace -O<letter> options (#3436).
|
||||||
|
* Changed --no-merge-const-pool to -fno-merge-const-pool (#3436).
|
||||||
|
* Changed --no-decoration to remove output whitespace (#3460). [Kamil Rakoczy]
|
||||||
|
* Support compile time trace signal selection with tracing_on/off (#3323). [Shunyao CAD]
|
||||||
|
* Support non-ANSI interface port declarations (#3439). [Geza Lore, Shunyao CAD]
|
||||||
|
* Support concat assignment to packed array (#3446).
|
||||||
|
* Improve conditional merging optimization (#3125). [Geza Lore, Shunyao CAD]
|
||||||
|
* Define VM_TRACE_VCD when tracing in VCD format. [Geza Lore, Shunyao CAD]
|
||||||
|
* Add assert when VerilatedContext is mis-deleted (#3121). [Rupert Swarbrick]
|
||||||
|
* Internal prep work towards timing control. [Krzysztof Bieganski/Antmicro]
|
||||||
|
* Fix hang with large case statement optimization (#3405). [Mike Urbach]
|
||||||
|
* Fix UNOPTFLAT warning from initial static var (#3406). [Kamil Rakoczy]
|
||||||
|
* Fix compile error when enable VL_LEAK_CHECKS (#3411). [HungMingWu]
|
||||||
|
* Fix cmake rules to support higher-level targets (#3377) (#3386). [Martin Stadler]
|
||||||
|
* Fix BLKANDNBLK on $readmem/$writemem (#3379). [Alex Solomatnikov]
|
||||||
|
* Fix 'with' operator with type casting (#3387). [xiak95]
|
||||||
|
* Fix incorrect conditional merging (#3409). [Raynard Qiao]
|
||||||
|
* Fix passing VL_TRACE_FST_WRITER_THREAD in CMake build. [Geza Lore, Shunyao CAD]
|
||||||
|
* Fix compile error under strict C++11 mode (#3463). [Kevin Kiningham]
|
||||||
|
* Fix public unpacked input ports (#3465). [Todd Strader]
|
||||||
|
|
||||||
|
|
||||||
|
Verilator 4.222 2022-05-02
|
||||||
|
==========================
|
||||||
|
|
||||||
|
**Minor:**
|
||||||
|
|
||||||
|
* Split --prof-threads into --prof-exec and --prof-pgo (#3365). [Geza Lore, Shunyao CAD]
|
||||||
|
* Deprecate 'vluint64_t' and similar types (#3255).
|
||||||
|
* Raise error on assignment to const in initial blocks. [Geza Lore, Shunyao CAD]
|
||||||
|
* Issue INITIALDLY/COMBDLY/BLKSEQ warnings consistent with Verilator execution. [Geza Lore, Shunyao CAD]
|
||||||
|
* Support LoongArch ISA multithreading (#3353) (#3354). [Xi Zhang]
|
||||||
|
* Fix MSVC localtime_s (#3124).
|
||||||
|
* Fix Bison 3.8.2 error (#3366). [elike-ypq]
|
||||||
|
* Fix rare bug in -Oz (V3Localize) (#3286). [Geza Lore, Shunyao CAD]
|
||||||
|
* Fix tracing interfaces inside interfaces (#3309). [Kevin Millis]
|
||||||
|
* Fix filenames with dots overwriting debug .vpp files (#3373).
|
||||||
|
* Fix including VK_USER_OBJS in make library (#3370) (#3382). [Julien Margetts]
|
||||||
|
* Fix hang in generate symbol references (#3391) (#3398). [Yoda Lee]
|
||||||
|
* Fix missing #include <memory> (#3392). [Aliaksei Chapyzhenka]
|
||||||
|
* Fix crash in recursive module inlining (#3393). [david-sawatzke]
|
||||||
|
* Fix --protect-ids mangling names of library methods. [Geza Lore, Shunyao CAD]
|
||||||
|
* Fix foreach segmentation fault (#3400). [Kamil Rakoczy]
|
||||||
|
|
||||||
|
|
||||||
|
Verilator 4.220 2022-03-12
|
||||||
|
==========================
|
||||||
|
|
||||||
|
**Minor:**
|
||||||
|
|
||||||
|
* Removed the deprecated lint_off flag -msg; use -rule instead.
|
||||||
|
* Removed the deprecated "fl" attribute in XML output; use "loc" attribute instead.
|
||||||
|
* Suppress WIDTH warning on negate using carry bit (#3295). [Peter Monsson]
|
||||||
|
* Add trace dumpvars() call for selective runtime tracing (#3322). [Shunyao CAD]
|
||||||
|
* Add VERILATOR_VERSION_INTEGER for determining API (#3343). [Larry Doolittle]
|
||||||
|
* Improve various V3Combine algorithm details (#3328). [Yutetsu TAKATSUKASA]
|
||||||
|
* Improve various V3Order algorithm details. [Geza Lore]
|
||||||
|
* Fix MacOS arm64 build (#3285) (#3291). [Guokai Chen]
|
||||||
|
* Fix signed number operation (#3294) (#3308). [Raynard Qiao]
|
||||||
|
* Fix FST traces to include vector range (#3296) (#3297). [Jamie Iles]
|
||||||
|
* Fix skipping public enum values with four-state values (#3303).
|
||||||
|
* Fix $readmem file not found to be warning not error (#3310). [Alexander Grobman]
|
||||||
|
* Fix class stringification on wide arrays (#3312). [Iru Cai]
|
||||||
|
* Fix $fscanf etc to return -1 on EOF (#3313). [Jose Tejada]
|
||||||
|
* Fix public function arguments that are arrayed (#3316). [pawel256]
|
||||||
|
* Fix unnamedblk error on foreach (#3321). [Aliaksei Chapyzhenka]
|
||||||
|
* Fix crash in recursive module inlining (#3324). [Larry Doolittle]
|
||||||
|
* Fix VL_RESTORER behavior on passing a lvalue reference (#3326). [HungMingWu]
|
||||||
|
* Fix compile error with --trace-fst --sc (#3332). [leavinel]
|
||||||
|
* Fix cast to array types (#3333). [Todd Strader]
|
||||||
|
* Fix Vdeeptemp error with --threads and --compiler clang (#3338). [Per Karlsson]
|
||||||
|
|
||||||
|
|
||||||
|
Verilator 4.218 2022-01-17
|
||||||
|
==========================
|
||||||
|
|
||||||
|
**Major:**
|
||||||
|
|
||||||
|
* Primary inputs and outputs (VL_INW/VL_OUTW) now use VlWide type.
|
||||||
|
In general this should be backward compatible, but may lead to some
|
||||||
|
wrapper code needing changes.
|
||||||
|
* Option --cdc is deprecated and is planned for removal,
|
||||||
|
file a bug if this is still being used.
|
||||||
|
|
||||||
|
**Minor:**
|
||||||
|
|
||||||
|
* Support class static members (#2233).
|
||||||
|
* Support force/release (#2431) (#2593). [Shunyao CAD]
|
||||||
|
* Add 'forceable' attribute to allow forcing from C++. (#3272). [Geza Lore, Shunyao CAD]
|
||||||
|
* Support lower dimension looping in foreach loops (#3172). [Ehab Ibrahim]
|
||||||
|
* Support up to 64 bit enums for .next/.prev/.name (#3244). [Alexander Grobman]
|
||||||
|
* Reduce .rodata footprint of trace initialization (#3250). [Geza Lore, Shunyao CAD]
|
||||||
|
* Support FST tracing in hierarchical Verilation (#3251). [Yutetsu TAKATSUKASA]
|
||||||
|
* Use C++11 standard types for MacOS portability (#3254) (#3257). [Adrien Le Masle]
|
||||||
|
* Fix make support for BSD ar (#2999) (#3256). [Julie Schwartz]
|
||||||
|
* Fix bad ending address on $readmem (#3205). [Julie Schwartz]
|
||||||
|
* Fix MSWIN compile error (#2681). [Unai Martinez-Corral]
|
||||||
|
* Fix break under foreach loop (#3230).
|
||||||
|
* Fix VL_STREAML_FAST_QQI with 64 bit left-hand-side (#3232) (#3235). [Adrien Le Masle]
|
||||||
|
* Fix $sformat of inputs/outputs (#3236). [Adrien Le Masle]
|
||||||
|
* Fix associative array first method as statement (#3228). [Adrien Le Masle]
|
||||||
|
* Fix associative array foreach loop (#3229).
|
||||||
|
* Fix $fclose not accepting expressions (#3237). [Julie Schwartz]
|
||||||
|
* Fix $random not updating seed (#3238). [Julie Schwartz]
|
||||||
|
* Fix top level param overwrite when package has same param (#3241) (#3247). [Adrien Le Masle]
|
||||||
|
* Fix spurious UNUSED by ignoring inout pin connections (#3242). [Julie Schwartz]
|
||||||
|
* Fix splitting of _eval and other top level functions. [Geza Lore, Shunyao CAD]
|
||||||
|
* Fix internal error by inout port (#3258). [Yutetsu TAKATSUKASA]
|
||||||
|
* Fix GCC 11 compile error (#3273). [HungMingWu]
|
||||||
|
|
||||||
|
|
||||||
Verilator 4.216 2021-12-05
|
Verilator 4.216 2021-12-05
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
@@ -19,7 +198,7 @@ Verilator 4.216 2021-12-05
|
|||||||
**Minor:**
|
**Minor:**
|
||||||
|
|
||||||
* Internal code cleanups and improvements. [Geza Lore]
|
* Internal code cleanups and improvements. [Geza Lore]
|
||||||
* Improve --thread verilation-time performance.
|
* Improve --thread Verilation-time performance.
|
||||||
* Support task name in $display %m (#3211). [Julie Schwartz]
|
* Support task name in $display %m (#3211). [Julie Schwartz]
|
||||||
* Make 'bit', 'logic' and 'time' types unsigned by default. [Geza Lore]
|
* Make 'bit', 'logic' and 'time' types unsigned by default. [Geza Lore]
|
||||||
* Optimize $random concatenates/selects (#3114).
|
* Optimize $random concatenates/selects (#3114).
|
||||||
@@ -43,7 +222,7 @@ Verilator 4.214 2021-10-17
|
|||||||
|
|
||||||
**Major:**
|
**Major:**
|
||||||
|
|
||||||
* Add profile-guided optmization of mtasks (#3150).
|
* Add profile-guided optimization of mtasks (#3150).
|
||||||
|
|
||||||
**Minor:**
|
**Minor:**
|
||||||
|
|
||||||
@@ -73,7 +252,7 @@ Verilator 4.212 2021-09-01
|
|||||||
* Fix re-evaluation of logic dependent on state set in DPI exports (#3091). [Geza Lore]
|
* Fix re-evaluation of logic dependent on state set in DPI exports (#3091). [Geza Lore]
|
||||||
* Support unpacked array localparams in tasks/functions (#3078). [Geza Lore]
|
* Support unpacked array localparams in tasks/functions (#3078). [Geza Lore]
|
||||||
* Support timeunit/timeprecision in $unit.
|
* Support timeunit/timeprecision in $unit.
|
||||||
* Support assignment patterns as children of pins (#3041). [Krzysztof Bieganski]
|
* Support assignment patterns as children of pins (#3041). [Krzysztof Bieganski/Antmicro]
|
||||||
* Add --instr-count-dpi to tune assumed DPI import cost for multithreaded
|
* Add --instr-count-dpi to tune assumed DPI import cost for multithreaded
|
||||||
model scheduling. Default value changed to 200 (#3068). [Yinan Xu]
|
model scheduling. Default value changed to 200 (#3068). [Yinan Xu]
|
||||||
* Output files are split based on the set of headers required
|
* Output files are split based on the set of headers required
|
||||||
@@ -109,7 +288,7 @@ Verilator 4.210 2021-07-07
|
|||||||
|
|
||||||
* Add --prof-c to pass profiling to compiler (#3059). [Alexander Grobman]
|
* Add --prof-c to pass profiling to compiler (#3059). [Alexander Grobman]
|
||||||
* Optimize a lot more model variables into function locals (#3027). [Geza Lore]
|
* Optimize a lot more model variables into function locals (#3027). [Geza Lore]
|
||||||
* Support middle-of-design nested topmodules (#3026). [Dan Petrisko]
|
* Support middle-of-design nested top modules (#3026). [Dan Petrisko]
|
||||||
* Remove deprecated --no-relative-cfuncs option (#3024). [Geza Lore]
|
* Remove deprecated --no-relative-cfuncs option (#3024). [Geza Lore]
|
||||||
* Remove deprecated --inhibit-sim option (#3035). [Geza Lore]
|
* Remove deprecated --inhibit-sim option (#3035). [Geza Lore]
|
||||||
* Merge const static data globally into a new constant pool (#3013). [Geza Lore]
|
* Merge const static data globally into a new constant pool (#3013). [Geza Lore]
|
||||||
@@ -138,7 +317,7 @@ Verilator 4.204 2021-06-12
|
|||||||
* Prep work towards better ccache hashing/performance. [Geza Lore]
|
* Prep work towards better ccache hashing/performance. [Geza Lore]
|
||||||
* Fix assertion failure in bitOpTree optimization (#2891) (#2899). [Raynard Qiao]
|
* Fix assertion failure in bitOpTree optimization (#2891) (#2899). [Raynard Qiao]
|
||||||
* Fix DPI functions not seen as vpiModule (#2893). [Todd Strader]
|
* Fix DPI functions not seen as vpiModule (#2893). [Todd Strader]
|
||||||
* Fix bounds check in VL_SEL_IWII (#2910). [Krzysztof Bieganski]
|
* Fix bounds check in VL_SEL_IWII (#2910). [Krzysztof Bieganski/Antmicro]
|
||||||
* Fix slowdown in elaboration (#2911). [Nathan Graybeal]
|
* Fix slowdown in elaboration (#2911). [Nathan Graybeal]
|
||||||
* Fix initialization of assoc in assoc array (#2914). [myftptoyman]
|
* Fix initialization of assoc in assoc array (#2914). [myftptoyman]
|
||||||
* Fix make support for gmake 3.x (#2920) (#2921). [Philipp Wagner]
|
* Fix make support for gmake 3.x (#2920) (#2921). [Philipp Wagner]
|
||||||
@@ -148,10 +327,10 @@ Verilator 4.204 2021-06-12
|
|||||||
* Fix to emit 'else if' without nesting (#2944). [Geza Lore]
|
* Fix to emit 'else if' without nesting (#2944). [Geza Lore]
|
||||||
* Fix part select issues in LATCH warning (#2948) (#2938). [Julien Margetts]
|
* Fix part select issues in LATCH warning (#2948) (#2938). [Julien Margetts]
|
||||||
* Fix to not emit empty files with low split limits (#2961). [Geza Lore]
|
* Fix to not emit empty files with low split limits (#2961). [Geza Lore]
|
||||||
* Fix merging of assignments in C++ code (#2970). [Ruper Swarbrick]
|
* Fix merging of assignments in C++ code (#2970). [Rupert Swarbrick]
|
||||||
* Fix unused variable warnings (#2991). [Pieter Kapsenberg]
|
* Fix unused variable warnings (#2991). [Pieter Kapsenberg]
|
||||||
* Fix --protect-ids when using SV classes (#2994). [Geza Lore]
|
* Fix --protect-ids when using SV classes (#2994). [Geza Lore]
|
||||||
* Fix constant function calls with uninit value (#2995). [yanx21]
|
* Fix constant function calls with uninitialized value (#2995). [yanx21]
|
||||||
* Fix Makefiles to support Windows EXEEXT usage (#3008). [Miodrag Milanovic]
|
* Fix Makefiles to support Windows EXEEXT usage (#3008). [Miodrag Milanovic]
|
||||||
|
|
||||||
|
|
||||||
@@ -189,7 +368,7 @@ Verilator 4.202 2021-04-24
|
|||||||
* Fix Cygwin example compile issues (#2856). [Mark Shaw]
|
* Fix Cygwin example compile issues (#2856). [Mark Shaw]
|
||||||
* Fix select of with index variable (#2880). [Alexander Grobman]
|
* Fix select of with index variable (#2880). [Alexander Grobman]
|
||||||
* Fix cmake version number to be numeric (#2881). [Yuri Victorovich]
|
* Fix cmake version number to be numeric (#2881). [Yuri Victorovich]
|
||||||
* Fix MinGW not supportting 'localtime_r' (#2882). [HyungKi Jeong]
|
* Fix MinGW not supporting 'localtime_r' (#2882). [HyungKi Jeong]
|
||||||
* Fix cast from packed, typedef'ed interface signal (#2884). [Todd Strader]
|
* Fix cast from packed, typedef'ed interface signal (#2884). [Todd Strader]
|
||||||
* Fix VPI package reported as vpiModule (#2885). [Todd Strader]
|
* Fix VPI package reported as vpiModule (#2885). [Todd Strader]
|
||||||
* Fix dumping waveforms to multiple FST files (#2889). [David Metz]
|
* Fix dumping waveforms to multiple FST files (#2889). [David Metz]
|
||||||
@@ -253,7 +432,7 @@ Verilator 4.108 2021-01-10
|
|||||||
**Major:**
|
**Major:**
|
||||||
|
|
||||||
* Many VPI changes for IEEE compatibility, which may alter behavior from previous releases.
|
* Many VPI changes for IEEE compatibility, which may alter behavior from previous releases.
|
||||||
* Support randomize() class method and rand (#2607). [Krzysztof Bieganski]
|
* Support randomize() class method and rand (#2607). [Krzysztof Bieganski/Antmicro]
|
||||||
|
|
||||||
**Minor:**
|
**Minor:**
|
||||||
|
|
||||||
@@ -313,7 +492,7 @@ Verilator 4.104 2020-11-14
|
|||||||
* Support queue and associative array 'with' statements (#2616).
|
* Support queue and associative array 'with' statements (#2616).
|
||||||
* Support queue slicing (#2326).
|
* Support queue slicing (#2326).
|
||||||
* Support associative array pattern assignments and defaults.
|
* Support associative array pattern assignments and defaults.
|
||||||
* Support static methods and typedefs in classes (#2615). [Krzysztof Bieganski]
|
* Support static methods and typedefs in classes (#2615). [Krzysztof Bieganski/Antmicro]
|
||||||
* Add error on typedef referencing self (#2539). [Cody Piersall]
|
* Add error on typedef referencing self (#2539). [Cody Piersall]
|
||||||
* With --debug, turn off address space layout randomization.
|
* With --debug, turn off address space layout randomization.
|
||||||
* Fix iteration over mutating list bug in VPI (#2588). [Kaleb Barrett]
|
* Fix iteration over mutating list bug in VPI (#2588). [Kaleb Barrett]
|
||||||
@@ -336,7 +515,7 @@ Verilator 4.102 2020-10-15
|
|||||||
* Support # as a comment in -f files (#2497). [phantom-killua]
|
* Support # as a comment in -f files (#2497). [phantom-killua]
|
||||||
* Support 'this' (#2585). [Rafal Kapuscik]
|
* Support 'this' (#2585). [Rafal Kapuscik]
|
||||||
* Support defines for FST tracing (#2592). [Markus Krause]
|
* Support defines for FST tracing (#2592). [Markus Krause]
|
||||||
* Support non-overapping implication inside properties (#1292). [Peter Monsson]
|
* Support non-overlapping implication inside properties (#1292). [Peter Monsson]
|
||||||
* Fix timescale with --hierarchical (#2554). [Yutetsu TAKATSUKASA]
|
* Fix timescale with --hierarchical (#2554). [Yutetsu TAKATSUKASA]
|
||||||
* Fix cmake build with --hierarchical (#2560). [Yutetsu TAKATSUKASA]
|
* Fix cmake build with --hierarchical (#2560). [Yutetsu TAKATSUKASA]
|
||||||
* Fix -G dropping public indication (#2561). [Andrew Goessling]
|
* Fix -G dropping public indication (#2561). [Andrew Goessling]
|
||||||
@@ -362,7 +541,7 @@ Verilator 4.100 2020-09-07
|
|||||||
* Support (with limitations) class extern, class extends, virtual class.
|
* Support (with limitations) class extern, class extends, virtual class.
|
||||||
* Support $urandom, $urandom_range without stability.
|
* Support $urandom, $urandom_range without stability.
|
||||||
* Support assume property. [Peter Monsson]
|
* Support assume property. [Peter Monsson]
|
||||||
* Support non-overapping implication inside properties (#1292). [Peter Monsson]
|
* Support non-overlapping implication inside properties (#1292). [Peter Monsson]
|
||||||
* Fix false DECLFILENAME on black-boxed modules (#2430). [Philipp Wagner]
|
* Fix false DECLFILENAME on black-boxed modules (#2430). [Philipp Wagner]
|
||||||
* Fix naming of "id : begin" blocks.
|
* Fix naming of "id : begin" blocks.
|
||||||
* Fix class constructor error on assignments to const.
|
* Fix class constructor error on assignments to const.
|
||||||
@@ -3762,7 +3941,7 @@ Verilator 0.0 1994-07-08
|
|||||||
Copyright
|
Copyright
|
||||||
=========
|
=========
|
||||||
|
|
||||||
Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||||
can redistribute it and/or modify it under the terms of either the GNU
|
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
|
Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
Version 2.0.
|
Version 2.0.
|
||||||
|
|||||||
+11
-8
@@ -7,7 +7,7 @@
|
|||||||
#
|
#
|
||||||
#*****************************************************************************
|
#*****************************************************************************
|
||||||
#
|
#
|
||||||
# Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
# Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||||
# can redistribute it and/or modify it under the terms of either the GNU
|
# 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
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
@@ -322,7 +322,10 @@ cppcheck: $(CPPCHECK_DEP)
|
|||||||
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 -DVL_THREADED=1 $(CPPCHECK_INC) $<
|
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 -DVL_THREADED=1 $(CPPCHECK_INC) $<
|
||||||
|
|
||||||
CLANGTIDY = clang-tidy
|
CLANGTIDY = clang-tidy
|
||||||
CLANGTIDY_FLAGS = -config='' -checks='-fuchsia-*,-cppcoreguidelines-avoid-c-arrays,-cppcoreguidelines-init-variables'
|
CLANGTIDY_FLAGS = -config='' \
|
||||||
|
-header-filter='.*' \
|
||||||
|
-checks='-fuchsia-*,-cppcoreguidelines-avoid-c-arrays,-cppcoreguidelines-init-variables,-cppcoreguidelines-avoid-goto,-modernize-avoid-c-arrays,-readability-magic-numbers,-readability-simplify-boolean-expr,-cppcoreguidelines-macro-usage' \
|
||||||
|
|
||||||
CLANGTIDY_DEP = $(subst .h,.h.tidy,$(CPPCHECK_H)) \
|
CLANGTIDY_DEP = $(subst .h,.h.tidy,$(CPPCHECK_H)) \
|
||||||
$(subst .cpp,.cpp.tidy,$(CPPCHECK_CPP))
|
$(subst .cpp,.cpp.tidy,$(CPPCHECK_CPP))
|
||||||
CLANGTIDY_DEFS = -DVL_DEBUG=1 -DVL_THREADED=1 -DVL_CPPCHECK=1
|
CLANGTIDY_DEFS = -DVL_DEBUG=1 -DVL_THREADED=1 -DVL_CPPCHECK=1
|
||||||
@@ -331,7 +334,7 @@ clang-tidy: $(CLANGTIDY_DEP)
|
|||||||
%.cpp.tidy: %.cpp
|
%.cpp.tidy: %.cpp
|
||||||
$(CLANGTIDY) $(CLANGTIDY_FLAGS) $< -- $(CLANGTIDY_DEFS) $(CPPCHECK_INC) | 2>&1 tee $@
|
$(CLANGTIDY) $(CLANGTIDY_FLAGS) $< -- $(CLANGTIDY_DEFS) $(CPPCHECK_INC) | 2>&1 tee $@
|
||||||
%.h.tidy: %.h
|
%.h.tidy: %.h
|
||||||
$(CLANGTIDY) $(CLANGTIDY_FLAGS) $< -- $(CLANGTIDY_DEFS) $(CPPCHECK_INC) | 2>&1 tee $@
|
$(CLANGTIDY) $(CLANGTIDY_FLAGS) $< -- $(CLANGTIDY_DEFS) $(CPPCHECK_INC) -x c++-header | 2>&1 tee $@
|
||||||
|
|
||||||
analyzer-src:
|
analyzer-src:
|
||||||
-rm -rf src/obj_dbg
|
-rm -rf src/obj_dbg
|
||||||
@@ -343,13 +346,13 @@ analyzer-include:
|
|||||||
|
|
||||||
format: clang-format yapf format-pl-exec
|
format: clang-format yapf format-pl-exec
|
||||||
|
|
||||||
CLANGFORMAT = clang-format-11
|
CLANGFORMAT = clang-format-14
|
||||||
CLANGFORMAT_FLAGS = -i
|
CLANGFORMAT_FLAGS = -i
|
||||||
CLANGFORMAT_FILES = $(CPPCHECK_CPP) $(CPPCHECK_H) $(CPPCHECK_YL) test_regress/t/*.c* test_regress/t/*.h
|
CLANGFORMAT_FILES = $(CPPCHECK_CPP) $(CPPCHECK_H) $(CPPCHECK_YL) test_regress/t/*.c* test_regress/t/*.h
|
||||||
|
|
||||||
clang-format:
|
clang-format:
|
||||||
@$(CLANGFORMAT) --version | egrep 11.0 > /dev/null \
|
@$(CLANGFORMAT) --version | egrep 14.0 > /dev/null \
|
||||||
|| echo "*** You are not using clang-format 11.0, indents may differ from master's ***"
|
|| echo "*** You are not using clang-format-14, indents may differ from master's ***"
|
||||||
$(CLANGFORMAT) $(CLANGFORMAT_FLAGS) $(CLANGFORMAT_FILES)
|
$(CLANGFORMAT) $(CLANGFORMAT_FLAGS) $(CLANGFORMAT_FILES)
|
||||||
|
|
||||||
PY_PROGRAMS = \
|
PY_PROGRAMS = \
|
||||||
@@ -388,10 +391,10 @@ yapf:
|
|||||||
FLAKE8 = flake8
|
FLAKE8 = flake8
|
||||||
FLAKE8_FLAGS = \
|
FLAKE8_FLAGS = \
|
||||||
--extend-exclude=fastcov.py \
|
--extend-exclude=fastcov.py \
|
||||||
--ignore=E123,E129,E251,E501,W503,W504,E701
|
--ignore=E123,E129,E251,E402,E501,W503,W504,E701
|
||||||
|
|
||||||
PYLINT = pylint
|
PYLINT = pylint
|
||||||
PYLINT_FLAGS = --disable=R0801
|
PYLINT_FLAGS = --score=n --disable=R0801
|
||||||
|
|
||||||
lint-py:
|
lint-py:
|
||||||
-$(FLAKE8) $(FLAKE8_FLAGS) $(PY_PROGRAMS)
|
-$(FLAKE8) $(FLAKE8_FLAGS) $(PY_PROGRAMS)
|
||||||
|
|||||||
+20
-18
@@ -21,14 +21,14 @@ Welcome to Verilator
|
|||||||
.. list-table::
|
.. list-table::
|
||||||
|
|
||||||
* - **Welcome to Verilator, the fastest Verilog/SystemVerilog simulator.**
|
* - **Welcome to Verilator, the fastest Verilog/SystemVerilog simulator.**
|
||||||
* Accepts synthesizable Verilog or SystemVerilog
|
* Accepts Verilog or SystemVerilog
|
||||||
* Performs lint code-quality checks
|
* Performs lint code-quality checks
|
||||||
* Compiles into multithreaded C++, or SystemC
|
* Compiles into multithreaded C++, or SystemC
|
||||||
* Creates XML to front-end your own tools
|
* Creates XML to front-end your own tools
|
||||||
- |Logo|
|
- |Logo|
|
||||||
* - |verilator multithreaded performance|
|
* - |verilator multithreaded performance|
|
||||||
- **Fast**
|
- **Fast**
|
||||||
* Outperforms many commercial simulators
|
* Outperforms many closed-source commercial simulators
|
||||||
* Single- and multi-threaded output models
|
* Single- and multi-threaded output models
|
||||||
* - **Widely Used**
|
* - **Widely Used**
|
||||||
* Wide industry and academic deployment
|
* Wide industry and academic deployment
|
||||||
@@ -55,25 +55,25 @@ performing lint checks, and optionally inserting assertion checks and
|
|||||||
coverage-analysis points. It outputs single- or multi-threaded .cpp and .h
|
coverage-analysis points. It outputs single- or multi-threaded .cpp and .h
|
||||||
files, the "Verilated" code.
|
files, the "Verilated" code.
|
||||||
|
|
||||||
The user writes a little C++/SystemC wrapper file, which instantiates the
|
These Verilated C++/SystemC files are then compiled by a C++ compiler
|
||||||
"Verilated" model of the user's top level module. These C++/SystemC files
|
(gcc/clang/MSVC++), optionally along with a user's own C++/SystemC wrapper
|
||||||
are then compiled by a C++ compiler (gcc/clang/MSVC++). The resulting
|
file to instantiate the Verilated model. Executing the resulting executable
|
||||||
executable performs the design simulation. Verilator also supports linking
|
performs the design simulation. Verilator also supports linking Verilated
|
||||||
its generated libraries, optionally encrypted, into other simulators.
|
generated libraries, optionally encrypted, into other simulators.
|
||||||
|
|
||||||
Verilator may not be the best choice if you are expecting a full featured
|
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
|
replacement for a closed-source Verilog simulator, need SDF annotation,
|
||||||
if you are looking for a behavioral Verilog simulator e.g. for a quick
|
mixed-signal simulation, or are doing a quick class project (we recommend
|
||||||
class project (we recommend `Icarus Verilog`_ for this.) However, if you
|
`Icarus Verilog`_ for classwork.) However, if you are looking for a path
|
||||||
are looking for a path to migrate SystemVerilog to C++ or SystemC, or your
|
to migrate SystemVerilog to C++/SystemC, or want high speed simulation of
|
||||||
team is comfortable writing just a touch of C++ code, Verilator is the tool
|
synthesizable designs containing limited verification constructs, Verilator
|
||||||
for you.
|
is the tool for you.
|
||||||
|
|
||||||
|
|
||||||
Performance
|
Performance
|
||||||
===========
|
===========
|
||||||
|
|
||||||
Verilator does not simply convert Verilog HDL to C++ or SystemC. Rather,
|
Verilator does not directly translate Verilog HDL to C++ or SystemC. Rather,
|
||||||
Verilator compiles your code into a much faster optimized and optionally
|
Verilator compiles your code into a much faster optimized and optionally
|
||||||
thread-partitioned model, which is in turn wrapped inside a C++/SystemC
|
thread-partitioned model, which is in turn wrapped inside a C++/SystemC
|
||||||
module. The results are a compiled Verilog model that executes even on a
|
module. The results are a compiled Verilog model that executes even on a
|
||||||
@@ -84,9 +84,11 @@ multithreading (yielding 200-1000x total over interpreted simulators).
|
|||||||
|
|
||||||
Verilator has typically similar or better performance versus the
|
Verilator has typically similar or better performance versus the
|
||||||
closed-source Verilog simulators (Carbon Design Systems Carbonator,
|
closed-source Verilog simulators (Carbon Design Systems Carbonator,
|
||||||
Modelsim, Cadence Incisive/NC-Verilog, Synopsys VCS, VTOC, and Pragmatic
|
Modelsim/Questa, Cadence Incisive/NC-Verilog, Synopsys VCS, VTOC, and
|
||||||
CVer/CVC). But, Verilator is open-sourced, so you can spend on computes
|
Pragmatic CVer/CVC). But, Verilator is open-sourced, so you can spend on
|
||||||
rather than licenses. Thus Verilator gives you the best cycles/dollar.
|
computes rather than licenses. Thus Verilator gives you the best
|
||||||
|
cycles/dollar.
|
||||||
|
|
||||||
|
|
||||||
Installation & Documentation
|
Installation & Documentation
|
||||||
============================
|
============================
|
||||||
@@ -137,7 +139,7 @@ Related Projects
|
|||||||
Open License
|
Open License
|
||||||
============
|
============
|
||||||
|
|
||||||
Verilator is Copyright 2003-2021 by Wilson Snyder. (Report bugs to
|
Verilator is Copyright 2003-2022 by Wilson Snyder. (Report bugs to
|
||||||
`Verilator Issues <https://verilator.org/issues>`_.)
|
`Verilator Issues <https://verilator.org/issues>`_.)
|
||||||
|
|
||||||
Verilator is free software; you can redistribute it and/or modify it under
|
Verilator is free software; you can redistribute it and/or modify it under
|
||||||
|
|||||||
+39
-29
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env perl
|
#!/usr/bin/env perl
|
||||||
######################################################################
|
######################################################################
|
||||||
#
|
#
|
||||||
# Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
# Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||||
# can redistribute it and/or modify it under the terms of either the GNU
|
# 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
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
@@ -282,35 +282,40 @@ detailed descriptions of these arguments.
|
|||||||
--autoflush Flush streams after all $displays
|
--autoflush Flush streams after all $displays
|
||||||
--bbox-sys Blackbox unknown $system calls
|
--bbox-sys Blackbox unknown $system calls
|
||||||
--bbox-unsup Blackbox unsupported language features
|
--bbox-unsup Blackbox unsupported language features
|
||||||
--bin <filename> Override Verilator binary
|
|
||||||
--build Build model executable/library after Verilation
|
--build Build model executable/library after Verilation
|
||||||
-CFLAGS <flags> C++ compiler arguments for makefile
|
--build-dep-bin <filename> Override build dependency Verilator binary
|
||||||
|
--build-jobs <jobs> Parallelism for --build
|
||||||
--cc Create C++ output
|
--cc Create C++ output
|
||||||
--cdc Clock domain crossing analysis
|
--cdc Clock domain crossing analysis
|
||||||
|
-CFLAGS <flags> C++ compiler arguments for makefile
|
||||||
--clk <signal-name> Mark specified signal as clock
|
--clk <signal-name> Mark specified signal as clock
|
||||||
--make <build-tool> Generate scripts for specified build tool
|
--no-clk <signal-name> Prevent marking specified signal as clock
|
||||||
--compiler <compiler-name> Tune for specified C++ compiler
|
--compiler <compiler-name> Tune for specified C++ compiler
|
||||||
--converge-limit <loops> Tune convergence settle time
|
--converge-limit <loops> Tune convergence settle time
|
||||||
--coverage Enable all coverage
|
--coverage Enable all coverage
|
||||||
--coverage-line Enable line coverage
|
--coverage-line Enable line coverage
|
||||||
--coverage-max-width <width> Maximum array depth for coverage
|
--coverage-max-width <width> Maximum array depth for coverage
|
||||||
--coverage-toggle Enable toggle coverage
|
--coverage-toggle Enable toggle coverage
|
||||||
--coverage-user Enable SVL user coverage
|
|
||||||
--coverage-underscore Enable coverage of _signals
|
--coverage-underscore Enable coverage of _signals
|
||||||
|
--coverage-user Enable SVL user coverage
|
||||||
-D<var>[=<value>] Set preprocessor define
|
-D<var>[=<value>] Set preprocessor define
|
||||||
--debug Enable debugging
|
--debug Enable debugging
|
||||||
--debug-check Enable debugging assertions
|
--debug-check Enable debugging assertions
|
||||||
--no-debug-leak Disable leaking memory in --debug mode
|
--no-debug-leak Disable leaking memory in --debug mode
|
||||||
--debugi <level> Enable debugging at a specified level
|
--debugi <level> Enable debugging at a specified level
|
||||||
--debugi-<srcfile> <level> Enable debugging a source file at a level
|
--debugi-<srcfile> <level> Enable debugging a source file at a level
|
||||||
|
--no-decoration Disable comments and symbol decorations
|
||||||
--default-language <lang> Default language to parse
|
--default-language <lang> Default language to parse
|
||||||
+define+<var>=<value> Set preprocessor define
|
+define+<var>=<value> Set preprocessor define
|
||||||
--dpi-hdr-only Only produce the DPI header file
|
--dpi-hdr-only Only produce the DPI header file
|
||||||
--dump-defines Show preprocessor defines with -E
|
--dump-defines Show preprocessor defines with -E
|
||||||
--dump-tree Enable dumping .tree files
|
--dump-graph Enable dumping V3Graphs to .dot
|
||||||
--dump-treei <level> Enable dumping .tree files at a level
|
--dump-tree Enable dumping Ast .tree files
|
||||||
--dump-treei-<srcfile> <level> Enable dumping .tree file at a source file at a level
|
|
||||||
--dump-tree-addrids Use short identifiers instead of addresses
|
--dump-tree-addrids Use short identifiers instead of addresses
|
||||||
|
--dump-<srcfile> Enable dumping everything in source file
|
||||||
|
--dumpi-graph <level> Enable dumping V3Graphs to .dot files at level
|
||||||
|
--dumpi-tree <level> Enable dumping Ast .tree files at level
|
||||||
|
--dumpi-<srcfile> <level> Enable dumping everything in source file at level
|
||||||
-E Preprocess, but do not compile
|
-E Preprocess, but do not compile
|
||||||
--error-limit <value> Abort after this number of errors
|
--error-limit <value> Abort after this number of errors
|
||||||
--exe Link to create executable
|
--exe Link to create executable
|
||||||
@@ -319,7 +324,9 @@ detailed descriptions of these arguments.
|
|||||||
-f <file> Parse arguments from a file
|
-f <file> Parse arguments from a file
|
||||||
-FI <file> Force include of a file
|
-FI <file> Force include of a file
|
||||||
--flatten Force inlining of all modules, tasks and functions
|
--flatten Force inlining of all modules, tasks and functions
|
||||||
|
-fno-<optimization> Disable internal optimization stage
|
||||||
-G<name>=<value> Overwrite top-level parameter
|
-G<name>=<value> Overwrite top-level parameter
|
||||||
|
--gate-stmts <value> Tune gate optimizer depth
|
||||||
--gdb Run Verilator under GDB interactively
|
--gdb Run Verilator under GDB interactively
|
||||||
--gdbbt Run Verilator under GDB for backtrace
|
--gdbbt Run Verilator under GDB for backtrace
|
||||||
--generate-key Create random key for --protect-key
|
--generate-key Create random key for --protect-key
|
||||||
@@ -327,54 +334,52 @@ detailed descriptions of these arguments.
|
|||||||
--help Display this help
|
--help Display this help
|
||||||
--hierarchical Enable hierarchical Verilation
|
--hierarchical Enable hierarchical Verilation
|
||||||
-I<dir> Directory to search for includes
|
-I<dir> Directory to search for includes
|
||||||
-j <jobs> Parallelism for --build
|
|
||||||
--gate-stmts <value> Tune gate optimizer depth
|
|
||||||
--if-depth <value> Tune IFDEPTH warning
|
--if-depth <value> Tune IFDEPTH warning
|
||||||
+incdir+<dir> Directory to search for includes
|
+incdir+<dir> Directory to search for includes
|
||||||
--inline-mult <value> Tune module inlining
|
--inline-mult <value> Tune module inlining
|
||||||
--instr-count-dpi <value> Assumed dynamic instruction count of DPI imports
|
--instr-count-dpi <value> Assumed dynamic instruction count of DPI imports
|
||||||
-LDFLAGS <flags> Linker pre-object arguments for makefile
|
-j <jobs> Parallelism for --build (alias to --build-jobs)
|
||||||
--l2-name <value> Verilog scope name of the top module
|
--l2-name <value> Verilog scope name of the top module
|
||||||
--language <lang> Default language standard to parse
|
--language <lang> Default language standard to parse
|
||||||
|
-LDFLAGS <flags> Linker pre-object arguments for makefile
|
||||||
--lib-create <name> Create a DPI library
|
--lib-create <name> Create a DPI library
|
||||||
+libext+<ext>+[ext]... Extensions for finding modules
|
+libext+<ext>+[ext]... Extensions for finding modules
|
||||||
--lint-only Lint, but do not make output
|
--lint-only Lint, but do not make output
|
||||||
|
--make <build-tool> Generate scripts for specified build tool
|
||||||
-MAKEFLAGS <flags> Arguments to pass to make during --build
|
-MAKEFLAGS <flags> Arguments to pass to make during --build
|
||||||
|
--main Generate C++ main() file
|
||||||
--max-num-width <value> Maximum number width (default: 64K)
|
--max-num-width <value> Maximum number width (default: 64K)
|
||||||
--MMD Create .d dependency files
|
|
||||||
--MP Create phony dependency targets
|
|
||||||
--Mdir <directory> Name of output object directory
|
--Mdir <directory> Name of output object directory
|
||||||
--no-merge-const-pool Disable merging of different types in const pool
|
--MMD Create .d dependency files
|
||||||
--mod-prefix <topname> Name to prepend to lower classes
|
--mod-prefix <topname> Name to prepend to lower classes
|
||||||
--no-clk <signal-name> Prevent marking specified signal as clock
|
--MP Create phony dependency targets
|
||||||
--no-decoration Disable comments and symbol decorations
|
|
||||||
--no-pins64 Don't use vluint64_t's for 33-64 bit sigs
|
|
||||||
--no-skip-identical Disable skipping identical output
|
|
||||||
+notimingchecks Ignored
|
+notimingchecks Ignored
|
||||||
-O0 Disable optimizations
|
-O0 Disable optimizations
|
||||||
-O3 High performance optimizations
|
-O3 High performance optimizations
|
||||||
-O<optimization-letter> Selectable optimizations
|
-O<optimization-letter> Selectable optimizations
|
||||||
-o <executable> Name of final executable
|
-o <executable> Name of final executable
|
||||||
--no-order-clock-delay Disable ordering clock enable assignments
|
--no-order-clock-delay Disable ordering clock enable assignments
|
||||||
--no-verilate Skip verilation and just compile previously Verilated code.
|
--no-verilate Skip Verilation, only compile previously Verilated code
|
||||||
--output-split <statements> Split .cpp files into pieces
|
--output-split <statements> Split .cpp files into pieces
|
||||||
--output-split-cfuncs <statements> Split model functions
|
--output-split-cfuncs <statements> Split model functions
|
||||||
--output-split-ctrace <statements> Split tracing functions
|
--output-split-ctrace <statements> Split tracing functions
|
||||||
-P Disable line numbers and blanks with -E
|
-P Disable line numbers and blanks with -E
|
||||||
--pins-bv <bits> Specify types for top level ports
|
--pins-bv <bits> Specify types for top level ports
|
||||||
--pins-sc-uint Specify types for top level ports
|
|
||||||
--pins-sc-biguint Specify types for top level ports
|
--pins-sc-biguint Specify types for top level ports
|
||||||
|
--pins-sc-uint Specify types for top level ports
|
||||||
--pins-uint8 Specify types for top level ports
|
--pins-uint8 Specify types for top level ports
|
||||||
|
--no-pins64 Don't use uint64_t's for 33-64 bit sigs
|
||||||
--pipe-filter <command> Filter all input through a script
|
--pipe-filter <command> Filter all input through a script
|
||||||
--pp-comments Show preprocessor comments with -E
|
--pp-comments Show preprocessor comments with -E
|
||||||
--prefix <topname> Name of top level class
|
--prefix <topname> Name of top level class
|
||||||
|
--private Debugging; see docs
|
||||||
--prof-c Compile C++ code with profiling
|
--prof-c Compile C++ code with profiling
|
||||||
--prof-cfuncs Name functions for profiling
|
--prof-cfuncs Name functions for profiling
|
||||||
--prof-threads Enable generating gantt chart data for threads
|
--prof-exec Enable generating execution profile for gantt chart
|
||||||
--protect-key <key> Key for symbol protection
|
--prof-pgo Enable generating profiling data for PGO
|
||||||
--protect-ids Hash identifier names for obscurity
|
--protect-ids Hash identifier names for obscurity
|
||||||
|
--protect-key <key> Key for symbol protection
|
||||||
--protect-lib <name> Create a DPI protected library
|
--protect-lib <name> Create a DPI protected library
|
||||||
--private Debugging; see docs
|
|
||||||
--public Debugging; see docs
|
--public Debugging; see docs
|
||||||
--public-flat-rw Mark all variables, etc as public_flat_rw
|
--public-flat-rw Mark all variables, etc as public_flat_rw
|
||||||
-pvalue+<name>=<value> Overwrite toplevel parameter
|
-pvalue+<name>=<value> Overwrite toplevel parameter
|
||||||
@@ -385,6 +390,7 @@ detailed descriptions of these arguments.
|
|||||||
--rr Run Verilator and record with rr
|
--rr Run Verilator and record with rr
|
||||||
--savable Enable model save-restore
|
--savable Enable model save-restore
|
||||||
--sc Create SystemC output
|
--sc Create SystemC output
|
||||||
|
--no-skip-identical Disable skipping identical output
|
||||||
--stats Create statistics file
|
--stats Create statistics file
|
||||||
--stats-vars Provide statistics on variables
|
--stats-vars Provide statistics on variables
|
||||||
-sv Enable SystemVerilog parsing
|
-sv Enable SystemVerilog parsing
|
||||||
@@ -404,7 +410,7 @@ detailed descriptions of these arguments.
|
|||||||
--trace-max-width <width> Maximum array depth for tracing
|
--trace-max-width <width> Maximum array depth for tracing
|
||||||
--trace-params Enable tracing of parameters
|
--trace-params Enable tracing of parameters
|
||||||
--trace-structs Enable tracing structure names
|
--trace-structs Enable tracing structure names
|
||||||
--trace-threads <threads> Enable waveform creation on separate threads
|
--trace-threads <threads> Enable FST waveform creation on separate threads
|
||||||
--trace-underscore Enable tracing of _signals
|
--trace-underscore Enable tracing of _signals
|
||||||
-U<var> Undefine preprocessor define
|
-U<var> Undefine preprocessor define
|
||||||
--unroll-count <loops> Tune maximum loop iterations
|
--unroll-count <loops> Tune maximum loop iterations
|
||||||
@@ -412,6 +418,7 @@ detailed descriptions of these arguments.
|
|||||||
--unused-regexp <regexp> Tune UNUSED lint signals
|
--unused-regexp <regexp> Tune UNUSED lint signals
|
||||||
-V Verbose version and config
|
-V Verbose version and config
|
||||||
-v <filename> Verilog library
|
-v <filename> Verilog library
|
||||||
|
--no-verilate Skip verilation and just compile previously Verilated code.
|
||||||
+verilog1995ext+<ext> Synonym for +1364-1995ext+<ext>
|
+verilog1995ext+<ext> Synonym for +1364-1995ext+<ext>
|
||||||
+verilog2001ext+<ext> Synonym for +1364-2001ext+<ext>
|
+verilog2001ext+<ext> Synonym for +1364-2001ext+<ext>
|
||||||
--version Displays program version and exits
|
--version Displays program version and exits
|
||||||
@@ -426,6 +433,9 @@ detailed descriptions of these arguments.
|
|||||||
-Wno-lint Disable all lint warnings
|
-Wno-lint Disable all lint warnings
|
||||||
-Wno-style Disable all style warnings
|
-Wno-style Disable all style warnings
|
||||||
-Wpedantic Warn on compliance-test issues
|
-Wpedantic Warn on compliance-test issues
|
||||||
|
-Wwarn-<message> Enable specified warning message
|
||||||
|
-Wwarn-lint Enable lint warning message
|
||||||
|
-Wwarn-style Enable style warning message
|
||||||
--x-assign <mode> Assign non-initial Xs to this value
|
--x-assign <mode> Assign non-initial Xs to this value
|
||||||
--x-initial <mode> Assign initial Xs to this value
|
--x-initial <mode> Assign initial Xs to this value
|
||||||
--x-initial-edge Enable initial X->0 and X->1 edge triggers
|
--x-initial-edge Enable initial X->0 and X->1 edge triggers
|
||||||
@@ -445,10 +455,10 @@ description of these arguments.
|
|||||||
+verilator+error+limit+<value> Set error limit
|
+verilator+error+limit+<value> Set error limit
|
||||||
+verilator+help Display help
|
+verilator+help Display help
|
||||||
+verilator+noassert Disable assert checking
|
+verilator+noassert Disable assert checking
|
||||||
+verilator+prof+threads+file+<filename> Set profile filename
|
+verilator+prof+exec+file+<filename> Set execution profile filename
|
||||||
+verilator+prof+threads+start+<value> Set profile starting point
|
+verilator+prof+exec+start+<value> Set execution profile starting point
|
||||||
+verilator+prof+threads+window+<value> Set profile duration
|
+verilator+prof+exec+window+<value> Set execution profile duration
|
||||||
+verilator+prof+vlt+file+<filename> Set profile guided filename
|
+verilator+prof+vlt+file+<filename> Set PGO profile filename
|
||||||
+verilator+rand+reset+<value> Set random reset technique
|
+verilator+rand+reset+<value> Set random reset technique
|
||||||
+verilator+seed+<value> Set random seed
|
+verilator+seed+<value> Set random seed
|
||||||
+verilator+V Verbose version and config
|
+verilator+V Verbose version and config
|
||||||
@@ -459,7 +469,7 @@ description of these arguments.
|
|||||||
|
|
||||||
The latest version is available from L<https://verilator.org>.
|
The latest version is available from L<https://verilator.org>.
|
||||||
|
|
||||||
Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
|
Copyright 2003-2022 by Wilson Snyder. This program 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
|
||||||
either the GNU Lesser General Public License Version 3 or the Perl Artistic
|
either the GNU Lesser General Public License Version 3 or the Perl Artistic
|
||||||
License Version 2.0.
|
License Version 2.0.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ parser = argparse.ArgumentParser(
|
|||||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
description="""Report ccache behavior of a Verilated model build.""",
|
description="""Report ccache behavior of a Verilated model build.""",
|
||||||
epilog=
|
epilog=
|
||||||
"""Copyright 2002-2021 by Wilson Snyder. This program is free software; you
|
"""Copyright 2002-2022 by Wilson Snyder. This program is free software; you
|
||||||
can redistribute it and/or modify it under the terms of either the GNU
|
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
|
Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
Version 2.0.
|
Version 2.0.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env perl
|
#!/usr/bin/env perl
|
||||||
######################################################################
|
######################################################################
|
||||||
#
|
#
|
||||||
# Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
# Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||||
# can redistribute it and/or modify it under the terms of either the GNU
|
# 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
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
@@ -187,7 +187,7 @@ L<https://verilator.org/guide/latest/exe_verilator_coverage.html>.
|
|||||||
|
|
||||||
The latest version is available from L<https://verilator.org>.
|
The latest version is available from L<https://verilator.org>.
|
||||||
|
|
||||||
Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||||
can redistribute it and/or modify the Verilator internals under the terms
|
can redistribute it and/or modify the Verilator internals under the terms
|
||||||
of either the GNU Lesser General Public License Version 3 or the Perl
|
of either the GNU Lesser General Public License Version 3 or the Perl
|
||||||
Artistic License Version 2.0.
|
Artistic License Version 2.0.
|
||||||
|
|||||||
@@ -38,10 +38,10 @@ def diff_dir(a, b):
|
|||||||
|
|
||||||
anyfile = False
|
anyfile = False
|
||||||
for base in sorted(files.keys()):
|
for base in sorted(files.keys()):
|
||||||
|
if ('a' not in files[base]) or ('b' not in files[base]):
|
||||||
|
continue
|
||||||
a = files[base]['a']
|
a = files[base]['a']
|
||||||
b = files[base]['b']
|
b = files[base]['b']
|
||||||
if not a or not b:
|
|
||||||
continue
|
|
||||||
print("=" * 70)
|
print("=" * 70)
|
||||||
print("= %s <-> %s" % (a, b))
|
print("= %s <-> %s" % (a, b))
|
||||||
diff_file(a, b)
|
diff_file(a, b)
|
||||||
@@ -113,7 +113,7 @@ directories, ignoring irrelevant pointer differences.
|
|||||||
For documentation see
|
For documentation see
|
||||||
https://verilator.org/guide/latest/exe_verilator_difftree.html
|
https://verilator.org/guide/latest/exe_verilator_difftree.html
|
||||||
|
|
||||||
Copyright 2005-2021 by Wilson Snyder. This program is free software; you
|
Copyright 2005-2022 by Wilson Snyder. This program is free software; you
|
||||||
can redistribute it and/or modify it under the terms of either the GNU
|
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
|
Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
Version 2.0.
|
Version 2.0.
|
||||||
|
|||||||
+166
-145
@@ -9,7 +9,7 @@ import re
|
|||||||
import statistics
|
import statistics
|
||||||
# from pprint import pprint
|
# from pprint import pprint
|
||||||
|
|
||||||
Threads = collections.defaultdict(lambda: {})
|
Threads = collections.defaultdict(lambda: collections.defaultdict(lambda: {}))
|
||||||
Mtasks = collections.defaultdict(lambda: {})
|
Mtasks = collections.defaultdict(lambda: {})
|
||||||
Evals = collections.defaultdict(lambda: {})
|
Evals = collections.defaultdict(lambda: {})
|
||||||
EvalLoops = collections.defaultdict(lambda: {})
|
EvalLoops = collections.defaultdict(lambda: {})
|
||||||
@@ -30,12 +30,12 @@ def process(filename):
|
|||||||
|
|
||||||
def read_data(filename):
|
def read_data(filename):
|
||||||
with open(filename) as fh:
|
with open(filename) as fh:
|
||||||
re_prof = re.compile(
|
re_thread = re.compile(r'^VLPROFTHREAD (\d+)$')
|
||||||
r'^VLPROF mtask\s(\d+)\sstart\s(\d+)\selapsed\s(\d+)\spredict_start\s(\d+)\spredict_cost\s(\d+)\scpu\s(\d+)\son thread (\d+)'
|
re_record = re.compile(r'^VLPROFEXEC (\S+) (\d+)(.*)$')
|
||||||
)
|
re_payload_mtaskBegin = re.compile(
|
||||||
re_eval = re.compile(r'^VLPROF eval\sstart\s(\d+)\selapsed\s(\d+)')
|
r'id (\d+) predictStart (\d+) cpu (\d+)')
|
||||||
re_loop = re.compile(
|
re_payload_mtaskEnd = re.compile(r'id (\d+) predictCost (\d+)')
|
||||||
r'^VLPROF eval_loop\sstart\s(\d+)\selapsed\s(\d+)')
|
|
||||||
re_arg1 = re.compile(r'VLPROF arg\s+(\S+)\+([0-9.]*)\s*')
|
re_arg1 = re.compile(r'VLPROF arg\s+(\S+)\+([0-9.]*)\s*')
|
||||||
re_arg2 = re.compile(r'VLPROF arg\s+(\S+)\s+([0-9.]*)\s*$')
|
re_arg2 = re.compile(r'VLPROF arg\s+(\S+)\s+([0-9.]*)\s*$')
|
||||||
re_stat = re.compile(r'VLPROF stat\s+(\S+)\s+([0-9.]+)')
|
re_stat = re.compile(r'VLPROF stat\s+(\S+)\s+([0-9.]+)')
|
||||||
@@ -43,47 +43,60 @@ def read_data(filename):
|
|||||||
re_proc_cpu = re.compile(r'VLPROFPROC processor\s*:\s*(\d+)\s*$')
|
re_proc_cpu = re.compile(r'VLPROFPROC processor\s*:\s*(\d+)\s*$')
|
||||||
re_proc_dat = re.compile(r'VLPROFPROC ([a-z_ ]+)\s*:\s*(.*)$')
|
re_proc_dat = re.compile(r'VLPROFPROC ([a-z_ ]+)\s*:\s*(.*)$')
|
||||||
cpu = None
|
cpu = None
|
||||||
|
thread = None
|
||||||
|
|
||||||
|
lastEvalBeginTick = None
|
||||||
|
lastEvalLoopBeginTick = None
|
||||||
|
|
||||||
for line in fh:
|
for line in fh:
|
||||||
if re_prof.match(line):
|
recordMatch = re_record.match(line)
|
||||||
match = re_prof.match(line)
|
if recordMatch:
|
||||||
mtask = int(match.group(1))
|
kind, tick, payload = recordMatch.groups()
|
||||||
start = int(match.group(2))
|
tick = int(tick)
|
||||||
elapsed_time = int(match.group(3))
|
payload = payload.strip()
|
||||||
end = start + elapsed_time
|
if kind == "EVAL_BEGIN":
|
||||||
predict_start = int(match.group(4))
|
Evals[tick]['start'] = tick
|
||||||
predict_cost = int(match.group(5))
|
lastEvalBeginTick = tick
|
||||||
cpu = int(match.group(6))
|
elif kind == "EVAL_END":
|
||||||
thread = int(match.group(7))
|
Evals[lastEvalBeginTick]['end'] = tick
|
||||||
if start not in Threads[thread]:
|
lastEvalBeginTick = None
|
||||||
Threads[thread][start] = {}
|
elif kind == "EVAL_LOOP_BEGIN":
|
||||||
Threads[thread][start]['mtask'] = mtask
|
EvalLoops[tick]['start'] = tick
|
||||||
Threads[thread][start]['end'] = end
|
lastEvalLoopBeginTick = tick
|
||||||
Threads[thread][start]['cpu'] = cpu
|
elif kind == "EVAL_LOOP_END":
|
||||||
Threads[thread][start]['predict_start'] = predict_start
|
EvalLoops[lastEvalLoopBeginTick]['end'] = tick
|
||||||
Threads[thread][start]['predict_cost'] = predict_cost
|
lastEvalLoopBeginTick = None
|
||||||
|
elif kind == "MTASK_BEGIN":
|
||||||
if 'elapsed' not in Mtasks[mtask]:
|
mtask, predict_start, ecpu = re_payload_mtaskBegin.match(
|
||||||
Mtasks[mtask] = {'end': 0, 'elapsed': 0}
|
payload).groups()
|
||||||
Mtasks[mtask]['thread'] = thread
|
mtask = int(mtask)
|
||||||
Mtasks[mtask]['elapsed'] += elapsed_time
|
predict_start = int(predict_start)
|
||||||
Mtasks[mtask]['predict_start'] = predict_start
|
ecpu = int(ecpu)
|
||||||
Mtasks[mtask]['predict_cost'] = predict_cost
|
Threads[thread][tick]['mtask'] = mtask
|
||||||
Mtasks[mtask]['end'] = max(Mtasks[mtask]['end'], end)
|
Threads[thread][tick]['predict_start'] = predict_start
|
||||||
elif re_eval.match(line):
|
Threads[thread][tick]['cpu'] = ecpu
|
||||||
match = re_eval.match(line)
|
if 'elapsed' not in Mtasks[mtask]:
|
||||||
start = int(match.group(1))
|
Mtasks[mtask] = {'end': 0, 'elapsed': 0}
|
||||||
elapsed_time = int(match.group(2))
|
Mtasks[mtask]['begin'] = tick
|
||||||
Evals[start]['start'] = start
|
Mtasks[mtask]['thread'] = thread
|
||||||
Evals[start]['end'] = start + elapsed_time
|
Mtasks[mtask]['predict_start'] = predict_start
|
||||||
elif re_loop.match(line):
|
elif kind == "MTASK_END":
|
||||||
match = re_loop.match(line)
|
mtask, predict_cost = re_payload_mtaskEnd.match(
|
||||||
start = int(match.group(1))
|
payload).groups()
|
||||||
elapsed_time = int(match.group(2))
|
mtask = int(mtask)
|
||||||
EvalLoops[start]['start'] = start
|
predict_cost = int(predict_cost)
|
||||||
EvalLoops[start]['end'] = start + elapsed_time
|
begin = Mtasks[mtask]['begin']
|
||||||
elif re.match(r'^VLPROFTHREAD', line):
|
Threads[thread][begin]['end'] = tick
|
||||||
None # pylint: disable=pointless-statement
|
Threads[thread][begin]['predict_cost'] = predict_cost
|
||||||
|
Mtasks[mtask]['elapsed'] += tick - begin
|
||||||
|
Mtasks[mtask]['predict_cost'] = predict_cost
|
||||||
|
Mtasks[mtask]['end'] = max(Mtasks[mtask]['end'], tick)
|
||||||
|
elif Args.debug:
|
||||||
|
print("-Unknown execution trace record: %s" % line)
|
||||||
|
elif re_thread.match(line):
|
||||||
|
thread = int(re_thread.match(line).group(1))
|
||||||
|
elif re.match(r'^VLPROF(THREAD|VERSION)', line):
|
||||||
|
pass
|
||||||
elif re_arg1.match(line):
|
elif re_arg1.match(line):
|
||||||
match = re_arg1.match(line)
|
match = re_arg1.match(line)
|
||||||
Global['args'][match.group(1)] = match.group(2)
|
Global['args'][match.group(1)] = match.group(2)
|
||||||
@@ -105,7 +118,7 @@ def read_data(filename):
|
|||||||
value = re.sub(r'\s+$', '', value)
|
value = re.sub(r'\s+$', '', value)
|
||||||
Global['cpuinfo'][cpu][term] = value
|
Global['cpuinfo'][cpu][term] = value
|
||||||
elif re.match(r'^#', line):
|
elif re.match(r'^#', line):
|
||||||
None # pylint: disable=pointless-statement
|
pass
|
||||||
elif Args.debug:
|
elif Args.debug:
|
||||||
print("-Unk: %s" % line)
|
print("-Unk: %s" % line)
|
||||||
# TODO -- this is parsing text printed by a client.
|
# TODO -- this is parsing text printed by a client.
|
||||||
@@ -131,11 +144,13 @@ def report():
|
|||||||
plus = "+" if re.match(r'^\+', arg) else " "
|
plus = "+" if re.match(r'^\+', arg) else " "
|
||||||
print(" %s%s%s" % (arg, plus, Global['args'][arg]))
|
print(" %s%s%s" % (arg, plus, Global['args'][arg]))
|
||||||
|
|
||||||
nthreads = len(Threads)
|
nthreads = int(Global['stats']['threads'])
|
||||||
Global['cpus'] = {}
|
Global['cpus'] = {}
|
||||||
for thread in Threads:
|
for thread in Threads:
|
||||||
# Make potentially multiple characters per column
|
# Make potentially multiple characters per column
|
||||||
for start in Threads[thread]:
|
for start in Threads[thread]:
|
||||||
|
if not Threads[thread][start]:
|
||||||
|
continue
|
||||||
cpu = Threads[thread][start]['cpu']
|
cpu = Threads[thread][start]['cpu']
|
||||||
elapsed = Threads[thread][start]['end'] - start
|
elapsed = Threads[thread][start]['end'] - start
|
||||||
if cpu not in Global['cpus']:
|
if cpu not in Global['cpus']:
|
||||||
@@ -169,74 +184,79 @@ def report():
|
|||||||
print("\nAnalysis:")
|
print("\nAnalysis:")
|
||||||
print(" Total threads = %d" % nthreads)
|
print(" Total threads = %d" % nthreads)
|
||||||
print(" Total mtasks = %d" % len(Mtasks))
|
print(" Total mtasks = %d" % len(Mtasks))
|
||||||
ncpus = len(Global['cpus'])
|
ncpus = max(len(Global['cpus']), 1)
|
||||||
print(" Total cpus used = %d" % ncpus)
|
print(" Total cpus used = %d" % ncpus)
|
||||||
print(" Total yields = %d" % int(Global['stats']['yields']))
|
print(" Total yields = %d" %
|
||||||
|
int(Global['stats'].get('yields', 0)))
|
||||||
print(" Total evals = %d" % len(Evals))
|
print(" Total evals = %d" % len(Evals))
|
||||||
print(" Total eval loops = %d" % len(EvalLoops))
|
print(" Total eval loops = %d" % len(EvalLoops))
|
||||||
print(" Total eval time = %d rdtsc ticks" %
|
if Mtasks:
|
||||||
Global['measured_last_end'])
|
print(" Total eval time = %d rdtsc ticks" %
|
||||||
print(" Longest mtask time = %d rdtsc ticks" % long_mtask_time)
|
Global['measured_last_end'])
|
||||||
print(" All-thread mtask time = %d rdtsc ticks" %
|
print(" Longest mtask time = %d rdtsc ticks" % long_mtask_time)
|
||||||
measured_mt_mtask_time)
|
print(" All-thread mtask time = %d rdtsc ticks" %
|
||||||
long_efficiency = long_mtask_time / (Global.get('measured_last_end', 1)
|
measured_mt_mtask_time)
|
||||||
or 1)
|
long_efficiency = long_mtask_time / (Global.get(
|
||||||
print(" Longest-thread efficiency = %0.1f%%" % (long_efficiency * 100.0))
|
'measured_last_end', 1) or 1)
|
||||||
mt_efficiency = measured_mt_mtask_time / (
|
print(" Longest-thread efficiency = %0.1f%%" %
|
||||||
Global.get('measured_last_end', 1) * nthreads or 1)
|
(long_efficiency * 100.0))
|
||||||
print(" All-thread efficiency = %0.1f%%" % (mt_efficiency * 100.0))
|
mt_efficiency = measured_mt_mtask_time / (
|
||||||
print(" All-thread speedup = %0.1f" % (mt_efficiency * nthreads))
|
Global.get('measured_last_end', 1) * nthreads or 1)
|
||||||
if Global['rdtsc_cycle_time'] > 0:
|
print(" All-thread efficiency = %0.1f%%" %
|
||||||
ut = measured_mt_mtask_time / Global['rdtsc_cycle_time']
|
(mt_efficiency * 100.0))
|
||||||
print("tot_mtask_cpu=" + measured_mt_mtask_time + " cyc=" +
|
print(" All-thread speedup = %0.1f" %
|
||||||
Global['rdtsc_cycle_time'] + " ut=" + ut)
|
(mt_efficiency * nthreads))
|
||||||
|
if Global['rdtsc_cycle_time'] > 0:
|
||||||
|
ut = measured_mt_mtask_time / Global['rdtsc_cycle_time']
|
||||||
|
print("tot_mtask_cpu=" + measured_mt_mtask_time + " cyc=" +
|
||||||
|
Global['rdtsc_cycle_time'] + " ut=" + ut)
|
||||||
|
|
||||||
predict_mt_efficiency = predict_mt_mtask_time / (
|
predict_mt_efficiency = predict_mt_mtask_time / (
|
||||||
Global.get('predict_last_end', 1) * nthreads or 1)
|
Global.get('predict_last_end', 1) * nthreads or 1)
|
||||||
print("\nPrediction (what Verilator used for scheduling):")
|
print("\nPrediction (what Verilator used for scheduling):")
|
||||||
print(" All-thread efficiency = %0.1f%%" %
|
print(" All-thread efficiency = %0.1f%%" %
|
||||||
(predict_mt_efficiency * 100.0))
|
(predict_mt_efficiency * 100.0))
|
||||||
print(" All-thread speedup = %0.1f" %
|
print(" All-thread speedup = %0.1f" %
|
||||||
(predict_mt_efficiency * nthreads))
|
(predict_mt_efficiency * nthreads))
|
||||||
|
|
||||||
p2e_ratios = []
|
p2e_ratios = []
|
||||||
min_p2e = 1000000
|
min_p2e = 1000000
|
||||||
min_mtask = None
|
min_mtask = None
|
||||||
max_p2e = -1000000
|
max_p2e = -1000000
|
||||||
max_mtask = None
|
max_mtask = None
|
||||||
|
|
||||||
for mtask in sorted(Mtasks.keys()):
|
for mtask in sorted(Mtasks.keys()):
|
||||||
if Mtasks[mtask]['elapsed'] > 0:
|
if Mtasks[mtask]['elapsed'] > 0:
|
||||||
if Mtasks[mtask]['predict_cost'] == 0:
|
if Mtasks[mtask]['predict_cost'] == 0:
|
||||||
Mtasks[mtask]['predict_cost'] = 1 # don't log(0) below
|
Mtasks[mtask]['predict_cost'] = 1 # don't log(0) below
|
||||||
p2e_ratio = math.log(Mtasks[mtask]['predict_cost'] /
|
p2e_ratio = math.log(Mtasks[mtask]['predict_cost'] /
|
||||||
Mtasks[mtask]['elapsed'])
|
Mtasks[mtask]['elapsed'])
|
||||||
p2e_ratios.append(p2e_ratio)
|
p2e_ratios.append(p2e_ratio)
|
||||||
|
|
||||||
if p2e_ratio > max_p2e:
|
if p2e_ratio > max_p2e:
|
||||||
max_p2e = p2e_ratio
|
max_p2e = p2e_ratio
|
||||||
max_mtask = mtask
|
max_mtask = mtask
|
||||||
if p2e_ratio < min_p2e:
|
if p2e_ratio < min_p2e:
|
||||||
min_p2e = p2e_ratio
|
min_p2e = p2e_ratio
|
||||||
min_mtask = mtask
|
min_mtask = mtask
|
||||||
|
|
||||||
print("\nStatistics:")
|
print("\nMTask statistics:")
|
||||||
print(" min log(p2e) = %0.3f" % min_p2e, end="")
|
print(" min log(p2e) = %0.3f" % min_p2e, end="")
|
||||||
print(" from mtask %d (predict %d," %
|
print(" from mtask %d (predict %d," %
|
||||||
(min_mtask, Mtasks[min_mtask]['predict_cost']),
|
(min_mtask, Mtasks[min_mtask]['predict_cost']),
|
||||||
end="")
|
end="")
|
||||||
print(" elapsed %d)" % Mtasks[min_mtask]['elapsed'])
|
print(" elapsed %d)" % Mtasks[min_mtask]['elapsed'])
|
||||||
print(" max log(p2e) = %0.3f" % max_p2e, end="")
|
print(" max log(p2e) = %0.3f" % max_p2e, end="")
|
||||||
print(" from mtask %d (predict %d," %
|
print(" from mtask %d (predict %d," %
|
||||||
(max_mtask, Mtasks[max_mtask]['predict_cost']),
|
(max_mtask, Mtasks[max_mtask]['predict_cost']),
|
||||||
end="")
|
end="")
|
||||||
print(" elapsed %d)" % Mtasks[max_mtask]['elapsed'])
|
print(" elapsed %d)" % Mtasks[max_mtask]['elapsed'])
|
||||||
|
|
||||||
stddev = statistics.pstdev(p2e_ratios)
|
stddev = statistics.pstdev(p2e_ratios)
|
||||||
mean = statistics.mean(p2e_ratios)
|
mean = statistics.mean(p2e_ratios)
|
||||||
print(" mean = %0.3f" % mean)
|
print(" mean = %0.3f" % mean)
|
||||||
print(" stddev = %0.3f" % stddev)
|
print(" stddev = %0.3f" % stddev)
|
||||||
print(" e ^ stddev = %0.3f" % math.exp(stddev))
|
print(" e ^ stddev = %0.3f" % math.exp(stddev))
|
||||||
|
|
||||||
report_cpus()
|
report_cpus()
|
||||||
|
|
||||||
@@ -375,44 +395,45 @@ def write_vcd(filename):
|
|||||||
vcd['values'][eval_start][elcode] = n
|
vcd['values'][eval_start][elcode] = n
|
||||||
vcd['values'][eval_end][elcode] = None
|
vcd['values'][eval_end][elcode] = None
|
||||||
|
|
||||||
# Predicted graph
|
if Mtasks:
|
||||||
for eval_start in EvalLoops:
|
# Predicted graph
|
||||||
eval_end = EvalLoops[eval_start]['end']
|
for eval_start in EvalLoops:
|
||||||
# Compute scale so predicted graph is of same width as eval
|
eval_end = EvalLoops[eval_start]['end']
|
||||||
measured_scaling = (eval_end -
|
# Compute scale so predicted graph is of same width as eval
|
||||||
eval_start) / Global['predict_last_end']
|
measured_scaling = (eval_end -
|
||||||
# Predict mtasks that fill the time the eval occupied
|
eval_start) / Global['predict_last_end']
|
||||||
for mtask in Mtasks:
|
# Predict mtasks that fill the time the eval occupied
|
||||||
thread = Mtasks[mtask]['thread']
|
for mtask in Mtasks:
|
||||||
pred_scaled_start = eval_start + int(
|
thread = Mtasks[mtask]['thread']
|
||||||
Mtasks[mtask]['predict_start'] * measured_scaling)
|
pred_scaled_start = eval_start + int(
|
||||||
pred_scaled_end = eval_start + int(
|
Mtasks[mtask]['predict_start'] * measured_scaling)
|
||||||
(Mtasks[mtask]['predict_start'] +
|
pred_scaled_end = eval_start + int(
|
||||||
Mtasks[mtask]['predict_cost']) * measured_scaling)
|
(Mtasks[mtask]['predict_start'] +
|
||||||
if pred_scaled_start == pred_scaled_end:
|
Mtasks[mtask]['predict_cost']) * measured_scaling)
|
||||||
continue
|
if pred_scaled_start == pred_scaled_end:
|
||||||
|
continue
|
||||||
|
|
||||||
sig = "predicted_thread%d_mtask" % thread
|
sig = "predicted_thread%d_mtask" % thread
|
||||||
if sig not in vcd['sigs']['predicted_threads']:
|
if sig not in vcd['sigs']['predicted_threads']:
|
||||||
vcd['sigs']['predicted_threads'][sig] = code
|
vcd['sigs']['predicted_threads'][sig] = code
|
||||||
code += 1
|
code += 1
|
||||||
mcode = vcd['sigs']['predicted_threads'][sig]
|
mcode = vcd['sigs']['predicted_threads'][sig]
|
||||||
|
|
||||||
vcd['values'][pred_scaled_start][mcode] = mtask
|
vcd['values'][pred_scaled_start][mcode] = mtask
|
||||||
vcd['values'][pred_scaled_end][mcode] = None
|
vcd['values'][pred_scaled_end][mcode] = None
|
||||||
|
|
||||||
parallelism['predicted'][pred_scaled_start] += 1
|
parallelism['predicted'][pred_scaled_start] += 1
|
||||||
parallelism['predicted'][pred_scaled_end] -= 1
|
parallelism['predicted'][pred_scaled_end] -= 1
|
||||||
|
|
||||||
# Parallelism graph
|
# Parallelism graph
|
||||||
for measpred in ('measured', 'predicted'):
|
for measpred in ('measured', 'predicted'):
|
||||||
vcd['sigs']['Stats']["%s_parallelism" % measpred] = code
|
vcd['sigs']['Stats']["%s_parallelism" % measpred] = code
|
||||||
pcode = code
|
pcode = code
|
||||||
code += 1
|
code += 1
|
||||||
value = 0
|
value = 0
|
||||||
for time in sorted(parallelism[measpred].keys()):
|
for time in sorted(parallelism[measpred].keys()):
|
||||||
value += parallelism[measpred][time]
|
value += parallelism[measpred][time]
|
||||||
vcd['values'][time][pcode] = value
|
vcd['values'][time][pcode] = value
|
||||||
|
|
||||||
# Create output file
|
# Create output file
|
||||||
fh.write("$version Generated by verilator_gantt $end\n")
|
fh.write("$version Generated by verilator_gantt $end\n")
|
||||||
@@ -463,7 +484,7 @@ parser = argparse.ArgumentParser(
|
|||||||
For documentation see
|
For documentation see
|
||||||
https://verilator.org/guide/latest/exe_verilator_gantt.html
|
https://verilator.org/guide/latest/exe_verilator_gantt.html
|
||||||
|
|
||||||
Copyright 2018-2021 by Wilson Snyder. This program is free software; you
|
Copyright 2018-2022 by Wilson Snyder. This program is free software; you
|
||||||
can redistribute it and/or modify it under the terms of either the GNU
|
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
|
Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
Version 2.0.
|
Version 2.0.
|
||||||
@@ -476,10 +497,10 @@ parser.add_argument('--no-vcd',
|
|||||||
action='store_true')
|
action='store_true')
|
||||||
parser.add_argument('--vcd',
|
parser.add_argument('--vcd',
|
||||||
help='filename for vcd outpue',
|
help='filename for vcd outpue',
|
||||||
default='profile_threads.vcd')
|
default='profile_exec.vcd')
|
||||||
parser.add_argument('filename',
|
parser.add_argument('filename',
|
||||||
help='input profile_threads.dat filename to process',
|
help='input profile_exec.dat filename to process',
|
||||||
default='profile_threads.dat')
|
default='profile_exec.dat')
|
||||||
|
|
||||||
Args = parser.parse_args()
|
Args = parser.parse_args()
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env perl
|
#!/usr/bin/env perl
|
||||||
# DESCRIPTION: Print include statements for each ARGV
|
# DESCRIPTION: Print include statements for each ARGV
|
||||||
#
|
#
|
||||||
# Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
# Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||||
# can redistribute it and/or modify it under the terms of either the GNU
|
# 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
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ in each Verilog block.
|
|||||||
For documentation see
|
For documentation see
|
||||||
https://verilator.org/guide/latest/exe_verilator_profcfunc.html
|
https://verilator.org/guide/latest/exe_verilator_profcfunc.html
|
||||||
|
|
||||||
Copyright 2002-2021 by Wilson Snyder. This program is free software; you
|
Copyright 2002-2022 by Wilson Snyder. This program is free software; you
|
||||||
can redistribute it and/or modify it under the terms of either the GNU
|
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
|
Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
Version 2.0.
|
Version 2.0.
|
||||||
|
|||||||
+11
-3
@@ -19,6 +19,10 @@ set -x
|
|||||||
|
|
||||||
cd $(dirname "$0")/..
|
cd $(dirname "$0")/..
|
||||||
|
|
||||||
|
# Avoid occasional cpan failures "Issued certificate has expired."
|
||||||
|
export PERL_LWP_SSL_VERIFY_HOSTNAME=0
|
||||||
|
echo "check_certificate = off" >> ~/.wgetrc
|
||||||
|
|
||||||
fatal() {
|
fatal() {
|
||||||
echo "ERROR: $(basename "$0"): $1" >&2; exit 1;
|
echo "ERROR: $(basename "$0"): $1" >&2; exit 1;
|
||||||
}
|
}
|
||||||
@@ -54,8 +58,12 @@ if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then
|
|||||||
|
|
||||||
if [ "$CI_OS_NAME" = "linux" ]; then
|
if [ "$CI_OS_NAME" = "linux" ]; then
|
||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
sudo apt-get install libfl-dev libgoogle-perftools-dev ccache
|
sudo apt-get install libfl-dev ccache
|
||||||
if [ "$CI_RUNS_ON" = "ubuntu-20.04" ]; then
|
if [ "$CI_RUNS_ON" != "ubuntu-22.04" ]; then
|
||||||
|
# Some conflict of libunwind verison on 22.04, can live without it for now
|
||||||
|
sudo apt-get install libgoogle-perftools-dev
|
||||||
|
fi
|
||||||
|
if [ "$CI_RUNS_ON" = "ubuntu-20.04" ] || [ "$CI_RUNS_ON" = "ubuntu-22.04" ]; then
|
||||||
sudo apt-get install libsystemc libsystemc-dev
|
sudo apt-get install libsystemc libsystemc-dev
|
||||||
fi
|
fi
|
||||||
if [ "$COVERAGE" = 1 ]; then
|
if [ "$COVERAGE" = 1 ]; then
|
||||||
@@ -85,7 +93,7 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
|
|||||||
sudo apt-get update
|
sudo apt-get update
|
||||||
# libfl-dev needed for internal coverage's test runs
|
# libfl-dev needed for internal coverage's test runs
|
||||||
sudo apt-get install gdb gtkwave lcov libfl-dev ccache
|
sudo apt-get install gdb gtkwave lcov libfl-dev ccache
|
||||||
if [ "$CI_RUNS_ON" = "ubuntu-20.04" ]; then
|
if [ "$CI_RUNS_ON" = "ubuntu-20.04" ] || [ "$CI_RUNS_ON" = "ubuntu-22.04" ]; then
|
||||||
sudo apt-get install libsystemc-dev
|
sudo apt-get install libsystemc-dev
|
||||||
fi
|
fi
|
||||||
if [ "$CI_M32" = 1 ]; then
|
if [ "$CI_M32" = 1 ]; then
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
FROM ubuntu:20.04
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& DEBIAN_FRONTEND=noninteractive \
|
&& DEBIAN_FRONTEND=noninteractive \
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ Verilator build. It uses the following parameters:
|
|||||||
|
|
||||||
- Source revision (default: master)
|
- Source revision (default: master)
|
||||||
|
|
||||||
- Compiler (GCC 9.3.0, clang 10.0.0, default: 9.3.0)
|
- Compiler (GCC 10.3.0, clang 10.0.0, default: 10.3.0)
|
||||||
|
|
||||||
The container is published as ``verilator/verilator-buildenv`` on `docker
|
The container is published as ``verilator/verilator-buildenv`` on `docker
|
||||||
hub
|
hub
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
FROM ubuntu:20.04
|
FROM ubuntu:22.04
|
||||||
|
|
||||||
RUN apt-get update \
|
RUN apt-get update \
|
||||||
&& DEBIAN_FRONTEND=noninteractive \
|
&& DEBIAN_FRONTEND=noninteractive \
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
# DESCRIPTION: codecov.io config
|
# DESCRIPTION: codecov.io config
|
||||||
#
|
#
|
||||||
# Copyright 2020-2021 by Wilson Snyder. This program is free software; you
|
# Copyright 2020-2022 by Wilson Snyder. This program is free software; you
|
||||||
# can redistribute it and/or modify it under the terms of either the GNU
|
# 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
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
|
|||||||
+21
-15
@@ -1,20 +1,20 @@
|
|||||||
# DESCRIPTION: Process this file with autoconf to produce a configure script.
|
# DESCRIPTION: Process this file with autoconf to produce a configure script.
|
||||||
#
|
#
|
||||||
# Copyright 2003-2021 by Wilson Snyder. Verilator is free software; you
|
# Copyright 2003-2022 by Wilson Snyder. Verilator is free software; you
|
||||||
# can redistribute it and/or modify it under the terms of either the GNU Lesser
|
# 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.
|
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
|
||||||
#AC_INIT([Verilator],[#.### devel])
|
|
||||||
AC_INIT([Verilator],[4.216 2021-12-05],
|
|
||||||
[https://verilator.org],
|
|
||||||
[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
|
||||||
# Then 'make maintainer-dist'
|
# Then 'make maintainer-dist'
|
||||||
|
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||||
|
#AC_INIT([Verilator],[#.### devel])
|
||||||
|
AC_INIT([Verilator],[4.228 2022-10-01],
|
||||||
|
[https://verilator.org],
|
||||||
|
[verilator],[https://verilator.org])
|
||||||
|
|
||||||
AC_CONFIG_HEADER(src/config_build.h)
|
AC_CONFIG_HEADERS(src/config_build.h)
|
||||||
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc verilator-config.cmake verilator-config-version.cmake)
|
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc verilator-config.cmake verilator-config-version.cmake)
|
||||||
|
|
||||||
# Version
|
# Version
|
||||||
@@ -22,6 +22,8 @@ AC_MSG_RESULT([configuring for $PACKAGE_STRING])
|
|||||||
PACKAGE_VERSION_NUMBER=`AS_ECHO("$PACKAGE_VERSION") | sed 's/ .*//g'`
|
PACKAGE_VERSION_NUMBER=`AS_ECHO("$PACKAGE_VERSION") | sed 's/ .*//g'`
|
||||||
AC_SUBST(PACKAGE_VERSION_NUMBER)
|
AC_SUBST(PACKAGE_VERSION_NUMBER)
|
||||||
AC_DEFINE_UNQUOTED([PACKAGE_VERSION_NUMBER_STRING],["$PACKAGE_VERSION_NUMBER"],[Package version as a number])
|
AC_DEFINE_UNQUOTED([PACKAGE_VERSION_NUMBER_STRING],["$PACKAGE_VERSION_NUMBER"],[Package version as a number])
|
||||||
|
VERILATOR_VERSION_INTEGER=`AS_ECHO("$PACKAGE_VERSION") | [sed 's/\([0-9]\)\.\([0-9][0-9][0-9]\) .*/\1\2000/g']`
|
||||||
|
AC_SUBST(VERILATOR_VERSION_INTEGER)
|
||||||
|
|
||||||
# Ignore automake flags passed by Ubuntu builds
|
# Ignore automake flags passed by Ubuntu builds
|
||||||
AC_ARG_ENABLE([dependency-tracking],
|
AC_ARG_ENABLE([dependency-tracking],
|
||||||
@@ -143,10 +145,10 @@ AC_SUBST(CFG_WITH_LONGTESTS)
|
|||||||
AC_MSG_RESULT($CFG_WITH_LONGTESTS)
|
AC_MSG_RESULT($CFG_WITH_LONGTESTS)
|
||||||
|
|
||||||
# Compiler flags (ensure they are not empty to avoid configure defaults)
|
# Compiler flags (ensure they are not empty to avoid configure defaults)
|
||||||
CFLAGS+=" "
|
CFLAGS="$CFLAGS "
|
||||||
CPPFLAGS+=" "
|
CPPFLAGS="$CPPFLAGS "
|
||||||
CXXFLAGS+=" "
|
CXXFLAGS="$CXXFLAGS "
|
||||||
LDFLAGS+=" "
|
LDFLAGS="$LDFLAGS "
|
||||||
|
|
||||||
# Checks for programs.
|
# Checks for programs.
|
||||||
AC_PROG_CC
|
AC_PROG_CC
|
||||||
@@ -346,14 +348,18 @@ AC_SUBST(CFG_CXXFLAGS_PROFILE)
|
|||||||
|
|
||||||
# Flag to select newest language standard supported
|
# Flag to select newest language standard supported
|
||||||
# Macros work such that first option that passes is the one we take
|
# Macros work such that first option that passes is the one we take
|
||||||
# Currently enabled c++14 due to packaged SystemC dependency
|
# Currently enable c++17/c++14 due to packaged SystemC dependency
|
||||||
# c++14 is the newest that Verilator is regressed to support
|
# c++17 is the newest that Verilator is regularly tested to support
|
||||||
# c++11 is the oldest that Verilator supports
|
# c++11 is the oldest that Verilator supports
|
||||||
# gnu is requried for Cygwin to compile verilated.h successfully
|
# gnu is requried for Cygwin to compile verilated.h successfully
|
||||||
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++20)
|
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++20)
|
||||||
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++20)
|
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++20)
|
||||||
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++17)
|
case "$(which lsb_release 2>&1 > /dev/null && lsb_release -d)" in
|
||||||
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++17)
|
*Arch*Linux* | *Ubuntu*22.04*)
|
||||||
|
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++17)
|
||||||
|
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++17)
|
||||||
|
;;
|
||||||
|
esac
|
||||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++14)
|
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++14)
|
||||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++14)
|
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++14)
|
||||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++11)
|
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++11)
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
*.html
|
*.html
|
||||||
*.pdf
|
*.pdf
|
||||||
_build
|
_build
|
||||||
|
guide/spelling.txt
|
||||||
|
|||||||
@@ -3,12 +3,17 @@ under the Developer Certificate of Origin (https://developercertificate.org/).
|
|||||||
|
|
||||||
Please see the Verilator manual for 200+ additional contributors. Thanks to all.
|
Please see the Verilator manual for 200+ additional contributors. Thanks to all.
|
||||||
|
|
||||||
|
Adrien Le Masle
|
||||||
Ahmed El-Mahmoudy
|
Ahmed El-Mahmoudy
|
||||||
|
Aleksander Kiryk
|
||||||
Alex Chadwick
|
Alex Chadwick
|
||||||
Àlex Torregrosa
|
Àlex Torregrosa
|
||||||
|
Aliaksei Chapyzhenka
|
||||||
Ameya Vikram Singh
|
Ameya Vikram Singh
|
||||||
Andreas Kuster
|
Andreas Kuster
|
||||||
|
Arkadiusz Kozdra
|
||||||
Chris Randall
|
Chris Randall
|
||||||
|
Chuxuan Wang
|
||||||
Conor McCullough
|
Conor McCullough
|
||||||
Dan Petrisko
|
Dan Petrisko
|
||||||
Daniel Bates
|
Daniel Bates
|
||||||
@@ -16,6 +21,7 @@ David Horton
|
|||||||
David Metz
|
David Metz
|
||||||
David Stanford
|
David Stanford
|
||||||
David Turner
|
David Turner
|
||||||
|
Drew Ranck
|
||||||
Drew Taussig
|
Drew Taussig
|
||||||
Driss Hafdi
|
Driss Hafdi
|
||||||
Edgar E. Iglesias
|
Edgar E. Iglesias
|
||||||
@@ -27,17 +33,23 @@ Geza Lore
|
|||||||
Gianfranco Costamagna
|
Gianfranco Costamagna
|
||||||
Glen Gibb
|
Glen Gibb
|
||||||
Graham Rushton
|
Graham Rushton
|
||||||
|
Guokai Chen
|
||||||
|
Gustav Svensk
|
||||||
Harald Heckmann
|
Harald Heckmann
|
||||||
Howard Su
|
Howard Su
|
||||||
Huang Rui
|
Huang Rui
|
||||||
|
Huanghuang Zhou
|
||||||
|
HungMingWu
|
||||||
HyungKi Jeong
|
HyungKi Jeong
|
||||||
Iru Cai
|
Iru Cai
|
||||||
Ivan Vnučec
|
Ivan Vnučec
|
||||||
Iztok Jeras
|
Iztok Jeras
|
||||||
|
Jake Merdich
|
||||||
James Hanlon
|
James Hanlon
|
||||||
James Hutchinson
|
James Hutchinson
|
||||||
James Pallister
|
James Pallister
|
||||||
Jamey Hicks
|
Jamey Hicks
|
||||||
|
Jamie Iles
|
||||||
Jan Van Winkel
|
Jan Van Winkel
|
||||||
Jean Berniolles
|
Jean Berniolles
|
||||||
Jeremy Bennett
|
Jeremy Bennett
|
||||||
@@ -48,31 +60,38 @@ Josh Redford
|
|||||||
Julie Schwartz
|
Julie Schwartz
|
||||||
Julien Margetts
|
Julien Margetts
|
||||||
Kaleb Barrett
|
Kaleb Barrett
|
||||||
|
Kamil Rakoczy
|
||||||
Kanad Kanhere
|
Kanad Kanhere
|
||||||
Keith Colbert
|
Keith Colbert
|
||||||
Kevin Kiningham
|
Kevin Kiningham
|
||||||
Krzysztof Bieganski
|
Krzysztof Bieganski
|
||||||
Kuba Ober
|
Kuba Ober
|
||||||
|
Larry Doolittle
|
||||||
Ludwig Rogiers
|
Ludwig Rogiers
|
||||||
Lukasz Dalek
|
Lukasz Dalek
|
||||||
Maarten De Braekeleer
|
Maarten De Braekeleer
|
||||||
Maciej Sobkowski
|
Maciej Sobkowski
|
||||||
Marco Widmer
|
Marco Widmer
|
||||||
|
Mariusz Glebocki
|
||||||
Markus Krause
|
Markus Krause
|
||||||
Marlon James
|
Marlon James
|
||||||
Marshal Qiao
|
Marshal Qiao
|
||||||
Martin Schmidt
|
Martin Schmidt
|
||||||
|
Martin Stadler
|
||||||
Matthew Ballance
|
Matthew Ballance
|
||||||
Michael Killough
|
Michael Killough
|
||||||
Michaël Lefebvre
|
Michaël Lefebvre
|
||||||
Mike Popoloski
|
Mike Popoloski
|
||||||
Miodrag Milanović
|
Miodrag Milanović
|
||||||
|
Mladen Slijepcevic
|
||||||
Morten Borup Petersen
|
Morten Borup Petersen
|
||||||
|
Mostafa Gamal
|
||||||
Nandu Raj
|
Nandu Raj
|
||||||
Nathan Kohagen
|
Nathan Kohagen
|
||||||
Nathan Myers
|
Nathan Myers
|
||||||
Patrick Stewart
|
Patrick Stewart
|
||||||
Paul Wright
|
Paul Wright
|
||||||
|
Pawel Sagan
|
||||||
Peter Horvath
|
Peter Horvath
|
||||||
Peter Monsson
|
Peter Monsson
|
||||||
Philipp Wagner
|
Philipp Wagner
|
||||||
@@ -81,8 +100,10 @@ Pieter Kapsenberg
|
|||||||
Piotr Binkowski
|
Piotr Binkowski
|
||||||
Qingyao Sun
|
Qingyao Sun
|
||||||
Rafal Kapuscik
|
Rafal Kapuscik
|
||||||
|
Raynard Qiao
|
||||||
Richard Myers
|
Richard Myers
|
||||||
Rupert Swarbrick
|
Rupert Swarbrick
|
||||||
|
Ryszard Rozak
|
||||||
Samuel Riedel
|
Samuel Riedel
|
||||||
Sean Cross
|
Sean Cross
|
||||||
Sebastien Van Cauwenberghe
|
Sebastien Van Cauwenberghe
|
||||||
@@ -99,12 +120,17 @@ Tomasz Gorochowik
|
|||||||
Tymoteusz Blazejczyk
|
Tymoteusz Blazejczyk
|
||||||
Udi Finkelstein
|
Udi Finkelstein
|
||||||
Unai Martinez-Corral
|
Unai Martinez-Corral
|
||||||
|
Varun Koyyalagunta
|
||||||
Vassilis Papaefstathiou
|
Vassilis Papaefstathiou
|
||||||
Veripool API Bot
|
Veripool API Bot
|
||||||
Victor Besyakov
|
Victor Besyakov
|
||||||
|
William D. Jones
|
||||||
Wilson Snyder
|
Wilson Snyder
|
||||||
|
Xi Zhang
|
||||||
|
Yoda Lee
|
||||||
Yossi Nivin
|
Yossi Nivin
|
||||||
Yuri Victorovich
|
Yuri Victorovich
|
||||||
Yutetsu TAKATSUKASA
|
Yutetsu TAKATSUKASA
|
||||||
|
Yu-Sheng Lin
|
||||||
Yves Mathieu
|
Yves Mathieu
|
||||||
Zhanglei Wang
|
Zhanglei Wang
|
||||||
|
|||||||
+3
-1
@@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
# Code available from: https://verilator.org
|
# Code available from: https://verilator.org
|
||||||
#
|
#
|
||||||
# Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
# Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||||
# can redistribute it and/or modify it under the terms of either the GNU
|
# 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
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
@@ -35,6 +35,7 @@ default:
|
|||||||
# Intermediate rules
|
# Intermediate rules
|
||||||
|
|
||||||
vl-extract: ../bin/verilator ../Changes
|
vl-extract: ../bin/verilator ../Changes
|
||||||
|
ln -sf ../spelling.txt guide/spelling.txt
|
||||||
mkdir -p _build/gen
|
mkdir -p _build/gen
|
||||||
$(PYTHON3) bin/vl_sphinx_extract ../bin/verilator
|
$(PYTHON3) bin/vl_sphinx_extract ../bin/verilator
|
||||||
sed 's/`/\&96;/g' < ../Changes > _build/gen/Changes
|
sed 's/`/\&96;/g' < ../Changes > _build/gen/Changes
|
||||||
@@ -77,6 +78,7 @@ 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 -f guide/spelling.txt
|
||||||
|
|
||||||
distclean maintainer-clean::
|
distclean maintainer-clean::
|
||||||
rm -f *.info* *.1 *.html *.pdf $(INFOS)
|
rm -f *.info* *.1 *.html *.pdf $(INFOS)
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ parser = argparse.ArgumentParser(
|
|||||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
description="""Read a file and extract documentation data.""",
|
description="""Read a file and extract documentation data.""",
|
||||||
epilog=
|
epilog=
|
||||||
""" Copyright 2021-2021 by Wilson Snyder. This package is free software;
|
""" Copyright 2021-2022 by Wilson Snyder. This package is free software;
|
||||||
you can redistribute it and/or modify it under the terms of either the GNU
|
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
|
Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
Version 2.0.
|
Version 2.0.
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ parser = argparse.ArgumentParser(
|
|||||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||||
description="""Post-process Sphinx HTML.""",
|
description="""Post-process Sphinx HTML.""",
|
||||||
epilog=
|
epilog=
|
||||||
""" Copyright 2021-2021 by Wilson Snyder. This package is free software;
|
""" Copyright 2021-2022 by Wilson Snyder. This package is free software;
|
||||||
you can redistribute it and/or modify it under the terms of either the GNU
|
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
|
Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
Version 2.0.
|
Version 2.0.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
****************
|
****************
|
||||||
|
|||||||
+2
-1
@@ -13,6 +13,7 @@ from datetime import datetime
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
sys.path.insert(0, os.path.abspath('./_ext'))
|
sys.path.insert(0, os.path.abspath('./_ext'))
|
||||||
|
|
||||||
import sphinx_rtd_theme # pylint: disable=wrong-import-position,
|
import sphinx_rtd_theme # pylint: disable=wrong-import-position,
|
||||||
@@ -36,7 +37,7 @@ def setup(app):
|
|||||||
# -- Project information
|
# -- Project information
|
||||||
|
|
||||||
project = 'Verilator'
|
project = 'Verilator'
|
||||||
copyright = '2021 by Wilson Snyder, under LGPL-3.0 or Artistic-2.0'
|
copyright = '2022 by Wilson Snyder, under LGPL-3.0 or Artistic-2.0'
|
||||||
author = 'Wilson Snyder'
|
author = 'Wilson Snyder'
|
||||||
|
|
||||||
# The master toctree document.
|
# The master toctree document.
|
||||||
|
|||||||
+22
-60
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
.. _Connecting:
|
.. _Connecting:
|
||||||
@@ -86,58 +86,17 @@ Connecting to C++
|
|||||||
In C++ output mode (:vlopt:`--cc`), the Verilator generated model class is a
|
In C++ output mode (:vlopt:`--cc`), the Verilator generated model class is a
|
||||||
simple C++ class. The user must write a C++ wrapper and main loop for the
|
simple C++ class. The user must write a C++ wrapper and main loop for the
|
||||||
simulation, which instantiates the model class, and link with the Verilated
|
simulation, which instantiates the model class, and link with the Verilated
|
||||||
model. Here is a simple example:
|
model.
|
||||||
|
|
||||||
.. code-block:: C++
|
Refer to ``examples/make_tracing_c`` in the distribution for a detailed
|
||||||
|
commented example.
|
||||||
|
|
||||||
#include <verilated.h> // Defines common routines
|
Top level IO signals are read and written as members of the model. You
|
||||||
#include <iostream> // Need std::cout
|
call the model's :code:`eval()` method to evaluate the model. When the
|
||||||
#include "Vtop.h" // From Verilating "top.v"
|
simulation is complete call the model's :code:`final()` method to execute
|
||||||
|
any SystemVerilog final blocks, and complete any assertions. See
|
||||||
|
:ref:`Evaluation Loop`.
|
||||||
|
|
||||||
Vtop *top; // Instantiation of model
|
|
||||||
|
|
||||||
vluint64_t main_time = 0; // Current simulation time
|
|
||||||
// This is a 64-bit integer to reduce wrap over issues and
|
|
||||||
// allow modulus. This is in units of the timeprecision
|
|
||||||
// used in Verilog (or from --timescale-override)
|
|
||||||
|
|
||||||
double sc_time_stamp() { // Called by $time in Verilog
|
|
||||||
return main_time; // converts to double, to match
|
|
||||||
// what SystemC does
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
|
||||||
Verilated::commandArgs(argc, argv); // Remember args
|
|
||||||
|
|
||||||
top = new Vtop; // Create model
|
|
||||||
|
|
||||||
top->reset_l = 0; // Set some inputs
|
|
||||||
|
|
||||||
while (!Verilated::gotFinish()) {
|
|
||||||
if (main_time > 10) {
|
|
||||||
top->reset_l = 1; // Deassert reset
|
|
||||||
}
|
|
||||||
if ((main_time % 10) == 1) {
|
|
||||||
top->clk = 1; // Toggle clock
|
|
||||||
}
|
|
||||||
if ((main_time % 10) == 6) {
|
|
||||||
top->clk = 0;
|
|
||||||
}
|
|
||||||
top->eval(); // Evaluate model
|
|
||||||
cout << top->out << endl; // Read a output
|
|
||||||
main_time++; // Time passes...
|
|
||||||
}
|
|
||||||
|
|
||||||
top->final(); // Done simulating
|
|
||||||
// // (Though this example doesn't get here)
|
|
||||||
delete top;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Note top level IO signals are read and written as members of the model. You
|
|
||||||
call the :code:`eval()` method to evaluate the model. When the simulation is
|
|
||||||
complete call the :code:`final()` method to execute any SystemVerilog final
|
|
||||||
blocks, and complete any assertions. See :ref:`Evaluation Loop`.
|
|
||||||
|
|
||||||
|
|
||||||
Connecting to SystemC
|
Connecting to SystemC
|
||||||
@@ -150,7 +109,7 @@ netlist as an instantiation.
|
|||||||
The SC_MODULE gets the same pinout as the Verilog module, with the
|
The SC_MODULE gets the same pinout as the Verilog module, with the
|
||||||
following type conversions: Pins of a single bit become bool. Pins 2-32
|
following type conversions: Pins of a single bit become bool. Pins 2-32
|
||||||
bits wide become uint32_t's. Pins 33-64 bits wide become sc_bv's or
|
bits wide become uint32_t's. Pins 33-64 bits wide become sc_bv's or
|
||||||
vluint64_t's depending on the :vlopt:`--no-pins64` option. Wider pins
|
uint64_t's depending on the :vlopt:`--no-pins64` option. Wider pins
|
||||||
become sc_bv's. (Uints simulate the fastest so are used where possible.)
|
become sc_bv's. (Uints simulate the fastest so are used where possible.)
|
||||||
|
|
||||||
Model internals, including lower level sub-modules are not pure SystemC
|
Model internals, including lower level sub-modules are not pure SystemC
|
||||||
@@ -200,7 +159,7 @@ DPI System Task/Functions
|
|||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
Verilator extends the DPI format to allow using the same scheme to
|
Verilator extends the DPI format to allow using the same scheme to
|
||||||
efficiently add system functions. Simply use a dollar-sign prefixed system
|
efficiently add system functions. Use a dollar-sign prefixed system
|
||||||
function name for the import, but note it must be escaped.
|
function name for the import, but note it must be escaped.
|
||||||
|
|
||||||
.. code-block:: sv
|
.. code-block:: sv
|
||||||
@@ -257,7 +216,9 @@ with respect to that top level module, then the scope could be set with
|
|||||||
|
|
||||||
#include "svdpi.h"
|
#include "svdpi.h"
|
||||||
...
|
...
|
||||||
svSetScope(svGetScopeFromName("TOP.dut"));
|
const svScope scope = svGetScopeFromName("TOP.dut");
|
||||||
|
assert(scope); // Check for nullptr if scope not found
|
||||||
|
svSetScope(scope);
|
||||||
|
|
||||||
(Remember that Verilator adds a "TOP" to the top of the module hierarchy.)
|
(Remember that Verilator adds a "TOP" to the top of the module hierarchy.)
|
||||||
|
|
||||||
@@ -422,12 +383,12 @@ accesses the above signal "readme" would be:
|
|||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
cat >sim_main.cpp <<'<<EOF'
|
cat >sim_main.cpp <<'EOF'
|
||||||
#include "Vour.h"
|
#include "Vour.h"
|
||||||
#include "verilated.h"
|
#include "verilated.h"
|
||||||
#include "verilated_vpi.h" // Required to get definitions
|
#include "verilated_vpi.h" // Required to get definitions
|
||||||
|
|
||||||
vluint64_t main_time = 0; // See comments in first example
|
uint64_t main_time = 0; // See comments in first example
|
||||||
double sc_time_stamp() { return main_time; }
|
double sc_time_stamp() { return main_time; }
|
||||||
|
|
||||||
void read_and_check() {
|
void read_and_check() {
|
||||||
@@ -444,14 +405,15 @@ accesses the above signal "readme" would be:
|
|||||||
|
|
||||||
int main(int argc, char** argv, char** env) {
|
int main(int argc, char** argv, char** env) {
|
||||||
Verilated::commandArgs(argc, argv);
|
Verilated::commandArgs(argc, argv);
|
||||||
Vour* top = new Vour;
|
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
|
||||||
Verilated::internalsDump(); // See scopes to help debug
|
const std::unique_ptr<Vour> top{new Vour{contextp.get()}};
|
||||||
while (!Verilated::gotFinish()) {
|
|
||||||
|
contextp->internalsDump(); // See scopes to help debug
|
||||||
|
while (!contextp->gotFinish()) {
|
||||||
top->eval();
|
top->eval();
|
||||||
VerilatedVpi::callValueCbs(); // For signal callbacks
|
VerilatedVpi::callValueCbs(); // For signal callbacks
|
||||||
read_and_check();
|
read_and_check();
|
||||||
}
|
}
|
||||||
delete top;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
EOF
|
EOF
|
||||||
@@ -506,7 +468,7 @@ structure. If a ``VerilatedContext`` is not created prior to creating a
|
|||||||
model, a default global one is created automatically.
|
model, a default global one is created automatically.
|
||||||
|
|
||||||
The ``Verilated::`` methods, including the ``Verilated::commandArgs`` call
|
The ``Verilated::`` methods, including the ``Verilated::commandArgs`` call
|
||||||
shown above, simply call VerilatedContext methods using the default global
|
shown above, call VerilatedContext methods using the default global
|
||||||
VerilatedContext. (Technically they operate on the last one used by a
|
VerilatedContext. (Technically they operate on the last one used by a
|
||||||
given thread.) If you are using multiple simulation contexts you should
|
given thread.) If you are using multiple simulation contexts you should
|
||||||
not use the Verilated:: methods, and instead always use VerilatedContext
|
not use the Verilated:: methods, and instead always use VerilatedContext
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
*******************************
|
*******************************
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
************************
|
************************
|
||||||
@@ -23,14 +23,14 @@ Contributors
|
|||||||
Many people have provided ideas and other assistance with Verilator.
|
Many people have provided ideas and other assistance with Verilator.
|
||||||
|
|
||||||
Verilator is receiving major development support from the `CHIPS Alliance
|
Verilator is receiving major development support from the `CHIPS Alliance
|
||||||
<https://chipsalliance.org>`_.
|
<https://chipsalliance.org>`_ and `Shunyao CAD <https://shunyaocad.com>`_.
|
||||||
|
|
||||||
Previous major corporate sponsors of Verilator, by providing significant
|
Previous major corporate sponsors of Verilator, by providing significant
|
||||||
contributions of time or funds included include: Atmel Corporation, Cavium
|
contributions of time or funds included include: Atmel Corporation, Cavium
|
||||||
Inc., Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd.,
|
Inc., Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd.,
|
||||||
Hicamp Systems, Intel Corporation, Mindspeed Technologies Inc., MicroTune
|
Hicamp Systems, Intel Corporation, Mindspeed Technologies Inc., MicroTune
|
||||||
Inc., picoChip Designs Ltd., Sun Microsystems Inc., Nauticus Networks Inc.,
|
Inc., picoChip Designs Ltd., Sun Microsystems Inc., Nauticus Networks Inc.,
|
||||||
and SiCortex Inc.
|
SiCortex Inc, and Shunyao CAD.
|
||||||
|
|
||||||
The people who have contributed major functionality are: Byron Bradley,
|
The people who have contributed major functionality are: Byron Bradley,
|
||||||
Jeremy Bennett, Lane Brooks, John Coiner, Duane Galbi, Geza Lore, Todd
|
Jeremy Bennett, Lane Brooks, John Coiner, Duane Galbi, Geza Lore, Todd
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
*********
|
*********
|
||||||
@@ -8,7 +8,7 @@ Copyright
|
|||||||
The latest version of Verilator is available from `https://verilator.org
|
The latest version of Verilator is available from `https://verilator.org
|
||||||
<https://verilator.org>`_.
|
<https://verilator.org>`_.
|
||||||
|
|
||||||
Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||||
can redistribute it and/or modify the Verilator internals under the terms
|
can redistribute it and/or modify the Verilator internals under the terms
|
||||||
of either the GNU Lesser General Public License Version 3 or the Perl
|
of either the GNU Lesser General Public License Version 3 or the Perl
|
||||||
Artistic License Version 2.0.
|
Artistic License Version 2.0.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
Deprecations
|
Deprecations
|
||||||
@@ -16,10 +16,22 @@ Verilated_heavy.h
|
|||||||
"verilated.h". Verilated_heavy.h is planned for removal no sooner than
|
"verilated.h". Verilated_heavy.h is planned for removal no sooner than
|
||||||
July 2022.
|
July 2022.
|
||||||
|
|
||||||
Configuration File -msg
|
Option `--cdc`
|
||||||
The :vlopt:`lint_off` "-msg" option has been replaced with the "-rule"
|
The experimental `--cdc` option is believed to be generally unused and is
|
||||||
option. "-msg" is planned for removal no sooner than January 2021.
|
planned for removal no sooner than January 2023.
|
||||||
|
|
||||||
XML locations
|
Option `-O<letter>`
|
||||||
The XML "fl" attribute has been replaced with the "loc" attribute. "fl"
|
The debug `-O<letter>` options have been replaced with
|
||||||
is planned for removal no sooner than January 2021.
|
`-fno-<optimization>` debug options to match GCC. The old options are
|
||||||
|
planned for removal no sooner than June 2023.
|
||||||
|
|
||||||
|
Option `--prof-threads`
|
||||||
|
The `--prof-threads` option has been superseded by the `--prof-exec` and
|
||||||
|
`--prof-pgo` options and is planned for removal no sooner than April 2023.
|
||||||
|
|
||||||
|
Verilated model options `+verilator+prof+threads+*`
|
||||||
|
The `+verilator+prof+threads+start`, `+verilator+prof+threads+window` and
|
||||||
|
`+verilator+prof+threads+file` options have been superseded by the
|
||||||
|
`+verilator+prof+exec+start`, `+verilator+prof+exec+window` and
|
||||||
|
`+verilator+prof+exec+file` options respectively and are planned for removal
|
||||||
|
no sooner than April 2023.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
Environment
|
Environment
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
.. _Example C++ Execution:
|
.. _Example C++ Execution:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
First you need Verilator installed, see :ref:`Installation`. In brief, if
|
First you need Verilator installed, see :ref:`Installation`. In brief, if
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
.. _Examples in the Distribution:
|
.. _Examples in the Distribution:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
.. _Example SystemC Execution:
|
.. _Example SystemC Execution:
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
.. _Examples:
|
.. _Examples:
|
||||||
|
|||||||
+24
-12
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
.. _Simulation Runtime Arguments:
|
.. _Simulation Runtime Arguments:
|
||||||
@@ -8,7 +8,7 @@ Simulation Runtime Arguments
|
|||||||
|
|
||||||
The following are the arguments that may be passed to a Verilated
|
The following are the arguments that may be passed to a Verilated
|
||||||
executable, provided that executable calls
|
executable, provided that executable calls
|
||||||
:code:`Verilated::commandArgs()`.
|
:code:`VerilatedContext*->commandArgs(argc, argv)`.
|
||||||
|
|
||||||
All simulation runtime arguments begin with "+verilator", so that the
|
All simulation runtime arguments begin with "+verilator", so that the
|
||||||
user's executable may skip over all "+verilator" arguments when parsing its
|
user's executable may skip over all "+verilator" arguments when parsing its
|
||||||
@@ -38,33 +38,45 @@ Summary:
|
|||||||
|
|
||||||
Display help and exit.
|
Display help and exit.
|
||||||
|
|
||||||
.. option:: +verilator+prof+threads+file+<filename>
|
.. option:: +verilator+prof+exec+file+<filename>
|
||||||
|
|
||||||
When a model was Verilated using :vlopt:`--prof-threads`, sets the
|
When a model was Verilated using :vlopt:`--prof-exec`, sets the
|
||||||
simulation runtime filename to dump to. Defaults to
|
simulation runtime filename to dump to. Defaults to
|
||||||
:file:`profile_threads.dat`.
|
:file:`profile_exec.dat`.
|
||||||
|
|
||||||
.. option:: +verilator+prof+threads+start+<value>
|
.. option:: +verilator+prof+exec+start+<value>
|
||||||
|
|
||||||
When a model was Verilated using :vlopt:`--prof-threads`, the simulation
|
When a model was Verilated using :vlopt:`--prof-exec`, the simulation
|
||||||
runtime will wait until $time is at this value (expressed in units of
|
runtime will wait until $time is at this value (expressed in units of
|
||||||
the time precision), then start the profiling warmup, then
|
the time precision), then start the profiling warmup, then
|
||||||
capturing. Generally this should be set to some time that is well within
|
capturing. Generally this should be set to some time that is well within
|
||||||
the normal operation of the simulation, i.e. outside of reset. If 0, the
|
the normal operation of the simulation, i.e. outside of reset. If 0, the
|
||||||
dump is disabled. Defaults to 1.
|
dump is disabled. Defaults to 1.
|
||||||
|
|
||||||
.. option:: +verilator+prof+threads+window+<value>
|
.. option:: +verilator+prof+exec+window+<value>
|
||||||
|
|
||||||
When a model was Verilated using :vlopt:`--prof-threads`, after $time
|
When a model was Verilated using :vlopt:`--prof-exec`, after $time
|
||||||
reaches :vlopt:`+verilator+prof+threads+start+\<value\>`, Verilator will
|
reaches :vlopt:`+verilator+prof+exec+start+\<value\>`, Verilator will
|
||||||
warm up the profiling for this number of eval() calls, then will capture
|
warm up the profiling for this number of eval() calls, then will capture
|
||||||
the profiling of this number of eval() calls. Defaults to 2, which
|
the profiling of this number of eval() calls. Defaults to 2, which
|
||||||
makes sense for a single-clock-domain module where it's typical to want
|
makes sense for a single-clock-domain module where it's typical to want
|
||||||
to capture one posedge eval() and one negedge eval().
|
to capture one posedge eval() and one negedge eval().
|
||||||
|
|
||||||
|
.. option:: +verilator+prof+threads+file+<filename>
|
||||||
|
|
||||||
|
Deprecated. Alias for :vlopt:`+verilator+prof+exec+file+\<filename\>`
|
||||||
|
|
||||||
|
.. option:: +verilator+prof+threads+start+<value>
|
||||||
|
|
||||||
|
Deprecated. Alias for :vlopt:`+verilator+prof+exec+start+\<value\>`
|
||||||
|
|
||||||
|
.. option:: +verilator+prof+threads+window+<value>
|
||||||
|
|
||||||
|
Deprecated. Alias for :vlopt:`+verilator+prof+exec+window+\<filename\>`
|
||||||
|
|
||||||
.. option:: +verilator+prof+vlt+file+<filename>
|
.. option:: +verilator+prof+vlt+file+<filename>
|
||||||
|
|
||||||
When a model was Verilated using :vlopt:`--prof-threads`, sets the
|
When a model was Verilated using :vlopt:`--prof-pgo`, sets the
|
||||||
profile-guided optimization data runtime filename to dump to. Defaults
|
profile-guided optimization data runtime filename to dump to. Defaults
|
||||||
to :file:`profile.vlt`.
|
to :file:`profile.vlt`.
|
||||||
|
|
||||||
@@ -84,7 +96,7 @@ Summary:
|
|||||||
.. option:: +verilator+noassert
|
.. option:: +verilator+noassert
|
||||||
|
|
||||||
Disable assert checking per runtime argument. This is the same as
|
Disable assert checking per runtime argument. This is the same as
|
||||||
calling :code:`Verilated::assertOn(false)` in the model.
|
calling :code:`VerilatedContext*->assertOn(false)` in the model.
|
||||||
|
|
||||||
.. option:: +verilator+V
|
.. option:: +verilator+V
|
||||||
|
|
||||||
|
|||||||
+291
-147
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
verilator Arguments
|
verilator Arguments
|
||||||
@@ -99,10 +99,10 @@ Summary:
|
|||||||
.. option:: --bbox-sys
|
.. option:: --bbox-sys
|
||||||
|
|
||||||
Black box any unknown $system task or function calls. System tasks will
|
Black box any unknown $system task or function calls. System tasks will
|
||||||
simply become no-operations, and system functions will be replaced with
|
become no-operations, and system functions will be replaced with unsized
|
||||||
unsized zero. Arguments to such functions will be parsed, but not
|
zero. Arguments to such functions will be parsed, but not otherwise
|
||||||
otherwise checked. This prevents errors when linting in the presence of
|
checked. This prevents errors when linting in the presence of company
|
||||||
company specific PLI calls.
|
specific PLI calls.
|
||||||
|
|
||||||
Using this argument will likely cause incorrect simulation.
|
Using this argument will likely cause incorrect simulation.
|
||||||
|
|
||||||
@@ -115,13 +115,6 @@ Summary:
|
|||||||
|
|
||||||
Using this argument will likely cause incorrect simulation.
|
Using this argument will likely cause incorrect simulation.
|
||||||
|
|
||||||
.. option:: --bin <filename>
|
|
||||||
|
|
||||||
Rarely needed. Override the default filename for Verilator itself.
|
|
||||||
When a dependency (.d) file is created, this filename will become a
|
|
||||||
source dependency, such that a change in this binary will have make
|
|
||||||
rebuild the output files.
|
|
||||||
|
|
||||||
.. option:: --build
|
.. option:: --build
|
||||||
|
|
||||||
After generating the SystemC/C++ code, Verilator will invoke the
|
After generating the SystemC/C++ code, Verilator will invoke the
|
||||||
@@ -129,15 +122,23 @@ Summary:
|
|||||||
is also used). Verilator manages the build itself, and for this --build
|
is also used). Verilator manages the build itself, and for this --build
|
||||||
requires GNU Make to be available on the platform.
|
requires GNU Make to be available on the platform.
|
||||||
|
|
||||||
.. option:: -CFLAGS <flags>
|
.. option:: --build-dep-bin <filename>
|
||||||
|
|
||||||
Add specified C compiler argument to the generated makefiles. For
|
Rarely needed. When a dependency (.d) file is created, this filename
|
||||||
multiple flags either pass them as a single argument with space
|
will become a source dependency, such that a change in this binary will
|
||||||
separators quoted in the shell (:command:`-CFLAGS "-a -b"`), or use
|
have make rebuild the output files. Defaults to the full path to the
|
||||||
multiple -CFLAGS options (:command:`-CFLAGS -a -CFLAGS -b`).
|
Verilator binary.
|
||||||
|
|
||||||
When make is run on the generated makefile these will be passed to the
|
This option was named `--bin` prior to version 4.228.
|
||||||
C++ compiler (g++/clang++/msvc++).
|
|
||||||
|
.. option:: --build-jobs [<value>]
|
||||||
|
|
||||||
|
Specify the level of parallelism for :vlopt:`--build`. If zero, uses the
|
||||||
|
number of threads in the current hardware. Otherwise, the <value> must
|
||||||
|
be a positive integer specifying the maximum number of parallel build
|
||||||
|
jobs.
|
||||||
|
|
||||||
|
See also :vlopt:`-j`.
|
||||||
|
|
||||||
.. option:: --cc
|
.. option:: --cc
|
||||||
|
|
||||||
@@ -156,6 +157,16 @@ Summary:
|
|||||||
have interest in adding more traditional CDC checks, please contact the
|
have interest in adding more traditional CDC checks, please contact the
|
||||||
authors.
|
authors.
|
||||||
|
|
||||||
|
.. option:: -CFLAGS <flags>
|
||||||
|
|
||||||
|
Add specified C compiler argument to the generated makefiles. For
|
||||||
|
multiple flags either pass them as a single argument with space
|
||||||
|
separators quoted in the shell (:command:`-CFLAGS "-a -b"`), or use
|
||||||
|
multiple -CFLAGS options (:command:`-CFLAGS -a -CFLAGS -b`).
|
||||||
|
|
||||||
|
When make is run on the generated makefile these will be passed to the
|
||||||
|
C++ compiler (g++/clang++/msvc++).
|
||||||
|
|
||||||
.. option:: --clk <signal-name>
|
.. option:: --clk <signal-name>
|
||||||
|
|
||||||
With :vlopt:`--clk`, the specified signal-name is taken as a root clock
|
With :vlopt:`--clk`, the specified signal-name is taken as a root clock
|
||||||
@@ -179,6 +190,11 @@ Summary:
|
|||||||
remove it from the combinatorial logic reevaluation checking code. This
|
remove it from the combinatorial logic reevaluation checking code. This
|
||||||
may greatly improve performance.
|
may greatly improve performance.
|
||||||
|
|
||||||
|
.. option:: --no-clk <signal-name>
|
||||||
|
|
||||||
|
Prevent the specified signal from being marked as clock. See
|
||||||
|
:vlopt:`--clk`.
|
||||||
|
|
||||||
.. option:: --compiler <compiler-name>
|
.. option:: --compiler <compiler-name>
|
||||||
|
|
||||||
Enables workarounds for the specified C++ compiler (list below).
|
Enables workarounds for the specified C++ compiler (list below).
|
||||||
@@ -250,8 +266,8 @@ Summary:
|
|||||||
generally is a less-optimized binary with symbols present (so GDB can be used on it).
|
generally is a less-optimized binary with symbols present (so GDB can be used on it).
|
||||||
* Enable debugging messages (equivalent to :vlopt:`--debugi 3 <--debugi>`).
|
* Enable debugging messages (equivalent to :vlopt:`--debugi 3 <--debugi>`).
|
||||||
* Enable internal assertions (equivalent to :vlopt:`--debug-check`).
|
* Enable internal assertions (equivalent to :vlopt:`--debug-check`).
|
||||||
* Enable intermediate form dump files (equivalent to :vlopt:`--dump-treei 3
|
* Enable intermediate form dump files (equivalent to :vlopt:`--dumpi-tree 3
|
||||||
<--dump-treei>`).
|
<--dumpi-tree>`).
|
||||||
* Leak to make node numbers unique (equivalent to :vlopt:`--debug-leak
|
* Leak to make node numbers unique (equivalent to :vlopt:`--debug-leak
|
||||||
<--no-debug-leak>`.
|
<--no-debug-leak>`.
|
||||||
* Call abort() instead of exit() if there are any errors (so GDB can see
|
* Call abort() instead of exit() if there are any errors (so GDB can see
|
||||||
@@ -288,6 +304,13 @@ Summary:
|
|||||||
<--debugi>`). Higher levels produce more detailed messages. See
|
<--debugi>`). Higher levels produce more detailed messages. See
|
||||||
:vlopt:`--debug` for other implications of enabling debug.
|
:vlopt:`--debug` for other implications of enabling debug.
|
||||||
|
|
||||||
|
.. option:: --no-decoration
|
||||||
|
|
||||||
|
When creating output Verilated code, minimize comments, white space,
|
||||||
|
symbol names and other decorative items, at the cost of greatly reduced
|
||||||
|
readability. This may assist C++ compile times. This will not typically
|
||||||
|
change the ultimate model's performance, but may in some cases.
|
||||||
|
|
||||||
.. option:: --default-language <value>
|
.. option:: --default-language <value>
|
||||||
|
|
||||||
Select the language to be used by default when first processing each
|
Select the language to be used by default when first processing each
|
||||||
@@ -335,26 +358,21 @@ Summary:
|
|||||||
|
|
||||||
touch foo.v ; verilator -E --dump-defines foo.v
|
touch foo.v ; verilator -E --dump-defines foo.v
|
||||||
|
|
||||||
|
.. option:: --dump-graph
|
||||||
|
|
||||||
|
Rarely needed. Enable dumping V3Graph .dot debug files with dumping
|
||||||
|
level 3. Before Verilator 4.228, :vlopt:`--dump-tree` used
|
||||||
|
to include this option.
|
||||||
|
|
||||||
.. option:: --dump-tree
|
.. option:: --dump-tree
|
||||||
|
|
||||||
Rarely needed. Enable writing .tree debug files with dumping level 3,
|
Rarely needed. Enable dumping Ast .tree debug files with dumping level 3,
|
||||||
which dumps the standard critical stages. For details on the format see
|
which dumps the standard critical stages. For details on the format see
|
||||||
the Verilator Internals manual. :vlopt:`--dump-tree` is enabled
|
the Verilator Internals manual. :vlopt:`--dump-tree` is enabled
|
||||||
automatically with :vlopt:`--debug`, so :vlopt:`--debug --no-dump-tree
|
automatically with :vlopt:`--debug`, so :vlopt:`--debug --no-dump-tree
|
||||||
<--dump-tree>` may be useful if the dump files are large and not
|
<--dump-tree>` may be useful if the dump files are large and not
|
||||||
desired.
|
desired.
|
||||||
|
|
||||||
.. option:: --dump-treei <level>
|
|
||||||
|
|
||||||
.. option:: --dump-treei-<srcfile> <level>
|
|
||||||
|
|
||||||
Rarely needed - for developer use. Set internal tree dumping level
|
|
||||||
globally to a specific dumping level or set the specified Verilator
|
|
||||||
source file to the specified tree dumping level (e.g.
|
|
||||||
:vlopt:`--dump-treei-V3Order 9 <--dump-treei>`). Level 0 disables dumps
|
|
||||||
and is equivalent to :vlopt:`--no-dump-tree <--dump-tree>`. Level 9
|
|
||||||
enables dumping of every stage.
|
|
||||||
|
|
||||||
.. option:: --dump-tree-addrids
|
.. option:: --dump-tree-addrids
|
||||||
|
|
||||||
Rarely needed - for developer use. Replace AST node addresses with
|
Rarely needed - for developer use. Replace AST node addresses with
|
||||||
@@ -364,6 +382,28 @@ Summary:
|
|||||||
by a newly allocated node after a node with the same address has been
|
by a newly allocated node after a node with the same address has been
|
||||||
dumped then freed.
|
dumped then freed.
|
||||||
|
|
||||||
|
.. option:: --dump-<srcfile>
|
||||||
|
|
||||||
|
Rarely needed - for developer use. Enable all dumping in the given
|
||||||
|
source file at level 3.
|
||||||
|
|
||||||
|
.. option:: --dumpi-graph <level>
|
||||||
|
|
||||||
|
Rarely needed - for developer use. Set internal V3Graph dumping level
|
||||||
|
globally to the specified value.
|
||||||
|
|
||||||
|
.. option:: --dumpi-tree <level>
|
||||||
|
|
||||||
|
Rarely needed - for developer use. Set internal Ast dumping level
|
||||||
|
globally to the specified value.
|
||||||
|
|
||||||
|
.. option:: --dumpi-<srcfile> <level>
|
||||||
|
|
||||||
|
Rarely needed - for developer use. Set the dumping level in the
|
||||||
|
specified Verilator source file to the specified value (e.g.
|
||||||
|
:vlopt:`--dumpi-V3Order 9`). Level 0 disables dumps and is equivalent
|
||||||
|
to :vlopt:`--no-dump-<srcfile>`. Level 9 enables dumping of everything.
|
||||||
|
|
||||||
.. option:: -E
|
.. option:: -E
|
||||||
|
|
||||||
Preprocess the source code, but do not compile, similar to C++
|
Preprocess the source code, but do not compile, similar to C++
|
||||||
@@ -431,6 +471,78 @@ Summary:
|
|||||||
flattening large designs may require significant CPU time, memory and
|
flattening large designs may require significant CPU time, memory and
|
||||||
storage.
|
storage.
|
||||||
|
|
||||||
|
.. option:: -fno-acyc-simp
|
||||||
|
|
||||||
|
.. option:: -fno-assemble
|
||||||
|
|
||||||
|
.. option:: -fno-case
|
||||||
|
|
||||||
|
.. option:: -fno-combine
|
||||||
|
|
||||||
|
.. option:: -fno-const
|
||||||
|
|
||||||
|
.. option:: -fno-const-bit-op-tree
|
||||||
|
|
||||||
|
.. option:: -fno-dedup
|
||||||
|
|
||||||
|
.. option:: -fno-expand
|
||||||
|
|
||||||
|
.. option:: -fno-gate
|
||||||
|
|
||||||
|
.. option:: -fno-inline
|
||||||
|
|
||||||
|
.. option:: -fno-life
|
||||||
|
|
||||||
|
.. option:: -fno-life-post
|
||||||
|
|
||||||
|
.. option:: -fno-localize
|
||||||
|
|
||||||
|
.. option:: -fno-merge-cond
|
||||||
|
|
||||||
|
.. option:: -fno-merge-cond-motion
|
||||||
|
|
||||||
|
.. option:: -fno-merge-const-pool
|
||||||
|
|
||||||
|
.. option:: -fno-reloop
|
||||||
|
|
||||||
|
.. option:: -fno-reorder
|
||||||
|
|
||||||
|
.. option:: -fno-split
|
||||||
|
|
||||||
|
.. option:: -fno-subst
|
||||||
|
|
||||||
|
.. option:: -fno-subst-const
|
||||||
|
|
||||||
|
.. option:: -fno-table
|
||||||
|
|
||||||
|
Rarely needed. Disables one of the internal optimization steps. These
|
||||||
|
are typically used only when recommended by a maintainer to help debug
|
||||||
|
or work around an issue.
|
||||||
|
|
||||||
|
.. option:: -future0 <option>
|
||||||
|
|
||||||
|
Rarely needed. Suppress an unknown Verilator option for an option that
|
||||||
|
takes no additional arguments. This is used to allow scripts written
|
||||||
|
with pragmas for a later version of Verilator to run under a older
|
||||||
|
version. e.g. :code:`-future0 option --option` would on older versions
|
||||||
|
that do not understand :code:`--option` or :code:`+option` suppress what
|
||||||
|
would otherwise be an invalid option error, and on newer versions that
|
||||||
|
implement :code:`--option`, :code:`-future0 option --option` would have
|
||||||
|
the :code:`-future0 option` ignored and the :code:`--option` would
|
||||||
|
function appropriately.
|
||||||
|
|
||||||
|
.. option:: -future1 <option>
|
||||||
|
|
||||||
|
Rarely needed. Suppress an unknown Verilator option for an option that
|
||||||
|
takes an additional argument. This is used to allow scripts written
|
||||||
|
with pragmas for a later version of Verilator to run under a older
|
||||||
|
version. e.g. :code:`-future1 option --option arg` would on older
|
||||||
|
versions that do not understand :code:`--option arg` or :code:`+option
|
||||||
|
arg` suppress what would otherwise be an invalid option error, and on
|
||||||
|
newer versions that implement :code:`--option arg`, :code:`-future1
|
||||||
|
option --option arg` would have the :code:`-future1 option` ignored and
|
||||||
|
the :code:`--option arg` would function appropriately.
|
||||||
|
|
||||||
.. option:: -G<name>=<value>
|
.. option:: -G<name>=<value>
|
||||||
|
|
||||||
Overwrites the given parameter of the toplevel module. The value is
|
Overwrites the given parameter of the toplevel module. The value is
|
||||||
@@ -531,26 +643,10 @@ Summary:
|
|||||||
|
|
||||||
.. option:: -j [<value>]
|
.. option:: -j [<value>]
|
||||||
|
|
||||||
Specify the level of parallelism for :vlopt:`--build`. The <value> must
|
Specify the level of parallelism for :vlopt:`--build` if
|
||||||
be a positive integer specifying the maximum number of parallel build
|
:vlopt:`--build-jobs` isn't provided. If zero, uses the number of threads
|
||||||
jobs, or can be omitted. When <value> is omitted, the build will not try
|
in the current hardware. Otherwise, the <value> must be a positive
|
||||||
to limit the number of parallel build jobs but attempt to execute all
|
integer specifying the maximum number of parallel build jobs.
|
||||||
independent build steps in parallel.
|
|
||||||
|
|
||||||
.. option:: -LDFLAGS <flags>
|
|
||||||
|
|
||||||
Add specified C linker arguments to the generated makefiles. For multiple
|
|
||||||
flags either pass them as a single argument with space separators quoted
|
|
||||||
in the shell (``-LDFLAGS "-a -b"``), or use multiple -LDFLAGS arguments
|
|
||||||
(``-LDFLAGS -a -LDFLAGS -b``).
|
|
||||||
|
|
||||||
When make is run on the generated makefile these will be passed to the
|
|
||||||
C++ linker (ld) **after** the primary file being linked. This flag is
|
|
||||||
called :vlopt:`-LDFLAGS` as that's the traditional name in simulators;
|
|
||||||
it's would have been better called LDLIBS as that's the Makefile
|
|
||||||
variable it controls. (In Make, LDFLAGS is before the first object,
|
|
||||||
LDLIBS after. -L libraries need to be in the Make variable LDLIBS, not
|
|
||||||
LDFLAGS.)
|
|
||||||
|
|
||||||
.. option:: --l2-name <value>
|
.. option:: --l2-name <value>
|
||||||
|
|
||||||
@@ -568,12 +664,20 @@ Summary:
|
|||||||
A synonym for :vlopt:`--default-language`, for compatibility with other
|
A synonym for :vlopt:`--default-language`, for compatibility with other
|
||||||
tools and earlier versions of Verilator.
|
tools and earlier versions of Verilator.
|
||||||
|
|
||||||
.. option:: +libext+<ext>[+<ext>][...]
|
.. option:: -LDFLAGS <flags>
|
||||||
|
|
||||||
Specify the extensions that should be used for finding modules. If for
|
Add specified C linker arguments to the generated makefiles. For multiple
|
||||||
example module "my" is referenced, look in :file:`my.<ext>`. Note
|
flags either pass them as a single argument with space separators quoted
|
||||||
"+libext+" is fairly standard across Verilog tools. Defaults to
|
in the shell (``-LDFLAGS "-a -b"``), or use multiple -LDFLAGS arguments
|
||||||
".v+.sv".
|
(``-LDFLAGS -a -LDFLAGS -b``).
|
||||||
|
|
||||||
|
When make is run on the generated makefile these will be passed to the
|
||||||
|
C++ linker (ld) **after** the primary file being linked. This flag is
|
||||||
|
called :vlopt:`-LDFLAGS` as that's the traditional name in simulators;
|
||||||
|
it's would have been better called LDLIBS as that's the Makefile
|
||||||
|
variable it controls. (In Make, LDFLAGS is before the first object,
|
||||||
|
LDLIBS after. -L libraries need to be in the Make variable LDLIBS, not
|
||||||
|
LDFLAGS.)
|
||||||
|
|
||||||
.. option:: --lib-create <name>
|
.. option:: --lib-create <name>
|
||||||
|
|
||||||
@@ -592,6 +696,13 @@ Summary:
|
|||||||
|
|
||||||
See also :vlopt:`--protect-lib`.
|
See also :vlopt:`--protect-lib`.
|
||||||
|
|
||||||
|
.. option:: +libext+<ext>[+<ext>][...]
|
||||||
|
|
||||||
|
Specify the extensions that should be used for finding modules. If for
|
||||||
|
example module "my" is referenced, look in :file:`my.<ext>`. Note
|
||||||
|
"+libext+" is fairly standard across Verilog tools. Defaults to
|
||||||
|
".v+.sv".
|
||||||
|
|
||||||
.. option:: --lint-only
|
.. option:: --lint-only
|
||||||
|
|
||||||
Check the files for lint violations only, do not create any other
|
Check the files for lint violations only, do not create any other
|
||||||
@@ -625,22 +736,20 @@ Summary:
|
|||||||
(e.g. ``-MAKEFLAGS -l -MAKEFLAGS -k``). Use of this option should not be
|
(e.g. ``-MAKEFLAGS -l -MAKEFLAGS -k``). Use of this option should not be
|
||||||
required for simple builds using the host toolchain.
|
required for simple builds using the host toolchain.
|
||||||
|
|
||||||
|
.. option:: --main
|
||||||
|
|
||||||
|
Generates a top-level C++ main() file that supports parsing arguments,
|
||||||
|
but does not drive any inputs. This is sufficient to use for top-level
|
||||||
|
SystemVerilog designs that has no inputs, and does not need the C++ to
|
||||||
|
do any time advancement.
|
||||||
|
|
||||||
|
Implies :vlopt:`--cc` if no other output mode was provided.
|
||||||
|
|
||||||
.. option:: --max-num-width <value>
|
.. option:: --max-num-width <value>
|
||||||
|
|
||||||
Set the maximum number literal width (e.g. in 1024'd22 this it the
|
Set the maximum number literal width (e.g. in 1024'd22 this it the
|
||||||
1024). Defaults to 64K.
|
1024). Defaults to 64K.
|
||||||
|
|
||||||
.. option:: --MMD =item --no-MMD
|
|
||||||
|
|
||||||
Enable/disable creation of .d dependency files, used for make dependency
|
|
||||||
detection, similar to gcc -MMD option. By default this option is
|
|
||||||
enabled for :vlopt:`--cc` or :vlopt:`--sc` modes.
|
|
||||||
|
|
||||||
.. option:: --MP
|
|
||||||
|
|
||||||
When creating .d dependency files with :vlopt:`--MMD` option, make phony
|
|
||||||
targets. Similar to :command:`gcc -MP` option.
|
|
||||||
|
|
||||||
.. option:: --Mdir <directory>
|
.. option:: --Mdir <directory>
|
||||||
|
|
||||||
Specifies the name of the Make object directory. All generated files
|
Specifies the name of the Make object directory. All generated files
|
||||||
@@ -648,40 +757,23 @@ Summary:
|
|||||||
The directory is created if it does not exist and the parent directories
|
The directory is created if it does not exist and the parent directories
|
||||||
exist; otherwise manually create the Mdir before calling Verilator.
|
exist; otherwise manually create the Mdir before calling Verilator.
|
||||||
|
|
||||||
.. option:: --no-merge-const-pool
|
.. option:: --MMD
|
||||||
|
|
||||||
Rarely needed. In order to minimize cache footprint, values of different
|
.. option:: --no-MMD
|
||||||
data type, that are yet emitted identically in C++ are merged in the
|
|
||||||
constant pool. This option disables this and causes every constant pool
|
Enable/disable creation of .d dependency files, used for make dependency
|
||||||
entry with a distinct data type to be emitted separately.
|
detection, similar to gcc -MMD option. By default this option is
|
||||||
|
enabled for :vlopt:`--cc` or :vlopt:`--sc` modes.
|
||||||
|
|
||||||
.. option:: --mod-prefix <topname>
|
.. option:: --mod-prefix <topname>
|
||||||
|
|
||||||
Specifies the name to prepend to all lower level classes. Defaults to
|
Specifies the name to prepend to all lower level classes. Defaults to
|
||||||
the same as :vlopt:`--prefix`.
|
the same as :vlopt:`--prefix`.
|
||||||
|
|
||||||
.. option:: --no-clk <signal-name>
|
.. option:: --MP
|
||||||
|
|
||||||
Prevent the specified signal from being marked as clock. See
|
When creating .d dependency files with :vlopt:`--MMD` option, make phony
|
||||||
:vlopt:`--clk`.
|
targets. Similar to :command:`gcc -MP` option.
|
||||||
|
|
||||||
.. option:: --no-decoration
|
|
||||||
|
|
||||||
When creating output Verilated code, minimize comments, white space,
|
|
||||||
symbol names and other decorative items, at the cost of greatly reduced
|
|
||||||
readability. This may assist C++ compile times. This will not typically
|
|
||||||
change the ultimate model's performance, but may in some cases.
|
|
||||||
|
|
||||||
.. option:: --no-pins64
|
|
||||||
|
|
||||||
Backward compatible alias for :vlopt:`--pins-bv 33 <--pins-bv>`.
|
|
||||||
|
|
||||||
.. option:: --no-skip-identical =item --skip-identical
|
|
||||||
|
|
||||||
Rarely needed. Disables or enables skipping execution of Verilator if
|
|
||||||
all source files are identical, and all output files exist with newer
|
|
||||||
dates. By default this option is enabled for :vlopt:`--cc` or
|
|
||||||
:vlopt:`--sc` modes only.
|
|
||||||
|
|
||||||
.. option:: +notimingchecks
|
.. option:: +notimingchecks
|
||||||
|
|
||||||
@@ -703,9 +795,9 @@ Summary:
|
|||||||
|
|
||||||
Rarely needed. Enables or disables a specific optimizations, with the
|
Rarely needed. Enables or disables a specific optimizations, with the
|
||||||
optimization selected based on the letter passed. A lowercase letter
|
optimization selected based on the letter passed. A lowercase letter
|
||||||
disables an optimization, an upper case letter enables it. This is
|
disables an optimization, an upper case letter enables it. This option
|
||||||
intended for debugging use only; see the source code for
|
is deprecated and the various `-f<optimization>` arguments should be
|
||||||
version-dependent mappings of optimizations to -O letters.
|
used instead.
|
||||||
|
|
||||||
.. option:: -o <executable>
|
.. option:: -o <executable>
|
||||||
|
|
||||||
@@ -760,15 +852,10 @@ Summary:
|
|||||||
With :vlopt:`-E`, disable generation of :code:`&96;line` markers and
|
With :vlopt:`-E`, disable generation of :code:`&96;line` markers and
|
||||||
blank lines, similar to :command:`gcc -P`.
|
blank lines, similar to :command:`gcc -P`.
|
||||||
|
|
||||||
.. option:: --pins64
|
|
||||||
|
|
||||||
Backward compatible alias for :vlopt:`--pins-bv 65 <--pins-bv>`. Note
|
|
||||||
that's a 65, not a 64.
|
|
||||||
|
|
||||||
.. option:: --pins-bv <width>
|
.. option:: --pins-bv <width>
|
||||||
|
|
||||||
Specifies SystemC inputs/outputs of greater than or equal to <width>
|
Specifies SystemC inputs/outputs of greater than or equal to <width>
|
||||||
bits wide should use sc_bv's instead of uint32/vluint64_t's. The
|
bits wide should use sc_bv's instead of uint32/uint64_t's. The
|
||||||
default is "--pins-bv 65", and the value must be less than or equal
|
default is "--pins-bv 65", and the value must be less than or equal
|
||||||
to 65. Versions before Verilator 3.671 defaulted to "--pins-bv 33".
|
to 65. Versions before Verilator 3.671 defaulted to "--pins-bv 33".
|
||||||
The more sc_bv is used, the worse for performance. Use the
|
The more sc_bv is used, the worse for performance. Use the
|
||||||
@@ -797,6 +884,15 @@ Summary:
|
|||||||
of uint32_t. Likewise pins of width 9-16 will use uint16_t instead of
|
of uint32_t. Likewise pins of width 9-16 will use uint16_t instead of
|
||||||
uint32_t.
|
uint32_t.
|
||||||
|
|
||||||
|
.. option:: --pins64
|
||||||
|
|
||||||
|
Backward compatible alias for :vlopt:`--pins-bv 65 <--pins-bv>`. Note
|
||||||
|
that's a 65, not a 64.
|
||||||
|
|
||||||
|
.. option:: --no-pins64
|
||||||
|
|
||||||
|
Backward compatible alias for :vlopt:`--pins-bv 33 <--pins-bv>`.
|
||||||
|
|
||||||
.. option:: --pipe-filter <command>
|
.. option:: --pipe-filter <command>
|
||||||
|
|
||||||
Rarely needed. Verilator will spawn the specified command as a
|
Rarely needed. Verilator will spawn the specified command as a
|
||||||
@@ -826,6 +922,11 @@ Summary:
|
|||||||
prepended to the name of the :vlopt:`--top` option, or V prepended to
|
prepended to the name of the :vlopt:`--top` option, or V prepended to
|
||||||
the first Verilog filename passed on the command line.
|
the first Verilog filename passed on the command line.
|
||||||
|
|
||||||
|
.. option:: --private
|
||||||
|
|
||||||
|
Opposite of :vlopt:`--public`. Is the default; this option exists for
|
||||||
|
backwards compatibility.
|
||||||
|
|
||||||
.. option:: --prof-c
|
.. option:: --prof-c
|
||||||
|
|
||||||
When compiling the C++ code, enable the compiler's profiling flag
|
When compiling the C++ code, enable the compiler's profiling flag
|
||||||
@@ -845,27 +946,19 @@ Summary:
|
|||||||
|
|
||||||
Using :vlopt:`--prof-cfuncs` also enables :vlopt:`--prof-c`.
|
Using :vlopt:`--prof-cfuncs` also enables :vlopt:`--prof-c`.
|
||||||
|
|
||||||
|
.. option:: --prof-exec
|
||||||
|
|
||||||
|
Enable collection of execution trace, that can be converted into a gantt
|
||||||
|
chart with verilator_gantt See :ref:`Execution Profiling`.
|
||||||
|
|
||||||
|
.. option:: --prof-pgo
|
||||||
|
|
||||||
|
Enable collection of profiling data for profile guided Verilation. Currently
|
||||||
|
this is only useful with :vlopt:`--threads`. See :ref:`Thread PGO`.
|
||||||
|
|
||||||
.. option:: --prof-threads
|
.. option:: --prof-threads
|
||||||
|
|
||||||
Enable gantt chart data collection for threaded builds. See :ref:`Thread
|
Deprecated. Same as --prof-exec and --prof-pgo together.
|
||||||
Profiling` and :ref:`Thread PGO`.
|
|
||||||
|
|
||||||
.. option:: --protect-key <key>
|
|
||||||
|
|
||||||
Specifies the private key for :vlopt:`--protect-ids`. For best security
|
|
||||||
this key should be 16 or more random bytes, a reasonable secure choice
|
|
||||||
is the output of :command:`verilator --generate-key` . Typically, a key
|
|
||||||
would be created by the user once for a given protected design library,
|
|
||||||
then every Verilator run for subsequent versions of that library would
|
|
||||||
be passed the same :vlopt:`--protect-key`. Thus, if the input Verilog is
|
|
||||||
similar between library versions (Verilator runs), the Verilated code
|
|
||||||
will likewise be mostly similar.
|
|
||||||
|
|
||||||
If :vlopt:`--protect-key` is not specified and a key is needed,
|
|
||||||
Verilator will generate a new key for every Verilator run. As the key is
|
|
||||||
not saved, this is best for security, but means every Verilator run will
|
|
||||||
give vastly different output even for identical input, perhaps harming
|
|
||||||
compile times (and certainly thrashing any "ccache").
|
|
||||||
|
|
||||||
.. option:: --protect-ids
|
.. option:: --protect-ids
|
||||||
|
|
||||||
@@ -884,9 +977,26 @@ Summary:
|
|||||||
|
|
||||||
Using DPI imports/exports is allowed and generally relatively safe in
|
Using DPI imports/exports is allowed and generally relatively safe in
|
||||||
terms of information disclosed, which is limited to the DPI function
|
terms of information disclosed, which is limited to the DPI function
|
||||||
prototyptes. Use of the VPI is not recommended as many design details
|
prototypes. Use of the VPI is not recommended as many design details
|
||||||
may be exposed, and an INSECURE warning will be issued.
|
may be exposed, and an INSECURE warning will be issued.
|
||||||
|
|
||||||
|
.. option:: --protect-key <key>
|
||||||
|
|
||||||
|
Specifies the private key for :vlopt:`--protect-ids`. For best security
|
||||||
|
this key should be 16 or more random bytes, a reasonable secure choice
|
||||||
|
is the output of :command:`verilator --generate-key` . Typically, a key
|
||||||
|
would be created by the user once for a given protected design library,
|
||||||
|
then every Verilator run for subsequent versions of that library would
|
||||||
|
be passed the same :vlopt:`--protect-key`. Thus, if the input Verilog is
|
||||||
|
similar between library versions (Verilator runs), the Verilated code
|
||||||
|
will likewise be mostly similar.
|
||||||
|
|
||||||
|
If :vlopt:`--protect-key` is not specified and a key is needed,
|
||||||
|
Verilator will generate a new key for every Verilator run. As the key is
|
||||||
|
not saved, this is best for security, but means every Verilator run will
|
||||||
|
give vastly different output even for identical input, perhaps harming
|
||||||
|
compile times (and certainly thrashing any "ccache").
|
||||||
|
|
||||||
.. option:: --protect-lib <name>
|
.. option:: --protect-lib <name>
|
||||||
|
|
||||||
Produces a DPI library similar to :vlopt:`--lib-create`, but hides
|
Produces a DPI library similar to :vlopt:`--lib-create`, but hides
|
||||||
@@ -898,11 +1008,6 @@ Summary:
|
|||||||
in the distribution for a demonstration of how to build and use the DPI
|
in the distribution for a demonstration of how to build and use the DPI
|
||||||
library.
|
library.
|
||||||
|
|
||||||
.. option:: --private
|
|
||||||
|
|
||||||
Opposite of :vlopt:`--public`. Is the default; this option exists for
|
|
||||||
backwards compatibility.
|
|
||||||
|
|
||||||
.. option:: --public
|
.. option:: --public
|
||||||
|
|
||||||
This is only for historical debug use. Using it may result in
|
This is only for historical debug use. Using it may result in
|
||||||
@@ -995,6 +1100,15 @@ Summary:
|
|||||||
|
|
||||||
Specifies SystemC output mode; see also :vlopt:`--cc` option.
|
Specifies SystemC output mode; see also :vlopt:`--cc` option.
|
||||||
|
|
||||||
|
.. option:: --skip-identical
|
||||||
|
|
||||||
|
.. option:: --no-skip-identical
|
||||||
|
|
||||||
|
Rarely needed. Disables or enables skipping execution of Verilator if
|
||||||
|
all source files are identical, and all output files exist with newer
|
||||||
|
dates. By default this option is enabled for :vlopt:`--cc` or
|
||||||
|
:vlopt:`--sc` modes only.
|
||||||
|
|
||||||
.. option:: --stats
|
.. option:: --stats
|
||||||
|
|
||||||
Creates a dump file with statistics on the design in
|
Creates a dump file with statistics on the design in
|
||||||
@@ -1032,7 +1146,8 @@ Summary:
|
|||||||
is not thread safe. With "--threads 1", the generated model is single
|
is not thread safe. With "--threads 1", the generated model is single
|
||||||
threaded but may run in a multithreaded environment. With "--threads N",
|
threaded but may run in a multithreaded environment. With "--threads N",
|
||||||
where N >= 2, the model is generated to run multithreaded on up to N
|
where N >= 2, the model is generated to run multithreaded on up to N
|
||||||
threads. See :ref:`Multithreading`.
|
threads. See :ref:`Multithreading`. This option also applies to
|
||||||
|
:vlopt:`--trace` (but not :vlopt:`--trace-fst`).
|
||||||
|
|
||||||
.. option:: --threads-dpi all
|
.. option:: --threads-dpi all
|
||||||
|
|
||||||
@@ -1110,7 +1225,8 @@ Summary:
|
|||||||
Having tracing compiled in may result in some small performance losses,
|
Having tracing compiled in may result in some small performance losses,
|
||||||
even when tracing is not turned on during model execution.
|
even when tracing is not turned on during model execution.
|
||||||
|
|
||||||
See also :vlopt:`--trace-threads` option.
|
When using :vlopt:`--threads`, VCD tracing is parallelized, using the
|
||||||
|
same number of threads as passed to :vlopt:`--threads`.
|
||||||
|
|
||||||
.. option:: --trace-coverage
|
.. option:: --trace-coverage
|
||||||
|
|
||||||
@@ -1164,12 +1280,12 @@ Summary:
|
|||||||
.. option:: --trace-threads *threads*
|
.. option:: --trace-threads *threads*
|
||||||
|
|
||||||
Enable waveform tracing using separate threads. This is typically faster
|
Enable waveform tracing using separate threads. This is typically faster
|
||||||
in simulation runtime but uses more total compute. This option is
|
in simulation runtime but uses more total compute. This option only
|
||||||
independent of, and works with, both :vlopt:`--trace` and
|
applies to :vlopt:`--trace-fst`. FST tracing can utilize at most
|
||||||
:vlopt:`--trace-fst`. Different trace formats can take advantage of
|
"--trace-threads 2". This overrides :vlopt:`--no-threads`.
|
||||||
more trace threads to varying degrees. Currently VCD tracing can utilize
|
|
||||||
at most "--trace-threads 1", and FST tracing can utilize at most
|
This option is accepted, but has absolutely no effect with
|
||||||
"--trace-threads 2". This overrides :vlopt:`--no-threads` .
|
:vlopt:`--trace`, which respects :vlopt:`--threads` instead.
|
||||||
|
|
||||||
.. option:: --trace-underscore
|
.. option:: --trace-underscore
|
||||||
|
|
||||||
@@ -1364,9 +1480,10 @@ Summary:
|
|||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
This option applies only to values which are explicitly written as X
|
This option applies only to values which are explicitly written as X
|
||||||
in the Verilog source code. Initial values of clocks are set to 0
|
in modules (not classes) in the Verilog source code. Initial values
|
||||||
unless `--x-initial-edge` is specified. Initial values of all other
|
of clocks are set to 0 unless `--x-initial-edge` is
|
||||||
state holding variables are controlled with `--x-initial`.
|
specified. Initial values of all other state holding variables are
|
||||||
|
controlled with `--x-initial`.
|
||||||
|
|
||||||
.. option:: --x-initial 0
|
.. option:: --x-initial 0
|
||||||
|
|
||||||
@@ -1513,7 +1630,7 @@ The grammar of configuration commands is as follows:
|
|||||||
.. option:: no_clocker -module "<modulename>" [-function "<funcname>"] -var "<signame>"
|
.. option:: no_clocker -module "<modulename>" [-function "<funcname>"] -var "<signame>"
|
||||||
|
|
||||||
Indicates that the signal is used as clock or not. This information is
|
Indicates that the signal is used as clock or not. This information is
|
||||||
used by Verilator to mark the signal and any derrived signals as
|
used by Verilator to mark the signal and any derived signals as
|
||||||
clocker. See :vlopt:`--clk`.
|
clocker. See :vlopt:`--clk`.
|
||||||
|
|
||||||
Same as :option:`/*verilator&32;clocker*/` metacomment.
|
Same as :option:`/*verilator&32;clocker*/` metacomment.
|
||||||
@@ -1528,6 +1645,14 @@ The grammar of configuration commands is as follows:
|
|||||||
|
|
||||||
Same as :option:`/*verilator&32;coverage_block_off*/` metacomment.
|
Same as :option:`/*verilator&32;coverage_block_off*/` metacomment.
|
||||||
|
|
||||||
|
.. option:: forceable -module "<modulename>" -var "<signame>"
|
||||||
|
|
||||||
|
Generate public `<signame>__VforceEn` and `<signame>__VforceVal` signals
|
||||||
|
that can be used to force/release a signal from C++ code. The force control
|
||||||
|
signals are created as :option:`public_flat` signals.
|
||||||
|
|
||||||
|
Same as :option:`/*verilator&32;forceable*/` metacomment.
|
||||||
|
|
||||||
.. option:: full_case -file "<filename>" -lines <lineno>
|
.. option:: full_case -file "<filename>" -lines <lineno>
|
||||||
|
|
||||||
.. option:: parallel_case -file "<filename>" -lines <lineno>
|
.. option:: parallel_case -file "<filename>" -lines <lineno>
|
||||||
@@ -1629,7 +1754,7 @@ The grammar of configuration commands is as follows:
|
|||||||
.. option:: sc_bv -module "<modulename>" [-function "<funcname>"] -var "<signame>"
|
.. option:: sc_bv -module "<modulename>" [-function "<funcname>"] -var "<signame>"
|
||||||
|
|
||||||
Sets the port to be of :code:`sc_bv<{width}>` type, instead of bool,
|
Sets the port to be of :code:`sc_bv<{width}>` type, instead of bool,
|
||||||
vluint32_t or vluint64_t. Same as :option:`/*verilator&32;sc_bv*/`
|
uint32_t or uint64_t. Same as :option:`/*verilator&32;sc_bv*/`
|
||||||
metacomment.
|
metacomment.
|
||||||
|
|
||||||
.. option:: sformat [-module "<modulename>"] [-task "<taskname>"] -var "<signame>"
|
.. option:: sformat [-module "<modulename>"] [-task "<taskname>"] -var "<signame>"
|
||||||
@@ -1658,9 +1783,28 @@ The grammar of configuration commands is as follows:
|
|||||||
|
|
||||||
.. option:: tracing_off [-file "<filename>" [-lines <line> [ - <line> ]]]
|
.. option:: tracing_off [-file "<filename>" [-lines <line> [ - <line> ]]]
|
||||||
|
|
||||||
Enable/disable waveform tracing for all future signals declared in the
|
.. option:: tracing_on [-scope "<scopename>" [-levels <levels> ]]
|
||||||
specified filename (or wildcard with '\*' or '?', or all files if
|
|
||||||
omitted) and range of line numbers (or all lines if omitted).
|
|
||||||
|
|
||||||
For tracing_off, instances below any module in the files/ranges
|
.. option:: tracing_off [-scope "<scopename>" [-levels <levels> ]]
|
||||||
specified will also not be traced.
|
|
||||||
|
Enable/disable waveform tracing for all future signals declared in
|
||||||
|
all files.
|
||||||
|
|
||||||
|
With -file, enable/disable waveform tracing in the specified
|
||||||
|
filename (or wildcard with '\*' or '?'), and -line range of line
|
||||||
|
numbers (or all lines if omitted).
|
||||||
|
|
||||||
|
For tracing_off with -file, instances below any module in the
|
||||||
|
files/ranges specified will also not be traced. To overcome this
|
||||||
|
feature, use tracing_on on the upper module declaration and on any
|
||||||
|
cells, or use the -scope flavor of the command.
|
||||||
|
|
||||||
|
With -scope enable/disable waveform tracing for the specified scope (or
|
||||||
|
wildcard with '\*' or '?'), and optional --levels number of levels
|
||||||
|
below. These controls only take place after other file/line/module
|
||||||
|
based controls have indicated the signal should be traced.
|
||||||
|
|
||||||
|
With -levels (used with -scope), the number of levels below that
|
||||||
|
scope which the rule is to match, where 0 means all levels below, 1
|
||||||
|
the exact level as the provided scope, and 2 meaning an additional
|
||||||
|
level of children below the provided scope, etc.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
verilator_coverage
|
verilator_coverage
|
||||||
@@ -67,7 +67,7 @@ which have low coverage are written to the output directory.
|
|||||||
|
|
||||||
Specifies if the coverage point does not include the count number of
|
Specifies if the coverage point does not include the count number of
|
||||||
coverage hits, then the coverage point will be considered above the
|
coverage hits, then the coverage point will be considered above the
|
||||||
threashold, and the coverage report will put a "%" to indicate the coverage
|
threshold, and the coverage report will put a "%" to indicate the coverage
|
||||||
is not sufficient. Defaults to 10.
|
is not sufficient. Defaults to 10.
|
||||||
|
|
||||||
.. option:: --help
|
.. option:: --help
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
verilator_gantt
|
verilator_gantt
|
||||||
@@ -13,7 +13,7 @@ For an overview of use of verilator_gantt, see :ref:`Profiling`.
|
|||||||
Gantt Chart VCD
|
Gantt Chart VCD
|
||||||
---------------
|
---------------
|
||||||
|
|
||||||
Verilated_gnatt creates a value change dump (VCD) format dump file which
|
Verilated_gantt creates a value change dump (VCD) format dump file which
|
||||||
may be viewed in a waveform viewer (e.g. C<GTKWave>):
|
may be viewed in a waveform viewer (e.g. C<GTKWave>):
|
||||||
|
|
||||||
.. figure:: figures/fig_gantt_min.png
|
.. figure:: figures/fig_gantt_min.png
|
||||||
@@ -72,7 +72,7 @@ verilator_gantt Arguments
|
|||||||
|
|
||||||
.. option:: <filename>
|
.. option:: <filename>
|
||||||
|
|
||||||
The filename to read data from, defaults to "profile_threads.dat".
|
The filename to read data from, defaults to "profile_exec.dat".
|
||||||
|
|
||||||
.. option:: --help
|
.. option:: --help
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
verilator_profcfunc
|
verilator_profcfunc
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
*********************************
|
*********************************
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
*******************
|
*******************
|
||||||
@@ -185,7 +185,7 @@ or "`ifdef`"'s may break other tools.
|
|||||||
.. option:: /*verilator&32;no_clocker*/
|
.. option:: /*verilator&32;no_clocker*/
|
||||||
|
|
||||||
Specifies that the signal is used as clock or not. This information is
|
Specifies that the signal is used as clock or not. This information is
|
||||||
used by Verilator to mark the signal and any derrived signals as
|
used by Verilator to mark the signal and any derived signals as
|
||||||
clocker. See :vlopt:`--clk`.
|
clocker. See :vlopt:`--clk`.
|
||||||
|
|
||||||
Same as :option:`clocker` and :option:`no_clocker` in configuration
|
Same as :option:`clocker` and :option:`no_clocker` in configuration
|
||||||
@@ -209,6 +209,20 @@ or "`ifdef`"'s may break other tools.
|
|||||||
(if appropriate :vlopt:`--coverage` flags are passed) after being
|
(if appropriate :vlopt:`--coverage` flags are passed) after being
|
||||||
disabled earlier with :option:`/*verilator&32;coverage_off*/`.
|
disabled earlier with :option:`/*verilator&32;coverage_off*/`.
|
||||||
|
|
||||||
|
.. option:: /*verilator&32;forceable*/
|
||||||
|
|
||||||
|
Specifies that the signal (net or variable) should be made forceable from
|
||||||
|
C++ code by generating public `<signame>__VforceEn` and
|
||||||
|
`<signame>__VforceVal` signals The force control signals are created as
|
||||||
|
:option:`public_flat` signals.
|
||||||
|
|
||||||
|
To force a marked signal from C++, set the corresponding `__VforceVal`
|
||||||
|
variable to the desired value, and the `__VforceEn` signal to the bit-mask
|
||||||
|
indicating which bits of the signal to force. To force all bits of the
|
||||||
|
target signal, set `__VforceEn` to all ones. To release the signal (or part
|
||||||
|
thereof), set appropriate bits of the `__VforceEn` signal to zero.
|
||||||
|
|
||||||
|
Same as :option:`forceable` in configuration files.
|
||||||
|
|
||||||
.. _verilator_hier_block:
|
.. _verilator_hier_block:
|
||||||
|
|
||||||
@@ -431,7 +445,7 @@ or "`ifdef`"'s may break other tools.
|
|||||||
.. option:: /*verilator&32;sc_bv*/
|
.. option:: /*verilator&32;sc_bv*/
|
||||||
|
|
||||||
Used after a port declaration. It sets the port to be of
|
Used after a port declaration. It sets the port to be of
|
||||||
:code:`sc_bv<{width}>` type, instead of bool, vluint32_t or vluint64_t.
|
:code:`sc_bv<{width}>` type, instead of bool, uint32_t or uint64_t.
|
||||||
This may be useful if the port width is parameterized and the
|
This may be useful if the port width is parameterized and the
|
||||||
instantiating C++ code wants to always have a sc_bv so it can accept any
|
instantiating C++ code wants to always have a sc_bv so it can accept any
|
||||||
width. In general you should avoid using this attribute when not
|
width. In general you should avoid using this attribute when not
|
||||||
|
|||||||
+39
-23
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
******************************
|
******************************
|
||||||
@@ -37,15 +37,15 @@ Does Verilator run under Windows?
|
|||||||
|
|
||||||
Yes, ideally run Ubuntu under Windows Subsystem for Linux (WSL2).
|
Yes, ideally run Ubuntu under Windows Subsystem for Linux (WSL2).
|
||||||
Alternatively use Cygwin, though this tends to be slower and is not
|
Alternatively use Cygwin, though this tends to be slower and is not
|
||||||
regurally tested. Verilated output also compiles under Microsoft Visual
|
regularly tested. Verilated output also compiles under Microsoft Visual
|
||||||
C++, but this is also not regurally tested.
|
C++, but this is also not regularly tested.
|
||||||
|
|
||||||
|
|
||||||
Can you provide binaries?
|
Can you provide binaries?
|
||||||
"""""""""""""""""""""""""
|
"""""""""""""""""""""""""
|
||||||
|
|
||||||
You can install Verilator via the system package manager (apt, yum, etc.)
|
You can install Verilator via the system package manager (apt, yum, etc.)
|
||||||
on many Linux distributions, including Debian, Ubuntu, SuSE, RedHat, and
|
on many Linux distributions, including Debian, Ubuntu, SuSE, Red Hat, and
|
||||||
others. These packages are provided by the Linux distributions and
|
others. These packages are provided by the Linux distributions and
|
||||||
generally will lag the version of the mainline Verilator repository. If no
|
generally will lag the version of the mainline Verilator repository. If no
|
||||||
binary package is available for your distribution, how about you set one
|
binary package is available for your distribution, how about you set one
|
||||||
@@ -72,23 +72,38 @@ a good thing for getting working silicon.
|
|||||||
Will Verilator output remain under my own license/copyright?
|
Will Verilator output remain under my own license/copyright?
|
||||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
Yes, it's just like using GCC on your programs; this is why Verilator uses
|
Your SystemVerilog, VPI/DPI, or main() C++ code remains under your own license.
|
||||||
the "GNU **Lesser** Public License Version 3" instead of the more typical
|
|
||||||
"GNU Public License". See the licenses for details, but in brief, if you
|
It's just like how using GCC on your programs does not change the copyright
|
||||||
change Verilator itself or the header files Verilator includes, you must
|
of your program; this is why Verilator uses the "GNU **Lesser** Public
|
||||||
make the source code available under the GNU Lesser Public License.
|
License Version 3" instead of the more typical "GNU Public License". See
|
||||||
However, Verilator output (the Verilated code) only "include"s the licensed
|
the licenses for details.
|
||||||
files, and so you are **not** required to open-source release any output
|
|
||||||
from Verilator.
|
Some examples:
|
||||||
|
|
||||||
|
* Any SystemVerilog or other input fed into Verilator remain your own.
|
||||||
|
|
||||||
|
* Any of your VPI/DPI C++ routines that Verilator calls remain your own.
|
||||||
|
|
||||||
|
* Any of your main() C++ code that calls into Verilator remain your own.
|
||||||
|
|
||||||
|
* If you change Verilator itself, for example changing or adding a file
|
||||||
|
under the src/ directory in the repository, you must make the source code
|
||||||
|
available under the GNU Lesser Public License.
|
||||||
|
|
||||||
|
* If you change a header Verilator provides, for example under include/ in
|
||||||
|
the repository, you must make the source code available under the GNU
|
||||||
|
Lesser Public License.
|
||||||
|
|
||||||
You also have the option of using the Perl Artistic License, which again
|
You also have the option of using the Perl Artistic License, which again
|
||||||
does not require you to release your Verilog or generated code, and also
|
does not require you to release your Verilog, C++, or generated code. This
|
||||||
allows you to modify Verilator for internal use without distributing the
|
license also allows you to modify Verilator for internal use without
|
||||||
modified version. But please contribute back to the community!
|
distributing the modified version. But please contribute back to the
|
||||||
|
community!
|
||||||
|
|
||||||
One limit is that you cannot under either license release a closed-source
|
Under both license you can offer a commercial product that is based on
|
||||||
Verilog simulation product incorporating Verilator. That is you can have a
|
Verilator either directly or embedded within. However under both licenses,
|
||||||
commercial product, but must make the source code available.
|
any changes you make to Verilator for such a product must be open sourced.
|
||||||
|
|
||||||
As is standard with Open Source, contributions back to Verilator will be
|
As is standard with Open Source, contributions back to Verilator will be
|
||||||
placed under the Verilator copyright and LGPL/Artistic license. Small test
|
placed under the Verilator copyright and LGPL/Artistic license. Small test
|
||||||
@@ -134,7 +149,8 @@ B. Or, for finer-grained control, or C++ files with multiple Verilated
|
|||||||
...
|
...
|
||||||
Verilated::traceEverOn(true);
|
Verilated::traceEverOn(true);
|
||||||
VerilatedVcdC* tfp = new VerilatedVcdC;
|
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||||
topp->trace(tfp, 99); // Trace 99 levels of hierarchy
|
topp->trace(tfp, 99); // Trace 99 levels of hierarchy (or see below)
|
||||||
|
// tfp->dumpvars(1, "t"); // trace 1 level under "t"
|
||||||
tfp->open("obj_dir/t_trace_ena_cc/simx.vcd");
|
tfp->open("obj_dir/t_trace_ena_cc/simx.vcd");
|
||||||
...
|
...
|
||||||
while (contextp->time() < sim_time && !contextp->gotFinish()) {
|
while (contextp->time() < sim_time && !contextp->gotFinish()) {
|
||||||
@@ -353,8 +369,8 @@ also use the "import DPI" SystemVerilog feature to call C code (see the
|
|||||||
chapter above). There is also limited VPI access to public signals.
|
chapter above). There is also limited VPI access to public signals.
|
||||||
|
|
||||||
If you want something more complex, since Verilator emits standard C++
|
If you want something more complex, since Verilator emits standard C++
|
||||||
code, you can simply write your own C++ routines that can access and modify
|
code, you can write your own C++ routines that can access and modify signal
|
||||||
signal values without needing any PLI interface code, and call it with
|
values without needing any PLI interface code, and call it with
|
||||||
$c("{any_c++_statement}").
|
$c("{any_c++_statement}").
|
||||||
|
|
||||||
See the :ref:`Connecting` section.
|
See the :ref:`Connecting` section.
|
||||||
@@ -444,7 +460,7 @@ the signal, as you would any other member variable.
|
|||||||
Signals are the smallest of 8-bit unsigned chars (equivalent to uint8_t),
|
Signals are the smallest of 8-bit unsigned chars (equivalent to uint8_t),
|
||||||
16-bit unsigned shorts (uint16_t), 32-bit unsigned longs (uint32_t), or
|
16-bit unsigned shorts (uint16_t), 32-bit unsigned longs (uint32_t), or
|
||||||
64-bit unsigned long longs (uint64_t) that fits the width of the signal.
|
64-bit unsigned long longs (uint64_t) that fits the width of the signal.
|
||||||
Generally, you can use just uint32_t's for 1 to 32 bits, or vluint64_t for
|
Generally, you can use just uint32_t's for 1 to 32 bits, or uint64_t for
|
||||||
1 to 64 bits, and the compiler will properly up-convert smaller entities.
|
1 to 64 bits, and the compiler will properly up-convert smaller entities.
|
||||||
Note even signed ports are declared as unsigned; you must sign extend
|
Note even signed ports are declared as unsigned; you must sign extend
|
||||||
yourself to the appropriate signal width.
|
yourself to the appropriate signal width.
|
||||||
@@ -481,7 +497,7 @@ by your code or you'll get strange results.
|
|||||||
Should a module be in Verilog or SystemC?
|
Should a module be in Verilog or SystemC?
|
||||||
"""""""""""""""""""""""""""""""""""""""""
|
"""""""""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
Sometimes there is a block that just interconnects instances, and have a
|
Sometimes there is a block that only interconnects instances, and have a
|
||||||
choice as to if you write it in Verilog or SystemC. Everything else being
|
choice as to if you write it in Verilog or SystemC. Everything else being
|
||||||
equal, best performance is when Verilator sees all of the design. So, look
|
equal, best performance is when Verilator sees all of the design. So, look
|
||||||
at the hierarchy of your design, labeling instances as to if they are
|
at the hierarchy of your design, labeling instances as to if they are
|
||||||
|
|||||||
+18
-12
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
*****
|
*****
|
||||||
@@ -50,7 +50,7 @@ For --cc/--sc, it creates:
|
|||||||
- Make include file with class names (from --make gmake)
|
- Make include file with class names (from --make gmake)
|
||||||
* - *{prefix}*\ _hier.mk
|
* - *{prefix}*\ _hier.mk
|
||||||
- Make file for hierarchy blocks (from --make gmake)
|
- Make file for hierarchy blocks (from --make gmake)
|
||||||
* - *{prefix|*\ _hierMkArgs.f
|
* - *{prefix}*\ _hierMkArgs.f
|
||||||
- Arguments for hierarchical Verilation (from --make gmake)
|
- Arguments for hierarchical Verilation (from --make gmake)
|
||||||
* - *{prefix}*\ _hierCMakeArgs.f
|
* - *{prefix}*\ _hierCMakeArgs.f
|
||||||
- Arguments for hierarchical Verilation (from --make cmake)
|
- Arguments for hierarchical Verilation (from --make cmake)
|
||||||
@@ -62,13 +62,17 @@ For --cc/--sc, it creates:
|
|||||||
- Top level (SystemVerilog $root) internal header file
|
- Top level (SystemVerilog $root) internal header file
|
||||||
* - *{prefix}*\ ___024root.cpp
|
* - *{prefix}*\ ___024root.cpp
|
||||||
- Top level (SystemVerilog $root) internal C++ file
|
- Top level (SystemVerilog $root) internal C++ file
|
||||||
* - *{prefix}*___024root*{__n}*\ .cpp
|
* - *{prefix}*\ ___024root\ *{__n}*\ .cpp
|
||||||
- Additional top level internal C++ files (from --output-split)
|
- Additional top level internal C++ files
|
||||||
|
* - *{prefix}*\ ___024root\ *{__DepSet_hash__n}*\ .cpp
|
||||||
|
- Additional top level internal C++ files (hashed to reduce build times)
|
||||||
* - *{prefix}*\ ___024root__Slow\ *{__n}*\ .cpp
|
* - *{prefix}*\ ___024root__Slow\ *{__n}*\ .cpp
|
||||||
- Infrequent cold routines
|
- Infrequent cold routines
|
||||||
* - *{prefix}*\ ___024root__Trace{__n}*\ .cpp
|
* - *{prefix}*\ ___024root\ *{__DepSet_hash__n}*\ .cpp
|
||||||
|
- Infrequent cold routines (hashed to reduce build times)
|
||||||
|
* - *{prefix}*\ ___024root__Trace\ *{__n}*\ .cpp
|
||||||
- Wave file generation code (from --trace)
|
- Wave file generation code (from --trace)
|
||||||
* - *{prefix}*\ ___024root__Trace__Slow{__n}*\ .cpp
|
* - *{prefix}*\ ___024root__Trace__Slow\ *{__n}*\ .cpp
|
||||||
- Wave file generation code (from --trace)
|
- Wave file generation code (from --trace)
|
||||||
* - *{prefix}*\ __Dpi.h
|
* - *{prefix}*\ __Dpi.h
|
||||||
- DPI import and export declarations (from --dpi)
|
- DPI import and export declarations (from --dpi)
|
||||||
@@ -87,7 +91,9 @@ For --cc/--sc, it creates:
|
|||||||
* - *{prefix}{each_verilog_module}*\ .cpp
|
* - *{prefix}{each_verilog_module}*\ .cpp
|
||||||
- Lower level internal C++ files
|
- Lower level internal C++ files
|
||||||
* - *{prefix}{each_verilog_module}{__n}*\ .cpp
|
* - *{prefix}{each_verilog_module}{__n}*\ .cpp
|
||||||
- Additional lower C++ files (from --output-split)
|
- Additional lower C++ files
|
||||||
|
* - *{prefix}{each_verilog_module}{__DepSet_hash__n}*\ .cpp
|
||||||
|
- Additional lower C++ files (hased to reduce build times)
|
||||||
|
|
||||||
For --hierarchy mode, it creates:
|
For --hierarchy mode, it creates:
|
||||||
|
|
||||||
@@ -120,7 +126,7 @@ In certain debug and other modes, it also creates:
|
|||||||
- Debugging graph files (from --debug)
|
- Debugging graph files (from --debug)
|
||||||
* - *{prefix}{misc}*\ .tree
|
* - *{prefix}{misc}*\ .tree
|
||||||
- Debugging files (from --debug)
|
- Debugging files (from --debug)
|
||||||
* - {mod_prefix}_{each_verilog_module}*{__n}*\ .vpp
|
* - {mod_prefix}_{each_verilog_base_filename}*\ .vpp
|
||||||
- Pre-processed verilog (from --debug)
|
- Pre-processed verilog (from --debug)
|
||||||
|
|
||||||
After running Make, the C++ compiler may produce the following:
|
After running Make, the C++ compiler may produce the following:
|
||||||
@@ -155,13 +161,13 @@ The Verilated executable may produce the following:
|
|||||||
* - gmon.out
|
* - gmon.out
|
||||||
- GCC/clang code profiler output, often fed into :command:`verilator_profcfunc`
|
- GCC/clang code profiler output, often fed into :command:`verilator_profcfunc`
|
||||||
* - profile.vlt
|
* - profile.vlt
|
||||||
- -profile data file for :ref:`Thread PGO`
|
- --prof-pgo data file for :ref:`Thread PGO`
|
||||||
* - profile_threads.dat
|
* - profile_exec.dat
|
||||||
- -profile-threads data file for :command:`verilator_gnatt`
|
- --prof-exec data file for :command:`verilator_gantt`
|
||||||
|
|
||||||
Verilator_gantt may produce the following:
|
Verilator_gantt may produce the following:
|
||||||
|
|
||||||
.. list-table::
|
.. list-table::
|
||||||
|
|
||||||
* - profile_threads.vcd
|
* - profile_exec.vcd
|
||||||
- Gantt report waveform output
|
- Gantt report waveform output
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
######################
|
######################
|
||||||
|
|||||||
+16
-8
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
.. _Installation:
|
.. _Installation:
|
||||||
@@ -77,7 +77,7 @@ OS Requirements
|
|||||||
---------------
|
---------------
|
||||||
|
|
||||||
Verilator is developed and has primary testing on Ubuntu, with additional
|
Verilator is developed and has primary testing on Ubuntu, with additional
|
||||||
testing on FreeBSD and Apple OS-X. Versions have also built on Redhat
|
testing on FreeBSD and Apple OS-X. Versions have also built on Red Hat
|
||||||
Linux, and other flavors of GNU/Linux-ish platforms. Verilator also works
|
Linux, and other flavors of GNU/Linux-ish platforms. Verilator also works
|
||||||
on Windows Subsystem for Linux (WSL2), Windows under Cygwin, and Windows
|
on Windows Subsystem for Linux (WSL2), Windows under Cygwin, and Windows
|
||||||
under MinGW (gcc -mno-cygwin). Verilated output (not Verilator itself)
|
under MinGW (gcc -mno-cygwin). Verilated output (not Verilator itself)
|
||||||
@@ -87,7 +87,7 @@ compiles under all the options above, plus using MSVC++.
|
|||||||
Install Prerequisites
|
Install Prerequisites
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
To build or run Verilator you need these standard packages:
|
To build or run Verilator, you need these standard packages:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
@@ -98,13 +98,20 @@ To build or run Verilator you need these standard packages:
|
|||||||
sudo apt-get install libfl-dev # Ubuntu only (ignore if gives error)
|
sudo apt-get install libfl-dev # Ubuntu only (ignore if gives error)
|
||||||
sudo apt-get install zlibc zlib1g zlib1g-dev # Ubuntu only (ignore if gives error)
|
sudo apt-get install zlibc zlib1g zlib1g-dev # Ubuntu only (ignore if gives error)
|
||||||
|
|
||||||
To build or run the following are optional but should be installed for good
|
To build or run Verilator, the following are optional but should be installed
|
||||||
performance:
|
for good performance:
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
sudo apt-get install ccache # If present at build, needed for run
|
sudo apt-get install ccache # If present at build, needed for run
|
||||||
sudo apt-get install libgoogle-perftools-dev numactl perl-doc
|
sudo apt-get install libgoogle-perftools-dev numactl
|
||||||
|
|
||||||
|
The following is optional but is recommended for nicely rendered command line
|
||||||
|
help when running Verilator:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
sudo apt-get install perl-doc
|
||||||
|
|
||||||
To build Verilator you will need to install these packages; these do not
|
To build Verilator you will need to install these packages; these do not
|
||||||
need to be present to run Verilator:
|
need to be present to run Verilator:
|
||||||
@@ -117,8 +124,9 @@ Those developing Verilator itself may also want these (see internals.rst):
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
sudo apt-get install gdb graphviz cmake clang clang-format-11 gprof lcov
|
sudo apt-get install gdb graphviz cmake clang clang-format-14 gprof lcov
|
||||||
sudo pip3 install sphinx sphinx_rtd_theme breathe
|
sudo apt-get install yapf3
|
||||||
|
sudo pip3 install sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe
|
||||||
cpan install Pod::Perldoc
|
cpan install Pod::Perldoc
|
||||||
cpan install Parallel::Forker
|
cpan install Parallel::Forker
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
***************
|
***************
|
||||||
@@ -92,7 +92,7 @@ appropriate code to detect failing cases at simulation runtime and print an
|
|||||||
|
|
||||||
Verilator likewise also asserts any "unique" or "priority" SystemVerilog
|
Verilator likewise also asserts any "unique" or "priority" SystemVerilog
|
||||||
keywords on case statement, as well as "unique" on if statements. However,
|
keywords on case statement, as well as "unique" on if statements. However,
|
||||||
"priority if" is currently simply ignored.
|
"priority if" is currently ignored.
|
||||||
|
|
||||||
|
|
||||||
.. _Language Limitations:
|
.. _Language Limitations:
|
||||||
@@ -136,7 +136,7 @@ ___05F (5F is the hex code of an underscore.)
|
|||||||
Bind
|
Bind
|
||||||
----
|
----
|
||||||
|
|
||||||
sVerilator only supports bind to a target module name, not to an
|
Verilator only supports bind to a target module name, not to an
|
||||||
instance path.
|
instance path.
|
||||||
|
|
||||||
|
|
||||||
@@ -174,9 +174,9 @@ Structures and Unions
|
|||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
Presently Verilator only supports packed structs and packed unions. Rand
|
Presently Verilator only supports packed structs and packed unions. Rand
|
||||||
and randc tags on members are simply ignored. All structures and unions
|
and randc tags on members are ignored. All structures and unions are
|
||||||
are represented as a single vector, which means that generating one member
|
represented as a single vector, which means that generating one member of a
|
||||||
of a structure from blocking, and another from non-blocking assignments is
|
structure from blocking, and another from non-blocking assignments is
|
||||||
unsupported.
|
unsupported.
|
||||||
|
|
||||||
|
|
||||||
@@ -336,6 +336,24 @@ Verilator does not support SEREs yet. All assertion and coverage
|
|||||||
statements must be simple expressions that complete in one cycle.
|
statements must be simple expressions that complete in one cycle.
|
||||||
|
|
||||||
|
|
||||||
|
Force statement
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Verilator supports the procedural `force` (and corresponding `release`)
|
||||||
|
statement. The behavior of the `force` statement however does not entirely
|
||||||
|
comply with the IEEE 1800 SystemVerilog standard. According to the standard,
|
||||||
|
when a procedural statement of the form `force a = b;` is executed, the
|
||||||
|
simulation should behave as if from that point forwards, a continuous
|
||||||
|
assignment `assign a = b;` have been added to override the drivers of `a`.
|
||||||
|
More specifically: the value of `a` should be updated, whenever the value of
|
||||||
|
`b` changes, all the way until a `release a;` statement is executed.
|
||||||
|
Verilator instead evaluates the current value of `b` at the time the `force`
|
||||||
|
statement is executed, and forces `a` to that value, without updating it
|
||||||
|
until a new `force` or `release` statement is encountered that applies to
|
||||||
|
`a`. This non-standard behavior is nevertheless consistent with some other
|
||||||
|
simulators.
|
||||||
|
|
||||||
|
|
||||||
Encrypted Verilog
|
Encrypted Verilog
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
@@ -471,7 +489,7 @@ $test$plusargs, $value$plusargs
|
|||||||
|
|
||||||
.. code-block:: C++
|
.. code-block:: C++
|
||||||
|
|
||||||
Verilated::commandArgs(argc, argv);
|
{VerilatedContext*} ->commandArgs(argc, argv);
|
||||||
|
|
||||||
to register the command line before calling $test$plusargs or
|
to register the command line before calling $test$plusargs or
|
||||||
$value$plusargs.
|
$value$plusargs.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
********
|
********
|
||||||
|
|||||||
+24
-24
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
.. _Simulating:
|
.. _Simulating:
|
||||||
@@ -7,9 +7,9 @@
|
|||||||
Simulating (Verilated-Model Runtime)
|
Simulating (Verilated-Model Runtime)
|
||||||
************************************
|
************************************
|
||||||
|
|
||||||
This section describes items related to simulating, that using a Verilated
|
This section describes items related to simulating, that is, the use of a
|
||||||
model's executable. For the runtime arguments to a simulated model, see
|
Verilated model's executable. For the runtime arguments to a simulated
|
||||||
:ref:`Simulation Runtime Arguments`.
|
model, see :ref:`Simulation Runtime Arguments`.
|
||||||
|
|
||||||
|
|
||||||
.. _Benchmarking & Optimization:
|
.. _Benchmarking & Optimization:
|
||||||
@@ -279,26 +279,25 @@ To use profiling:
|
|||||||
is being spent.
|
is being spent.
|
||||||
|
|
||||||
|
|
||||||
.. _Thread Profiling:
|
.. _Execution Profiling:
|
||||||
|
|
||||||
Thread Profiling
|
Execution Profiling
|
||||||
================
|
===================
|
||||||
|
|
||||||
When using multithreaded mode (:vlopt:`--threads`), it is useful to see
|
For performance optimization, it is useful to see statistics and visualize how
|
||||||
statistics and visualize how well the multiple CPUs are being utilized.
|
execution time is distributed in a verilated model.
|
||||||
|
|
||||||
With the :vlopt:`--prof-threads` option, Verilator will:
|
With the :vlopt:`--prof-exec` option, Verilator will:
|
||||||
|
|
||||||
* Add code to the Verilated model to record the start and end time of each
|
* Add code to the Verilated model to record execution flow.
|
||||||
macro-task across a number of calls to eval. (What is a macro-task? See
|
|
||||||
the Verilator internals document (:file:`docs/internals.rst` in the
|
|
||||||
distribution.)
|
|
||||||
|
|
||||||
* Add code to save profiling data in non-human-friendly form to the file
|
* Add code to save profiling data in non-human-friendly form to the file
|
||||||
specified with :vlopt:`+verilator+prof+threads+file+\<filename\>`.
|
specified with :vlopt:`+verilator+prof+exec+file+\<filename\>`.
|
||||||
|
|
||||||
* Add code to save profiling data for thread profile-guided
|
* In multi-threaded models, add code to record the start and end time of each
|
||||||
optimization. See :ref:`Thread PGO`.
|
macro-task across a number of calls to eval. (What is a macro-task? See the
|
||||||
|
Verilator internals document (:file:`docs/internals.rst` in the
|
||||||
|
distribution.)
|
||||||
|
|
||||||
The :command:`verilator_gantt` program may then be run to transform the
|
The :command:`verilator_gantt` program may then be run to transform the
|
||||||
saved profiling file into a nicer visual format and produce some related
|
saved profiling file into a nicer visual format and produce some related
|
||||||
@@ -406,8 +405,8 @@ others as they prove beneficial.
|
|||||||
Thread Profile-Guided Optimization
|
Thread Profile-Guided Optimization
|
||||||
----------------------------------
|
----------------------------------
|
||||||
|
|
||||||
Verilator supports thread profile-guided optimization (Thread PGO) to
|
Verilator supports profile-guided optimization (Verilation) of multi-threaded
|
||||||
improve multithreaded performance.
|
models (Thread PGO) to improve performance.
|
||||||
|
|
||||||
When using multithreading, Verilator computes how long macro tasks take and
|
When using multithreading, Verilator computes how long macro tasks take and
|
||||||
tries to balance those across threads. (What is a macro-task? See the
|
tries to balance those across threads. (What is a macro-task? See the
|
||||||
@@ -417,13 +416,14 @@ balanced, leading to decreased performance. Thread PGO allows collecting
|
|||||||
profiling data to replace the estimates and better optimize these
|
profiling data to replace the estimates and better optimize these
|
||||||
decisions.
|
decisions.
|
||||||
|
|
||||||
To use Thread PGO, Verilate the model with the :vlopt:`--prof-threads`
|
To use Thread PGO, Verilate the model with the :vlopt:`--prof-pgo` option. This
|
||||||
option.
|
will code to the verilated model to save profiling data for profile-guided
|
||||||
|
optimization.
|
||||||
|
|
||||||
Run the model executable. When the executable exits, it will create a
|
Run the model executable. When the executable exits, it will create a
|
||||||
profile.vlt file.
|
profile.vlt file.
|
||||||
|
|
||||||
Rerun Verilator, optionally omitting the :vlopt:`--prof-threads` option,
|
Rerun Verilator, optionally omitting the :vlopt:`--prof-pgo` option,
|
||||||
and adding the profile.vlt generated earlier to the command line.
|
and adding the profile.vlt generated earlier to the command line.
|
||||||
|
|
||||||
Note there is no Verilator equivalent to GCC's --fprofile-use. Verilator's
|
Note there is no Verilator equivalent to GCC's --fprofile-use. Verilator's
|
||||||
@@ -433,8 +433,8 @@ directly without any prefix.
|
|||||||
If results from multiple simulations are to be used in generating the
|
If results from multiple simulations are to be used in generating the
|
||||||
optimization, multiple simulation's profile.vlt may be concatenated
|
optimization, multiple simulation's profile.vlt may be concatenated
|
||||||
externally, or each of the files may be fed as separate command line
|
externally, or each of the files may be fed as separate command line
|
||||||
options into Verilator. Verilator will simply sum the profile results, so
|
options into Verilator. Verilator will sum the profile results, so a
|
||||||
a longer running test will have proportionally more weight for optimization
|
longer running test will have proportionally more weight for optimization
|
||||||
than a shorter running test.
|
than a shorter running test.
|
||||||
|
|
||||||
If you provide any profile feedback data to Verilator, and it cannot use
|
If you provide any profile feedback data to Verilator, and it cannot use
|
||||||
|
|||||||
+17
-13
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
**********
|
**********
|
||||||
@@ -68,7 +68,7 @@ multi-core SoC.
|
|||||||
|
|
||||||
Verilator is run in hierarchical mode on the whole SoC. Verilator will
|
Verilator is run in hierarchical mode on the whole SoC. Verilator will
|
||||||
make two models, one for the CPU hierarchy block, and one for the SoC. The
|
make two models, one for the CPU hierarchy block, and one for the SoC. The
|
||||||
Verialted code for the SoC will automatically call the CPU Verilated model.
|
Verilated code for the SoC will automatically call the CPU Verilated model.
|
||||||
|
|
||||||
The current hierarchical Verilation is based on :vlopt:`--lib-create`. Each
|
The current hierarchical Verilation is based on :vlopt:`--lib-create`. Each
|
||||||
hierarchy block is Verilated into a library. User modules of the hierarchy
|
hierarchy block is Verilated into a library. User modules of the hierarchy
|
||||||
@@ -221,9 +221,13 @@ model, it may be beneficial to performance to adjust the
|
|||||||
influences the partitioning of the model by adjusting the assumed execution
|
influences the partitioning of the model by adjusting the assumed execution
|
||||||
time of DPI imports.
|
time of DPI imports.
|
||||||
|
|
||||||
The :vlopt:`--trace-threads` options can be used to produce trace dumps
|
When using :vlopt:`--trace` to perform VCD tracing, the VCD trace
|
||||||
using multiple threads. If :vlopt:`--trace-threads` is set without
|
construction is parallelized using the same number of threads as specified
|
||||||
:vlopt:`--threads`, then :vlopt:`--trace-threads` will imply
|
with :vlopt:`--threads`, and is executed on the same thread pool as the model.
|
||||||
|
|
||||||
|
The :vlopt:`--trace-threads` options can be used with :vlopt:`--trace-fst`
|
||||||
|
to offload FST tracing using multiple threads. If :vlopt:`--trace-threads` is
|
||||||
|
given without :vlopt:`--threads`, then :vlopt:`--trace-threads` will imply
|
||||||
:vlopt:`--threads 1 <--threads>`, i.e.: the support libraries will be
|
:vlopt:`--threads 1 <--threads>`, i.e.: the support libraries will be
|
||||||
thread safe.
|
thread safe.
|
||||||
|
|
||||||
@@ -231,12 +235,12 @@ With :vlopt:`--trace-threads 0 <--trace-threads>`, trace dumps are produced
|
|||||||
on the main thread. This again gives the highest single thread performance.
|
on the main thread. This again gives the highest single thread performance.
|
||||||
|
|
||||||
With :vlopt:`--trace-threads {N} <--trace-threads>`, where N is at least 1,
|
With :vlopt:`--trace-threads {N} <--trace-threads>`, where N is at least 1,
|
||||||
N additional threads will be created and managed by the trace files (e.g.:
|
up to N additional threads will be created and managed by the trace files
|
||||||
VerilatedVcdC or VerilatedFstC), to generate the trace dump. The main
|
(e.g.: VerilatedFstC), to offload construction of the trace dump. The main
|
||||||
thread will be released to proceed with execution as soon as possible,
|
thread will be released to proceed with execution as soon as possible, though
|
||||||
though some blocking of the main thread is still necessary while capturing
|
some blocking of the main thread is still necessary while capturing the
|
||||||
the trace. Different trace formats can utilize a various number of
|
trace. FST tracing can utilize up to 2 offload threads, so there is no use
|
||||||
threads. See the :vlopt:`--trace-threads` option.
|
of setting :vlopt:`--trace-threads` higher than 2 at the moment.
|
||||||
|
|
||||||
When running a multithreaded model, the default Linux task scheduler often
|
When running a multithreaded model, the default Linux task scheduler often
|
||||||
works against the model, by assuming threads are short lived, and thus
|
works against the model, by assuming threads are short lived, and thus
|
||||||
@@ -265,7 +269,7 @@ This will limit memory to socket 0, and threads to cores 0, 1, 2, 3,
|
|||||||
(presumably on socket 0) optimizing performance. Of course this must be
|
(presumably on socket 0) optimizing performance. Of course this must be
|
||||||
adjusted if you want another simulator using e.g. socket 1, or if you
|
adjusted if you want another simulator using e.g. socket 1, or if you
|
||||||
Verilated with a different number of threads. To see what CPUs are
|
Verilated with a different number of threads. To see what CPUs are
|
||||||
actually used, use :vlopt:`--prof-threads`.
|
actually used, use :vlopt:`--prof-exec`.
|
||||||
|
|
||||||
|
|
||||||
Multithreaded Verilog and Library Support
|
Multithreaded Verilog and Library Support
|
||||||
@@ -441,7 +445,7 @@ SystemC include directories and link to the SystemC libraries.
|
|||||||
|
|
||||||
.. describe:: TRACE_THREADS
|
.. describe:: TRACE_THREADS
|
||||||
|
|
||||||
Optional. Generated multi-threaded trace dumping, same as
|
Optional. Generated multi-threaded FST trace dumping, same as
|
||||||
"--trace-threads".
|
"--trace-threads".
|
||||||
|
|
||||||
.. describe:: TOP_MODULE
|
.. describe:: TOP_MODULE
|
||||||
|
|||||||
+14
-14
@@ -1,4 +1,4 @@
|
|||||||
.. Copyright 2003-2021 by Wilson Snyder.
|
.. Copyright 2003-2022 by Wilson Snyder.
|
||||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
|
||||||
*******************
|
*******************
|
||||||
@@ -12,7 +12,7 @@ Disabling Warnings
|
|||||||
Warnings may be disabled in multiple ways:
|
Warnings may be disabled in multiple ways:
|
||||||
|
|
||||||
#. Disable the warning in the source code. When the warning is printed it
|
#. Disable the warning in the source code. When the warning is printed it
|
||||||
will include a warning code. Simply surround the offending line with a
|
will include a warning code. Surround the offending line with a
|
||||||
:code:`/*verilator&32;lint_off*/` and :code:`/*verilator&32;lint_on*/`
|
:code:`/*verilator&32;lint_off*/` and :code:`/*verilator&32;lint_on*/`
|
||||||
metacomment pair:
|
metacomment pair:
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ List Of Warnings
|
|||||||
always @(posedge clk) foo[0] <= ...
|
always @(posedge clk) foo[0] <= ...
|
||||||
always_comb foo[1] = ...
|
always_comb foo[1] = ...
|
||||||
|
|
||||||
Simply use a different register for the flop:
|
Instead use a different register for the flop:
|
||||||
|
|
||||||
.. code-block:: sv
|
.. code-block:: sv
|
||||||
|
|
||||||
@@ -284,7 +284,7 @@ List Of Warnings
|
|||||||
|
|
||||||
.. TODO better example
|
.. TODO better example
|
||||||
|
|
||||||
Warns that it is simply better style to use casez, and "?" in place of
|
Warns that it is better style to use casez, and "?" in place of
|
||||||
"x"'s. See
|
"x"'s. See
|
||||||
`http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf
|
`http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf
|
||||||
<http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf>`_
|
<http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf>`_
|
||||||
@@ -447,7 +447,7 @@ List Of Warnings
|
|||||||
p0();
|
p0();
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
Other tools with similar warnings: Veriable's forbid_defparam_rule.
|
Other tools with similar warnings: Verible's forbid_defparam_rule.
|
||||||
|
|
||||||
|
|
||||||
.. option:: DEPRECATED
|
.. option:: DEPRECATED
|
||||||
@@ -518,7 +518,7 @@ List Of Warnings
|
|||||||
Another way DIDNOTCONVERGE may occur is if # delays are used to generate
|
Another way DIDNOTCONVERGE may occur is if # delays are used to generate
|
||||||
clocks. Verilator ignores the delays and gives an :option:`ASSIGNDLY`
|
clocks. Verilator ignores the delays and gives an :option:`ASSIGNDLY`
|
||||||
or :option:`STMTDLY` warning. If these were suppressed, due to the
|
or :option:`STMTDLY` warning. If these were suppressed, due to the
|
||||||
absense of the delay, the code may now oscillate.
|
absence of the delay, the code may now oscillate.
|
||||||
|
|
||||||
Finally, rare, more difficult cases can be debugged like a C++ program;
|
Finally, rare, more difficult cases can be debugged like a C++ program;
|
||||||
either enter :command:`gdb` and use its tracing facilities, or edit the
|
either enter :command:`gdb` and use its tracing facilities, or edit the
|
||||||
@@ -528,7 +528,7 @@ List Of Warnings
|
|||||||
.. option:: ENDCAPSULATED
|
.. option:: ENDCAPSULATED
|
||||||
|
|
||||||
Warns that a class member is declared is local or protected, but is
|
Warns that a class member is declared is local or protected, but is
|
||||||
being accessed from outside that class (if local) or a derrived class
|
being accessed from outside that class (if local) or a derived class
|
||||||
(if protected).
|
(if protected).
|
||||||
|
|
||||||
Ignoring this warning will only suppress the lint check, it will
|
Ignoring this warning will only suppress the lint check, it will
|
||||||
@@ -924,7 +924,7 @@ List Of Warnings
|
|||||||
simulate correctly.
|
simulate correctly.
|
||||||
|
|
||||||
Other tools with similar warnings: Icarus Verilog's portbind, "warning:
|
Other tools with similar warnings: Icarus Verilog's portbind, "warning:
|
||||||
Instantiating module ... with dangling impot port (...)". Slang's
|
Instantiating module ... with dangling input port (...)". Slang's
|
||||||
unconnected-port, "port '...' has no connection".
|
unconnected-port, "port '...' has no connection".
|
||||||
|
|
||||||
|
|
||||||
@@ -1212,12 +1212,12 @@ List Of Warnings
|
|||||||
.. include:: ../../docs/gen/ex_STMTDLY_msg.rst
|
.. include:: ../../docs/gen/ex_STMTDLY_msg.rst
|
||||||
|
|
||||||
This is a warning because Verilator does not support delayed statements.
|
This is a warning because Verilator does not support delayed statements.
|
||||||
It will simply ignore all such delays. In many cases ignoring a delay
|
It will ignore all such delays. In many cases ignoring a delay might be
|
||||||
might be harmless, but if the delayed statement is, as in this example,
|
harmless, but if the delayed statement is, as in this example, used to
|
||||||
used to cause some important action at a later time, it might be an
|
cause some important action at a later time, it might be an important
|
||||||
important difference.
|
difference.
|
||||||
|
|
||||||
Some possible work arounds:
|
Some possible workarounds:
|
||||||
|
|
||||||
* Move the delayed statement into the C++ wrapper file, where the
|
* Move the delayed statement into the C++ wrapper file, where the
|
||||||
stimulus and clock generation can be done in C++.
|
stimulus and clock generation can be done in C++.
|
||||||
@@ -1506,7 +1506,7 @@ List Of Warnings
|
|||||||
Error that a construct might be legal according to IEEE but is not
|
Error that a construct might be legal according to IEEE but is not
|
||||||
currently supported by Verilator.
|
currently supported by Verilator.
|
||||||
|
|
||||||
A typical workaround is to recode the construct into a simpler and more
|
A typical workaround is to rewrite the construct into a simpler and more
|
||||||
common alternative language construct.
|
common alternative language construct.
|
||||||
|
|
||||||
Alternatively, check if the construct is supported by other tools, and
|
Alternatively, check if the construct is supported by other tools, and
|
||||||
|
|||||||
+110
-31
@@ -96,10 +96,11 @@ this.
|
|||||||
Each ``AstNode`` has pointers to up to four children, accessed by the
|
Each ``AstNode`` has pointers to up to four children, accessed by the
|
||||||
``op1p`` through ``op4p`` methods. These methods are then abstracted in a
|
``op1p`` through ``op4p`` methods. These methods are then abstracted in a
|
||||||
specific Ast\* node class to a more specific name. For example with the
|
specific Ast\* node class to a more specific name. For example with the
|
||||||
``AstIf`` node (for ``if`` statements), ``ifsp`` calls ``op2p`` to give the
|
``AstIf`` node (for ``if`` statements), ``thensp`` calls ``op2p`` to give the
|
||||||
pointer to the AST for the "then" block, while ``elsesp`` calls ``op3p`` to
|
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
|
give the pointer to the AST for the "else" block, or NULL if there is not
|
||||||
one.
|
one. These accessors are automatically generated by ``astgen`` after
|
||||||
|
parsing the ``@astgen`` directives in the specific ``AstNode`` subclasses.
|
||||||
|
|
||||||
``AstNode`` has the concept of a next and previous AST - for example the
|
``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
|
next and previous statements in a block. Pointers to the AST for these
|
||||||
@@ -114,11 +115,11 @@ By convention, each function/method uses the variable ``nodep`` as a
|
|||||||
pointer to the ``AstNode`` currently being processed.
|
pointer to the ``AstNode`` currently being processed.
|
||||||
|
|
||||||
|
|
||||||
``AstNVisitor``
|
``VNVisitor``
|
||||||
^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
The passes are implemented by AST visitor classes. These are implemented by
|
The passes are implemented by AST visitor classes. These are implemented by
|
||||||
subclasses of the abstract class, ``AstNVisitor``. Each pass creates an
|
subclasses of the abstract class, ``VNVisitor``. Each pass creates an
|
||||||
instance of the visitor class, which in turn implements a method to perform
|
instance of the visitor class, which in turn implements a method to perform
|
||||||
the pass.
|
the pass.
|
||||||
|
|
||||||
@@ -268,13 +269,13 @@ Estimating Logic Costs
|
|||||||
|
|
||||||
To compute the cost of any given path through the graph, Verilator
|
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
|
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
|
cost which is the sum of its tasks' costs. We assume that communication
|
||||||
communication overhead and synchronization overhead are zero, so the cost
|
overhead and synchronization overhead are zero, so the cost of any given
|
||||||
of any given path through the graph is simply the sum of macro-task
|
path through the graph is the sum of macro-task execution costs. Sarkar
|
||||||
execution costs. Sarkar does almost the same thing, except that he has
|
does almost the same thing, except that he has nonzero estimates for
|
||||||
nonzero estimates for synchronization costs.
|
synchronization costs.
|
||||||
|
|
||||||
Verilator's cost estimates are assigned by ``InstrCountCostVisitor``. This
|
Verilator's cost estimates are assigned by ``InstrCountVisitor``. This
|
||||||
class is perhaps the most fragile piece of the multithread
|
class is perhaps the most fragile piece of the multithread
|
||||||
implementation. It's easy to have a bug where you count something cheap
|
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.
|
(eg. accessing one element of a huge array) as if it were expensive (eg.
|
||||||
@@ -301,7 +302,7 @@ prerequisites on other threads have finished.
|
|||||||
|
|
||||||
The synchronization cost is cheap if the prereqs are done. If they're not,
|
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
|
fragmentation (idle CPU cores waiting) is possible. This is the major
|
||||||
source of overhead in this approach. The ``--prof-threads`` switch and the
|
source of overhead in this approach. The ``--prof-exec`` switch and the
|
||||||
``verilator_gantt`` script can visualize the time lost to such
|
``verilator_gantt`` script can visualize the time lost to such
|
||||||
fragmentation.
|
fragmentation.
|
||||||
|
|
||||||
@@ -501,32 +502,109 @@ code:
|
|||||||
The ``astgen`` Script
|
The ``astgen`` Script
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
Some of the code implementing passes is extremely repetitive, and must be
|
The ``astgen`` script is used to generate some of the repetitive C++ code
|
||||||
implemented for each sub-class of ``AstNode``. However, while repetitive,
|
related to the ``AstNode`` type hierarchy. An example is the abstract ``visit``
|
||||||
there is more variability than can be handled in C++ macros.
|
methods in ``VNVisitor``. There are other uses, please see the ``*__gen*``
|
||||||
|
files in the bulid directories and the ``astgen`` script itself for details. A
|
||||||
|
description of the more advanced features of ``astgen`` are provided here.
|
||||||
|
|
||||||
In Verilator this is implemented by using a 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``
|
Generating ``AstNode`` members
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Some of the member s of ``AstNode`` sub-classes are generated by ``astgen``.
|
||||||
|
These are emitted as pre-processor macro definitions, which then need to be
|
||||||
|
added to the ``AstNode`` sub-classes they correspond to. Specifically ``class
|
||||||
|
AstFoo`` should contain an instance of ``ASTGEN_MEMBERS_Foo;`` at class scope.
|
||||||
|
The ``astgen`` script checks and errors if this is not present. The method
|
||||||
|
generated depends on whether the class is a concrete final class, or an
|
||||||
|
abstract ``AstNode*`` base-class, and on ``@astgen`` directives present in
|
||||||
|
comment sections in the body of the ``AstNode`` sub-class definitions.
|
||||||
|
|
||||||
|
|
||||||
|
List of ``@astgen`` directives
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
``@astgen`` directives in comments contained in the body of ``AstNode``
|
||||||
|
sub-class definitions are parsed and contribute to the code generated by
|
||||||
|
``astgen``. The general syntax is ``@astgen <keywords> := <description>``,
|
||||||
|
where ``<keywords>`` determines what is being defined, and ``<description>`` is
|
||||||
|
a ``<keywords>`` dependent description of the definition. The list of
|
||||||
|
``@astgen`` directives is as follows:
|
||||||
|
|
||||||
|
|
||||||
|
``op<N>`` operand directives
|
||||||
|
"""""""""""""""""""""""""""""
|
||||||
|
|
||||||
|
The ``op1``, ``op2``, ``op3`` and ``op4`` directives are used to describe the
|
||||||
|
name and type of the up to 4 child operands of a node. The syntax of the
|
||||||
|
``<description>`` field is ``<identifier> : <type>``, where ``<identifier>``
|
||||||
|
will be used as the base name of the generated operand accessors, and
|
||||||
|
``<type>`` is one of:
|
||||||
|
|
||||||
|
1. An ``AstNode`` sub-class, defining the operand to be of that type, always
|
||||||
|
no-null, and with an always null ``nextp()``. That is, the child node is
|
||||||
|
always present, and is a single ``AstNode`` (as opposed to a list).
|
||||||
|
|
||||||
|
2. ``Optional[<AstNode sub-class>]``. This is just like in point 1 above, but
|
||||||
|
defines the child node to be optional, meaning it may be null.
|
||||||
|
|
||||||
|
3. ``List[AstNode sub-class]`` describes a list operand, which means the child
|
||||||
|
node may have a non-null ``nextp()`` and in addition the child itself may be
|
||||||
|
null, representing an empty list.
|
||||||
|
|
||||||
|
|
||||||
|
An example of the full syntax of the directive is
|
||||||
|
``@astgen op1 := lhsp : AstNodeMath``.
|
||||||
|
|
||||||
|
``astnode`` generates accessors for the child nodes based on these directives.
|
||||||
|
For non-list children, the names of the getter and setter both are that of the
|
||||||
|
given ``<identifier>``. For list type children, the getter is ``<identifier>``,
|
||||||
|
and instead of the setter, there an ``add<Identifier>`` method is generated
|
||||||
|
that appends new nodes (or lists of nodes) to the child list.
|
||||||
|
|
||||||
|
``alias op<N>`` operand alias directives
|
||||||
|
""""""""""""""""""""""""""""""""""""""""
|
||||||
|
|
||||||
|
If a super-class already defined a name and type for a child node using the
|
||||||
|
``op<N>`` directive, but a more appropriate name exists in the context of a
|
||||||
|
sub-class, then the alias directive can be used to introduce an additional name
|
||||||
|
for the child node. The is ``alias op<N> := <identifier>`` where
|
||||||
|
``<identifier>`` is the new name. ``op<N>`` must have been defined in some
|
||||||
|
super-class of the current node.
|
||||||
|
|
||||||
|
Example: ``@astgen alias op1 := condp``
|
||||||
|
|
||||||
|
|
||||||
|
Additional features of ``astgen``
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
In addition to generating ``AstNode`` members as described above,
|
||||||
|
``astgen`` is also use to handle some of the repetitive implementation code
|
||||||
|
that is still variable enough not to be handled in C++ macros.
|
||||||
|
|
||||||
|
In particular, ``astgen`` is used to pre-process some of the C++ source
|
||||||
|
files. For example in ``V3Const.cpp``, it 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
|
and ``obj_dbg`` sub-directories (the former for the optimized version of
|
||||||
Verilator, the latter for the debug version). So for example
|
Verilator, the latter for the debug version). So for example
|
||||||
``V3Const.cpp`` into ``V3Const__gen.cpp``.
|
``V3Const.cpp`` into ``V3Const__gen.cpp``.
|
||||||
|
|
||||||
|
|
||||||
Visitor Functions -----------------
|
Visitor Functions
|
||||||
|
-----------------
|
||||||
|
|
||||||
Verilator uses the "Visitor" design pattern to implement its refinement and
|
Verilator uses the "Visitor" design pattern to implement its refinement and
|
||||||
optimization passes. This allows separation of the pass algorithm from the
|
optimization passes. This allows separation of the pass algorithm from the
|
||||||
AST on which it operates. Wikipedia provides an introduction to the concept
|
AST on which it operates. Wikipedia provides an introduction to the concept
|
||||||
at https://en.wikipedia.org/wiki/Visitor_pattern.
|
at https://en.wikipedia.org/wiki/Visitor_pattern.
|
||||||
|
|
||||||
As noted above, all visitors are derived classes of ``AstNVisitor``. All
|
As noted above, all visitors are derived classes of ``VNVisitor``. All
|
||||||
derived classes of ``AstNode`` implement the ``accept`` method, which takes
|
derived classes of ``AstNode`` implement the ``accept`` method, which takes
|
||||||
as argument a reference to an instance or a ``AstNVisitor`` derived class
|
as argument a reference to an instance or a ``VNVisitor`` derived class
|
||||||
and applies the visit method of the ``AstNVisitor`` to the invoking AstNode
|
and applies the visit method of the ``VNVisitor`` to the invoking AstNode
|
||||||
instance (i.e. ``this``).
|
instance (i.e. ``this``).
|
||||||
|
|
||||||
One possible difficulty is that a call to ``accept`` may perform an edit
|
One possible difficulty is that a call to ``accept`` may perform an edit
|
||||||
@@ -604,8 +682,8 @@ There are three ways data is passed between visitor functions.
|
|||||||
Iterators
|
Iterators
|
||||||
---------
|
---------
|
||||||
|
|
||||||
``AstNVisitor`` provides a set of iterators to facilitate walking over
|
``VNVisitor`` provides a set of iterators to facilitate walking over
|
||||||
the tree. Each operates on the current ``AstNVisitor`` class (as this)
|
the tree. Each operates on the current ``VNVisitor`` class (as this)
|
||||||
and takes an argument type ``AstNode*``.
|
and takes an argument type ``AstNode*``.
|
||||||
|
|
||||||
``iterate``
|
``iterate``
|
||||||
@@ -817,7 +895,7 @@ which you can install using cpan.
|
|||||||
|
|
||||||
There are some traps to avoid when running regression tests
|
There are some traps to avoid when running regression tests
|
||||||
|
|
||||||
- When checking the MANIFEST, the test will barf on unexpected code in the
|
- When checking the MANIFEST, the test will fail on unexpected code in the
|
||||||
Verilator tree. So make sure to keep any such code outside the tree.
|
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
|
- Not all Linux systems install Perldoc by default. This is needed for the
|
||||||
@@ -1153,8 +1231,9 @@ Generally what would you do to add a new feature?
|
|||||||
language and has a lot of back-and-forth with Verilator's grammar. Copy
|
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.
|
the appropriate rules to src/verilog.y and modify the productions.
|
||||||
|
|
||||||
4. If a new Ast type is needed, add it to V3AstNodes.h. Follow the
|
4. If a new Ast type is needed, add it to the appropriate V3AstNode*.h.
|
||||||
convention described above about the AstNode type hierarchy.
|
Follow the convention described above about the AstNode type hierarchy.
|
||||||
|
Ordering of definitions is enforced by ``astgen``.
|
||||||
|
|
||||||
5. Now you can run "test_regress/t/t_<newtestcase>.pl --debug" and it'll
|
5. Now you can run "test_regress/t/t_<newtestcase>.pl --debug" and it'll
|
||||||
probably fail but you'll see a
|
probably fail but you'll see a
|
||||||
@@ -1183,10 +1262,10 @@ Verilator ideally would support all of IEEE, and has the goal to get close
|
|||||||
to full support. However the following IEEE sections and features are not
|
to full support. However the following IEEE sections and features are not
|
||||||
anticipated to be ever implemented for the reasons indicated.
|
anticipated to be ever implemented for the reasons indicated.
|
||||||
|
|
||||||
IEEE 1800-2017 3.3 recursive modules
|
IEEE 1800-2017 3.3 modules within modules
|
||||||
Little/no tool support, and arguably not a good practice.
|
Little/no tool support, and arguably not a good practice.
|
||||||
IEEE 1800-2017 6.12 "shortreal"
|
IEEE 1800-2017 6.12 "shortreal"
|
||||||
Little/no tool support, and easily simply promoted to real.
|
Little/no tool support, and easily promoted to real.
|
||||||
IEEE 1800-2017 11.11 Min, typ, max
|
IEEE 1800-2017 11.11 Min, typ, max
|
||||||
No SDF support so will always use typical.
|
No SDF support so will always use typical.
|
||||||
IEEE 1800-2017 11.12 "let"
|
IEEE 1800-2017 11.12 "let"
|
||||||
@@ -1208,7 +1287,7 @@ IEEE 1800-2017 33 Config
|
|||||||
Distribution
|
Distribution
|
||||||
============
|
============
|
||||||
|
|
||||||
Copyright 2008-2021 by Wilson Snyder. Verilator is free software; you can
|
Copyright 2008-2022 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
|
||||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ ABCp
|
|||||||
Accellera
|
Accellera
|
||||||
Affe
|
Affe
|
||||||
Aleksander
|
Aleksander
|
||||||
|
Alexandre
|
||||||
Ami
|
Ami
|
||||||
Amir
|
Amir
|
||||||
Anastasiadis
|
Anastasiadis
|
||||||
|
Anikin
|
||||||
Antonin
|
Antonin
|
||||||
Antwerpen
|
Antwerpen
|
||||||
Arasanipalai
|
Arasanipalai
|
||||||
@@ -70,6 +72,7 @@ Eda
|
|||||||
Eddleston
|
Eddleston
|
||||||
Egbert
|
Egbert
|
||||||
Egil
|
Egil
|
||||||
|
Ehab
|
||||||
Eiler
|
Eiler
|
||||||
Eivind
|
Eivind
|
||||||
El
|
El
|
||||||
@@ -82,6 +85,7 @@ Fabrizio
|
|||||||
Fekete
|
Fekete
|
||||||
Ferrandi
|
Ferrandi
|
||||||
Flachs
|
Flachs
|
||||||
|
Flavien
|
||||||
Foletto
|
Foletto
|
||||||
Forker
|
Forker
|
||||||
Francillon
|
Francillon
|
||||||
@@ -104,6 +108,7 @@ Goessling
|
|||||||
Gonnen
|
Gonnen
|
||||||
Goorah
|
Goorah
|
||||||
Gossner
|
Gossner
|
||||||
|
Graybeal
|
||||||
Grobman
|
Grobman
|
||||||
Gunter
|
Gunter
|
||||||
Guo
|
Guo
|
||||||
@@ -121,6 +126,7 @@ Hornung
|
|||||||
Hossell
|
Hossell
|
||||||
Hsu
|
Hsu
|
||||||
Hyperthreading
|
Hyperthreading
|
||||||
|
Ibrahim
|
||||||
Iles
|
Iles
|
||||||
Inlines
|
Inlines
|
||||||
Inout
|
Inout
|
||||||
@@ -134,6 +140,7 @@ Jannis
|
|||||||
Jens
|
Jens
|
||||||
Jeras
|
Jeras
|
||||||
Jiuyang
|
Jiuyang
|
||||||
|
Joannou
|
||||||
Joly
|
Joly
|
||||||
Jullien
|
Jullien
|
||||||
Junji
|
Junji
|
||||||
@@ -147,6 +154,7 @@ Kamendje
|
|||||||
Kandadi
|
Kandadi
|
||||||
Kaplan
|
Kaplan
|
||||||
Karge
|
Karge
|
||||||
|
Karlsson
|
||||||
Katz
|
Katz
|
||||||
Katzman
|
Katzman
|
||||||
Keren
|
Keren
|
||||||
@@ -161,6 +169,7 @@ Kolecki
|
|||||||
Koonce
|
Koonce
|
||||||
Korteland
|
Korteland
|
||||||
Koszek
|
Koszek
|
||||||
|
Kouping
|
||||||
Kravitz
|
Kravitz
|
||||||
Krolnik
|
Krolnik
|
||||||
Kruse
|
Kruse
|
||||||
@@ -194,6 +203,7 @@ Mednick
|
|||||||
Michiels
|
Michiels
|
||||||
Microsystems
|
Microsystems
|
||||||
Milanovic
|
Milanovic
|
||||||
|
Millis
|
||||||
MinW
|
MinW
|
||||||
Mindspeed
|
Mindspeed
|
||||||
Miodrag
|
Miodrag
|
||||||
@@ -224,12 +234,14 @@ Petr
|
|||||||
Piechotka
|
Piechotka
|
||||||
Piersall
|
Piersall
|
||||||
Plunkett
|
Plunkett
|
||||||
|
Popolon
|
||||||
Popov
|
Popov
|
||||||
Prabhat
|
Prabhat
|
||||||
Prabhu
|
Prabhu
|
||||||
Prateek
|
Prateek
|
||||||
Pre
|
Pre
|
||||||
Preprocess
|
Preprocess
|
||||||
|
Pretet
|
||||||
Priyadharshini
|
Priyadharshini
|
||||||
Pullup
|
Pullup
|
||||||
Pulver
|
Pulver
|
||||||
@@ -262,12 +274,15 @@ Shi
|
|||||||
Shinkarovsky
|
Shinkarovsky
|
||||||
Shirakawa
|
Shirakawa
|
||||||
Shuba
|
Shuba
|
||||||
|
Shunyao
|
||||||
Slatter
|
Slatter
|
||||||
SoC
|
SoC
|
||||||
Sobhan
|
Sobhan
|
||||||
Sokorac
|
Sokorac
|
||||||
Solaris
|
Solaris
|
||||||
Solomatnikov
|
Solomatnikov
|
||||||
|
Solt
|
||||||
|
Southwell
|
||||||
Srini
|
Srini
|
||||||
Stamness
|
Stamness
|
||||||
Stephane
|
Stephane
|
||||||
@@ -286,6 +301,7 @@ SystemVerilog
|
|||||||
Takatsukasa
|
Takatsukasa
|
||||||
Tambe
|
Tambe
|
||||||
Tariq
|
Tariq
|
||||||
|
Tejada
|
||||||
Tengstrand
|
Tengstrand
|
||||||
Terpstra
|
Terpstra
|
||||||
Thiede
|
Thiede
|
||||||
@@ -293,8 +309,10 @@ Thierry
|
|||||||
Thyer
|
Thyer
|
||||||
Tichelaar
|
Tichelaar
|
||||||
Tomov
|
Tomov
|
||||||
|
Tood
|
||||||
Topa
|
Topa
|
||||||
Tota
|
Tota
|
||||||
|
Trefor
|
||||||
Tresidder
|
Tresidder
|
||||||
Tri
|
Tri
|
||||||
Tristate
|
Tristate
|
||||||
@@ -304,11 +322,13 @@ Ubixum
|
|||||||
Uints
|
Uints
|
||||||
Undefines
|
Undefines
|
||||||
Unsized
|
Unsized
|
||||||
|
Urbach
|
||||||
Uselib
|
Uselib
|
||||||
Usha
|
Usha
|
||||||
Usuario
|
Usuario
|
||||||
VERILATOR
|
VERILATOR
|
||||||
Vasu
|
Vasu
|
||||||
|
Vdeeptemp
|
||||||
Vdly
|
Vdly
|
||||||
Vemumtab
|
Vemumtab
|
||||||
Vemuri
|
Vemuri
|
||||||
@@ -351,7 +371,9 @@ Zhang
|
|||||||
abirkmanis
|
abirkmanis
|
||||||
accessor
|
accessor
|
||||||
accessors
|
accessors
|
||||||
|
adrienlemasle
|
||||||
agrobman
|
agrobman
|
||||||
|
ahouska
|
||||||
al
|
al
|
||||||
ala
|
ala
|
||||||
andit
|
andit
|
||||||
@@ -372,8 +394,12 @@ backtrace
|
|||||||
backtraces
|
backtraces
|
||||||
basename
|
basename
|
||||||
bbox
|
bbox
|
||||||
|
benchmarking
|
||||||
biguint
|
biguint
|
||||||
biops
|
biops
|
||||||
|
bitOpTree
|
||||||
|
bitOpTree
|
||||||
|
bitop
|
||||||
bitstoreal
|
bitstoreal
|
||||||
blackbox
|
blackbox
|
||||||
bokke
|
bokke
|
||||||
@@ -389,6 +415,7 @@ casez
|
|||||||
casted
|
casted
|
||||||
cb
|
cb
|
||||||
ccache
|
ccache
|
||||||
|
ccall
|
||||||
cdc
|
cdc
|
||||||
ceil
|
ceil
|
||||||
celldefine
|
celldefine
|
||||||
@@ -411,6 +438,8 @@ concat
|
|||||||
concats
|
concats
|
||||||
config
|
config
|
||||||
const
|
const
|
||||||
|
constexpr
|
||||||
|
constpool
|
||||||
coredump
|
coredump
|
||||||
countbits
|
countbits
|
||||||
countones
|
countones
|
||||||
@@ -426,6 +455,7 @@ da
|
|||||||
dat
|
dat
|
||||||
datadir
|
datadir
|
||||||
datafiles
|
datafiles
|
||||||
|
david
|
||||||
ddd
|
ddd
|
||||||
deassign
|
deassign
|
||||||
debugi
|
debugi
|
||||||
@@ -434,6 +464,7 @@ defname
|
|||||||
defparam
|
defparam
|
||||||
demangling
|
demangling
|
||||||
der
|
der
|
||||||
|
dereference
|
||||||
desassign
|
desassign
|
||||||
destructor
|
destructor
|
||||||
detections
|
detections
|
||||||
@@ -462,6 +493,7 @@ dumpvars
|
|||||||
dut
|
dut
|
||||||
dx
|
dx
|
||||||
elab
|
elab
|
||||||
|
elike
|
||||||
elsif
|
elsif
|
||||||
endcase
|
endcase
|
||||||
endcelldefine
|
endcelldefine
|
||||||
@@ -480,15 +512,18 @@ enums
|
|||||||
env
|
env
|
||||||
envvar
|
envvar
|
||||||
eof
|
eof
|
||||||
|
errae
|
||||||
erroring
|
erroring
|
||||||
et
|
et
|
||||||
eval
|
eval
|
||||||
|
evals
|
||||||
exe
|
exe
|
||||||
executables
|
executables
|
||||||
expr
|
expr
|
||||||
extern
|
extern
|
||||||
fanin
|
fanin
|
||||||
fasttrace
|
fasttrace
|
||||||
|
fauto
|
||||||
fbranch
|
fbranch
|
||||||
fclose
|
fclose
|
||||||
fdisplay
|
fdisplay
|
||||||
@@ -503,6 +538,7 @@ filt
|
|||||||
flto
|
flto
|
||||||
flushCall
|
flushCall
|
||||||
fopen
|
fopen
|
||||||
|
forceable
|
||||||
foreach
|
foreach
|
||||||
fprintf
|
fprintf
|
||||||
fprofile
|
fprofile
|
||||||
@@ -521,6 +557,7 @@ funcs
|
|||||||
fwrite
|
fwrite
|
||||||
gantt
|
gantt
|
||||||
gcc
|
gcc
|
||||||
|
gcda
|
||||||
gdb
|
gdb
|
||||||
genblk
|
genblk
|
||||||
genvar
|
genvar
|
||||||
@@ -552,6 +589,7 @@ incdir
|
|||||||
includer
|
includer
|
||||||
inferfaces
|
inferfaces
|
||||||
inhibitSim
|
inhibitSim
|
||||||
|
initarray
|
||||||
initializer
|
initializer
|
||||||
initializers
|
initializers
|
||||||
inits
|
inits
|
||||||
@@ -570,6 +608,7 @@ killua
|
|||||||
lang
|
lang
|
||||||
lcov
|
lcov
|
||||||
ld
|
ld
|
||||||
|
leavinel
|
||||||
len
|
len
|
||||||
libext
|
libext
|
||||||
libgoogle
|
libgoogle
|
||||||
@@ -584,6 +623,7 @@ ln
|
|||||||
loc
|
loc
|
||||||
localparam
|
localparam
|
||||||
localparams
|
localparams
|
||||||
|
localtime
|
||||||
logicals
|
logicals
|
||||||
longint
|
longint
|
||||||
lsb
|
lsb
|
||||||
@@ -618,6 +658,7 @@ multithreaded
|
|||||||
multithreading
|
multithreading
|
||||||
mutexes
|
mutexes
|
||||||
mux
|
mux
|
||||||
|
myftptoyman
|
||||||
mysignal
|
mysignal
|
||||||
namespace
|
namespace
|
||||||
nand
|
nand
|
||||||
@@ -642,15 +683,19 @@ onehot
|
|||||||
ooo
|
ooo
|
||||||
oprofile
|
oprofile
|
||||||
oversubscription
|
oversubscription
|
||||||
|
parallelized
|
||||||
param
|
param
|
||||||
parameterized
|
parameterized
|
||||||
params
|
params
|
||||||
parens
|
parens
|
||||||
|
pawel
|
||||||
pc
|
pc
|
||||||
pdf
|
pdf
|
||||||
perf
|
perf
|
||||||
perftools
|
perftools
|
||||||
|
pgo
|
||||||
picoChip
|
picoChip
|
||||||
|
pinIndex
|
||||||
pinout
|
pinout
|
||||||
plusargs
|
plusargs
|
||||||
pmos
|
pmos
|
||||||
@@ -676,6 +721,7 @@ prev
|
|||||||
printf
|
printf
|
||||||
printtimescale
|
printtimescale
|
||||||
profcfunc
|
profcfunc
|
||||||
|
profiler
|
||||||
prototyptes
|
prototyptes
|
||||||
ps
|
ps
|
||||||
pthread
|
pthread
|
||||||
@@ -703,12 +749,14 @@ regs
|
|||||||
reloop
|
reloop
|
||||||
resetall
|
resetall
|
||||||
respecified
|
respecified
|
||||||
|
rodata
|
||||||
rr
|
rr
|
||||||
rst
|
rst
|
||||||
runtime
|
runtime
|
||||||
runtimes
|
runtimes
|
||||||
rw
|
rw
|
||||||
sVerilator
|
sVerilator
|
||||||
|
sawatzke
|
||||||
sc
|
sc
|
||||||
scalared
|
scalared
|
||||||
sccanf
|
sccanf
|
||||||
@@ -724,6 +772,7 @@ specparam
|
|||||||
splitme
|
splitme
|
||||||
spp
|
spp
|
||||||
sqrt
|
sqrt
|
||||||
|
src
|
||||||
srcdir
|
srcdir
|
||||||
srcfile
|
srcfile
|
||||||
sscanf
|
sscanf
|
||||||
@@ -743,6 +792,7 @@ subcells
|
|||||||
subexpressions
|
subexpressions
|
||||||
submodule
|
submodule
|
||||||
submodules
|
submodules
|
||||||
|
substring
|
||||||
sv
|
sv
|
||||||
svBitVal
|
svBitVal
|
||||||
svBitVecVal
|
svBitVecVal
|
||||||
@@ -777,6 +827,7 @@ trunc
|
|||||||
txt
|
txt
|
||||||
typ
|
typ
|
||||||
typedef
|
typedef
|
||||||
|
typedef'ed
|
||||||
typedefed
|
typedefed
|
||||||
typedefs
|
typedefs
|
||||||
typename
|
typename
|
||||||
@@ -790,6 +841,7 @@ uniquified
|
|||||||
unistd
|
unistd
|
||||||
unlink
|
unlink
|
||||||
unlinked
|
unlinked
|
||||||
|
unnamedblk
|
||||||
unopt
|
unopt
|
||||||
unoptflat
|
unoptflat
|
||||||
unoptimizable
|
unoptimizable
|
||||||
@@ -839,11 +891,14 @@ writeme
|
|||||||
writemem
|
writemem
|
||||||
writememb
|
writememb
|
||||||
writememh
|
writememh
|
||||||
|
xiak
|
||||||
xin
|
xin
|
||||||
xml
|
xml
|
||||||
xnor
|
xnor
|
||||||
xout
|
xout
|
||||||
xuejiazidi
|
xuejiazidi
|
||||||
yanx
|
yanx
|
||||||
|
ypq
|
||||||
yurivict
|
yurivict
|
||||||
zdave
|
zdave
|
||||||
|
Øyvind
|
||||||
|
|||||||
+1
-4
@@ -46,9 +46,6 @@ The XML document consists of 4 sections within the top level
|
|||||||
hierarchy. Each instance is represented with the ``<cell>`` element
|
hierarchy. Each instance is represented with the ``<cell>`` element
|
||||||
with the following attributes:
|
with the following attributes:
|
||||||
|
|
||||||
- ``fl`` (deprecated): The file id and line number where the module
|
|
||||||
was instanced. Use ``loc`` instead.
|
|
||||||
|
|
||||||
- ``loc``: The file id, first line number, last line number, first
|
- ``loc``: The file id, first line number, last line number, first
|
||||||
column number and last column number of the identifier where the
|
column number and last column number of the identifier where the
|
||||||
module was instanced, separated by commas.
|
module was instanced, separated by commas.
|
||||||
@@ -73,7 +70,7 @@ The XML document consists of 4 sections within the top level
|
|||||||
Distribution
|
Distribution
|
||||||
============
|
============
|
||||||
|
|
||||||
Copyright 2020-2021 by Wilson Snyder. Verilator is free software; you can
|
Copyright 2020-2022 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
|
||||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||||
|
|
||||||
|
|||||||
@@ -33,5 +33,5 @@ add_executable(example ../make_tracing_c/sim_main.cpp)
|
|||||||
# Add the Verilated circuit to the target
|
# Add the Verilated circuit to the target
|
||||||
verilate(example COVERAGE TRACE
|
verilate(example COVERAGE TRACE
|
||||||
INCLUDE_DIRS "../make_tracing_c"
|
INCLUDE_DIRS "../make_tracing_c"
|
||||||
VERILATOR_ARGS -f ../make_tracing_c/input.vc -Os -x-assign 0
|
VERILATOR_ARGS -f ../make_tracing_c/input.vc -x-assign fast
|
||||||
SOURCES ../make_tracing_c/top.v)
|
SOURCES ../make_tracing_c/top.v)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ set_property(
|
|||||||
# Add the Verilated circuit to the target
|
# Add the Verilated circuit to the target
|
||||||
verilate(example SYSTEMC COVERAGE TRACE
|
verilate(example SYSTEMC COVERAGE TRACE
|
||||||
INCLUDE_DIRS "../make_tracing_sc"
|
INCLUDE_DIRS "../make_tracing_sc"
|
||||||
VERILATOR_ARGS -f ../make_tracing_sc/input.vc -Os -x-assign 0
|
VERILATOR_ARGS -f ../make_tracing_sc/input.vc -x-assign fast
|
||||||
SOURCES ../make_tracing_sc/top.v)
|
SOURCES ../make_tracing_sc/top.v)
|
||||||
|
|
||||||
verilator_link_systemc(example)
|
verilator_link_systemc(example)
|
||||||
|
|||||||
@@ -21,11 +21,14 @@ int main(int argc, char** argv, char** env) {
|
|||||||
// Prevent unused variable warnings
|
// Prevent unused variable warnings
|
||||||
if (false && argc && argv && env) {}
|
if (false && argc && argv && env) {}
|
||||||
|
|
||||||
|
// Construct a VerilatedContext to hold simulation time, etc.
|
||||||
|
VerilatedContext* contextp = new VerilatedContext;
|
||||||
|
|
||||||
// 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;
|
Vtop* top = new Vtop{contextp};
|
||||||
|
|
||||||
// Simulate until $finish
|
// Simulate until $finish
|
||||||
while (!Verilated::gotFinish()) {
|
while (!contextp->gotFinish()) {
|
||||||
|
|
||||||
// Evaluate model
|
// Evaluate model
|
||||||
top->eval();
|
top->eval();
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ VERILATOR_FLAGS =
|
|||||||
# Generate C++
|
# Generate C++
|
||||||
VERILATOR_FLAGS += -cc
|
VERILATOR_FLAGS += -cc
|
||||||
# Optimize
|
# Optimize
|
||||||
VERILATOR_FLAGS += -Os -x-assign 0
|
VERILATOR_FLAGS += -x-assign fast
|
||||||
# Warn abount lint issues; may not want this on less solid designs
|
# Warn abount lint issues; may not want this on less solid designs
|
||||||
VERILATOR_FLAGS += -Wall
|
VERILATOR_FLAGS += -Wall
|
||||||
# This example does not use vl_time_stamp but rather
|
# This example does not use vl_time_stamp but rather
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ int main(int argc, char** argv, char** env) {
|
|||||||
// When tracing, the contents of the secret module will not be seen
|
// When tracing, the contents of the secret module will not be seen
|
||||||
VerilatedVcdC* tfp = nullptr;
|
VerilatedVcdC* tfp = nullptr;
|
||||||
const char* flag = contextp->commandArgsPlusMatch("trace");
|
const char* flag = contextp->commandArgsPlusMatch("trace");
|
||||||
if (flag && 0 == strcmp(flag, "+trace")) {
|
if (flag && 0 == std::strcmp(flag, "+trace")) {
|
||||||
contextp->traceEverOn(true);
|
contextp->traceEverOn(true);
|
||||||
VL_PRINTF("Enabling waves into logs/vlt_dump.vcd...\n");
|
VL_PRINTF("Enabling waves into logs/vlt_dump.vcd...\n");
|
||||||
tfp = new VerilatedVcdC;
|
tfp = new VerilatedVcdC;
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ VERILATOR_FLAGS += -cc --exe
|
|||||||
# Generate makefile dependencies (not shown as complicates the Makefile)
|
# Generate makefile dependencies (not shown as complicates the Makefile)
|
||||||
#VERILATOR_FLAGS += -MMD
|
#VERILATOR_FLAGS += -MMD
|
||||||
# Optimize
|
# Optimize
|
||||||
VERILATOR_FLAGS += -Os -x-assign 0
|
VERILATOR_FLAGS += -x-assign fast
|
||||||
# Warn abount lint issues; may not want this on less solid designs
|
# Warn abount lint issues; may not want this on less solid designs
|
||||||
VERILATOR_FLAGS += -Wall
|
VERILATOR_FLAGS += -Wall
|
||||||
# Make waveforms
|
# Make waveforms
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ int main(int argc, char** argv, char** env) {
|
|||||||
// Using unique_ptr is similar to
|
// Using unique_ptr is similar to
|
||||||
// "VerilatedContext* contextp = new VerilatedContext" then deleting at end.
|
// "VerilatedContext* contextp = new VerilatedContext" then deleting at end.
|
||||||
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
|
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
|
||||||
|
// Do not instead make Vtop as a file-scope static variable, as the
|
||||||
|
// "C++ static initialization order fiasco" may cause a crash
|
||||||
|
|
||||||
// Set debug level, 0 is off, 9 is highest presently used
|
// Set debug level, 0 is off, 9 is highest presently used
|
||||||
// May be overridden by commandArgs argument parsing
|
// May be overridden by commandArgs argument parsing
|
||||||
@@ -69,7 +71,7 @@ int main(int argc, char** argv, char** env) {
|
|||||||
// Historical note, before Verilator 4.200 Verilated::gotFinish()
|
// Historical note, before Verilator 4.200 Verilated::gotFinish()
|
||||||
// was used above in place of contextp->gotFinish().
|
// was used above in place of contextp->gotFinish().
|
||||||
// Most of the contextp-> calls can use Verilated:: calls instead;
|
// Most of the contextp-> calls can use Verilated:: calls instead;
|
||||||
// the Verilated:: versions simply assume there's a single context
|
// the Verilated:: versions just assume there's a single context
|
||||||
// being used (per thread). It's faster and clearer to use the
|
// being used (per thread). It's faster and clearer to use the
|
||||||
// newer contextp-> versions.
|
// newer contextp-> versions.
|
||||||
|
|
||||||
@@ -103,8 +105,8 @@ int main(int argc, char** argv, char** env) {
|
|||||||
top->eval();
|
top->eval();
|
||||||
|
|
||||||
// Read outputs
|
// Read outputs
|
||||||
VL_PRINTF("[%" VL_PRI64 "d] clk=%x rstl=%x iquad=%" VL_PRI64 "x"
|
VL_PRINTF("[%" PRId64 "] clk=%x rstl=%x iquad=%" PRIx64 " -> oquad=%" PRIx64
|
||||||
" -> oquad=%" VL_PRI64 "x owide=%x_%08x_%08x\n",
|
" owide=%x_%08x_%08x\n",
|
||||||
contextp->time(), top->clk, top->reset_l, top->in_quad, top->out_quad,
|
contextp->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_wide[2], top->out_wide[1], top->out_wide[0]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ VERILATOR_FLAGS += -sc --exe
|
|||||||
# Generate makefile dependencies (not shown as complicates the Makefile)
|
# Generate makefile dependencies (not shown as complicates the Makefile)
|
||||||
#VERILATOR_FLAGS += -MMD
|
#VERILATOR_FLAGS += -MMD
|
||||||
# Optimize
|
# Optimize
|
||||||
VERILATOR_FLAGS += -Os -x-assign 0
|
VERILATOR_FLAGS += -x-assign fast
|
||||||
# Warn abount lint issues; may not want this on less solid designs
|
# Warn abount lint issues; may not want this on less solid designs
|
||||||
VERILATOR_FLAGS += -Wall
|
VERILATOR_FLAGS += -Wall
|
||||||
# Make waveforms
|
# Make waveforms
|
||||||
|
|||||||
@@ -58,11 +58,11 @@ int sc_main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
// Define interconnect
|
// Define interconnect
|
||||||
sc_signal<bool> reset_l;
|
sc_signal<bool> reset_l;
|
||||||
sc_signal<vluint32_t> in_small;
|
sc_signal<uint32_t> in_small;
|
||||||
sc_signal<vluint64_t> in_quad;
|
sc_signal<uint64_t> in_quad;
|
||||||
sc_signal<sc_bv<70>> in_wide;
|
sc_signal<sc_bv<70>> in_wide;
|
||||||
sc_signal<vluint32_t> out_small;
|
sc_signal<uint32_t> out_small;
|
||||||
sc_signal<vluint64_t> out_quad;
|
sc_signal<uint64_t> out_quad;
|
||||||
sc_signal<sc_bv<70>> out_wide;
|
sc_signal<sc_bv<70>> out_wide;
|
||||||
|
|
||||||
// Construct the Verilated model, from inside Vtop.h
|
// Construct the Verilated model, from inside Vtop.h
|
||||||
@@ -82,14 +82,14 @@ int sc_main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
// You must do one evaluation before enabling waves, in order to allow
|
// You must do one evaluation before enabling waves, in order to allow
|
||||||
// SystemC to interconnect everything for testing.
|
// SystemC to interconnect everything for testing.
|
||||||
sc_start(1, SC_NS);
|
sc_start(SC_ZERO_TIME);
|
||||||
|
|
||||||
#if VM_TRACE
|
#if VM_TRACE
|
||||||
// If verilator was invoked with --trace argument,
|
// If verilator was invoked with --trace argument,
|
||||||
// and if at run time passed the +trace argument, turn on tracing
|
// and if at run time passed the +trace argument, turn on tracing
|
||||||
VerilatedVcdSc* tfp = nullptr;
|
VerilatedVcdSc* tfp = nullptr;
|
||||||
const char* flag = Verilated::commandArgsPlusMatch("trace");
|
const char* flag = Verilated::commandArgsPlusMatch("trace");
|
||||||
if (flag && 0 == strcmp(flag, "+trace")) {
|
if (flag && 0 == std::strcmp(flag, "+trace")) {
|
||||||
cout << "Enabling waves into logs/vlt_dump.vcd...\n";
|
cout << "Enabling waves into logs/vlt_dump.vcd...\n";
|
||||||
tfp = new VerilatedVcdSc;
|
tfp = new VerilatedVcdSc;
|
||||||
top->trace(tfp, 99); // Trace 99 levels of hierarchy
|
top->trace(tfp, 99); // Trace 99 levels of hierarchy
|
||||||
|
|||||||
@@ -16,12 +16,13 @@ from shutil import copy2
|
|||||||
|
|
||||||
|
|
||||||
class VlFileCopy:
|
class VlFileCopy:
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
verilator_args, # presently all verilator options are passed-thru
|
verilator_args, # presently all verilator options are passed-thru
|
||||||
# ideally this script would check against options mentioned in help
|
# ideally this script would check against options mentioned in help
|
||||||
debug=0,
|
debug=0,
|
||||||
output_dir='copied'): # directory name we output file uses
|
output_dir='copied'): # directory name we output file uses
|
||||||
|
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
|
|
||||||
|
|||||||
@@ -14,12 +14,13 @@ import xml.etree.ElementTree as ET
|
|||||||
|
|
||||||
|
|
||||||
class VlHierGraph:
|
class VlHierGraph:
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
verilator_args, # presently all verilator options are passed-thru
|
verilator_args, # presently all verilator options are passed-thru
|
||||||
# ideally this script would check against options mentioned in help
|
# ideally this script would check against options mentioned in help
|
||||||
debug=0,
|
debug=0,
|
||||||
output_filename='graph.dot'): # output filename
|
output_filename='graph.dot'): # output filename
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
self.next_vertex_number = 0
|
self.next_vertex_number = 0
|
||||||
self.name_to_number = {}
|
self.name_to_number = {}
|
||||||
|
|||||||
@@ -140,6 +140,10 @@ void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint3
|
|||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(FST_MACOSX) || defined(__MINGW32__) || defined(__OpenBSD__) || defined(__FreeBSD__)
|
||||||
|
#define FST_UNBUFFERED_IO
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
/* Boolean expression more often true than false */
|
/* Boolean expression more often true than false */
|
||||||
#define FST_LIKELY(x) __builtin_expect(!!(x), 1)
|
#define FST_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||||
@@ -4577,12 +4581,11 @@ if(sectype == FST_BL_ZWRAPPER)
|
|||||||
if(!fcomp) { tmpfile_close(&fcomp, &xc->f_nam); return(0); }
|
if(!fcomp) { tmpfile_close(&fcomp, &xc->f_nam); return(0); }
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(FST_MACOSX)
|
#if defined(FST_UNBUFFERED_IO)
|
||||||
setvbuf(fcomp, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */
|
setvbuf(fcomp, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __MINGW32__
|
#ifdef __MINGW32__
|
||||||
setvbuf(fcomp, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */
|
|
||||||
xc->filename_unpacked = hf;
|
xc->filename_unpacked = hf;
|
||||||
#else
|
#else
|
||||||
if(hf)
|
if(hf)
|
||||||
@@ -4880,7 +4883,7 @@ if((!nam)||(!(xc->f=fopen(nam, "rb"))))
|
|||||||
char *hf = (char *)calloc(1, flen + 6);
|
char *hf = (char *)calloc(1, flen + 6);
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
#if defined(__MINGW32__) || defined(FST_MACOSX)
|
#if defined(FST_UNBUFFERED_IO)
|
||||||
setvbuf(xc->f, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */
|
setvbuf(xc->f, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+292
-177
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -47,36 +47,44 @@
|
|||||||
|
|
||||||
#define VERILATOR_VERILATED_CPP_
|
#define VERILATOR_VERILATED_CPP_
|
||||||
|
|
||||||
#include "verilatedos.h"
|
|
||||||
#include "verilated_imp.h"
|
|
||||||
|
|
||||||
#include "verilated_config.h"
|
#include "verilated_config.h"
|
||||||
|
#include "verilatedos.h"
|
||||||
|
|
||||||
|
#include "verilated_imp.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
#include <sstream>
|
#include <cstdlib>
|
||||||
#include <sys/stat.h> // mkdir
|
|
||||||
#include <list>
|
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
#include <list>
|
||||||
|
#include <sstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
|
#include <sys/stat.h> // mkdir
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#if defined(_WIN32) || defined(__MINGW32__)
|
#if defined(_WIN32) || defined(__MINGW32__)
|
||||||
# include <direct.h> // mkdir
|
# include <direct.h> // mkdir
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef VL_THREADED
|
||||||
|
# include "verilated_threads.h"
|
||||||
|
#endif
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
#include "verilated_trace.h"
|
||||||
|
|
||||||
// Max characters in static char string for VL_VALUE_STRING
|
// Max characters in static char string for VL_VALUE_STRING
|
||||||
constexpr unsigned VL_VALUE_STRING_MAX_WIDTH = 8192;
|
constexpr unsigned VL_VALUE_STRING_MAX_WIDTH = 8192;
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Static sanity checks
|
// Static sanity checks
|
||||||
|
|
||||||
static_assert(sizeof(vluint8_t) == 1, "vluint8_t is missized");
|
static_assert(sizeof(uint8_t) == 1, "uint8_t is missized");
|
||||||
static_assert(sizeof(vluint16_t) == 2, "vluint8_t is missized");
|
static_assert(sizeof(uint16_t) == 2, "uint8_t is missized");
|
||||||
static_assert(sizeof(vluint32_t) == 4, "vluint8_t is missized");
|
static_assert(sizeof(uint32_t) == 4, "uint8_t is missized");
|
||||||
static_assert(sizeof(vluint64_t) == 8, "vluint8_t is missized");
|
static_assert(sizeof(uint64_t) == 8, "uint8_t is missized");
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Global variables
|
// Global variables
|
||||||
@@ -168,6 +176,19 @@ void vl_stop_maybe(const char* filename, int linenum, const char* hier, bool may
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef VL_USER_WARN ///< Define this to override the vl_warn function
|
||||||
|
void vl_warn(const char* filename, int linenum, const char* hier, const char* msg) VL_MT_UNSAFE {
|
||||||
|
if (false && hier) {}
|
||||||
|
if (filename && filename[0]) {
|
||||||
|
// Not VL_PRINTF_MT, already on main thread
|
||||||
|
VL_PRINTF("%%Warning: %s:%d: %s\n", filename, linenum, msg);
|
||||||
|
} else {
|
||||||
|
VL_PRINTF("%%Warning: %s\n", msg);
|
||||||
|
}
|
||||||
|
Verilated::runFlushCallbacks();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Wrapper to call certain functions via messages when multithreaded
|
// Wrapper to call certain functions via messages when multithreaded
|
||||||
|
|
||||||
@@ -201,6 +222,16 @@ void VL_FATAL_MT(const char* filename, int linenum, const char* hier, const char
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VL_WARN_MT(const char* filename, int linenum, const char* hier, const char* msg) VL_MT_SAFE {
|
||||||
|
#ifdef VL_THREADED
|
||||||
|
VerilatedThreadMsgQueue::post(VerilatedMsg{[=]() { //
|
||||||
|
vl_warn(filename, linenum, hier, msg);
|
||||||
|
}});
|
||||||
|
#else
|
||||||
|
vl_warn(filename, linenum, hier, msg);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Debug prints
|
// Debug prints
|
||||||
|
|
||||||
@@ -220,21 +251,21 @@ std::string _vl_string_vprintf(const char* formatp, va_list ap) VL_MT_SAFE {
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
vluint64_t _vl_dbg_sequence_number() VL_MT_SAFE {
|
uint64_t _vl_dbg_sequence_number() VL_MT_SAFE {
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
static std::atomic<vluint64_t> sequence;
|
static std::atomic<uint64_t> sequence;
|
||||||
#else
|
#else
|
||||||
static vluint64_t sequence = 0;
|
static uint64_t sequence = 0;
|
||||||
#endif
|
#endif
|
||||||
return ++sequence;
|
return ++sequence;
|
||||||
}
|
}
|
||||||
|
|
||||||
vluint32_t VL_THREAD_ID() VL_MT_SAFE {
|
uint32_t VL_THREAD_ID() VL_MT_SAFE {
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
// Alternative is to use std::this_thread::get_id, but that returns a
|
// Alternative is to use std::this_thread::get_id, but that returns a
|
||||||
// hard-to-read number and is very slow
|
// hard-to-read number and is very slow
|
||||||
static std::atomic<vluint32_t> s_nextId(0);
|
static std::atomic<uint32_t> s_nextId(0);
|
||||||
static VL_THREAD_LOCAL vluint32_t t_myId = ++s_nextId;
|
static VL_THREAD_LOCAL uint32_t t_myId = ++s_nextId;
|
||||||
return t_myId;
|
return t_myId;
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
@@ -248,13 +279,13 @@ void VL_DBG_MSGF(const char* formatp, ...) VL_MT_SAFE {
|
|||||||
va_start(ap, formatp);
|
va_start(ap, formatp);
|
||||||
const std::string out = _vl_string_vprintf(formatp, ap);
|
const std::string out = _vl_string_vprintf(formatp, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
// printf("-imm-V{t%d,%" VL_PRI64 "d}%s", VL_THREAD_ID(), _vl_dbg_sequence_number(),
|
// printf("-imm-V{t%d,%" PRId64 "}%s", VL_THREAD_ID(), _vl_dbg_sequence_number(),
|
||||||
// out.c_str());
|
// out.c_str());
|
||||||
|
|
||||||
// Using VL_PRINTF not VL_PRINTF_MT so that we can call VL_DBG_MSGF
|
// Using VL_PRINTF not VL_PRINTF_MT so that we can call VL_DBG_MSGF
|
||||||
// from within the guts of the thread execution machinery (and it goes
|
// from within the guts of the thread execution machinery (and it goes
|
||||||
// to the screen and not into the queues we're debugging)
|
// to the screen and not into the queues we're debugging)
|
||||||
VL_PRINTF("-V{t%u,%" VL_PRI64 "u}%s", VL_THREAD_ID(), _vl_dbg_sequence_number(), out.c_str());
|
VL_PRINTF("-V{t%u,%" PRIu64 "}%s", VL_THREAD_ID(), _vl_dbg_sequence_number(), out.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
@@ -272,7 +303,7 @@ void VL_PRINTF_MT(const char* formatp, ...) VL_MT_SAFE {
|
|||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Random -- Mostly called at init time, so not inline.
|
// Random -- Mostly called at init time, so not inline.
|
||||||
|
|
||||||
static vluint32_t vl_sys_rand32() VL_MT_UNSAFE {
|
static uint32_t vl_sys_rand32() VL_MT_UNSAFE {
|
||||||
// Return random 32-bits using system library.
|
// Return random 32-bits using system library.
|
||||||
// Used only to construct seed for Verilator's PNRG.
|
// Used only to construct seed for Verilator's PNRG.
|
||||||
static VerilatedMutex s_mutex;
|
static VerilatedMutex s_mutex;
|
||||||
@@ -285,9 +316,9 @@ static vluint32_t vl_sys_rand32() VL_MT_UNSAFE {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
vluint64_t vl_rand64() VL_MT_SAFE {
|
uint64_t vl_rand64() VL_MT_SAFE {
|
||||||
static VL_THREAD_LOCAL vluint64_t t_state[2];
|
static VL_THREAD_LOCAL uint64_t t_state[2];
|
||||||
static VL_THREAD_LOCAL vluint32_t t_seedEpoch = 0;
|
static VL_THREAD_LOCAL uint32_t t_seedEpoch = 0;
|
||||||
// For speed, we use a thread-local epoch number to know when to reseed
|
// For speed, we use a thread-local epoch number to know when to reseed
|
||||||
// A thread always belongs to a single context, so this works out ok
|
// A thread always belongs to a single context, so this works out ok
|
||||||
if (VL_UNLIKELY(t_seedEpoch != VerilatedContextImp::randSeedEpoch())) {
|
if (VL_UNLIKELY(t_seedEpoch != VerilatedContextImp::randSeedEpoch())) {
|
||||||
@@ -301,7 +332,7 @@ vluint64_t vl_rand64() VL_MT_SAFE {
|
|||||||
if (VL_COUNTONES_I(t_state[1]) < 10) t_state[1] = ~t_state[1];
|
if (VL_COUNTONES_I(t_state[1]) < 10) t_state[1] = ~t_state[1];
|
||||||
}
|
}
|
||||||
// Xoroshiro128+ algorithm
|
// Xoroshiro128+ algorithm
|
||||||
const vluint64_t result = t_state[0] + t_state[1];
|
const uint64_t result = t_state[0] + t_state[1];
|
||||||
t_state[1] ^= t_state[0];
|
t_state[1] ^= t_state[0];
|
||||||
t_state[0] = (((t_state[0] << 55) | (t_state[0] >> 9)) ^ t_state[1] ^ (t_state[1] << 14));
|
t_state[0] = (((t_state[0] << 55) | (t_state[0] >> 9)) ^ t_state[1] ^ (t_state[1] << 14));
|
||||||
t_state[1] = (t_state[1] << 36) | (t_state[1] >> 28);
|
t_state[1] = (t_state[1] << 36) | (t_state[1] >> 28);
|
||||||
@@ -314,11 +345,17 @@ WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp) VL_MT_SAFE {
|
|||||||
return outwp;
|
return outwp;
|
||||||
}
|
}
|
||||||
|
|
||||||
IData VL_RANDOM_SEEDED_II(IData seed) VL_MT_SAFE {
|
IData VL_RANDOM_SEEDED_II(IData& seedr) VL_MT_SAFE {
|
||||||
|
// $random - seed is a new seed to apply, then we return new seed
|
||||||
|
Verilated::threadContextp()->randSeed(static_cast<int>(seedr));
|
||||||
|
seedr = VL_RANDOM_I();
|
||||||
|
return VL_RANDOM_I();
|
||||||
|
}
|
||||||
|
IData VL_URANDOM_SEEDED_II(IData seed) VL_MT_SAFE {
|
||||||
|
// $urandom - seed is a new seed to apply
|
||||||
Verilated::threadContextp()->randSeed(static_cast<int>(seed));
|
Verilated::threadContextp()->randSeed(static_cast<int>(seed));
|
||||||
return VL_RANDOM_I();
|
return VL_RANDOM_I();
|
||||||
}
|
}
|
||||||
|
|
||||||
IData VL_RAND_RESET_I(int obits) VL_MT_SAFE {
|
IData VL_RAND_RESET_I(int obits) VL_MT_SAFE {
|
||||||
if (Verilated::threadContextp()->randReset() == 0) return 0;
|
if (Verilated::threadContextp()->randReset() == 0) return 0;
|
||||||
IData data = ~0;
|
IData data = ~0;
|
||||||
@@ -380,11 +417,11 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, const WDataInP lwp, const WData
|
|||||||
const int vw = VL_WORDS_I(vmsbp1); // aka "n" in the algorithm
|
const int vw = VL_WORDS_I(vmsbp1); // aka "n" in the algorithm
|
||||||
|
|
||||||
if (vw == 1) { // Single divisor word breaks rest of algorithm
|
if (vw == 1) { // Single divisor word breaks rest of algorithm
|
||||||
vluint64_t k = 0;
|
uint64_t k = 0;
|
||||||
for (int j = uw - 1; j >= 0; --j) {
|
for (int j = uw - 1; j >= 0; --j) {
|
||||||
const vluint64_t unw64 = ((k << 32ULL) + static_cast<vluint64_t>(lwp[j]));
|
const uint64_t unw64 = ((k << 32ULL) + static_cast<uint64_t>(lwp[j]));
|
||||||
owp[j] = unw64 / static_cast<vluint64_t>(rwp[0]);
|
owp[j] = unw64 / static_cast<uint64_t>(rwp[0]);
|
||||||
k = unw64 - static_cast<vluint64_t>(owp[j]) * static_cast<vluint64_t>(rwp[0]);
|
k = unw64 - static_cast<uint64_t>(owp[j]) * static_cast<uint64_t>(rwp[0]);
|
||||||
}
|
}
|
||||||
if (is_modulus) {
|
if (is_modulus) {
|
||||||
owp[0] = k;
|
owp[0] = k;
|
||||||
@@ -394,8 +431,8 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, const WDataInP lwp, const WData
|
|||||||
}
|
}
|
||||||
|
|
||||||
// +1 word as we may shift during normalization
|
// +1 word as we may shift during normalization
|
||||||
vluint32_t un[VL_MULS_MAX_WORDS + 1]; // Fixed size, as MSVC++ doesn't allow [words] here
|
uint32_t un[VL_MULS_MAX_WORDS + 1]; // Fixed size, as MSVC++ doesn't allow [words] here
|
||||||
vluint32_t vn[VL_MULS_MAX_WORDS + 1]; // v normalized
|
uint32_t vn[VL_MULS_MAX_WORDS + 1]; // v normalized
|
||||||
|
|
||||||
// Zero for ease of debugging and to save having to zero for shifts
|
// Zero for ease of debugging and to save having to zero for shifts
|
||||||
// Note +1 as loop will use extra word
|
// Note +1 as loop will use extra word
|
||||||
@@ -404,7 +441,7 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, const WDataInP lwp, const WData
|
|||||||
// Algorithm requires divisor MSB to be set
|
// Algorithm requires divisor MSB to be set
|
||||||
// Copy and shift to normalize divisor so MSB of vn[vw-1] is set
|
// Copy and shift to normalize divisor so MSB of vn[vw-1] is set
|
||||||
const int s = 31 - VL_BITBIT_I(vmsbp1 - 1); // shift amount (0...31)
|
const int s = 31 - VL_BITBIT_I(vmsbp1 - 1); // shift amount (0...31)
|
||||||
const vluint32_t shift_mask = s ? 0xffffffff : 0; // otherwise >> 32 won't mask the value
|
const uint32_t shift_mask = s ? 0xffffffff : 0; // otherwise >> 32 won't mask the value
|
||||||
for (int i = vw - 1; i > 0; --i) {
|
for (int i = vw - 1; i > 0; --i) {
|
||||||
vn[i] = (rwp[i] << s) | (shift_mask & (rwp[i - 1] >> (32 - s)));
|
vn[i] = (rwp[i] << s) | (shift_mask & (rwp[i - 1] >> (32 - s)));
|
||||||
}
|
}
|
||||||
@@ -424,10 +461,10 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, const WDataInP lwp, const WData
|
|||||||
// Main loop
|
// Main loop
|
||||||
for (int j = uw - vw; j >= 0; --j) {
|
for (int j = uw - vw; j >= 0; --j) {
|
||||||
// Estimate
|
// Estimate
|
||||||
const vluint64_t unw64 = (static_cast<vluint64_t>(un[j + vw]) << 32ULL
|
const uint64_t unw64
|
||||||
| static_cast<vluint64_t>(un[j + vw - 1]));
|
= (static_cast<uint64_t>(un[j + vw]) << 32ULL | static_cast<uint64_t>(un[j + vw - 1]));
|
||||||
vluint64_t qhat = unw64 / static_cast<vluint64_t>(vn[vw - 1]);
|
uint64_t qhat = unw64 / static_cast<uint64_t>(vn[vw - 1]);
|
||||||
vluint64_t rhat = unw64 - qhat * static_cast<vluint64_t>(vn[vw - 1]);
|
uint64_t rhat = unw64 - qhat * static_cast<uint64_t>(vn[vw - 1]);
|
||||||
|
|
||||||
again:
|
again:
|
||||||
if (qhat >= 0x100000000ULL || ((qhat * vn[vw - 2]) > ((rhat << 32ULL) + un[j + vw - 2]))) {
|
if (qhat >= 0x100000000ULL || ((qhat * vn[vw - 2]) > ((rhat << 32ULL) + un[j + vw - 2]))) {
|
||||||
@@ -436,10 +473,10 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, const WDataInP lwp, const WData
|
|||||||
if (rhat < 0x100000000ULL) goto again;
|
if (rhat < 0x100000000ULL) goto again;
|
||||||
}
|
}
|
||||||
|
|
||||||
vlsint64_t t = 0; // Must be signed
|
int64_t t = 0; // Must be signed
|
||||||
vluint64_t k = 0;
|
uint64_t k = 0;
|
||||||
for (int i = 0; i < vw; ++i) {
|
for (int i = 0; i < vw; ++i) {
|
||||||
const vluint64_t p = qhat * vn[i]; // Multiply by estimate
|
const uint64_t p = qhat * vn[i]; // Multiply by estimate
|
||||||
t = un[i + j] - k - (p & 0xFFFFFFFFULL); // Subtract
|
t = un[i + j] - k - (p & 0xFFFFFFFFULL); // Subtract
|
||||||
un[i + j] = t;
|
un[i + j] = t;
|
||||||
k = (p >> 32ULL) - (t >> 32ULL);
|
k = (p >> 32ULL) - (t >> 32ULL);
|
||||||
@@ -453,7 +490,7 @@ WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, const WDataInP lwp, const WData
|
|||||||
owp[j]--;
|
owp[j]--;
|
||||||
k = 0;
|
k = 0;
|
||||||
for (int i = 0; i < vw; ++i) {
|
for (int i = 0; i < vw; ++i) {
|
||||||
t = static_cast<vluint64_t>(un[i + j]) + static_cast<vluint64_t>(vn[i]) + k;
|
t = static_cast<uint64_t>(un[i + j]) + static_cast<uint64_t>(vn[i]) + k;
|
||||||
un[i + j] = t;
|
un[i + j] = t;
|
||||||
k = t >> 32ULL;
|
k = t >> 32ULL;
|
||||||
}
|
}
|
||||||
@@ -584,7 +621,7 @@ double VL_ITOR_D_W(int lbits, const WDataInP lwp) VL_PURE {
|
|||||||
}
|
}
|
||||||
double VL_ISTOR_D_W(int lbits, const WDataInP lwp) VL_PURE {
|
double VL_ISTOR_D_W(int lbits, const WDataInP lwp) VL_PURE {
|
||||||
if (!VL_SIGN_W(lbits, lwp)) return VL_ITOR_D_W(lbits, lwp);
|
if (!VL_SIGN_W(lbits, lwp)) return VL_ITOR_D_W(lbits, lwp);
|
||||||
vluint32_t pos[VL_MULS_MAX_WORDS + 1]; // Fixed size, as MSVC++ doesn't allow [words] here
|
uint32_t pos[VL_MULS_MAX_WORDS + 1]; // Fixed size, as MSVC++ doesn't allow [words] here
|
||||||
VL_NEGATE_W(VL_WORDS_I(lbits), pos, lwp);
|
VL_NEGATE_W(VL_WORDS_I(lbits), pos, lwp);
|
||||||
_vl_clean_inplace_w(lbits, pos);
|
_vl_clean_inplace_w(lbits, pos);
|
||||||
return -VL_ITOR_D_W(lbits, pos);
|
return -VL_ITOR_D_W(lbits, pos);
|
||||||
@@ -643,7 +680,10 @@ std::string _vl_vsformat_time(char* tmp, T ld, int timeunit, bool left, size_t w
|
|||||||
if (std::numeric_limits<T>::is_integer) {
|
if (std::numeric_limits<T>::is_integer) {
|
||||||
constexpr int b = 128;
|
constexpr int b = 128;
|
||||||
constexpr int w = VL_WORDS_I(b);
|
constexpr int w = VL_WORDS_I(b);
|
||||||
VlWide<w> tmp0, tmp1, tmp2, tmp3;
|
VlWide<w> tmp0;
|
||||||
|
VlWide<w> tmp1;
|
||||||
|
VlWide<w> tmp2;
|
||||||
|
VlWide<w> tmp3;
|
||||||
|
|
||||||
WDataInP shifted = VL_EXTEND_WQ(b, 0, tmp0, static_cast<QData>(ld));
|
WDataInP shifted = VL_EXTEND_WQ(b, 0, tmp0, static_cast<QData>(ld));
|
||||||
if (shift < 0) {
|
if (shift < 0) {
|
||||||
@@ -658,10 +698,11 @@ std::string _vl_vsformat_time(char* tmp, T ld, int timeunit, bool left, size_t w
|
|||||||
const WDataInP integer = VL_DIV_WWW(b, tmp0, shifted, fracDigitsPow10);
|
const WDataInP integer = VL_DIV_WWW(b, tmp0, shifted, fracDigitsPow10);
|
||||||
const WDataInP frac = VL_MODDIV_WWW(b, tmp1, shifted, fracDigitsPow10);
|
const WDataInP frac = VL_MODDIV_WWW(b, tmp1, shifted, fracDigitsPow10);
|
||||||
const WDataInP max64Bit
|
const WDataInP max64Bit
|
||||||
= VL_EXTEND_WQ(b, 0, tmp2, std::numeric_limits<vluint64_t>::max()); // breaks shifted
|
= VL_EXTEND_WQ(b, 0, tmp2, std::numeric_limits<uint64_t>::max()); // breaks shifted
|
||||||
if (VL_GT_W(w, integer, max64Bit)) {
|
if (VL_GT_W(w, integer, max64Bit)) {
|
||||||
WDataOutP v = VL_ASSIGN_W(b, tmp3, integer); // breaks fracDigitsPow10
|
WDataOutP v = VL_ASSIGN_W(b, tmp3, integer); // breaks fracDigitsPow10
|
||||||
VlWide<w> zero, ten;
|
VlWide<w> zero;
|
||||||
|
VlWide<w> ten;
|
||||||
VL_ZERO_W(b, zero);
|
VL_ZERO_W(b, zero);
|
||||||
VL_EXTEND_WI(b, 0, ten, 10);
|
VL_EXTEND_WI(b, 0, ten, 10);
|
||||||
char buf[128]; // 128B is obviously long enough to represent 128bit integer in decimal
|
char buf[128]; // 128B is obviously long enough to represent 128bit integer in decimal
|
||||||
@@ -678,18 +719,17 @@ std::string _vl_vsformat_time(char* tmp, T ld, int timeunit, bool left, size_t w
|
|||||||
if (!fracDigits) {
|
if (!fracDigits) {
|
||||||
digits = VL_SNPRINTF(tmp, VL_VALUE_STRING_MAX_WIDTH, "%s%s", ptr, suffix.c_str());
|
digits = VL_SNPRINTF(tmp, VL_VALUE_STRING_MAX_WIDTH, "%s%s", ptr, suffix.c_str());
|
||||||
} else {
|
} else {
|
||||||
digits = VL_SNPRINTF(tmp, VL_VALUE_STRING_MAX_WIDTH, "%s.%0*" VL_PRI64 "u%s", ptr,
|
digits = VL_SNPRINTF(tmp, VL_VALUE_STRING_MAX_WIDTH, "%s.%0*" PRIu64 "%s", ptr,
|
||||||
fracDigits, VL_SET_QW(frac), suffix.c_str());
|
fracDigits, VL_SET_QW(frac), suffix.c_str());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const vluint64_t integer64 = VL_SET_QW(integer);
|
const uint64_t integer64 = VL_SET_QW(integer);
|
||||||
if (!fracDigits) {
|
if (!fracDigits) {
|
||||||
digits = VL_SNPRINTF(tmp, VL_VALUE_STRING_MAX_WIDTH, "%" VL_PRI64 "u%s", integer64,
|
digits = VL_SNPRINTF(tmp, VL_VALUE_STRING_MAX_WIDTH, "%" PRIu64 "%s", integer64,
|
||||||
suffix.c_str());
|
suffix.c_str());
|
||||||
} else {
|
} else {
|
||||||
digits = VL_SNPRINTF(tmp, VL_VALUE_STRING_MAX_WIDTH,
|
digits = VL_SNPRINTF(tmp, VL_VALUE_STRING_MAX_WIDTH, "%" PRIu64 ".%0*" PRIu64 "%s",
|
||||||
"%" VL_PRI64 "u.%0*" VL_PRI64 "u%s", integer64, fracDigits,
|
integer64, fracDigits, VL_SET_QW(frac), suffix.c_str());
|
||||||
VL_SET_QW(frac), suffix.c_str());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -850,9 +890,9 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
|||||||
int digits = 0;
|
int digits = 0;
|
||||||
std::string append;
|
std::string append;
|
||||||
if (lbits <= VL_QUADSIZE) {
|
if (lbits <= VL_QUADSIZE) {
|
||||||
digits = VL_SNPRINTF(
|
digits
|
||||||
t_tmp, VL_VALUE_STRING_MAX_WIDTH, "%" VL_PRI64 "d",
|
= VL_SNPRINTF(t_tmp, VL_VALUE_STRING_MAX_WIDTH, "%" PRId64,
|
||||||
static_cast<vlsint64_t>(VL_EXTENDS_QQ(lbits, lbits, ld)));
|
static_cast<int64_t>(VL_EXTENDS_QQ(lbits, lbits, ld)));
|
||||||
append = t_tmp;
|
append = t_tmp;
|
||||||
} else {
|
} else {
|
||||||
if (VL_SIGN_E(lbits, lwp[VL_WORDS_I(lbits) - 1])) {
|
if (VL_SIGN_E(lbits, lwp[VL_WORDS_I(lbits) - 1])) {
|
||||||
@@ -880,8 +920,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
|||||||
int digits = 0;
|
int digits = 0;
|
||||||
std::string append;
|
std::string append;
|
||||||
if (lbits <= VL_QUADSIZE) {
|
if (lbits <= VL_QUADSIZE) {
|
||||||
digits
|
digits = VL_SNPRINTF(t_tmp, VL_VALUE_STRING_MAX_WIDTH, "%" PRIu64, ld);
|
||||||
= VL_SNPRINTF(t_tmp, VL_VALUE_STRING_MAX_WIDTH, "%" VL_PRI64 "u", ld);
|
|
||||||
append = t_tmp;
|
append = t_tmp;
|
||||||
} else {
|
} else {
|
||||||
append = VL_DECIMAL_NW(lbits, lwp);
|
append = VL_DECIMAL_NW(lbits, lwp);
|
||||||
@@ -964,22 +1003,22 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool _vl_vsss_eof(FILE* fp, int floc) VL_MT_SAFE {
|
static bool _vl_vsss_eof(FILE* fp, int floc) VL_MT_SAFE {
|
||||||
if (VL_LIKELY(fp)) {
|
if (VL_LIKELY(fp)) {
|
||||||
return std::feof(fp) ? true : false; // true : false to prevent MSVC++ warning
|
return std::feof(fp) ? true : false; // true : false to prevent MSVC++ warning
|
||||||
} else {
|
} else {
|
||||||
return floc < 0;
|
return floc < 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static inline void _vl_vsss_advance(FILE* fp, int& floc) VL_MT_SAFE {
|
static void _vl_vsss_advance(FILE* fp, int& floc) VL_MT_SAFE {
|
||||||
if (VL_LIKELY(fp)) {
|
if (VL_LIKELY(fp)) {
|
||||||
std::fgetc(fp);
|
std::fgetc(fp);
|
||||||
} else {
|
} else {
|
||||||
floc -= 8;
|
floc -= 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static inline int _vl_vsss_peek(FILE* fp, int& floc, const WDataInP fromp,
|
static int _vl_vsss_peek(FILE* fp, int& floc, const WDataInP fromp,
|
||||||
const std::string& fstr) VL_MT_SAFE {
|
const std::string& fstr) VL_MT_SAFE {
|
||||||
// Get a character without advancing
|
// Get a character without advancing
|
||||||
if (VL_LIKELY(fp)) {
|
if (VL_LIKELY(fp)) {
|
||||||
const int data = std::fgetc(fp);
|
const int data = std::fgetc(fp);
|
||||||
@@ -996,17 +1035,16 @@ static inline int _vl_vsss_peek(FILE* fp, int& floc, const WDataInP fromp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static inline void _vl_vsss_skipspace(FILE* fp, int& floc, const WDataInP fromp,
|
static void _vl_vsss_skipspace(FILE* fp, int& floc, const WDataInP fromp,
|
||||||
const std::string& fstr) VL_MT_SAFE {
|
const std::string& fstr) VL_MT_SAFE {
|
||||||
while (true) {
|
while (true) {
|
||||||
const int c = _vl_vsss_peek(fp, floc, fromp, fstr);
|
const int c = _vl_vsss_peek(fp, floc, fromp, fstr);
|
||||||
if (c == EOF || !std::isspace(c)) return;
|
if (c == EOF || !std::isspace(c)) return;
|
||||||
_vl_vsss_advance(fp, floc);
|
_vl_vsss_advance(fp, floc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static inline void _vl_vsss_read_str(FILE* fp, int& floc, const WDataInP fromp,
|
static void _vl_vsss_read_str(FILE* fp, int& floc, const WDataInP fromp, const std::string& fstr,
|
||||||
const std::string& fstr, char* tmpp,
|
char* tmpp, const char* acceptp) VL_MT_SAFE {
|
||||||
const char* acceptp) VL_MT_SAFE {
|
|
||||||
// Read into tmp, consisting of characters from acceptp list
|
// Read into tmp, consisting of characters from acceptp list
|
||||||
char* cp = tmpp;
|
char* cp = tmpp;
|
||||||
while (true) {
|
while (true) {
|
||||||
@@ -1020,9 +1058,8 @@ static inline void _vl_vsss_read_str(FILE* fp, int& floc, const WDataInP fromp,
|
|||||||
*cp++ = '\0';
|
*cp++ = '\0';
|
||||||
// VL_DBG_MSGF(" _read got='"<<tmpp<<"'\n");
|
// VL_DBG_MSGF(" _read got='"<<tmpp<<"'\n");
|
||||||
}
|
}
|
||||||
static inline char* _vl_vsss_read_bin(FILE* fp, int& floc, const WDataInP fromp,
|
static char* _vl_vsss_read_bin(FILE* fp, int& floc, const WDataInP fromp, const std::string& fstr,
|
||||||
const std::string& fstr, char* beginp, std::size_t n,
|
char* beginp, std::size_t n, const bool inhibit = false) {
|
||||||
const bool inhibit = false) {
|
|
||||||
// Variant of _vl_vsss_read_str using the same underlying I/O functions but optimized
|
// Variant of _vl_vsss_read_str using the same underlying I/O functions but optimized
|
||||||
// specifically for block reads of N bytes (read operations are not demarcated by
|
// specifically for block reads of N bytes (read operations are not demarcated by
|
||||||
// whitespace). In the fp case, except descriptor to have been opened in binary mode.
|
// whitespace). In the fp case, except descriptor to have been opened in binary mode.
|
||||||
@@ -1034,12 +1071,11 @@ static inline char* _vl_vsss_read_bin(FILE* fp, int& floc, const WDataInP fromp,
|
|||||||
}
|
}
|
||||||
return beginp;
|
return beginp;
|
||||||
}
|
}
|
||||||
static inline void _vl_vsss_setbit(WDataOutP owp, int obits, int lsb, int nbits,
|
static void _vl_vsss_setbit(WDataOutP owp, int obits, int lsb, int nbits, IData ld) VL_MT_SAFE {
|
||||||
IData ld) VL_MT_SAFE {
|
|
||||||
for (; nbits && lsb < obits; nbits--, lsb++, ld >>= 1) { VL_ASSIGNBIT_WI(lsb, owp, ld & 1); }
|
for (; nbits && lsb < obits; nbits--, lsb++, ld >>= 1) { VL_ASSIGNBIT_WI(lsb, owp, ld & 1); }
|
||||||
}
|
}
|
||||||
static inline void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp,
|
static void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp,
|
||||||
size_t posstart, size_t posend) VL_MT_SAFE {
|
size_t posstart, size_t posend) VL_MT_SAFE {
|
||||||
// Read in base "2^^baseLog2" digits from strp[posstart..posend-1] into owp of size obits.
|
// Read in base "2^^baseLog2" digits from strp[posstart..posend-1] into owp of size obits.
|
||||||
int lsb = 0;
|
int lsb = 0;
|
||||||
for (int i = 0, pos = static_cast<int>(posend) - 1;
|
for (int i = 0, pos = static_cast<int>(posend) - 1;
|
||||||
@@ -1156,8 +1192,8 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
|||||||
_vl_vsss_skipspace(fp, floc, fromp, fstr);
|
_vl_vsss_skipspace(fp, floc, fromp, fstr);
|
||||||
_vl_vsss_read_str(fp, floc, fromp, fstr, t_tmp, "0123456789+-xXzZ?_");
|
_vl_vsss_read_str(fp, floc, fromp, fstr, t_tmp, "0123456789+-xXzZ?_");
|
||||||
if (!t_tmp[0]) goto done;
|
if (!t_tmp[0]) goto done;
|
||||||
vlsint64_t ld = 0;
|
int64_t ld = 0;
|
||||||
std::sscanf(t_tmp, "%30" VL_PRI64 "d", &ld);
|
std::sscanf(t_tmp, "%30" PRId64, &ld);
|
||||||
VL_SET_WQ(owp, ld);
|
VL_SET_WQ(owp, ld);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1170,7 +1206,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
|||||||
// cppcheck-suppress unusedStructMember // It's used
|
// cppcheck-suppress unusedStructMember // It's used
|
||||||
union {
|
union {
|
||||||
double r;
|
double r;
|
||||||
vlsint64_t ld;
|
int64_t ld;
|
||||||
} u;
|
} u;
|
||||||
u.r = std::strtod(t_tmp, nullptr);
|
u.r = std::strtod(t_tmp, nullptr);
|
||||||
VL_SET_WQ(owp, u.ld);
|
VL_SET_WQ(owp, u.ld);
|
||||||
@@ -1182,7 +1218,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
|||||||
_vl_vsss_read_str(fp, floc, fromp, fstr, t_tmp, "0123456789+-xXzZ?_");
|
_vl_vsss_read_str(fp, floc, fromp, fstr, t_tmp, "0123456789+-xXzZ?_");
|
||||||
if (!t_tmp[0]) goto done;
|
if (!t_tmp[0]) goto done;
|
||||||
QData ld = 0;
|
QData ld = 0;
|
||||||
std::sscanf(t_tmp, "%30" VL_PRI64 "u", &ld);
|
std::sscanf(t_tmp, "%30" PRIu64, &ld);
|
||||||
VL_SET_WQ(owp, ld);
|
VL_SET_WQ(owp, ld);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1425,11 +1461,12 @@ void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) VL_MT_SAFE {
|
|||||||
|
|
||||||
void VL_SFORMAT_X(int obits_ignored, std::string& output, const char* formatp, ...) VL_MT_SAFE {
|
void VL_SFORMAT_X(int obits_ignored, std::string& output, const char* formatp, ...) VL_MT_SAFE {
|
||||||
if (obits_ignored) {}
|
if (obits_ignored) {}
|
||||||
output = "";
|
std::string temp_output;
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, formatp);
|
va_start(ap, formatp);
|
||||||
_vl_vsformat(output, formatp, ap);
|
_vl_vsformat(temp_output, formatp, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
output = temp_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string VL_SFORMATF_NX(const char* formatp, ...) VL_MT_SAFE {
|
std::string VL_SFORMATF_NX(const char* formatp, ...) VL_MT_SAFE {
|
||||||
@@ -1470,7 +1507,7 @@ void VL_FWRITEF(IData fpi, const char* formatp, ...) VL_MT_SAFE {
|
|||||||
IData VL_FSCANF_IX(IData fpi, const char* formatp, ...) VL_MT_SAFE {
|
IData VL_FSCANF_IX(IData fpi, const char* formatp, ...) VL_MT_SAFE {
|
||||||
// While threadsafe, each thread can only access different file handles
|
// While threadsafe, each thread can only access different file handles
|
||||||
FILE* const fp = VL_CVT_I_FP(fpi);
|
FILE* const fp = VL_CVT_I_FP(fpi);
|
||||||
if (VL_UNLIKELY(!fp)) return 0;
|
if (VL_UNLIKELY(!fp)) return ~0U; // -1
|
||||||
|
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, formatp);
|
va_start(ap, formatp);
|
||||||
@@ -1578,8 +1615,8 @@ IData VL_SYSTEM_IW(int lhswords, const WDataInP lhsp) VL_MT_SAFE {
|
|||||||
return code >> 8; // Want exit status
|
return code >> 8; // Want exit status
|
||||||
}
|
}
|
||||||
|
|
||||||
IData VL_TESTPLUSARGS_I(const char* formatp) VL_MT_SAFE {
|
IData VL_TESTPLUSARGS_I(const std::string& format) VL_MT_SAFE {
|
||||||
const std::string& match = Verilated::threadContextp()->impp()->argPlusMatch(formatp);
|
const std::string& match = Verilated::threadContextp()->impp()->argPlusMatch(format.c_str());
|
||||||
return match.empty() ? 0 : 1;
|
return match.empty() ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1615,8 +1652,8 @@ IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) VL_M
|
|||||||
VL_ZERO_RESET_W(rbits, rwp);
|
VL_ZERO_RESET_W(rbits, rwp);
|
||||||
switch (std::tolower(fmt)) {
|
switch (std::tolower(fmt)) {
|
||||||
case 'd': {
|
case 'd': {
|
||||||
vlsint64_t lld = 0;
|
int64_t lld = 0;
|
||||||
std::sscanf(dp, "%30" VL_PRI64 "d", &lld);
|
std::sscanf(dp, "%30" PRId64, &lld);
|
||||||
VL_SET_WQ(rwp, lld);
|
VL_SET_WQ(rwp, lld);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1650,7 +1687,7 @@ IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) VL_M
|
|||||||
VL_SET_WQ(rwp, VL_CVT_Q_D(temp));
|
VL_SET_WQ(rwp, VL_CVT_Q_D(temp));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: // Other simulators simply return 0 in these cases and don't error out
|
default: // Other simulators return 0 in these cases and don't error out
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
_vl_clean_inplace_w(rbits, rwp);
|
_vl_clean_inplace_w(rbits, rwp);
|
||||||
@@ -1740,7 +1777,7 @@ std::string VL_CVT_PACK_STR_NW(int lwords, const WDataInP lwp) VL_MT_SAFE {
|
|||||||
|
|
||||||
std::string VL_PUTC_N(const std::string& lhs, IData rhs, CData ths) VL_PURE {
|
std::string VL_PUTC_N(const std::string& lhs, IData rhs, CData ths) VL_PURE {
|
||||||
std::string lstring = lhs;
|
std::string lstring = lhs;
|
||||||
const vlsint32_t rhs_s = rhs; // To signed value
|
const int32_t rhs_s = rhs; // To signed value
|
||||||
// 6.16.2:str.putc(i, c) does not change the value when i < 0 || i >= str.len() || c == 0
|
// 6.16.2:str.putc(i, c) does not change the value when i < 0 || i >= str.len() || c == 0
|
||||||
if (0 <= rhs_s && rhs < lhs.length() && ths != 0) lstring[rhs] = ths;
|
if (0 <= rhs_s && rhs < lhs.length() && ths != 0) lstring[rhs] = ths;
|
||||||
return lstring;
|
return lstring;
|
||||||
@@ -1748,15 +1785,15 @@ std::string VL_PUTC_N(const std::string& lhs, IData rhs, CData ths) VL_PURE {
|
|||||||
|
|
||||||
CData VL_GETC_N(const std::string& lhs, IData rhs) VL_PURE {
|
CData VL_GETC_N(const std::string& lhs, IData rhs) VL_PURE {
|
||||||
CData v = 0;
|
CData v = 0;
|
||||||
const vlsint32_t rhs_s = rhs; // To signed value
|
const int32_t rhs_s = rhs; // To signed value
|
||||||
// 6.16.3:str.getc(i) returns 0 if i < 0 || i >= str.len()
|
// 6.16.3:str.getc(i) returns 0 if i < 0 || i >= str.len()
|
||||||
if (0 <= rhs_s && rhs < lhs.length()) v = lhs[rhs];
|
if (0 <= rhs_s && rhs < lhs.length()) v = lhs[rhs];
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string VL_SUBSTR_N(const std::string& lhs, IData rhs, IData ths) VL_PURE {
|
std::string VL_SUBSTR_N(const std::string& lhs, IData rhs, IData ths) VL_PURE {
|
||||||
const vlsint32_t rhs_s = rhs; // To signed value
|
const int32_t rhs_s = rhs; // To signed value
|
||||||
const vlsint32_t ths_s = ths; // To signed value
|
const int32_t ths_s = ths; // To signed value
|
||||||
// 6.16.8:str.substr(i, j) returns an empty string when i < 0 || j < i || j >= str.len()
|
// 6.16.8:str.substr(i, j) returns an empty string when i < 0 || j < i || j >= str.len()
|
||||||
if (rhs_s < 0 || ths_s < rhs_s || ths >= lhs.length()) return "";
|
if (rhs_s < 0 || ths_s < rhs_s || ths >= lhs.length()) return "";
|
||||||
// Second parameter of std::string::substr(i, n) is length, not position as in SystemVerilog
|
// Second parameter of std::string::substr(i, n) is length, not position as in SystemVerilog
|
||||||
@@ -1795,7 +1832,7 @@ static const char* memhFormat(int nBits) {
|
|||||||
return t_buf;
|
return t_buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* formatBinary(int nBits, vluint32_t bits) {
|
static const char* formatBinary(int nBits, uint32_t bits) {
|
||||||
assert((nBits >= 1) && (nBits <= 32));
|
assert((nBits >= 1) && (nBits <= 32));
|
||||||
|
|
||||||
static VL_THREAD_LOCAL char t_buf[64];
|
static VL_THREAD_LOCAL char t_buf[64];
|
||||||
@@ -1812,12 +1849,11 @@ VlReadMem::VlReadMem(bool hex, int bits, const std::string& filename, QData star
|
|||||||
, m_bits{bits}
|
, m_bits{bits}
|
||||||
, m_filename(filename) // Need () or GCC 4.8 false warning
|
, m_filename(filename) // Need () or GCC 4.8 false warning
|
||||||
, m_end{end}
|
, m_end{end}
|
||||||
, m_addr{start}
|
, m_addr{start} {
|
||||||
, m_linenum{0} {
|
|
||||||
m_fp = std::fopen(filename.c_str(), "r");
|
m_fp = std::fopen(filename.c_str(), "r");
|
||||||
if (VL_UNLIKELY(!m_fp)) {
|
if (VL_UNLIKELY(!m_fp)) {
|
||||||
// We don't report the Verilog source filename as it slow to have to pass it down
|
// We don't report the Verilog source filename as it slow to have to pass it down
|
||||||
VL_FATAL_MT(filename.c_str(), 0, "", "$readmem file not found");
|
VL_WARN_MT(filename.c_str(), 0, "", "$readmem file not found");
|
||||||
// cppcheck-suppress resourceLeak // m_fp is nullptr - bug in cppcheck
|
// cppcheck-suppress resourceLeak // m_fp is nullptr - bug in cppcheck
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1876,6 +1912,7 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) {
|
|||||||
ignore_to_eol = true;
|
ignore_to_eol = true;
|
||||||
} else if (c == '@') {
|
} else if (c == '@') {
|
||||||
reading_addr = true;
|
reading_addr = true;
|
||||||
|
m_anyAddr = true;
|
||||||
m_addr = 0;
|
m_addr = 0;
|
||||||
}
|
}
|
||||||
// Check for hex or binary digits as file format requests
|
// Check for hex or binary digits as file format requests
|
||||||
@@ -1902,9 +1939,9 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) {
|
|||||||
lastc = c;
|
lastc = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (VL_UNLIKELY(m_end != ~0ULL && m_addr <= m_end)) {
|
if (VL_UNLIKELY(m_end != ~0ULL && m_addr <= m_end && !m_anyAddr)) {
|
||||||
VL_FATAL_MT(m_filename.c_str(), m_linenum, "",
|
VL_WARN_MT(m_filename.c_str(), m_linenum, "",
|
||||||
"$readmem file ended before specified final address (IEEE 2017 21.4)");
|
"$readmem file ended before specified final address (IEEE 2017 21.4)");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false; // EOF
|
return false; // EOF
|
||||||
@@ -1946,8 +1983,7 @@ void VlReadMem::setData(void* valuep, const std::string& rhs) {
|
|||||||
|
|
||||||
VlWriteMem::VlWriteMem(bool hex, int bits, const std::string& filename, QData start, QData end)
|
VlWriteMem::VlWriteMem(bool hex, int bits, const std::string& filename, QData start, QData end)
|
||||||
: m_hex{hex}
|
: m_hex{hex}
|
||||||
, m_bits{bits}
|
, m_bits{bits} {
|
||||||
, m_addr{0} {
|
|
||||||
if (VL_UNLIKELY(start > end)) {
|
if (VL_UNLIKELY(start > end)) {
|
||||||
VL_FATAL_MT(filename.c_str(), 0, "", "$writemem invalid address range");
|
VL_FATAL_MT(filename.c_str(), 0, "", "$writemem invalid address range");
|
||||||
return;
|
return;
|
||||||
@@ -1969,7 +2005,7 @@ VlWriteMem::~VlWriteMem() {
|
|||||||
void VlWriteMem::print(QData addr, bool addrstamp, const void* valuep) {
|
void VlWriteMem::print(QData addr, bool addrstamp, const void* valuep) {
|
||||||
if (VL_UNLIKELY(!m_fp)) return;
|
if (VL_UNLIKELY(!m_fp)) return;
|
||||||
if (addr != m_addr && addrstamp) { // Only assoc has time stamps
|
if (addr != m_addr && addrstamp) { // Only assoc has time stamps
|
||||||
fprintf(m_fp, "@%" VL_PRI64 "x\n", addr);
|
fprintf(m_fp, "@%" PRIx64 "\n", addr);
|
||||||
}
|
}
|
||||||
m_addr = addr + 1;
|
m_addr = addr + 1;
|
||||||
if (m_bits <= 8) {
|
if (m_bits <= 8) {
|
||||||
@@ -1998,9 +2034,9 @@ void VlWriteMem::print(QData addr, bool addrstamp, const void* valuep) {
|
|||||||
}
|
}
|
||||||
} else if (m_bits <= 64) {
|
} else if (m_bits <= 64) {
|
||||||
const QData* const datap = reinterpret_cast<const QData*>(valuep);
|
const QData* const datap = reinterpret_cast<const QData*>(valuep);
|
||||||
const vluint64_t value = VL_MASK_Q(m_bits) & *datap;
|
const uint64_t value = VL_MASK_Q(m_bits) & *datap;
|
||||||
const vluint32_t lo = value & 0xffffffff;
|
const uint32_t lo = value & 0xffffffff;
|
||||||
const vluint32_t hi = value >> 32;
|
const uint32_t hi = value >> 32;
|
||||||
if (m_hex) {
|
if (m_hex) {
|
||||||
fprintf(m_fp, memhFormat(m_bits - 32), hi);
|
fprintf(m_fp, memhFormat(m_bits - 32), hi);
|
||||||
fprintf(m_fp, "%08x\n", lo);
|
fprintf(m_fp, "%08x\n", lo);
|
||||||
@@ -2129,29 +2165,6 @@ void VL_WRITEMEM_N(bool hex, // Hex format, else binary
|
|||||||
//===========================================================================
|
//===========================================================================
|
||||||
// Timescale conversion
|
// Timescale conversion
|
||||||
|
|
||||||
// Helper function for conversion of timescale strings
|
|
||||||
// Converts (1|10|100)(s|ms|us|ns|ps|fs) to power of then
|
|
||||||
int VL_TIME_STR_CONVERT(const char* strp) VL_PURE {
|
|
||||||
int scale = 0;
|
|
||||||
if (!strp) return 0;
|
|
||||||
if (*strp++ != '1') return 0;
|
|
||||||
while (*strp == '0') {
|
|
||||||
++scale;
|
|
||||||
++strp;
|
|
||||||
}
|
|
||||||
switch (*strp++) {
|
|
||||||
case 's': break;
|
|
||||||
case 'm': scale -= 3; break;
|
|
||||||
case 'u': scale -= 6; break;
|
|
||||||
case 'n': scale -= 9; break;
|
|
||||||
case 'p': scale -= 12; break;
|
|
||||||
case 'f': scale -= 15; break;
|
|
||||||
default: return 0;
|
|
||||||
}
|
|
||||||
if ((scale < 0) && (*strp++ != 's')) return 0;
|
|
||||||
if (*strp) return 0;
|
|
||||||
return scale;
|
|
||||||
}
|
|
||||||
static const char* vl_time_str(int scale) VL_PURE {
|
static const char* vl_time_str(int scale) VL_PURE {
|
||||||
static const char* const names[]
|
static const char* const names[]
|
||||||
= {"100s", "10s", "1s", "100ms", "10ms", "1ms", "100us", "10us", "1us",
|
= {"100s", "10s", "1s", "100ms", "10ms", "1ms", "100us", "10us", "1us",
|
||||||
@@ -2206,8 +2219,8 @@ double vl_time_multiplier(int scale) VL_PURE {
|
|||||||
return pow10[scale];
|
return pow10[scale];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
vluint64_t vl_time_pow10(int n) {
|
uint64_t vl_time_pow10(int n) {
|
||||||
static const vluint64_t pow10[20] = {
|
static const uint64_t pow10[20] = {
|
||||||
1ULL,
|
1ULL,
|
||||||
10ULL,
|
10ULL,
|
||||||
100ULL,
|
100ULL,
|
||||||
@@ -2251,7 +2264,7 @@ VerilatedContext::VerilatedContext()
|
|||||||
: m_impdatap{new VerilatedContextImpData} {
|
: m_impdatap{new VerilatedContextImpData} {
|
||||||
Verilated::lastContextp(this);
|
Verilated::lastContextp(this);
|
||||||
Verilated::threadContextp(this);
|
Verilated::threadContextp(this);
|
||||||
m_ns.m_profThreadsFilename = "profile_threads.dat";
|
m_ns.m_profExecFilename = "profile_exec.dat";
|
||||||
m_ns.m_profVltFilename = "profile.vlt";
|
m_ns.m_profVltFilename = "profile.vlt";
|
||||||
m_fdps.resize(31);
|
m_fdps.resize(31);
|
||||||
std::fill(m_fdps.begin(), m_fdps.end(), static_cast<FILE*>(nullptr));
|
std::fill(m_fdps.begin(), m_fdps.end(), static_cast<FILE*>(nullptr));
|
||||||
@@ -2260,11 +2273,22 @@ VerilatedContext::VerilatedContext()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Must declare here not in interface, as otherwise forward declarations not known
|
// Must declare here not in interface, as otherwise forward declarations not known
|
||||||
VerilatedContext::~VerilatedContext() {}
|
VerilatedContext::~VerilatedContext() {
|
||||||
|
checkMagic(this);
|
||||||
|
m_magic = 0x1; // Arbitrary but 0x1 is what Verilator src uses for a deleted pointer
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerilatedContext::checkMagic(const VerilatedContext* contextp) {
|
||||||
|
if (VL_UNLIKELY(!contextp || contextp->m_magic != MAGIC)) {
|
||||||
|
VL_FATAL_MT("", 0, "", // LCOV_EXCL_LINE
|
||||||
|
"Attempt to create model using a bad/deleted VerilatedContext pointer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VerilatedContext::Serialized::Serialized() {
|
VerilatedContext::Serialized::Serialized() {
|
||||||
m_timeunit = VL_TIME_UNIT; // Initial value until overriden by _Vconfigure
|
constexpr int8_t picosecond = -12;
|
||||||
m_timeprecision = VL_TIME_PRECISION; // Initial value until overriden by _Vconfigure
|
m_timeunit = picosecond; // Initial value until overriden by _Vconfigure
|
||||||
|
m_timeprecision = picosecond; // Initial value until overriden by _Vconfigure
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerilatedContext::assertOn(bool flag) VL_MT_SAFE {
|
void VerilatedContext::assertOn(bool flag) VL_MT_SAFE {
|
||||||
@@ -2284,7 +2308,7 @@ std::string VerilatedContext::dumpfile() const VL_MT_SAFE_EXCLUDES(m_timeDumpMut
|
|||||||
return m_dumpfile;
|
return m_dumpfile;
|
||||||
}
|
}
|
||||||
std::string VerilatedContext::dumpfileCheck() const VL_MT_SAFE_EXCLUDES(m_timeDumpMutex) {
|
std::string VerilatedContext::dumpfileCheck() const VL_MT_SAFE_EXCLUDES(m_timeDumpMutex) {
|
||||||
const std::string out = dumpfile();
|
std::string out = dumpfile();
|
||||||
if (VL_UNLIKELY(out.empty())) {
|
if (VL_UNLIKELY(out.empty())) {
|
||||||
VL_PRINTF_MT("%%Warning: $dumpvar ignored as not proceeded by $dumpfile\n");
|
VL_PRINTF_MT("%%Warning: $dumpvar ignored as not proceeded by $dumpfile\n");
|
||||||
return "";
|
return "";
|
||||||
@@ -2319,21 +2343,21 @@ void VerilatedContext::gotFinish(bool flag) VL_MT_SAFE {
|
|||||||
const VerilatedLockGuard lock{m_mutex};
|
const VerilatedLockGuard lock{m_mutex};
|
||||||
m_s.m_gotFinish = flag;
|
m_s.m_gotFinish = flag;
|
||||||
}
|
}
|
||||||
void VerilatedContext::profThreadsStart(vluint64_t flag) VL_MT_SAFE {
|
void VerilatedContext::profExecStart(uint64_t flag) VL_MT_SAFE {
|
||||||
const VerilatedLockGuard lock{m_mutex};
|
const VerilatedLockGuard lock{m_mutex};
|
||||||
m_ns.m_profThreadsStart = flag;
|
m_ns.m_profExecStart = flag;
|
||||||
}
|
}
|
||||||
void VerilatedContext::profThreadsWindow(vluint64_t flag) VL_MT_SAFE {
|
void VerilatedContext::profExecWindow(uint64_t flag) VL_MT_SAFE {
|
||||||
const VerilatedLockGuard lock{m_mutex};
|
const VerilatedLockGuard lock{m_mutex};
|
||||||
m_ns.m_profThreadsWindow = flag;
|
m_ns.m_profExecWindow = flag;
|
||||||
}
|
}
|
||||||
void VerilatedContext::profThreadsFilename(const std::string& flag) VL_MT_SAFE {
|
void VerilatedContext::profExecFilename(const std::string& flag) VL_MT_SAFE {
|
||||||
const VerilatedLockGuard lock{m_mutex};
|
const VerilatedLockGuard lock{m_mutex};
|
||||||
m_ns.m_profThreadsFilename = flag;
|
m_ns.m_profExecFilename = flag;
|
||||||
}
|
}
|
||||||
std::string VerilatedContext::profThreadsFilename() const VL_MT_SAFE {
|
std::string VerilatedContext::profExecFilename() const VL_MT_SAFE {
|
||||||
const VerilatedLockGuard lock{m_mutex};
|
const VerilatedLockGuard lock{m_mutex};
|
||||||
return m_ns.m_profThreadsFilename;
|
return m_ns.m_profExecFilename;
|
||||||
}
|
}
|
||||||
void VerilatedContext::profVltFilename(const std::string& flag) VL_MT_SAFE {
|
void VerilatedContext::profVltFilename(const std::string& flag) VL_MT_SAFE {
|
||||||
const VerilatedLockGuard lock{m_mutex};
|
const VerilatedLockGuard lock{m_mutex};
|
||||||
@@ -2389,6 +2413,33 @@ const char* VerilatedContext::timeprecisionString() const VL_MT_SAFE {
|
|||||||
return vl_time_str(timeprecision());
|
return vl_time_str(timeprecision());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VerilatedContext::threads(unsigned n) {
|
||||||
|
if (n == 0) VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: Simulation threads must be >= 1");
|
||||||
|
|
||||||
|
if (m_threadPool) {
|
||||||
|
VL_FATAL_MT(
|
||||||
|
__FILE__, __LINE__, "",
|
||||||
|
"%Error: Cannot set simulation threads after the thread pool has been created.");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if VL_THREADED
|
||||||
|
if (m_threads == n) return; // To avoid unnecessary warnings
|
||||||
|
m_threads = n;
|
||||||
|
const unsigned hardwareThreadsAvailable = std::thread::hardware_concurrency();
|
||||||
|
if (m_threads > hardwareThreadsAvailable) {
|
||||||
|
VL_PRINTF_MT("%%Warning: System has %u hardware threads but simulation thread count set "
|
||||||
|
"to %u. This will likely cause significant slowdown.\n",
|
||||||
|
hardwareThreadsAvailable, m_threads);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (n > 1) {
|
||||||
|
VL_PRINTF_MT("%%Warning: Verilator run-time library built without VL_THREADS. Ignoring "
|
||||||
|
"call to 'VerilatedContext::threads' with argument %u.\n",
|
||||||
|
n);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void VerilatedContext::commandArgs(int argc, const char** argv) VL_MT_SAFE_EXCLUDES(m_argMutex) {
|
void VerilatedContext::commandArgs(int argc, const char** argv) VL_MT_SAFE_EXCLUDES(m_argMutex) {
|
||||||
const VerilatedLockGuard lock{m_argMutex};
|
const VerilatedLockGuard lock{m_argMutex};
|
||||||
m_args.m_argVec.clear(); // Empty first, then add
|
m_args.m_argVec.clear(); // Empty first, then add
|
||||||
@@ -2419,6 +2470,33 @@ void VerilatedContext::internalsDump() const VL_MT_SAFE {
|
|||||||
VerilatedImp::userDump();
|
VerilatedImp::userDump();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VerilatedContext::addModel(VerilatedModel* modelp) {
|
||||||
|
threadPoolp(); // Ensure thread pool is created, so m_threads cannot change any more
|
||||||
|
|
||||||
|
if (modelp->threads() > m_threads) {
|
||||||
|
std::ostringstream msg;
|
||||||
|
msg << "VerilatedContext has " << m_threads << " threads but model '"
|
||||||
|
<< modelp->modelName() << "' (instantiated as '" << modelp->hierName()
|
||||||
|
<< "') was Verilated with --threads " << modelp->threads() << ".\n";
|
||||||
|
const std::string str = msg.str();
|
||||||
|
VL_FATAL_MT(__FILE__, __LINE__, modelp->hierName(), str.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VerilatedVirtualBase* VerilatedContext::threadPoolp() {
|
||||||
|
if (m_threads == 1) return nullptr;
|
||||||
|
#if VL_THREADED
|
||||||
|
if (!m_threadPool) m_threadPool.reset(new VlThreadPool{this, m_threads - 1});
|
||||||
|
#endif
|
||||||
|
return m_threadPool.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
VerilatedVirtualBase*
|
||||||
|
VerilatedContext::enableExecutionProfiler(VerilatedVirtualBase* (*construct)(VerilatedContext&)) {
|
||||||
|
if (!m_executionProfiler) m_executionProfiler.reset(construct(*this));
|
||||||
|
return m_executionProfiler.get();
|
||||||
|
}
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// VerilatedContextImp:: Methods - command line
|
// VerilatedContextImp:: Methods - command line
|
||||||
|
|
||||||
@@ -2478,13 +2556,16 @@ std::pair<int, char**> VerilatedContextImp::argc_argv() VL_MT_SAFE_EXCLUDES(m_ar
|
|||||||
|
|
||||||
void VerilatedContextImp::commandArgVl(const std::string& arg) {
|
void VerilatedContextImp::commandArgVl(const std::string& arg) {
|
||||||
if (0 == std::strncmp(arg.c_str(), "+verilator+", std::strlen("+verilator+"))) {
|
if (0 == std::strncmp(arg.c_str(), "+verilator+", std::strlen("+verilator+"))) {
|
||||||
std::string value;
|
std::string str;
|
||||||
|
uint64_t u64;
|
||||||
if (arg == "+verilator+debug") {
|
if (arg == "+verilator+debug") {
|
||||||
Verilated::debug(4);
|
Verilated::debug(4);
|
||||||
} else if (commandArgVlValue(arg, "+verilator+debugi+", value /*ref*/)) {
|
} else if (commandArgVlUint64(arg, "+verilator+debugi+", u64, 0,
|
||||||
Verilated::debug(std::atoi(value.c_str()));
|
std::numeric_limits<int>::max())) {
|
||||||
} else if (commandArgVlValue(arg, "+verilator+error+limit+", value /*ref*/)) {
|
Verilated::debug(static_cast<int>(u64));
|
||||||
errorLimit(std::atoi(value.c_str()));
|
} else if (commandArgVlUint64(arg, "+verilator+error+limit+", u64, 0,
|
||||||
|
std::numeric_limits<int>::max())) {
|
||||||
|
errorLimit(static_cast<int>(u64));
|
||||||
} else if (arg == "+verilator+help") {
|
} else if (arg == "+verilator+help") {
|
||||||
VerilatedImp::versionDump();
|
VerilatedImp::versionDump();
|
||||||
VL_PRINTF_MT("For help, please see 'verilator --help'\n");
|
VL_PRINTF_MT("For help, please see 'verilator --help'\n");
|
||||||
@@ -2492,18 +2573,22 @@ void VerilatedContextImp::commandArgVl(const std::string& arg) {
|
|||||||
"Exiting due to command line argument (not an error)");
|
"Exiting due to command line argument (not an error)");
|
||||||
} else if (arg == "+verilator+noassert") {
|
} else if (arg == "+verilator+noassert") {
|
||||||
assertOn(false);
|
assertOn(false);
|
||||||
} else if (commandArgVlValue(arg, "+verilator+prof+threads+start+", value /*ref*/)) {
|
} else if (commandArgVlUint64(arg, "+verilator+prof+exec+start+", u64)
|
||||||
profThreadsStart(std::atoll(value.c_str()));
|
|| commandArgVlUint64(arg, "+verilator+prof+threads+start+", u64)) {
|
||||||
} else if (commandArgVlValue(arg, "+verilator+prof+threads+window+", value /*ref*/)) {
|
profExecStart(u64);
|
||||||
profThreadsWindow(std::atol(value.c_str()));
|
} else if (commandArgVlUint64(arg, "+verilator+prof+exec+window+", u64, 1)
|
||||||
} else if (commandArgVlValue(arg, "+verilator+prof+threads+file+", value /*ref*/)) {
|
|| commandArgVlUint64(arg, "+verilator+prof+threads+window+", u64, 1)) {
|
||||||
profThreadsFilename(value);
|
profExecWindow(u64);
|
||||||
} else if (commandArgVlValue(arg, "+verilator+prof+vlt+file+", value /*ref*/)) {
|
} else if (commandArgVlString(arg, "+verilator+prof+exec+file+", str)
|
||||||
profVltFilename(value);
|
|| commandArgVlString(arg, "+verilator+prof+threads+file+", str)) {
|
||||||
} else if (commandArgVlValue(arg, "+verilator+rand+reset+", value /*ref*/)) {
|
profExecFilename(str);
|
||||||
randReset(std::atoi(value.c_str()));
|
} else if (commandArgVlString(arg, "+verilator+prof+vlt+file+", str)) {
|
||||||
} else if (commandArgVlValue(arg, "+verilator+seed+", value /*ref*/)) {
|
profVltFilename(str);
|
||||||
randSeed(std::atoi(value.c_str()));
|
} else if (commandArgVlUint64(arg, "+verilator+rand+reset+", u64, 0, 2)) {
|
||||||
|
randReset(static_cast<int>(u64));
|
||||||
|
} else if (commandArgVlUint64(arg, "+verilator+seed+", u64, 1,
|
||||||
|
std::numeric_limits<int>::max())) {
|
||||||
|
randSeed(static_cast<int>(u64));
|
||||||
} else if (arg == "+verilator+V") {
|
} else if (arg == "+verilator+V") {
|
||||||
VerilatedImp::versionDump(); // Someday more info too
|
VerilatedImp::versionDump(); // Someday more info too
|
||||||
VL_FATAL_MT("COMMAND_LINE", 0, "",
|
VL_FATAL_MT("COMMAND_LINE", 0, "",
|
||||||
@@ -2513,12 +2598,14 @@ void VerilatedContextImp::commandArgVl(const std::string& arg) {
|
|||||||
VL_FATAL_MT("COMMAND_LINE", 0, "",
|
VL_FATAL_MT("COMMAND_LINE", 0, "",
|
||||||
"Exiting due to command line argument (not an error)");
|
"Exiting due to command line argument (not an error)");
|
||||||
} else {
|
} else {
|
||||||
VL_PRINTF_MT("%%Warning: Unknown +verilator runtime argument: '%s'\n", arg.c_str());
|
const std::string msg = "Unknown runtime argument: " + arg;
|
||||||
|
VL_FATAL_MT("COMMAND_LINE", 0, "", msg.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bool VerilatedContextImp::commandArgVlValue(const std::string& arg, const std::string& prefix,
|
|
||||||
std::string& valuer) {
|
bool VerilatedContextImp::commandArgVlString(const std::string& arg, const std::string& prefix,
|
||||||
|
std::string& valuer) {
|
||||||
const size_t len = prefix.length();
|
const size_t len = prefix.length();
|
||||||
if (0 == std::strncmp(prefix.c_str(), arg.c_str(), len)) {
|
if (0 == std::strncmp(prefix.c_str(), arg.c_str(), len)) {
|
||||||
valuer = arg.substr(len);
|
valuer = arg.substr(len);
|
||||||
@@ -2528,6 +2615,30 @@ bool VerilatedContextImp::commandArgVlValue(const std::string& arg, const std::s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VerilatedContextImp::commandArgVlUint64(const std::string& arg, const std::string& prefix,
|
||||||
|
uint64_t& valuer, uint64_t min, uint64_t max) {
|
||||||
|
std::string str;
|
||||||
|
if (commandArgVlString(arg, prefix, str)) {
|
||||||
|
const auto fail = [&](const std::string& extra = "") {
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "Argument '" << prefix << "' must be an unsigned integer";
|
||||||
|
if (min != std::numeric_limits<uint64_t>::min()) ss << ", greater than " << min - 1;
|
||||||
|
if (max != std::numeric_limits<uint64_t>::max()) ss << ", less than " << max + 1;
|
||||||
|
if (!extra.empty()) ss << ". " << extra;
|
||||||
|
const std::string& msg = ss.str();
|
||||||
|
VL_FATAL_MT("COMMAND_LINE", 0, "", msg.c_str());
|
||||||
|
};
|
||||||
|
|
||||||
|
if (std::any_of(str.begin(), str.end(), [](int c) { return !std::isdigit(c); })) fail();
|
||||||
|
char* end;
|
||||||
|
valuer = std::strtoull(str.c_str(), &end, 10);
|
||||||
|
if (errno == ERANGE) fail("Value out of range of uint64_t");
|
||||||
|
if (valuer < min || valuer > max) fail();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// VerilatedContext:: + VerilatedContextImp:: Methods - random
|
// VerilatedContext:: + VerilatedContextImp:: Methods - random
|
||||||
|
|
||||||
@@ -2536,20 +2647,19 @@ void VerilatedContext::randSeed(int val) VL_MT_SAFE {
|
|||||||
// and so the rand seed's mutex must also be static
|
// and so the rand seed's mutex must also be static
|
||||||
const VerilatedLockGuard lock{VerilatedContextImp::s().s_randMutex};
|
const VerilatedLockGuard lock{VerilatedContextImp::s().s_randMutex};
|
||||||
m_s.m_randSeed = val;
|
m_s.m_randSeed = val;
|
||||||
const vluint64_t newEpoch = VerilatedContextImp::s().s_randSeedEpoch + 1;
|
const uint64_t newEpoch = VerilatedContextImp::s().s_randSeedEpoch + 1;
|
||||||
// Obververs must see new epoch AFTER seed updated
|
// Obververs must see new epoch AFTER seed updated
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
std::atomic_signal_fence(std::memory_order_release);
|
std::atomic_signal_fence(std::memory_order_release);
|
||||||
#endif
|
#endif
|
||||||
VerilatedContextImp::s().s_randSeedEpoch = newEpoch;
|
VerilatedContextImp::s().s_randSeedEpoch = newEpoch;
|
||||||
}
|
}
|
||||||
vluint64_t VerilatedContextImp::randSeedDefault64() const VL_MT_SAFE {
|
uint64_t VerilatedContextImp::randSeedDefault64() const VL_MT_SAFE {
|
||||||
if (randSeed() != 0) {
|
if (randSeed() != 0) {
|
||||||
return ((static_cast<vluint64_t>(randSeed()) << 32)
|
return ((static_cast<uint64_t>(randSeed()) << 32) ^ (static_cast<uint64_t>(randSeed())));
|
||||||
^ (static_cast<vluint64_t>(randSeed())));
|
|
||||||
} else {
|
} else {
|
||||||
return ((static_cast<vluint64_t>(vl_sys_rand32()) << 32)
|
return ((static_cast<uint64_t>(vl_sys_rand32()) << 32)
|
||||||
^ (static_cast<vluint64_t>(vl_sys_rand32())));
|
^ (static_cast<uint64_t>(vl_sys_rand32())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2596,6 +2706,7 @@ const VerilatedScopeNameMap* VerilatedContext::scopeNameMap() VL_MT_SAFE {
|
|||||||
|
|
||||||
VerilatedSyms::VerilatedSyms(VerilatedContext* contextp)
|
VerilatedSyms::VerilatedSyms(VerilatedContext* contextp)
|
||||||
: _vm_contextp__(contextp ? contextp : Verilated::threadContextp()) {
|
: _vm_contextp__(contextp ? contextp : Verilated::threadContextp()) {
|
||||||
|
VerilatedContext::checkMagic(_vm_contextp__);
|
||||||
Verilated::threadContextp(_vm_contextp__);
|
Verilated::threadContextp(_vm_contextp__);
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
__Vm_evalMsgQp = new VerilatedEvalMsgQueue;
|
__Vm_evalMsgQp = new VerilatedEvalMsgQueue;
|
||||||
@@ -2603,6 +2714,7 @@ VerilatedSyms::VerilatedSyms(VerilatedContext* contextp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
VerilatedSyms::~VerilatedSyms() {
|
VerilatedSyms::~VerilatedSyms() {
|
||||||
|
VerilatedContext::checkMagic(_vm_contextp__);
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
delete __Vm_evalMsgQp;
|
delete __Vm_evalMsgQp;
|
||||||
#endif
|
#endif
|
||||||
@@ -2625,14 +2737,11 @@ void Verilated::debug(int level) VL_MT_SAFE {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* Verilated::catName(const char* n1, const char* n2, int scopet,
|
const char* Verilated::catName(const char* n1, const char* n2, const char* delimiter) VL_MT_SAFE {
|
||||||
const char* delimiter) VL_MT_SAFE {
|
|
||||||
// Returns new'ed data
|
|
||||||
// Used by symbol table creation to make module names
|
// Used by symbol table creation to make module names
|
||||||
static VL_THREAD_LOCAL char* t_strp = nullptr;
|
static VL_THREAD_LOCAL char* t_strp = nullptr;
|
||||||
static VL_THREAD_LOCAL size_t t_len = 0;
|
static VL_THREAD_LOCAL size_t t_len = 0;
|
||||||
const size_t newlen
|
const size_t newlen = std::strlen(n1) + std::strlen(n2) + std::strlen(delimiter) + 1;
|
||||||
= std::strlen(n1) + std::strlen(n2) + std::strlen(delimiter) + (scopet > 0 ? 2 : 1);
|
|
||||||
if (VL_UNLIKELY(!t_strp || newlen > t_len)) {
|
if (VL_UNLIKELY(!t_strp || newlen > t_len)) {
|
||||||
if (t_strp) delete[] t_strp;
|
if (t_strp) delete[] t_strp;
|
||||||
t_strp = new char[newlen];
|
t_strp = new char[newlen];
|
||||||
@@ -2640,8 +2749,6 @@ const char* Verilated::catName(const char* n1, const char* n2, int scopet,
|
|||||||
}
|
}
|
||||||
char* dp = t_strp;
|
char* dp = t_strp;
|
||||||
for (const char* sp = n1; *sp;) *dp++ = *sp++;
|
for (const char* sp = n1; *sp;) *dp++ = *sp++;
|
||||||
// Add scope type
|
|
||||||
if (scopet) *dp++ = (char)(0x80 + scopet);
|
|
||||||
for (const char* sp = delimiter; *sp;) *dp++ = *sp++;
|
for (const char* sp = delimiter; *sp;) *dp++ = *sp++;
|
||||||
for (const char* sp = n2; *sp;) *dp++ = *sp++;
|
for (const char* sp = n2; *sp;) *dp++ = *sp++;
|
||||||
*dp++ = '\0';
|
*dp++ = '\0';
|
||||||
@@ -2699,7 +2806,7 @@ void Verilated::runFlushCallbacks() VL_MT_SAFE {
|
|||||||
// When running internal code coverage (gcc --coverage, as opposed to
|
// When running internal code coverage (gcc --coverage, as opposed to
|
||||||
// verilator --coverage), dump coverage data to properly cover failing
|
// verilator --coverage), dump coverage data to properly cover failing
|
||||||
// tests.
|
// tests.
|
||||||
VL_GCOV_FLUSH();
|
VL_GCOV_DUMP();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Verilated::addExitCb(VoidPCb cb, void* datap) VL_MT_SAFE {
|
void Verilated::addExitCb(VoidPCb cb, void* datap) VL_MT_SAFE {
|
||||||
@@ -2782,6 +2889,14 @@ void VerilatedImp::versionDump() VL_MT_SAFE {
|
|||||||
VL_PRINTF_MT(" Version: %s %s\n", Verilated::productName(), Verilated::productVersion());
|
VL_PRINTF_MT(" Version: %s %s\n", Verilated::productName(), Verilated::productVersion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//===========================================================================
|
||||||
|
// VerilatedModel:: Methods
|
||||||
|
|
||||||
|
VerilatedModel::VerilatedModel(VerilatedContext& context)
|
||||||
|
: m_context{context} {}
|
||||||
|
|
||||||
|
std::unique_ptr<VerilatedTraceConfig> VerilatedModel::traceConfig() const { return nullptr; }
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
// VerilatedModule:: Methods
|
// VerilatedModule:: Methods
|
||||||
|
|
||||||
@@ -2798,8 +2913,8 @@ VerilatedModule::~VerilatedModule() {
|
|||||||
// VerilatedVar:: Methods
|
// VerilatedVar:: Methods
|
||||||
|
|
||||||
// cppcheck-suppress unusedFunction // Used by applications
|
// cppcheck-suppress unusedFunction // Used by applications
|
||||||
vluint32_t VerilatedVarProps::entSize() const {
|
uint32_t VerilatedVarProps::entSize() const {
|
||||||
vluint32_t size = 1;
|
uint32_t size = 1;
|
||||||
switch (vltype()) {
|
switch (vltype()) {
|
||||||
case VLVT_PTR: size = sizeof(void*); break;
|
case VLVT_PTR: size = sizeof(void*); break;
|
||||||
case VLVT_UINT8: size = sizeof(CData); break;
|
case VLVT_UINT8: size = sizeof(CData); break;
|
||||||
@@ -2822,7 +2937,7 @@ void* VerilatedVarProps::datapAdjustIndex(void* datap, int dim, int indx) const
|
|||||||
if (VL_UNLIKELY(dim <= 0 || dim > udims())) return nullptr;
|
if (VL_UNLIKELY(dim <= 0 || dim > udims())) return nullptr;
|
||||||
if (VL_UNLIKELY(indx < low(dim) || indx > high(dim))) return nullptr;
|
if (VL_UNLIKELY(indx < low(dim) || indx > high(dim))) return nullptr;
|
||||||
const int indxAdj = indx - low(dim);
|
const int indxAdj = indx - low(dim);
|
||||||
vluint8_t* bytep = reinterpret_cast<vluint8_t*>(datap);
|
uint8_t* bytep = reinterpret_cast<uint8_t*>(datap);
|
||||||
// If on index 1 of a 2 index array, then each index 1 is index2sz*entsz
|
// If on index 1 of a 2 index array, then each index 1 is index2sz*entsz
|
||||||
size_t slicesz = entSize();
|
size_t slicesz = entSize();
|
||||||
for (int d = dim + 1; d <= m_udims; ++d) slicesz *= elements(d);
|
for (int d = dim + 1; d <= m_udims; ++d) slicesz *= elements(d);
|
||||||
@@ -2843,7 +2958,7 @@ VerilatedScope::~VerilatedScope() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VerilatedScope::configure(VerilatedSyms* symsp, const char* prefixp, const char* suffixp,
|
void VerilatedScope::configure(VerilatedSyms* symsp, const char* prefixp, const char* suffixp,
|
||||||
const char* identifier, vlsint8_t timeunit,
|
const char* identifier, int8_t timeunit,
|
||||||
const Type& type) VL_MT_UNSAFE {
|
const Type& type) VL_MT_UNSAFE {
|
||||||
// Slowpath - called once/scope at construction
|
// Slowpath - called once/scope at construction
|
||||||
// We don't want the space and reference-count access overhead of strings.
|
// We don't want the space and reference-count access overhead of strings.
|
||||||
|
|||||||
+119
-53
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
|
#include "verilated_config.h"
|
||||||
#if VM_SC
|
#if VM_SC
|
||||||
# include "verilated_sc.h" // Get SYSTEMC_VERSION and time declarations
|
# include "verilated_sc.h" // Get SYSTEMC_VERSION and time declarations
|
||||||
#endif
|
#endif
|
||||||
@@ -80,14 +81,19 @@
|
|||||||
#endif
|
#endif
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
|
class VerilatedContext;
|
||||||
class VerilatedContextImp;
|
class VerilatedContextImp;
|
||||||
class VerilatedContextImpData;
|
class VerilatedContextImpData;
|
||||||
class VerilatedCovContext;
|
class VerilatedCovContext;
|
||||||
class VerilatedEvalMsgQueue;
|
class VerilatedEvalMsgQueue;
|
||||||
class VerilatedFst;
|
class VerilatedFst;
|
||||||
class VerilatedFstC;
|
class VerilatedFstC;
|
||||||
|
class VerilatedFstSc;
|
||||||
class VerilatedScope;
|
class VerilatedScope;
|
||||||
class VerilatedScopeNameMap;
|
class VerilatedScopeNameMap;
|
||||||
|
template <class, class>
|
||||||
|
class VerilatedTrace;
|
||||||
|
class VerilatedTraceConfig;
|
||||||
class VerilatedVar;
|
class VerilatedVar;
|
||||||
class VerilatedVarNameMap;
|
class VerilatedVarNameMap;
|
||||||
class VerilatedVcd;
|
class VerilatedVcd;
|
||||||
@@ -99,11 +105,11 @@ class VerilatedVcdSc;
|
|||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// P // Packed data of bit type (C/S/I/Q/W)
|
// P // Packed data of bit type (C/S/I/Q/W)
|
||||||
using CData = vluint8_t; ///< Data representing 'bit' of 1-8 packed bits
|
using CData = uint8_t; ///< Data representing 'bit' of 1-8 packed bits
|
||||||
using SData = vluint16_t; ///< Data representing 'bit' of 9-16 packed bits
|
using SData = uint16_t; ///< Data representing 'bit' of 9-16 packed bits
|
||||||
using IData = vluint32_t; ///< Data representing 'bit' of 17-32 packed bits
|
using IData = uint32_t; ///< Data representing 'bit' of 17-32 packed bits
|
||||||
using QData = vluint64_t; ///< Data representing 'bit' of 33-64 packed bits
|
using QData = uint64_t; ///< Data representing 'bit' of 33-64 packed bits
|
||||||
using EData = vluint32_t; ///< Data representing one element of WData array
|
using EData = uint32_t; ///< Data representing one element of WData array
|
||||||
using WData = EData; ///< Data representing >64 packed bits (used as pointer)
|
using WData = EData; ///< Data representing >64 packed bits (used as pointer)
|
||||||
// F = float; // No typedef needed; Verilator uses float
|
// F = float; // No typedef needed; Verilator uses float
|
||||||
// D = double; // No typedef needed; Verilator uses double
|
// D = double; // No typedef needed; Verilator uses double
|
||||||
@@ -113,7 +119,7 @@ using WData = EData; ///< Data representing >64 packed bits (used as poin
|
|||||||
using WDataInP = const WData*; ///< 'bit' of >64 packed bits as array input to a function
|
using WDataInP = const WData*; ///< 'bit' of >64 packed bits as array input to a function
|
||||||
using WDataOutP = WData*; ///< 'bit' of >64 packed bits as array output from a function
|
using WDataOutP = WData*; ///< 'bit' of >64 packed bits as array output from a function
|
||||||
|
|
||||||
enum VerilatedVarType : vluint8_t {
|
enum VerilatedVarType : uint8_t {
|
||||||
VLVT_UNKNOWN = 0,
|
VLVT_UNKNOWN = 0,
|
||||||
VLVT_PTR, // Pointer to something
|
VLVT_PTR, // Pointer to something
|
||||||
VLVT_UINT8, // AKA CData
|
VLVT_UINT8, // AKA CData
|
||||||
@@ -141,11 +147,11 @@ enum VerilatedVarFlags {
|
|||||||
// Mutex and threading support
|
// Mutex and threading support
|
||||||
|
|
||||||
// Return current thread ID (or 0), not super fast, cache if needed
|
// Return current thread ID (or 0), not super fast, cache if needed
|
||||||
extern vluint32_t VL_THREAD_ID() VL_MT_SAFE;
|
extern uint32_t VL_THREAD_ID() VL_MT_SAFE;
|
||||||
|
|
||||||
#if VL_THREADED
|
#if VL_THREADED
|
||||||
|
|
||||||
#define VL_LOCK_SPINS 50000 /// Number of times to spin for a mutex before relaxing
|
#define VL_LOCK_SPINS 50000 /// Number of times to spin for a mutex before yielding
|
||||||
|
|
||||||
/// Mutex, wrapped to allow -fthread_safety checks
|
/// Mutex, wrapped to allow -fthread_safety checks
|
||||||
class VL_CAPABILITY("mutex") VerilatedMutex final {
|
class VL_CAPABILITY("mutex") VerilatedMutex final {
|
||||||
@@ -224,7 +230,7 @@ public:
|
|||||||
class VerilatedAssertOneThread final {
|
class VerilatedAssertOneThread final {
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
#if defined(VL_THREADED) && defined(VL_DEBUG)
|
#if defined(VL_THREADED) && defined(VL_DEBUG)
|
||||||
vluint32_t m_threadid; // Thread that is legal
|
uint32_t m_threadid; // Thread that is legal
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
// The constructor establishes the thread id for all later calls.
|
// The constructor establishes the thread id for all later calls.
|
||||||
@@ -250,6 +256,40 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
/// Base class of a Verilator generated (Verilated) model.
|
||||||
|
///
|
||||||
|
/// VerilatedModel is a base class of the user facing primary class generated
|
||||||
|
/// by Verilator.
|
||||||
|
|
||||||
|
class VerilatedModel VL_NOT_FINAL {
|
||||||
|
VL_UNCOPYABLE(VerilatedModel);
|
||||||
|
|
||||||
|
VerilatedContext& m_context; // The VerilatedContext this model is instantiated under
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit VerilatedModel(VerilatedContext& context);
|
||||||
|
virtual ~VerilatedModel() = default;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Returns the VerilatedContext this model is instantiated under
|
||||||
|
/// Used to get to e.g. simulation time via contextp()->time()
|
||||||
|
VerilatedContext* contextp() const { return &m_context; }
|
||||||
|
/// Returns the hierarchical name of this module instance.
|
||||||
|
virtual const char* hierName() const = 0;
|
||||||
|
/// Returns the name of this model (the name of the generated model class).
|
||||||
|
virtual const char* modelName() const = 0;
|
||||||
|
/// Returns the thread level parallelism, this model was Verilated with. Always 1 or higher.
|
||||||
|
virtual unsigned threads() const = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// The following are for use by Verilator internals only
|
||||||
|
template <class, class>
|
||||||
|
friend class VerilatedTrace;
|
||||||
|
// Run-time trace configuration requested by this model
|
||||||
|
virtual std::unique_ptr<VerilatedTraceConfig> traceConfig() const;
|
||||||
|
};
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
/// Base class for all Verilated module classes.
|
/// Base class for all Verilated module classes.
|
||||||
|
|
||||||
@@ -264,10 +304,6 @@ public:
|
|||||||
const char* name() const { return m_namep; } ///< Return name of module
|
const char* name() const { return m_namep; } ///< Return name of module
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Declare a module, ala SC_MODULE
|
|
||||||
#define VL_MODULE(modname) class modname VL_NOT_FINAL : public VerilatedModule
|
|
||||||
// Not class final in VL_MODULE, as users might be abstracting our models (--hierarchical)
|
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Functions overridable by user defines
|
// Functions overridable by user defines
|
||||||
// (Internals however must use VL_PRINTF_MT, which calls these.)
|
// (Internals however must use VL_PRINTF_MT, which calls these.)
|
||||||
@@ -318,10 +354,10 @@ protected:
|
|||||||
bool m_fatalOnVpiError = true; // Fatal on vpi error/unsupported
|
bool m_fatalOnVpiError = true; // Fatal on vpi error/unsupported
|
||||||
bool m_gotError = false; // A $finish statement executed
|
bool m_gotError = false; // A $finish statement executed
|
||||||
bool m_gotFinish = false; // A $finish or $stop statement executed
|
bool m_gotFinish = false; // A $finish or $stop statement executed
|
||||||
vluint64_t m_time = 0; // Current $time (unscaled), 0=at zero, or legacy
|
uint64_t m_time = 0; // Current $time (unscaled), 0=at zero, or legacy
|
||||||
// Slow path
|
// Slow path
|
||||||
vlsint8_t m_timeunit; // Time unit as 0..15
|
int8_t m_timeunit; // Time unit as 0..15
|
||||||
vlsint8_t m_timeprecision; // Time precision as 0..15
|
int8_t m_timeprecision; // Time precision as 0..15
|
||||||
int m_errorCount = 0; // Number of errors
|
int m_errorCount = 0; // Number of errors
|
||||||
int m_errorLimit = 1; // Stop on error number
|
int m_errorLimit = 1; // Stop on error number
|
||||||
int m_randReset = 0; // Random reset: 0=all 0s, 1=all 1s, 2=random
|
int m_randReset = 0; // Random reset: 0=all 0s, 1=all 1s, 2=random
|
||||||
@@ -342,10 +378,10 @@ protected:
|
|||||||
struct NonSerialized { // Non-serialized information
|
struct NonSerialized { // Non-serialized information
|
||||||
// These are reloaded from on command-line settings, so do not need to persist
|
// These are reloaded from on command-line settings, so do not need to persist
|
||||||
// Fast path
|
// Fast path
|
||||||
vluint64_t m_profThreadsStart = 1; // +prof+threads starting time
|
uint64_t m_profExecStart = 1; // +prof+exec+start time
|
||||||
vluint32_t m_profThreadsWindow = 2; // +prof+threads window size
|
uint32_t m_profExecWindow = 2; // +prof+exec+window size
|
||||||
// Slow path
|
// Slow path
|
||||||
std::string m_profThreadsFilename; // +prof+threads filename
|
std::string m_profExecFilename; // +prof+exec+file filename
|
||||||
std::string m_profVltFilename; // +prof+vlt filename
|
std::string m_profVltFilename; // +prof+vlt filename
|
||||||
} m_ns;
|
} m_ns;
|
||||||
|
|
||||||
@@ -360,6 +396,16 @@ protected:
|
|||||||
|
|
||||||
// Implementation details
|
// Implementation details
|
||||||
const std::unique_ptr<VerilatedContextImpData> m_impdatap;
|
const std::unique_ptr<VerilatedContextImpData> m_impdatap;
|
||||||
|
// Number of threads to use for simulation (size of m_threadPool + 1 for main thread)
|
||||||
|
#ifdef VL_THREADED
|
||||||
|
unsigned m_threads = std::thread::hardware_concurrency();
|
||||||
|
#else
|
||||||
|
const unsigned m_threads = 1;
|
||||||
|
#endif
|
||||||
|
// The thread pool shared by all models added to this context
|
||||||
|
std::unique_ptr<VerilatedVirtualBase> m_threadPool;
|
||||||
|
// The execution profiler shared by all models added to this context
|
||||||
|
std::unique_ptr<VerilatedVirtualBase> m_executionProfiler;
|
||||||
// Coverage access
|
// Coverage access
|
||||||
std::unique_ptr<VerilatedVirtualBase> m_coveragep; // Pointer for coveragep()
|
std::unique_ptr<VerilatedVirtualBase> m_coveragep; // Pointer for coveragep()
|
||||||
|
|
||||||
@@ -372,6 +418,10 @@ protected:
|
|||||||
// List of free descriptors in the MCT region [4, 32)
|
// List of free descriptors in the MCT region [4, 32)
|
||||||
std::vector<IData> m_fdFreeMct VL_GUARDED_BY(m_fdMutex);
|
std::vector<IData> m_fdFreeMct VL_GUARDED_BY(m_fdMutex);
|
||||||
|
|
||||||
|
// Magic to check for bad construction
|
||||||
|
static constexpr uint64_t MAGIC = 0xC35F9A6E5298EE6EULL; // SHA256 "VerilatedContext"
|
||||||
|
uint64_t m_magic = MAGIC;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VL_UNCOPYABLE(VerilatedContext);
|
VL_UNCOPYABLE(VerilatedContext);
|
||||||
@@ -407,9 +457,9 @@ public:
|
|||||||
VerilatedCovContext* coveragep() VL_MT_SAFE;
|
VerilatedCovContext* coveragep() VL_MT_SAFE;
|
||||||
/// Set debug level
|
/// Set debug level
|
||||||
/// Debug is currently global, but for forward compatibility have a per-context method
|
/// Debug is currently global, but for forward compatibility have a per-context method
|
||||||
static void debug(int val) VL_MT_SAFE;
|
static inline void debug(int val) VL_MT_SAFE;
|
||||||
/// Return debug level
|
/// Return debug level
|
||||||
static int debug() VL_MT_SAFE;
|
static inline int debug() VL_MT_SAFE;
|
||||||
/// Set current number of errors/assertions
|
/// Set current number of errors/assertions
|
||||||
void errorCount(int val) VL_MT_SAFE;
|
void errorCount(int val) VL_MT_SAFE;
|
||||||
/// Increment current number of errors/assertions
|
/// Increment current number of errors/assertions
|
||||||
@@ -466,16 +516,16 @@ public:
|
|||||||
/// timeInc, operating on the thread's context.
|
/// timeInc, operating on the thread's context.
|
||||||
///
|
///
|
||||||
/// * Else, if VL_TIME_STAMP64 is defined, time comes from the legacy
|
/// * Else, if VL_TIME_STAMP64 is defined, time comes from the legacy
|
||||||
/// 'vluint64_t vl_time_stamp64()' which must a function be defined by
|
/// 'uint64_t vl_time_stamp64()' which must a function be defined by
|
||||||
/// the user's wrapper.
|
/// the user's wrapper.
|
||||||
///
|
///
|
||||||
/// * Else, time comes from the legacy 'double sc_time_stamp()' which
|
/// * Else, time comes from the legacy 'double sc_time_stamp()' which
|
||||||
/// must be a function defined by the user's wrapper.
|
/// must be a function defined by the user's wrapper.
|
||||||
vluint64_t time() const VL_MT_SAFE;
|
inline uint64_t time() const VL_MT_SAFE;
|
||||||
/// Set current simulation time. See time() for side effect details
|
/// Set current simulation time. See time() for side effect details
|
||||||
void time(vluint64_t value) VL_MT_SAFE { m_s.m_time = value; }
|
void time(uint64_t value) VL_MT_SAFE { m_s.m_time = value; }
|
||||||
/// Advance current simulation time. See time() for side effect details
|
/// Advance current simulation time. See time() for side effect details
|
||||||
void timeInc(vluint64_t add) VL_MT_UNSAFE { m_s.m_time += add; }
|
void timeInc(uint64_t add) VL_MT_UNSAFE { m_s.m_time += add; }
|
||||||
/// Return time units as power-of-ten
|
/// Return time units as power-of-ten
|
||||||
int timeunit() const VL_MT_SAFE { return -m_s.m_timeunit; }
|
int timeunit() const VL_MT_SAFE { return -m_s.m_timeunit; }
|
||||||
/// Set time units as power-of-ten
|
/// Set time units as power-of-ten
|
||||||
@@ -489,6 +539,12 @@ public:
|
|||||||
/// Get time precision as IEEE-standard text
|
/// Get time precision as IEEE-standard text
|
||||||
const char* timeprecisionString() const VL_MT_SAFE;
|
const char* timeprecisionString() const VL_MT_SAFE;
|
||||||
|
|
||||||
|
/// Get number of threads used for simulation (including the main thread)
|
||||||
|
unsigned threads() const { return m_threads; }
|
||||||
|
/// Set number of threads used for simulation (including the main thread)
|
||||||
|
/// Can only be called before the thread pool is created (before first model is added).
|
||||||
|
void threads(unsigned n);
|
||||||
|
|
||||||
/// Allow traces to at some point be enabled (disables some optimizations)
|
/// Allow traces to at some point be enabled (disables some optimizations)
|
||||||
void traceEverOn(bool flag) VL_MT_SAFE {
|
void traceEverOn(bool flag) VL_MT_SAFE {
|
||||||
if (flag) calcUnusedSigs(true);
|
if (flag) calcUnusedSigs(true);
|
||||||
@@ -504,25 +560,32 @@ public:
|
|||||||
/// releases - contact the authors before production use.
|
/// releases - contact the authors before production use.
|
||||||
void scopesDump() const VL_MT_SAFE;
|
void scopesDump() const VL_MT_SAFE;
|
||||||
|
|
||||||
public: // But for internal use only
|
// METHODS - public but for internal use only
|
||||||
|
|
||||||
// Internal: access to implementation class
|
// Internal: access to implementation class
|
||||||
VerilatedContextImp* impp() { return reinterpret_cast<VerilatedContextImp*>(this); }
|
VerilatedContextImp* impp() { return reinterpret_cast<VerilatedContextImp*>(this); }
|
||||||
const VerilatedContextImp* impp() const {
|
const VerilatedContextImp* impp() const {
|
||||||
return reinterpret_cast<const VerilatedContextImp*>(this);
|
return reinterpret_cast<const VerilatedContextImp*>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addModel(VerilatedModel*);
|
||||||
|
|
||||||
|
VerilatedVirtualBase* threadPoolp();
|
||||||
|
VerilatedVirtualBase*
|
||||||
|
enableExecutionProfiler(VerilatedVirtualBase* (*construct)(VerilatedContext&));
|
||||||
|
|
||||||
// Internal: $dumpfile
|
// Internal: $dumpfile
|
||||||
void dumpfile(const std::string& flag) VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
|
void dumpfile(const std::string& flag) VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
|
||||||
std::string dumpfile() const VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
|
std::string dumpfile() const VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
|
||||||
std::string dumpfileCheck() const VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
|
std::string dumpfileCheck() const VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
|
||||||
|
|
||||||
// Internal: --prof-threads related settings
|
// Internal: --prof-exec related settings
|
||||||
void profThreadsStart(vluint64_t flag) VL_MT_SAFE;
|
void profExecStart(uint64_t flag) VL_MT_SAFE;
|
||||||
vluint64_t profThreadsStart() const VL_MT_SAFE { return m_ns.m_profThreadsStart; }
|
uint64_t profExecStart() const VL_MT_SAFE { return m_ns.m_profExecStart; }
|
||||||
void profThreadsWindow(vluint64_t flag) VL_MT_SAFE;
|
void profExecWindow(uint64_t flag) VL_MT_SAFE;
|
||||||
vluint32_t profThreadsWindow() const VL_MT_SAFE { return m_ns.m_profThreadsWindow; }
|
uint32_t profExecWindow() const VL_MT_SAFE { return m_ns.m_profExecWindow; }
|
||||||
void profThreadsFilename(const std::string& flag) VL_MT_SAFE;
|
void profExecFilename(const std::string& flag) VL_MT_SAFE;
|
||||||
std::string profThreadsFilename() const VL_MT_SAFE;
|
std::string profExecFilename() const VL_MT_SAFE;
|
||||||
void profVltFilename(const std::string& flag) VL_MT_SAFE;
|
void profVltFilename(const std::string& flag) VL_MT_SAFE;
|
||||||
std::string profVltFilename() const VL_MT_SAFE;
|
std::string profVltFilename() const VL_MT_SAFE;
|
||||||
|
|
||||||
@@ -533,6 +596,10 @@ public: // But for internal use only
|
|||||||
// Internal: Serialization setup
|
// Internal: Serialization setup
|
||||||
static constexpr size_t serialized1Size() VL_PURE { return sizeof(m_s); }
|
static constexpr size_t serialized1Size() VL_PURE { return sizeof(m_s); }
|
||||||
void* serialized1Ptr() VL_MT_UNSAFE { return &m_s; }
|
void* serialized1Ptr() VL_MT_UNSAFE { return &m_s; }
|
||||||
|
|
||||||
|
// Internal: Check magic number
|
||||||
|
static void checkMagic(const VerilatedContext* contextp);
|
||||||
|
void selfTestClearMagic() { m_magic = 0x2; }
|
||||||
};
|
};
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
@@ -557,7 +624,7 @@ public: // But for internal use only
|
|||||||
|
|
||||||
class VerilatedScope final {
|
class VerilatedScope final {
|
||||||
public:
|
public:
|
||||||
enum Type : vluint8_t {
|
enum Type : uint8_t {
|
||||||
SCOPE_MODULE,
|
SCOPE_MODULE,
|
||||||
SCOPE_OTHER
|
SCOPE_OTHER
|
||||||
}; // Type of a scope, currently module is only interesting
|
}; // Type of a scope, currently module is only interesting
|
||||||
@@ -570,28 +637,28 @@ private:
|
|||||||
VerilatedVarNameMap* m_varsp = nullptr; // Variable map
|
VerilatedVarNameMap* m_varsp = nullptr; // Variable map
|
||||||
const char* m_namep = nullptr; // Scope name (Slowpath)
|
const char* m_namep = nullptr; // Scope name (Slowpath)
|
||||||
const char* m_identifierp = nullptr; // Identifier of scope (with escapes removed)
|
const char* m_identifierp = nullptr; // Identifier of scope (with escapes removed)
|
||||||
vlsint8_t m_timeunit = 0; // Timeunit in negative power-of-10
|
int8_t m_timeunit = 0; // Timeunit in negative power-of-10
|
||||||
Type m_type = SCOPE_OTHER; // Type of the scope
|
Type m_type = SCOPE_OTHER; // Type of the scope
|
||||||
|
|
||||||
public: // But internals only - called from VerilatedModule's
|
public: // But internals only - called from VerilatedModule's
|
||||||
VerilatedScope() = default;
|
VerilatedScope() = default;
|
||||||
~VerilatedScope();
|
~VerilatedScope();
|
||||||
void configure(VerilatedSyms* symsp, const char* prefixp, const char* suffixp,
|
void configure(VerilatedSyms* symsp, const char* prefixp, const char* suffixp,
|
||||||
const char* identifier, vlsint8_t timeunit, const Type& type) VL_MT_UNSAFE;
|
const char* identifier, int8_t timeunit, const Type& type) VL_MT_UNSAFE;
|
||||||
void exportInsert(int finalize, const char* namep, void* cb) VL_MT_UNSAFE;
|
void exportInsert(int finalize, const char* namep, void* cb) VL_MT_UNSAFE;
|
||||||
void varInsert(int finalize, const char* namep, void* datap, bool isParam,
|
void varInsert(int finalize, const char* namep, void* datap, bool isParam,
|
||||||
VerilatedVarType vltype, int vlflags, int dims, ...) VL_MT_UNSAFE;
|
VerilatedVarType vltype, int vlflags, int dims, ...) VL_MT_UNSAFE;
|
||||||
// ACCESSORS
|
// ACCESSORS
|
||||||
const char* name() const { return m_namep; }
|
const char* name() const { return m_namep; }
|
||||||
const char* identifier() const { return m_identifierp; }
|
const char* identifier() const { return m_identifierp; }
|
||||||
vlsint8_t timeunit() const { return m_timeunit; }
|
int8_t timeunit() const { return m_timeunit; }
|
||||||
inline VerilatedSyms* symsp() const { return m_symsp; }
|
VerilatedSyms* symsp() const { return m_symsp; }
|
||||||
VerilatedVar* varFind(const char* namep) const VL_MT_SAFE_POSTINIT;
|
VerilatedVar* varFind(const char* namep) const VL_MT_SAFE_POSTINIT;
|
||||||
VerilatedVarNameMap* varsp() const VL_MT_SAFE_POSTINIT { return m_varsp; }
|
VerilatedVarNameMap* varsp() const VL_MT_SAFE_POSTINIT { return m_varsp; }
|
||||||
void scopeDump() const;
|
void scopeDump() const;
|
||||||
void* exportFindError(int funcnum) const;
|
void* exportFindError(int funcnum) const;
|
||||||
static void* exportFindNullError(int funcnum) VL_MT_SAFE;
|
static void* exportFindNullError(int funcnum) VL_MT_SAFE;
|
||||||
static inline void* exportFind(const VerilatedScope* scopep, int funcnum) VL_MT_SAFE {
|
static void* exportFind(const VerilatedScope* scopep, int funcnum) VL_MT_SAFE {
|
||||||
if (VL_UNLIKELY(!scopep)) return exportFindNullError(funcnum);
|
if (VL_UNLIKELY(!scopep)) return exportFindNullError(funcnum);
|
||||||
if (VL_LIKELY(funcnum < scopep->m_funcnumMax)) {
|
if (VL_LIKELY(funcnum < scopep->m_funcnumMax)) {
|
||||||
// m_callbacksp must be declared, as Max'es are > 0
|
// m_callbacksp must be declared, as Max'es are > 0
|
||||||
@@ -634,9 +701,9 @@ class Verilated final {
|
|||||||
// Fast path
|
// Fast path
|
||||||
VerilatedContext* t_contextp = nullptr; // Thread's context
|
VerilatedContext* t_contextp = nullptr; // Thread's context
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
vluint32_t t_mtaskId = 0; // mtask# executing on this thread
|
uint32_t t_mtaskId = 0; // mtask# executing on this thread
|
||||||
// Messages maybe pending on thread, needs end-of-eval calls
|
// Messages maybe pending on thread, needs end-of-eval calls
|
||||||
vluint32_t t_endOfEvalReqd = 0;
|
uint32_t t_endOfEvalReqd = 0;
|
||||||
#endif
|
#endif
|
||||||
const VerilatedScope* t_dpiScopep = nullptr; // DPI context scope
|
const VerilatedScope* t_dpiScopep = nullptr; // DPI context scope
|
||||||
const char* t_dpiFilename = nullptr; // DPI context filename
|
const char* t_dpiFilename = nullptr; // DPI context filename
|
||||||
@@ -660,7 +727,7 @@ public:
|
|||||||
/// Return debug level
|
/// Return debug level
|
||||||
/// When multithreaded this may not immediately react to another thread
|
/// When multithreaded this may not immediately react to another thread
|
||||||
/// changing the level (no mutex)
|
/// changing the level (no mutex)
|
||||||
static inline int debug() VL_MT_SAFE { return s_debug; }
|
static int debug() VL_MT_SAFE { return s_debug; }
|
||||||
#else
|
#else
|
||||||
/// Return constant 0 debug level, so C++'s optimizer rips up
|
/// Return constant 0 debug level, so C++'s optimizer rips up
|
||||||
static constexpr int debug() VL_PURE { return 0; }
|
static constexpr int debug() VL_PURE { return 0; }
|
||||||
@@ -758,11 +825,11 @@ public:
|
|||||||
/// Return VerilatedContext::randSeed using current thread's VerilatedContext
|
/// Return VerilatedContext::randSeed using current thread's VerilatedContext
|
||||||
static int randSeed() VL_MT_SAFE { return Verilated::threadContextp()->randSeed(); }
|
static int randSeed() VL_MT_SAFE { return Verilated::threadContextp()->randSeed(); }
|
||||||
/// Call VerilatedContext::time using current thread's VerilatedContext
|
/// Call VerilatedContext::time using current thread's VerilatedContext
|
||||||
static void time(vluint64_t val) VL_MT_SAFE { Verilated::threadContextp()->time(val); }
|
static void time(uint64_t val) VL_MT_SAFE { Verilated::threadContextp()->time(val); }
|
||||||
/// Return VerilatedContext::time using current thread's VerilatedContext
|
/// Return VerilatedContext::time using current thread's VerilatedContext
|
||||||
static vluint64_t time() VL_MT_SAFE { return Verilated::threadContextp()->time(); }
|
static uint64_t time() VL_MT_SAFE { return Verilated::threadContextp()->time(); }
|
||||||
/// Call VerilatedContext::timeInc using current thread's VerilatedContext
|
/// Call VerilatedContext::timeInc using current thread's VerilatedContext
|
||||||
static void timeInc(vluint64_t add) VL_MT_UNSAFE { Verilated::threadContextp()->timeInc(add); }
|
static void timeInc(uint64_t add) VL_MT_UNSAFE { Verilated::threadContextp()->timeInc(add); }
|
||||||
// Deprecated
|
// Deprecated
|
||||||
static int timeunit() VL_MT_SAFE { return Verilated::threadContextp()->timeunit(); }
|
static int timeunit() VL_MT_SAFE { return Verilated::threadContextp()->timeunit(); }
|
||||||
static int timeprecision() VL_MT_SAFE { return Verilated::threadContextp()->timeprecision(); }
|
static int timeprecision() VL_MT_SAFE { return Verilated::threadContextp()->timeprecision(); }
|
||||||
@@ -820,11 +887,10 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
|
||||||
// METHODS - INTERNAL USE ONLY (but public due to what uses it)
|
// METHODS - INTERNAL USE ONLY (but public due to what uses it)
|
||||||
// Internal: Create a new module name by concatenating two strings
|
// Internal: Create a new module name by concatenating two strings
|
||||||
static const char* catName(const char* n1, const char* n2, int scopet = 0,
|
// Returns pointer to thread-local static data (overwritten on next call)
|
||||||
const char* delimiter = "."); // Returns static data
|
static const char* catName(const char* n1, const char* n2, const char* delimiter = ".");
|
||||||
|
|
||||||
// Internal: Throw signal assertion
|
// Internal: Throw signal assertion
|
||||||
static void nullPointerError(const char* filename, int linenum) VL_ATTR_NORETURN VL_MT_SAFE;
|
static void nullPointerError(const char* filename, int linenum) VL_ATTR_NORETURN VL_MT_SAFE;
|
||||||
@@ -848,8 +914,8 @@ public:
|
|||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
// Internal: Set the mtaskId, called when an mtask starts
|
// Internal: Set the mtaskId, called when an mtask starts
|
||||||
// Per thread, so no need to be in VerilatedContext
|
// Per thread, so no need to be in VerilatedContext
|
||||||
static void mtaskId(vluint32_t id) VL_MT_SAFE { t_s.t_mtaskId = id; }
|
static void mtaskId(uint32_t id) VL_MT_SAFE { t_s.t_mtaskId = id; }
|
||||||
static vluint32_t mtaskId() VL_MT_SAFE { return t_s.t_mtaskId; }
|
static uint32_t mtaskId() VL_MT_SAFE { return t_s.t_mtaskId; }
|
||||||
static void endOfEvalReqdInc() VL_MT_SAFE { ++t_s.t_endOfEvalReqd; }
|
static void endOfEvalReqdInc() VL_MT_SAFE { ++t_s.t_endOfEvalReqd; }
|
||||||
static void endOfEvalReqdDec() VL_MT_SAFE { --t_s.t_endOfEvalReqd; }
|
static void endOfEvalReqdDec() VL_MT_SAFE { --t_s.t_endOfEvalReqd; }
|
||||||
|
|
||||||
@@ -867,8 +933,8 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
inline void VerilatedContext::debug(int val) VL_MT_SAFE { Verilated::debug(val); }
|
void VerilatedContext::debug(int val) VL_MT_SAFE { Verilated::debug(val); }
|
||||||
inline int VerilatedContext::debug() VL_MT_SAFE { return Verilated::debug(); }
|
int VerilatedContext::debug() VL_MT_SAFE { return Verilated::debug(); }
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Data Types
|
// Data Types
|
||||||
|
|||||||
+13
-24
@@ -2,7 +2,7 @@
|
|||||||
######################################################################
|
######################################################################
|
||||||
# DESCRIPTION: Makefile commands for all verilated target files
|
# DESCRIPTION: Makefile commands for all verilated target files
|
||||||
#
|
#
|
||||||
# Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
# Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||||
# can redistribute it and/or modify it under the terms of either the GNU
|
# 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
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
@@ -56,6 +56,7 @@ VK_CPPFLAGS_ALWAYS += \
|
|||||||
-DVM_SC=$(VM_SC) \
|
-DVM_SC=$(VM_SC) \
|
||||||
-DVM_TRACE=$(VM_TRACE) \
|
-DVM_TRACE=$(VM_TRACE) \
|
||||||
-DVM_TRACE_FST=$(VM_TRACE_FST) \
|
-DVM_TRACE_FST=$(VM_TRACE_FST) \
|
||||||
|
-DVM_TRACE_VCD=$(VM_TRACE_VCD) \
|
||||||
$(CFG_CXXFLAGS_NO_UNUSED) \
|
$(CFG_CXXFLAGS_NO_UNUSED) \
|
||||||
|
|
||||||
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||||
@@ -141,26 +142,6 @@ ifneq ($(VM_THREADS),0)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq ($(VM_TRACE_THREADS),0)
|
|
||||||
ifneq ($(VM_TRACE_THREADS),)
|
|
||||||
ifeq ($(findstring -DVL_THREADED,$(CPPFLAGS)),)
|
|
||||||
$(error VM_TRACE_THREADS requires VM_THREADS)
|
|
||||||
endif
|
|
||||||
CPPFLAGS += -DVL_TRACE_THREADED
|
|
||||||
VK_C11=1
|
|
||||||
VK_LIBS_THREADED=1
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
ifneq ($(VM_TRACE_FST_WRITER_THREAD),0)
|
|
||||||
ifneq ($(VM_TRACE_FST_WRITER_THREAD),)
|
|
||||||
CPPFLAGS += -DVL_TRACE_FST_WRITER_THREAD
|
|
||||||
VK_C11=1
|
|
||||||
VK_LIBS_THREADED=1
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifneq ($(VK_C11),0)
|
ifneq ($(VK_C11),0)
|
||||||
ifneq ($(VK_C11),)
|
ifneq ($(VK_C11),)
|
||||||
# Need C++11 at least, so always default to newest
|
# Need C++11 at least, so always default to newest
|
||||||
@@ -186,13 +167,17 @@ VM_SLOW += $(VM_CLASSES_SLOW) $(VM_SUPPORT_SLOW)
|
|||||||
VK_FAST_OBJS = $(addsuffix .o, $(VM_FAST))
|
VK_FAST_OBJS = $(addsuffix .o, $(VM_FAST))
|
||||||
VK_SLOW_OBJS = $(addsuffix .o, $(VM_SLOW))
|
VK_SLOW_OBJS = $(addsuffix .o, $(VM_SLOW))
|
||||||
|
|
||||||
VK_USER_OBJS = $(addsuffix .o, $(VM_USER_CLASSES))
|
VK_USER_OBJS = $(addsuffix .o, $(VM_USER_CLASSES))
|
||||||
|
|
||||||
# Note VM_GLOBAL_FAST and VM_GLOBAL_SLOW holds the files required from the
|
# Note VM_GLOBAL_FAST and VM_GLOBAL_SLOW holds the files required from the
|
||||||
# run-time library. In practice everything is actually in VM_GLOBAL_FAST,
|
# run-time library. In practice everything is actually in VM_GLOBAL_FAST,
|
||||||
# but keeping the distinction for compatibility for now.
|
# but keeping the distinction for compatibility for now.
|
||||||
VK_GLOBAL_OBJS = $(addsuffix .o, $(VM_GLOBAL_FAST) $(VM_GLOBAL_SLOW))
|
VK_GLOBAL_OBJS = $(addsuffix .o, $(VM_GLOBAL_FAST) $(VM_GLOBAL_SLOW))
|
||||||
|
|
||||||
|
# Need to re-build if the generated makefile changes, as compiler options might
|
||||||
|
# have changed.
|
||||||
|
$(VK_GLOBAL_OBJS): $(VM_PREFIX).mk
|
||||||
|
|
||||||
ifneq ($(VM_PARALLEL_BUILDS),1)
|
ifneq ($(VM_PARALLEL_BUILDS),1)
|
||||||
# Fast build for small designs: All .cpp files in one fell swoop. This
|
# Fast build for small designs: All .cpp files in one fell swoop. This
|
||||||
# saves total compute, but can be slower if only a little changes. It is
|
# saves total compute, but can be slower if only a little changes. It is
|
||||||
@@ -223,7 +208,9 @@ endif
|
|||||||
$(info Archive $(AR) -rcs $@ $^)
|
$(info Archive $(AR) -rcs $@ $^)
|
||||||
$(foreach L, $(filter-out %.a,$^), $(shell echo $L >>[email protected]_deplist.tmp))
|
$(foreach L, $(filter-out %.a,$^), $(shell echo $L >>[email protected]_deplist.tmp))
|
||||||
@if test $(words $(filter %.a,$^)) -eq 0; then \
|
@if test $(words $(filter %.a,$^)) -eq 0; then \
|
||||||
$(AR) -rcs $@ @[email protected]_deplist.tmp; \
|
$(RM) -f $@; \
|
||||||
|
cat [email protected]_deplist.tmp | xargs $(AR) -rc $@; \
|
||||||
|
$(AR) -s $@; \
|
||||||
else \
|
else \
|
||||||
$(RM) -rf [email protected]; \
|
$(RM) -rf [email protected]; \
|
||||||
for archive in $(filter %.a,$^); do \
|
for archive in $(filter %.a,$^); do \
|
||||||
@@ -232,7 +219,9 @@ endif
|
|||||||
$(AR) -x ../../$${archive}; \
|
$(AR) -x ../../$${archive}; \
|
||||||
cd ../..; \
|
cd ../..; \
|
||||||
done; \
|
done; \
|
||||||
$(AR) -rcs $@ @[email protected]_deplist.tmp [email protected]/*/*.o; \
|
$(RM) -f $@; \
|
||||||
|
cat [email protected]_deplist.tmp | xargs $(AR) -rc $@; \
|
||||||
|
$(AR) -rcs $@ [email protected]/*/*.o; \
|
||||||
fi \
|
fi \
|
||||||
; $(RM) -rf [email protected]_deplist.tmp [email protected]
|
; $(RM) -rf [email protected]_deplist.tmp [email protected]
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -20,6 +20,11 @@
|
|||||||
// Autoconf substitutes this with the strings from AC_INIT.
|
// Autoconf substitutes this with the strings from AC_INIT.
|
||||||
#define VERILATOR_PRODUCT "@PACKAGE_NAME@"
|
#define VERILATOR_PRODUCT "@PACKAGE_NAME@"
|
||||||
|
|
||||||
/// Verilator version name, e.g. "1.000 2000-01-01"
|
/// Verilator version name, e.g. "1.002 2000-01-01"
|
||||||
// Autoconf substitutes this with the strings from AC_INIT.
|
// Autoconf substitutes this with the strings from AC_INIT.
|
||||||
#define VERILATOR_VERSION "@PACKAGE_VERSION@"
|
#define VERILATOR_VERSION "@PACKAGE_VERSION@"
|
||||||
|
|
||||||
|
/// Verilator version number as integer
|
||||||
|
/// As major * 100000 + minor * 1000, e.g. 1002000 == 1.002
|
||||||
|
// Autoconf substitutes this with the strings from AC_INIT.
|
||||||
|
#define VERILATOR_VERSION_INTEGER @VERILATOR_VERSION_INTEGER@
|
||||||
|
|||||||
+23
-21
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||||
// can redistribute it and/or modify it under the terms of either the GNU
|
// 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
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -22,13 +22,16 @@
|
|||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
#include "verilated.h"
|
|
||||||
#include "verilated_cov.h"
|
#include "verilated_cov.h"
|
||||||
|
|
||||||
|
#include "verilated.h"
|
||||||
#include "verilated_cov_key.h"
|
#include "verilated_cov_key.h"
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// VerilatedCovConst
|
// VerilatedCovConst
|
||||||
@@ -58,7 +61,7 @@ public: // But only local to this file
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
virtual ~VerilatedCovImpItem() = default;
|
virtual ~VerilatedCovImpItem() = default;
|
||||||
virtual vluint64_t count() const = 0;
|
virtual uint64_t count() const = 0;
|
||||||
virtual void zero() const = 0;
|
virtual void zero() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -68,22 +71,23 @@ public: // But only local to this file
|
|||||||
// This isn't in the header file for auto-magic conversion because it
|
// This isn't in the header file for auto-magic conversion because it
|
||||||
// inlines to too much code and makes compilation too slow.
|
// inlines to too much code and makes compilation too slow.
|
||||||
|
|
||||||
template <class T> class VerilatedCoverItemSpec final : public VerilatedCovImpItem {
|
template <class T>
|
||||||
|
class VerilatedCoverItemSpec final : public VerilatedCovImpItem {
|
||||||
private:
|
private:
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
T* m_countp; // Count value
|
T* m_countp; // Count value
|
||||||
public:
|
public:
|
||||||
// METHODS
|
// METHODS
|
||||||
// cppcheck-suppress truncLongCastReturn
|
// cppcheck-suppress truncLongCastReturn
|
||||||
virtual vluint64_t count() const override { return *m_countp; }
|
uint64_t count() const override { return *m_countp; }
|
||||||
virtual void zero() const override { *m_countp = 0; }
|
void zero() const override { *m_countp = 0; }
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
// cppcheck-suppress noExplicitConstructor
|
// cppcheck-suppress noExplicitConstructor
|
||||||
explicit VerilatedCoverItemSpec(T* countp)
|
explicit VerilatedCoverItemSpec(T* countp)
|
||||||
: m_countp{countp} {
|
: m_countp{countp} {
|
||||||
*m_countp = 0;
|
*m_countp = 0;
|
||||||
}
|
}
|
||||||
virtual ~VerilatedCoverItemSpec() override = default;
|
~VerilatedCoverItemSpec() override = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
@@ -102,7 +106,7 @@ private:
|
|||||||
using ItemList = std::deque<VerilatedCovImpItem*>;
|
using ItemList = std::deque<VerilatedCovImpItem*>;
|
||||||
|
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
VerilatedMutex m_mutex; // Protects all members
|
mutable VerilatedMutex m_mutex; // Protects all members
|
||||||
ValueIndexMap m_valueIndexes VL_GUARDED_BY(m_mutex); // Unique arbitrary value for values
|
ValueIndexMap m_valueIndexes VL_GUARDED_BY(m_mutex); // Unique arbitrary value for values
|
||||||
IndexValueMap m_indexValues VL_GUARDED_BY(m_mutex); // Unique arbitrary value for keys
|
IndexValueMap m_indexValues VL_GUARDED_BY(m_mutex); // Unique arbitrary value for keys
|
||||||
ItemList m_items VL_GUARDED_BY(m_mutex); // List of all items
|
ItemList m_items VL_GUARDED_BY(m_mutex); // List of all items
|
||||||
@@ -121,11 +125,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class VerilatedCovContext;
|
friend class VerilatedCovContext;
|
||||||
virtual ~VerilatedCovImp() override { clearGuts(); }
|
~VerilatedCovImp() override { clearGuts(); }
|
||||||
static VerilatedCovImp& imp() VL_MT_SAFE {
|
|
||||||
static VerilatedCovImp s_singleton;
|
|
||||||
return s_singleton;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// PRIVATE METHODS
|
// PRIVATE METHODS
|
||||||
@@ -208,7 +208,7 @@ private:
|
|||||||
// Forward to . so we have a whole word
|
// Forward to . so we have a whole word
|
||||||
const std::string suffix = *bpost ? std::string{bpost + 1} : "";
|
const std::string suffix = *bpost ? std::string{bpost + 1} : "";
|
||||||
|
|
||||||
const std::string out = prefix + "*" + suffix;
|
std::string out = prefix + "*" + suffix;
|
||||||
|
|
||||||
// cout << "\nch pre="<<prefix<<" s="<<suffix<<"\nch a="<<old<<"\nch b="<<add
|
// cout << "\nch pre="<<prefix<<" s="<<suffix<<"\nch a="<<old<<"\nch b="<<add
|
||||||
// <<"\ncho="<<out<<endl;
|
// <<"\ncho="<<out<<endl;
|
||||||
@@ -231,7 +231,7 @@ private:
|
|||||||
// Little selftest
|
// Little selftest
|
||||||
#define SELF_CHECK(got, exp) \
|
#define SELF_CHECK(got, exp) \
|
||||||
do { \
|
do { \
|
||||||
if ((got) != (exp)) VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: selftest\n"); \
|
if ((got) != (exp)) VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: selftest"); \
|
||||||
} while (0)
|
} while (0)
|
||||||
SELF_CHECK(combineHier("a.b.c", "a.b.c"), "a.b.c");
|
SELF_CHECK(combineHier("a.b.c", "a.b.c"), "a.b.c");
|
||||||
SELF_CHECK(combineHier("a.b.c", "a.b"), "a.b*");
|
SELF_CHECK(combineHier("a.b.c", "a.b"), "a.b*");
|
||||||
@@ -358,7 +358,7 @@ public:
|
|||||||
Verilated::quiesce();
|
Verilated::quiesce();
|
||||||
const VerilatedLockGuard lock{m_mutex};
|
const 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");
|
||||||
#endif
|
#endif
|
||||||
selftest();
|
selftest();
|
||||||
|
|
||||||
@@ -371,7 +371,7 @@ public:
|
|||||||
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
|
||||||
std::map<const std::string, std::pair<std::string, vluint64_t>> eventCounts;
|
std::map<const std::string, std::pair<std::string, uint64_t>> eventCounts;
|
||||||
for (const auto& itemp : m_items) {
|
for (const auto& itemp : m_items) {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string hier;
|
std::string hier;
|
||||||
@@ -438,11 +438,11 @@ void VerilatedCovContext::clearNonMatch(const char* matchp) VL_MT_SAFE {
|
|||||||
}
|
}
|
||||||
void VerilatedCovContext::zero() VL_MT_SAFE { impp()->zero(); }
|
void VerilatedCovContext::zero() VL_MT_SAFE { impp()->zero(); }
|
||||||
void VerilatedCovContext::write(const char* filenamep) VL_MT_SAFE { impp()->write(filenamep); }
|
void VerilatedCovContext::write(const char* filenamep) VL_MT_SAFE { impp()->write(filenamep); }
|
||||||
void VerilatedCovContext::_inserti(vluint32_t* itemp) VL_MT_SAFE {
|
void VerilatedCovContext::_inserti(uint32_t* itemp) VL_MT_SAFE {
|
||||||
impp()->inserti(new VerilatedCoverItemSpec<vluint32_t>{itemp});
|
impp()->inserti(new VerilatedCoverItemSpec<uint32_t>{itemp});
|
||||||
}
|
}
|
||||||
void VerilatedCovContext::_inserti(vluint64_t* itemp) VL_MT_SAFE {
|
void VerilatedCovContext::_inserti(uint64_t* itemp) VL_MT_SAFE {
|
||||||
impp()->inserti(new VerilatedCoverItemSpec<vluint64_t>{itemp});
|
impp()->inserti(new VerilatedCoverItemSpec<uint64_t>{itemp});
|
||||||
}
|
}
|
||||||
void VerilatedCovContext::_insertf(const char* filename, int lineno) VL_MT_SAFE {
|
void VerilatedCovContext::_insertf(const char* filename, int lineno) VL_MT_SAFE {
|
||||||
impp()->insertf(filename, lineno);
|
impp()->insertf(filename, lineno);
|
||||||
@@ -514,8 +514,10 @@ VerilatedCovContext* VerilatedCov::threadCovp() VL_MT_SAFE {
|
|||||||
|
|
||||||
VerilatedCovContext* VerilatedContext::coveragep() VL_MT_SAFE {
|
VerilatedCovContext* VerilatedContext::coveragep() VL_MT_SAFE {
|
||||||
static VerilatedMutex s_mutex;
|
static VerilatedMutex s_mutex;
|
||||||
|
// cppcheck-suppress identicalInnerCondition
|
||||||
if (VL_UNLIKELY(!m_coveragep)) {
|
if (VL_UNLIKELY(!m_coveragep)) {
|
||||||
const VerilatedLockGuard lock{s_mutex};
|
const VerilatedLockGuard lock{s_mutex};
|
||||||
|
// cppcheck-suppress identicalInnerCondition
|
||||||
if (VL_LIKELY(!m_coveragep)) { // Not redundant, prevents race
|
if (VL_LIKELY(!m_coveragep)) { // Not redundant, prevents race
|
||||||
m_coveragep.reset(new VerilatedCovImp);
|
m_coveragep.reset(new VerilatedCovImp);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-8
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||||
// can redistribute it and/or modify it under the terms of either the GNU
|
// 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
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -26,6 +26,7 @@
|
|||||||
#define VERILATOR_VERILATED_COV_H_
|
#define VERILATOR_VERILATED_COV_H_
|
||||||
|
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
|
|
||||||
#include "verilated.h"
|
#include "verilated.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@@ -72,7 +73,7 @@ class VerilatedCovImp;
|
|||||||
///
|
///
|
||||||
/// Example:
|
/// Example:
|
||||||
///
|
///
|
||||||
/// vluint32_t m_cases[10]; // Storage for coverage data
|
/// uint32_t m_cases[10]; // Storage for coverage data
|
||||||
/// constructor() {
|
/// constructor() {
|
||||||
/// // Initialize
|
/// // Initialize
|
||||||
/// for (int i = 0; i < 10; ++i) m_cases[i] = 0;
|
/// for (int i = 0; i < 10; ++i) m_cases[i] = 0;
|
||||||
@@ -88,7 +89,8 @@ class VerilatedCovImp;
|
|||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Convert VL_COVER_INSERT value arguments to strings, is \internal
|
// Convert VL_COVER_INSERT value arguments to strings, is \internal
|
||||||
|
|
||||||
template <class T> std::string vlCovCvtToStr(const T& t) VL_PURE {
|
template <class T>
|
||||||
|
std::string vlCovCvtToStr(const T& t) VL_PURE {
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
os << t;
|
os << t;
|
||||||
return os.str();
|
return os.str();
|
||||||
@@ -120,14 +122,15 @@ public:
|
|||||||
/// Zero coverage points
|
/// Zero coverage points
|
||||||
void zero() VL_MT_SAFE;
|
void zero() VL_MT_SAFE;
|
||||||
|
|
||||||
public: // But Internal use only
|
// METHODS - public but Internal use only
|
||||||
|
|
||||||
// Insert a coverage item
|
// Insert a coverage item
|
||||||
// We accept from 1-30 key/value pairs, all as strings.
|
// We accept from 1-30 key/value pairs, all as strings.
|
||||||
// Call _insert1, followed by _insert2 and _insert3
|
// Call _insert1, followed by _insert2 and _insert3
|
||||||
// Do not call directly; use VL_COVER_INSERT or higher level macros instead
|
// Do not call directly; use VL_COVER_INSERT or higher level macros instead
|
||||||
// _insert1: Remember item pointer with count. (Not const, as may add zeroing function)
|
// _insert1: Remember item pointer with count. (Not const, as may add zeroing function)
|
||||||
void _inserti(vluint32_t* itemp) VL_MT_SAFE;
|
void _inserti(uint32_t* itemp) VL_MT_SAFE;
|
||||||
void _inserti(vluint64_t* itemp) VL_MT_SAFE;
|
void _inserti(uint64_t* itemp) VL_MT_SAFE;
|
||||||
// _insert2: Set default filename and line number
|
// _insert2: Set default filename and line number
|
||||||
void _insertf(const char* filename, int lineno) VL_MT_SAFE;
|
void _insertf(const char* filename, int lineno) VL_MT_SAFE;
|
||||||
// _insert3: Set parameters
|
// _insert3: Set parameters
|
||||||
@@ -157,8 +160,8 @@ protected:
|
|||||||
friend class VerilatedCovImp;
|
friend class VerilatedCovImp;
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
// Internal: Only made as part of VerilatedCovImp
|
// Internal: Only made as part of VerilatedCovImp
|
||||||
VerilatedCovContext() {}
|
VerilatedCovContext() = default;
|
||||||
virtual ~VerilatedCovContext() {}
|
~VerilatedCovContext() override = default;
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
// Internal: access to implementation class
|
// Internal: access to implementation class
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||||
// can redistribute it and/or modify it under the terms of either the GNU
|
// 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
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2009-2021 by Wilson Snyder. This program is free software; you can
|
// Copyright 2009-2022 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -28,7 +28,9 @@
|
|||||||
#define VERILATOR_VERILATED_DPI_CPP_
|
#define VERILATOR_VERILATED_DPI_CPP_
|
||||||
|
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
|
|
||||||
#include "verilated_dpi.h"
|
#include "verilated_dpi.h"
|
||||||
|
|
||||||
#include "verilated_imp.h"
|
#include "verilated_imp.h"
|
||||||
|
|
||||||
// On MSVC++ we need svdpi.h to declare exports, not imports
|
// On MSVC++ we need svdpi.h to declare exports, not imports
|
||||||
@@ -179,7 +181,7 @@ void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal s, int lbit, int w
|
|||||||
//======================================================================
|
//======================================================================
|
||||||
// Open array internals
|
// Open array internals
|
||||||
|
|
||||||
static inline const VerilatedDpiOpenVar* _vl_openhandle_varp(const svOpenArrayHandle h) {
|
static const VerilatedDpiOpenVar* _vl_openhandle_varp(const svOpenArrayHandle h) {
|
||||||
if (VL_UNLIKELY(!h)) {
|
if (VL_UNLIKELY(!h)) {
|
||||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||||
"%%Error: DPI svOpenArrayHandle function called with nullptr handle");
|
"%%Error: DPI svOpenArrayHandle function called with nullptr handle");
|
||||||
@@ -417,7 +419,7 @@ static void _vl_svPutBitArrElem(const svOpenArrayHandle d, svBit value, int narg
|
|||||||
}
|
}
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// DPI accessors that simply call above functions
|
// DPI accessors that call above functions
|
||||||
|
|
||||||
void* svGetArrElemPtr(const svOpenArrayHandle h, int indx1, ...) {
|
void* svGetArrElemPtr(const svOpenArrayHandle h, int indx1, ...) {
|
||||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(h);
|
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(h);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -27,6 +27,7 @@
|
|||||||
#define VERILATOR_VERILATED_DPI_H_
|
#define VERILATOR_VERILATED_DPI_H_
|
||||||
|
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
|
|
||||||
#include "verilated.h" // Also presumably included by caller
|
#include "verilated.h" // Also presumably included by caller
|
||||||
#include "verilated_sym_props.h"
|
#include "verilated_sym_props.h"
|
||||||
|
|
||||||
|
|||||||
+85
-41
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||||
// can redistribute it and/or modify it under the terms of either the GNU
|
// 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
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
#include "verilated_fst_c.h"
|
#include "verilated_fst_c.h"
|
||||||
|
|
||||||
// GTKWave configuration
|
// GTKWave configuration
|
||||||
#ifdef VL_TRACE_FST_WRITER_THREAD
|
#ifdef VL_THREADED
|
||||||
# define HAVE_LIBPTHREAD
|
# define HAVE_LIBPTHREAD
|
||||||
# define FST_WRITER_PARALLEL
|
# define FST_WRITER_PARALLEL
|
||||||
#endif
|
#endif
|
||||||
@@ -83,15 +83,16 @@ static_assert(static_cast<int>(FST_ST_VCD_PROGRAM) == static_cast<int>(VLT_TRACE
|
|||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Specialization of the generics for this trace format
|
// Specialization of the generics for this trace format
|
||||||
|
|
||||||
#define VL_DERIVED_T VerilatedFst
|
#define VL_SUB_T VerilatedFst
|
||||||
#include "verilated_trace_imp.cpp"
|
#define VL_BUF_T VerilatedFstBuffer
|
||||||
#undef VL_DERIVED_T
|
#include "verilated_trace_imp.h"
|
||||||
|
#undef VL_SUB_T
|
||||||
|
#undef VL_BUF_T
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// VerilatedFst
|
// VerilatedFst
|
||||||
|
|
||||||
VerilatedFst::VerilatedFst(void* fst)
|
VerilatedFst::VerilatedFst(void* /*fst*/) {}
|
||||||
: m_fst{fst} {}
|
|
||||||
|
|
||||||
VerilatedFst::~VerilatedFst() {
|
VerilatedFst::~VerilatedFst() {
|
||||||
if (m_fst) fstWriterClose(m_fst);
|
if (m_fst) fstWriterClose(m_fst);
|
||||||
@@ -104,14 +105,12 @@ void VerilatedFst::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
|||||||
m_fst = fstWriterCreate(filename, 1);
|
m_fst = fstWriterCreate(filename, 1);
|
||||||
fstWriterSetPackType(m_fst, FST_WR_PT_LZ4);
|
fstWriterSetPackType(m_fst, FST_WR_PT_LZ4);
|
||||||
fstWriterSetTimescaleFromString(m_fst, timeResStr().c_str()); // lintok-begin-on-ref
|
fstWriterSetTimescaleFromString(m_fst, timeResStr().c_str()); // lintok-begin-on-ref
|
||||||
#ifdef VL_TRACE_FST_WRITER_THREAD
|
if (m_useFstWriterThread) fstWriterSetParallelMode(m_fst, 1);
|
||||||
fstWriterSetParallelMode(m_fst, 1);
|
|
||||||
#endif
|
|
||||||
fullDump(true); // First dump must be full for fst
|
fullDump(true); // First dump must be full for fst
|
||||||
|
|
||||||
m_curScope.clear();
|
m_curScope.clear();
|
||||||
|
|
||||||
VerilatedTrace<VerilatedFst>::traceInit();
|
Super::traceInit();
|
||||||
|
|
||||||
// Clear the scope stack
|
// Clear the scope stack
|
||||||
auto it = m_curScope.begin();
|
auto it = m_curScope.begin();
|
||||||
@@ -122,7 +121,7 @@ void VerilatedFst::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
|||||||
|
|
||||||
// convert m_code2symbol into an array for fast lookup
|
// convert m_code2symbol into an array for fast lookup
|
||||||
if (!m_symbolp) {
|
if (!m_symbolp) {
|
||||||
m_symbolp = new fstHandle[nextCode()];
|
m_symbolp = new fstHandle[nextCode()]{0};
|
||||||
for (const auto& i : m_code2symbol) m_symbolp[i.first] = i.second;
|
for (const auto& i : m_code2symbol) m_symbolp[i.first] = i.second;
|
||||||
}
|
}
|
||||||
m_code2symbol.clear();
|
m_code2symbol.clear();
|
||||||
@@ -133,23 +132,23 @@ void VerilatedFst::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
|||||||
|
|
||||||
void VerilatedFst::close() VL_MT_SAFE_EXCLUDES(m_mutex) {
|
void VerilatedFst::close() VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||||
const VerilatedLockGuard lock{m_mutex};
|
const VerilatedLockGuard lock{m_mutex};
|
||||||
VerilatedTrace<VerilatedFst>::closeBase();
|
Super::closeBase();
|
||||||
fstWriterClose(m_fst);
|
fstWriterClose(m_fst);
|
||||||
m_fst = nullptr;
|
m_fst = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerilatedFst::flush() VL_MT_SAFE_EXCLUDES(m_mutex) {
|
void VerilatedFst::flush() VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||||
const VerilatedLockGuard lock{m_mutex};
|
const VerilatedLockGuard lock{m_mutex};
|
||||||
VerilatedTrace<VerilatedFst>::flushBase();
|
Super::flushBase();
|
||||||
fstWriterFlushContext(m_fst);
|
fstWriterFlushContext(m_fst);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerilatedFst::emitTimeChange(vluint64_t timeui) { fstWriterEmitTimeChange(m_fst, timeui); }
|
void VerilatedFst::emitTimeChange(uint64_t timeui) { fstWriterEmitTimeChange(m_fst, timeui); }
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Decl
|
// Decl
|
||||||
|
|
||||||
void VerilatedFst::declDTypeEnum(int dtypenum, const char* name, vluint32_t elements,
|
void VerilatedFst::declDTypeEnum(int dtypenum, const char* name, uint32_t elements,
|
||||||
unsigned int minValbits, const char** itemNamesp,
|
unsigned int minValbits, const char** itemNamesp,
|
||||||
const char** itemValuesp) {
|
const char** itemValuesp) {
|
||||||
const fstEnumHandle enumNum
|
const fstEnumHandle enumNum
|
||||||
@@ -157,19 +156,21 @@ void VerilatedFst::declDTypeEnum(int dtypenum, const char* name, vluint32_t elem
|
|||||||
m_local2fstdtype[dtypenum] = enumNum;
|
m_local2fstdtype[dtypenum] = enumNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerilatedFst::declare(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
void VerilatedFst::declare(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
fstVarType vartype, bool array, int arraynum, bool bussed, int msb,
|
||||||
|
int lsb) {
|
||||||
const int bits = ((msb > lsb) ? (msb - lsb) : (lsb - msb)) + 1;
|
const int bits = ((msb > lsb) ? (msb - lsb) : (lsb - msb)) + 1;
|
||||||
|
|
||||||
VerilatedTrace<VerilatedFst>::declCode(code, bits, false);
|
const bool enabled = Super::declCode(code, name, bits, false);
|
||||||
|
if (!enabled) return;
|
||||||
|
|
||||||
std::istringstream nameiss{name};
|
std::string nameasstr = namePrefix() + name;
|
||||||
|
std::istringstream nameiss{nameasstr};
|
||||||
std::istream_iterator<std::string> beg(nameiss);
|
std::istream_iterator<std::string> beg(nameiss);
|
||||||
std::istream_iterator<std::string> end;
|
std::istream_iterator<std::string> end;
|
||||||
std::list<std::string> tokens(beg, end); // Split name
|
std::list<std::string> tokens(beg, end); // Split name
|
||||||
std::string symbol_name{tokens.back()};
|
std::string symbol_name{tokens.back()};
|
||||||
tokens.pop_back(); // Remove symbol name from hierarchy
|
tokens.pop_back(); // Remove symbol name from hierarchy
|
||||||
tokens.insert(tokens.begin(), moduleName()); // Add current module to the hierarchy
|
|
||||||
std::string tmpModName;
|
std::string tmpModName;
|
||||||
|
|
||||||
// Find point where current and new scope diverge
|
// Find point where current and new scope diverge
|
||||||
@@ -195,9 +196,9 @@ void VerilatedFst::declare(vluint32_t code, const char* name, int dtypenum, fstV
|
|||||||
// If the scope ends with a non-ascii character, it will be 0x80 + fstScopeType
|
// If the scope ends with a non-ascii character, it will be 0x80 + fstScopeType
|
||||||
fstWriterSetScope(m_fst, static_cast<fstScopeType>(new_it->back() & 0x7f),
|
fstWriterSetScope(m_fst, static_cast<fstScopeType>(new_it->back() & 0x7f),
|
||||||
tmpModName.c_str(), nullptr);
|
tmpModName.c_str(), nullptr);
|
||||||
} else
|
} else {
|
||||||
fstWriterSetScope(m_fst, FST_ST_VCD_SCOPE, new_it->c_str(), nullptr);
|
fstWriterSetScope(m_fst, FST_ST_VCD_SCOPE, new_it->c_str(), nullptr);
|
||||||
|
}
|
||||||
m_curScope.push_back(*new_it);
|
m_curScope.push_back(*new_it);
|
||||||
new_it = tokens.erase(new_it);
|
new_it = tokens.erase(new_it);
|
||||||
}
|
}
|
||||||
@@ -205,6 +206,7 @@ void VerilatedFst::declare(vluint32_t code, const char* name, int dtypenum, fstV
|
|||||||
std::stringstream name_ss;
|
std::stringstream name_ss;
|
||||||
name_ss << symbol_name;
|
name_ss << symbol_name;
|
||||||
if (array) name_ss << "[" << arraynum << "]";
|
if (array) name_ss << "[" << arraynum << "]";
|
||||||
|
if (bussed) name_ss << " [" << msb << ":" << lsb << "]";
|
||||||
std::string name_str = name_ss.str();
|
std::string name_str = name_ss.str();
|
||||||
|
|
||||||
if (dtypenum > 0) {
|
if (dtypenum > 0) {
|
||||||
@@ -221,66 +223,108 @@ void VerilatedFst::declare(vluint32_t code, const char* name, int dtypenum, fstV
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VerilatedFst::declBit(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
void VerilatedFst::declBit(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||||
fstVarType vartype, bool array, int arraynum) {
|
fstVarType vartype, bool array, int arraynum) {
|
||||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, 0, 0);
|
declare(code, name, dtypenum, vardir, vartype, array, arraynum, false, 0, 0);
|
||||||
}
|
}
|
||||||
void VerilatedFst::declBus(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
void VerilatedFst::declBus(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
||||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, msb, lsb);
|
declare(code, name, dtypenum, vardir, vartype, array, arraynum, true, msb, lsb);
|
||||||
}
|
}
|
||||||
void VerilatedFst::declQuad(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
void VerilatedFst::declQuad(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
||||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, msb, lsb);
|
declare(code, name, dtypenum, vardir, vartype, array, arraynum, true, msb, lsb);
|
||||||
}
|
}
|
||||||
void VerilatedFst::declArray(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
void VerilatedFst::declArray(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
||||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, msb, lsb);
|
declare(code, name, dtypenum, vardir, vartype, array, arraynum, true, msb, lsb);
|
||||||
}
|
}
|
||||||
void VerilatedFst::declDouble(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
void VerilatedFst::declDouble(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||||
fstVarType vartype, bool array, int arraynum) {
|
fstVarType vartype, bool array, int arraynum) {
|
||||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, 63, 0);
|
declare(code, name, dtypenum, vardir, vartype, array, arraynum, false, 63, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Get/commit trace buffer
|
||||||
|
|
||||||
|
VerilatedFst::Buffer* VerilatedFst::getTraceBuffer() {
|
||||||
|
#ifdef VL_THREADED
|
||||||
|
if (offload()) return new OffloadBuffer{*this};
|
||||||
|
#endif
|
||||||
|
return new Buffer{*this};
|
||||||
|
}
|
||||||
|
|
||||||
|
void VerilatedFst::commitTraceBuffer(VerilatedFst::Buffer* bufp) {
|
||||||
|
#ifdef VL_THREADED
|
||||||
|
if (offload()) {
|
||||||
|
OffloadBuffer* const offloadBufferp = static_cast<OffloadBuffer*>(bufp);
|
||||||
|
if (offloadBufferp->m_offloadBufferWritep) {
|
||||||
|
m_offloadBufferWritep = offloadBufferp->m_offloadBufferWritep;
|
||||||
|
return; // Buffer will be deleted by the offload thread
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
delete bufp;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Configure
|
||||||
|
|
||||||
|
void VerilatedFst::configure(const VerilatedTraceConfig& config) {
|
||||||
|
// If at least one model requests the FST writer thread, then use it
|
||||||
|
m_useFstWriterThread |= config.m_useFstWriterThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// VerilatedFstBuffer implementation
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Trace rendering primitives
|
||||||
|
|
||||||
// Note: emit* are only ever called from one place (full* in
|
// Note: emit* are only ever called from one place (full* in
|
||||||
// verilated_trace_imp.cpp, which is included in this file at the top),
|
// verilated_trace_imp.h, which is included in this file at the top),
|
||||||
// so always inline them.
|
// so always inline them.
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedFst::emitBit(vluint32_t code, CData newval) {
|
void VerilatedFstBuffer::emitBit(uint32_t code, CData newval) {
|
||||||
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
|
||||||
fstWriterEmitValueChange(m_fst, m_symbolp[code], newval ? "1" : "0");
|
fstWriterEmitValueChange(m_fst, m_symbolp[code], newval ? "1" : "0");
|
||||||
}
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedFst::emitCData(vluint32_t code, CData newval, int bits) {
|
void VerilatedFstBuffer::emitCData(uint32_t code, CData newval, int bits) {
|
||||||
char buf[VL_BYTESIZE];
|
char buf[VL_BYTESIZE];
|
||||||
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
|
||||||
cvtCDataToStr(buf, newval << (VL_BYTESIZE - bits));
|
cvtCDataToStr(buf, newval << (VL_BYTESIZE - bits));
|
||||||
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
|
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedFst::emitSData(vluint32_t code, SData newval, int bits) {
|
void VerilatedFstBuffer::emitSData(uint32_t code, SData newval, int bits) {
|
||||||
char buf[VL_SHORTSIZE];
|
char buf[VL_SHORTSIZE];
|
||||||
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
|
||||||
cvtSDataToStr(buf, newval << (VL_SHORTSIZE - bits));
|
cvtSDataToStr(buf, newval << (VL_SHORTSIZE - bits));
|
||||||
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
|
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedFst::emitIData(vluint32_t code, IData newval, int bits) {
|
void VerilatedFstBuffer::emitIData(uint32_t code, IData newval, int bits) {
|
||||||
char buf[VL_IDATASIZE];
|
char buf[VL_IDATASIZE];
|
||||||
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
|
||||||
cvtIDataToStr(buf, newval << (VL_IDATASIZE - bits));
|
cvtIDataToStr(buf, newval << (VL_IDATASIZE - bits));
|
||||||
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
|
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedFst::emitQData(vluint32_t code, QData newval, int bits) {
|
void VerilatedFstBuffer::emitQData(uint32_t code, QData newval, int bits) {
|
||||||
char buf[VL_QUADSIZE];
|
char buf[VL_QUADSIZE];
|
||||||
|
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
|
||||||
cvtQDataToStr(buf, newval << (VL_QUADSIZE - bits));
|
cvtQDataToStr(buf, newval << (VL_QUADSIZE - bits));
|
||||||
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
|
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedFst::emitWData(vluint32_t code, const WData* newvalp, int bits) {
|
void VerilatedFstBuffer::emitWData(uint32_t code, const WData* newvalp, int bits) {
|
||||||
int words = VL_WORDS_I(bits);
|
int words = VL_WORDS_I(bits);
|
||||||
char* wp = m_strbuf;
|
char* wp = m_strbuf;
|
||||||
// Convert the most significant word
|
// Convert the most significant word
|
||||||
@@ -296,6 +340,6 @@ void VerilatedFst::emitWData(vluint32_t code, const WData* newvalp, int bits) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
VL_ATTR_ALWINLINE
|
VL_ATTR_ALWINLINE
|
||||||
void VerilatedFst::emitDouble(vluint32_t code, double newval) {
|
void VerilatedFstBuffer::emitDouble(uint32_t code, double newval) {
|
||||||
fstWriterEmitValueChange(m_fst, m_symbolp[code], &newval);
|
fstWriterEmitValueChange(m_fst, m_symbolp[code], &newval);
|
||||||
}
|
}
|
||||||
|
|||||||
+96
-44
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||||
// can redistribute it and/or modify it under the terms of either the GNU
|
// 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
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -31,60 +31,64 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
class VerilatedFstBuffer;
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// VerilatedFst
|
// VerilatedFst
|
||||||
// Base class to create a Verilator FST dump
|
// Base class to create a Verilator FST dump
|
||||||
// This is an internally used class - see VerilatedFstC for what to call from applications
|
// This is an internally used class - see VerilatedFstC for what to call from applications
|
||||||
|
|
||||||
class VerilatedFst final : public VerilatedTrace<VerilatedFst> {
|
class VerilatedFst final : public VerilatedTrace<VerilatedFst, VerilatedFstBuffer> {
|
||||||
|
public:
|
||||||
|
using Super = VerilatedTrace<VerilatedFst, VerilatedFstBuffer>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Give the superclass access to private bits (to avoid virtual functions)
|
friend VerilatedFstBuffer; // Give the buffer access to the private bits
|
||||||
friend class VerilatedTrace<VerilatedFst>;
|
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// FST specific internals
|
// FST specific internals
|
||||||
|
|
||||||
void* m_fst;
|
void* m_fst = nullptr;
|
||||||
std::map<vluint32_t, fstHandle> m_code2symbol;
|
std::map<uint32_t, fstHandle> m_code2symbol;
|
||||||
std::map<int, fstEnumHandle> m_local2fstdtype;
|
std::map<int, fstEnumHandle> m_local2fstdtype;
|
||||||
std::list<std::string> m_curScope;
|
std::list<std::string> m_curScope;
|
||||||
fstHandle* m_symbolp = nullptr; // same as m_code2symbol, but as an array
|
fstHandle* m_symbolp = nullptr; // same as m_code2symbol, but as an array
|
||||||
char* m_strbuf = nullptr; // String buffer long enough to hold maxBits() chars
|
char* m_strbuf = nullptr; // String buffer long enough to hold maxBits() chars
|
||||||
|
|
||||||
|
bool m_useFstWriterThread = false; // Whether to use the separate FST writer thread
|
||||||
|
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VL_UNCOPYABLE(VerilatedFst);
|
VL_UNCOPYABLE(VerilatedFst);
|
||||||
void declare(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
void declare(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
fstVarType vartype, bool array, int arraynum, bool bussed, int msb, int lsb);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Implementation of VerilatedTrace interface
|
// Implementation of VerilatedTrace interface
|
||||||
|
|
||||||
// Implementations of protected virtual methods for VerilatedTrace
|
// Called when the trace moves forward to a new time point
|
||||||
virtual void emitTimeChange(vluint64_t timeui) override;
|
void emitTimeChange(uint64_t timeui) override;
|
||||||
|
|
||||||
// Hooks called from VerilatedTrace
|
// Hooks called from VerilatedTrace
|
||||||
virtual bool preFullDump() override { return isOpen(); }
|
bool preFullDump() override { return isOpen(); }
|
||||||
virtual bool preChangeDump() override { return isOpen(); }
|
bool preChangeDump() override { return isOpen(); }
|
||||||
|
|
||||||
// Implementations of duck-typed methods for VerilatedTrace. These are
|
// Trace buffer management
|
||||||
// called from only one place (namely full*) so always inline them.
|
Buffer* getTraceBuffer() override;
|
||||||
inline void emitBit(vluint32_t code, CData newval);
|
void commitTraceBuffer(Buffer*) override;
|
||||||
inline void emitCData(vluint32_t code, CData newval, int bits);
|
|
||||||
inline void emitSData(vluint32_t code, SData newval, int bits);
|
// Configure sub-class
|
||||||
inline void emitIData(vluint32_t code, IData newval, int bits);
|
void configure(const VerilatedTraceConfig&) override;
|
||||||
inline void emitQData(vluint32_t code, QData newval, int bits);
|
|
||||||
inline void emitWData(vluint32_t code, const WData* newvalp, int bits);
|
|
||||||
inline void emitDouble(vluint32_t code, double newval);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// External interface to client code
|
// External interface to client code
|
||||||
// (All must be threadsafe)
|
|
||||||
|
|
||||||
|
// CONSTRUCTOR
|
||||||
explicit VerilatedFst(void* fst = nullptr);
|
explicit VerilatedFst(void* fst = nullptr);
|
||||||
~VerilatedFst();
|
~VerilatedFst();
|
||||||
|
|
||||||
|
// METHODS - All must be thread safe
|
||||||
// Open the file; call isOpen() to see if errors
|
// Open the file; call isOpen() to see if errors
|
||||||
void open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex);
|
void open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||||
// Close the file
|
// Close the file
|
||||||
@@ -97,32 +101,75 @@ public:
|
|||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Internal interface to Verilator generated code
|
// Internal interface to Verilator generated code
|
||||||
|
|
||||||
// Inside dumping routines, declare a data type
|
void declBit(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||||
void declDTypeEnum(int dtypenum, const char* name, vluint32_t elements,
|
|
||||||
unsigned int minValbits, const char** itemNamesp, const char** itemValuesp);
|
|
||||||
|
|
||||||
// Inside dumping routines, declare a signal
|
|
||||||
void declBit(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
|
||||||
fstVarType vartype, bool array, int arraynum);
|
fstVarType vartype, bool array, int arraynum);
|
||||||
void declBus(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
void declBus(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
||||||
void declQuad(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
void declQuad(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
||||||
void declArray(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
void declArray(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
||||||
void declDouble(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
void declDouble(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||||
fstVarType vartype, bool array, int arraynum);
|
fstVarType vartype, bool array, int arraynum);
|
||||||
|
|
||||||
|
void declDTypeEnum(int dtypenum, const char* name, uint32_t elements, unsigned int minValbits,
|
||||||
|
const char** itemNamesp, const char** itemValuesp);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef DOXYGEN
|
#ifndef DOXYGEN
|
||||||
// Declare specialization here as it's used in VerilatedFstC just below
|
// Declare specialization here as it's used in VerilatedFstC just below
|
||||||
template <> void VerilatedTrace<VerilatedFst>::dump(vluint64_t timeui);
|
template <>
|
||||||
template <> void VerilatedTrace<VerilatedFst>::set_time_unit(const char* unitp);
|
void VerilatedFst::Super::dump(uint64_t time);
|
||||||
template <> void VerilatedTrace<VerilatedFst>::set_time_unit(const std::string& unit);
|
template <>
|
||||||
template <> void VerilatedTrace<VerilatedFst>::set_time_resolution(const char* unitp);
|
void VerilatedFst::Super::set_time_unit(const char* unitp);
|
||||||
template <> void VerilatedTrace<VerilatedFst>::set_time_resolution(const std::string& unit);
|
template <>
|
||||||
|
void VerilatedFst::Super::set_time_unit(const std::string& unit);
|
||||||
|
template <>
|
||||||
|
void VerilatedFst::Super::set_time_resolution(const char* unitp);
|
||||||
|
template <>
|
||||||
|
void VerilatedFst::Super::set_time_resolution(const std::string& unit);
|
||||||
|
template <>
|
||||||
|
void VerilatedFst::Super::dumpvars(int level, const std::string& hier);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// VerilatedFstBuffer
|
||||||
|
|
||||||
|
class VerilatedFstBuffer VL_NOT_FINAL {
|
||||||
|
// Give the trace file access to the private bits
|
||||||
|
friend VerilatedFst;
|
||||||
|
friend VerilatedFst::Super;
|
||||||
|
friend VerilatedFst::Buffer;
|
||||||
|
friend VerilatedFst::OffloadBuffer;
|
||||||
|
|
||||||
|
VerilatedFst& m_owner; // Trace file owning this buffer. Required by subclasses.
|
||||||
|
|
||||||
|
// The FST file handle
|
||||||
|
void* const m_fst = m_owner.m_fst;
|
||||||
|
// code to fstHande map, as an array
|
||||||
|
const fstHandle* const m_symbolp = m_owner.m_symbolp;
|
||||||
|
// String buffer long enough to hold maxBits() chars
|
||||||
|
char* const m_strbuf = m_owner.m_strbuf;
|
||||||
|
|
||||||
|
// CONSTRUCTOR
|
||||||
|
explicit VerilatedFstBuffer(VerilatedFst& owner)
|
||||||
|
: m_owner{owner} {}
|
||||||
|
virtual ~VerilatedFstBuffer() = default;
|
||||||
|
|
||||||
|
//=========================================================================
|
||||||
|
// Implementation of VerilatedTraceBuffer interface
|
||||||
|
|
||||||
|
// Implementations of duck-typed methods for VerilatedTraceBuffer. These are
|
||||||
|
// called from only one place (the full* methods), so always inline them.
|
||||||
|
VL_ATTR_ALWINLINE void emitBit(uint32_t code, CData newval);
|
||||||
|
VL_ATTR_ALWINLINE void emitCData(uint32_t code, CData newval, int bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitSData(uint32_t code, SData newval, int bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitIData(uint32_t code, IData newval, int bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitQData(uint32_t code, QData newval, int bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitWData(uint32_t code, const WData* newvalp, int bits);
|
||||||
|
VL_ATTR_ALWINLINE void emitDouble(uint32_t code, double newval);
|
||||||
|
};
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// VerilatedFstC
|
// VerilatedFstC
|
||||||
/// Create a FST dump file in C standalone (no SystemC) simulations.
|
/// Create a FST dump file in C standalone (no SystemC) simulations.
|
||||||
@@ -139,7 +186,7 @@ public:
|
|||||||
explicit VerilatedFstC(void* filep = nullptr)
|
explicit VerilatedFstC(void* filep = nullptr)
|
||||||
: m_sptrace{filep} {}
|
: m_sptrace{filep} {}
|
||||||
/// Destruct, flush, and close the dump
|
/// Destruct, flush, and close the dump
|
||||||
~VerilatedFstC() { close(); }
|
virtual ~VerilatedFstC() { close(); }
|
||||||
|
|
||||||
// METHODS - User called
|
// METHODS - User called
|
||||||
|
|
||||||
@@ -154,12 +201,12 @@ public:
|
|||||||
/// Write one cycle of dump data
|
/// Write one cycle of dump data
|
||||||
/// Call with the current context's time just after eval'ed,
|
/// Call with the current context's time just after eval'ed,
|
||||||
/// e.g. ->dump(contextp->time())
|
/// e.g. ->dump(contextp->time())
|
||||||
void dump(vluint64_t timeui) { m_sptrace.dump(timeui); }
|
void dump(uint64_t timeui) { m_sptrace.dump(timeui); }
|
||||||
/// Write one cycle of dump data - backward compatible and to reduce
|
/// Write one cycle of dump data - backward compatible and to reduce
|
||||||
/// conversion warnings. It's better to use a vluint64_t time instead.
|
/// conversion warnings. It's better to use a uint64_t time instead.
|
||||||
void dump(double timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
|
void dump(double timestamp) { dump(static_cast<uint64_t>(timestamp)); }
|
||||||
void dump(vluint32_t timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
|
void dump(uint32_t timestamp) { dump(static_cast<uint64_t>(timestamp)); }
|
||||||
void dump(int timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
|
void dump(int timestamp) { dump(static_cast<uint64_t>(timestamp)); }
|
||||||
|
|
||||||
// METHODS - Internal/backward compatible
|
// METHODS - Internal/backward compatible
|
||||||
// \protectedsection
|
// \protectedsection
|
||||||
@@ -178,9 +225,14 @@ public:
|
|||||||
void set_time_resolution(const std::string& unit) VL_MT_SAFE {
|
void set_time_resolution(const std::string& unit) VL_MT_SAFE {
|
||||||
m_sptrace.set_time_resolution(unit);
|
m_sptrace.set_time_resolution(unit);
|
||||||
}
|
}
|
||||||
|
// Set variables to dump, using $dumpvars format
|
||||||
|
// If level = 0, dump everything and hier is then ignored
|
||||||
|
void dumpvars(int level, const std::string& hier) VL_MT_SAFE {
|
||||||
|
m_sptrace.dumpvars(level, hier);
|
||||||
|
}
|
||||||
|
|
||||||
// Internal class access
|
// Internal class access
|
||||||
inline VerilatedFst* spTrace() { return &m_sptrace; };
|
VerilatedFst* spTrace() { return &m_sptrace; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // guard
|
#endif // guard
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// THIS MODULE IS PUBLICLY LICENSED
|
// THIS MODULE IS PUBLICLY LICENSED
|
||||||
//
|
//
|
||||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||||
// can redistribute it and/or modify it under the terms of either the GNU
|
// 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
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -22,11 +22,23 @@
|
|||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
|
|
||||||
#include "verilated_fst_sc.h"
|
#include "verilated_fst_sc.h"
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
|
||||||
|
void VerilatedFstSc::open(const char* filename) {
|
||||||
|
if (!sc_core::sc_get_curr_simcontext()->elaboration_done()) {
|
||||||
|
vl_fatal(__FILE__, __LINE__, "VerilatedFstSc",
|
||||||
|
("%Error: VerilatedFstSc::open(\"" + std::string{filename}
|
||||||
|
+ "\") is called before sc_core::sc_start(). "
|
||||||
|
"Run sc_core::sc_start(sc_core::SC_ZERO_TIME) before opening a wave file.")
|
||||||
|
.c_str());
|
||||||
|
}
|
||||||
|
VerilatedFstC::open(filename);
|
||||||
|
}
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// SystemC 2.1.v1
|
// SystemC 2.1.v1
|
||||||
// cppcheck-suppress unusedFunction
|
// cppcheck-suppress unusedFunction
|
||||||
@@ -52,9 +64,6 @@ void VerilatedFstSc::trace(const unsigned int&, const std::string&, const char**
|
|||||||
DECL_TRACE_METHOD_B( unsigned short )
|
DECL_TRACE_METHOD_B( unsigned short )
|
||||||
DECL_TRACE_METHOD_B( unsigned int )
|
DECL_TRACE_METHOD_B( unsigned int )
|
||||||
DECL_TRACE_METHOD_B( unsigned long )
|
DECL_TRACE_METHOD_B( unsigned long )
|
||||||
#ifdef SYSTEMC_64BIT_PATCHES
|
|
||||||
DECL_TRACE_METHOD_B( unsigned long long)
|
|
||||||
#endif
|
|
||||||
DECL_TRACE_METHOD_B( char )
|
DECL_TRACE_METHOD_B( char )
|
||||||
DECL_TRACE_METHOD_B( short )
|
DECL_TRACE_METHOD_B( short )
|
||||||
DECL_TRACE_METHOD_B( int )
|
DECL_TRACE_METHOD_B( int )
|
||||||
|
|||||||
+17
-13
@@ -1,7 +1,7 @@
|
|||||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
//
|
//
|
||||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you can
|
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -23,8 +23,11 @@
|
|||||||
#define _VERILATED_FST_SC_H_ 1
|
#define _VERILATED_FST_SC_H_ 1
|
||||||
|
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
#include "verilated_sc.h"
|
|
||||||
#include "verilated_fst_c.h"
|
#include "verilated_fst_c.h"
|
||||||
|
#include "verilated_sc.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// VerilatedFstSc
|
// VerilatedFstSc
|
||||||
@@ -49,31 +52,35 @@ public:
|
|||||||
}
|
}
|
||||||
spTrace()->set_time_resolution(sc_get_time_resolution().to_string());
|
spTrace()->set_time_resolution(sc_get_time_resolution().to_string());
|
||||||
}
|
}
|
||||||
virtual ~VerilatedFstSc() { close(); }
|
~VerilatedFstSc() override { close(); }
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
/// Called by SystemC simulate()
|
/// Called by SystemC simulate()
|
||||||
virtual void cycle(bool delta_cycle) {
|
void cycle(bool delta_cycle) override {
|
||||||
if (!delta_cycle) { this->dump(sc_time_stamp().to_double()); }
|
if (!delta_cycle) { this->dump(sc_time_stamp().to_double()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Override VerilatedFstC. Must be called after starting simulation.
|
||||||
|
// Note: this is not a virtual function in the base class, so no 'override'
|
||||||
|
virtual void open(const char* filename) VL_MT_SAFE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Fake outs for linker
|
/// Fake outs for linker
|
||||||
|
|
||||||
#ifdef NC_SYSTEMC
|
#ifdef NC_SYSTEMC
|
||||||
// Cadence Incisive has these as abstract functions so we must create them
|
// Cadence Incisive has these as abstract functions so we must create them
|
||||||
virtual void set_time_unit(int exponent10_seconds) {} // deprecated
|
void set_time_unit(int exponent10_seconds) override {} // deprecated
|
||||||
#endif
|
#endif
|
||||||
virtual void set_time_unit(double v, sc_time_unit tu) {} // LCOV_EXCL_LINE
|
void set_time_unit(double v, sc_time_unit tu) override {} // LCOV_EXCL_LINE
|
||||||
|
|
||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// SystemC 2.1.v1
|
// SystemC 2.1.v1
|
||||||
#define DECL_TRACE_METHOD_A(tp) virtual void trace(const tp& object, const std::string& name);
|
#define DECL_TRACE_METHOD_A(tp) void trace(const tp& object, const std::string& name) override;
|
||||||
#define DECL_TRACE_METHOD_B(tp) \
|
#define DECL_TRACE_METHOD_B(tp) \
|
||||||
virtual void trace(const tp& object, const std::string& name, int width);
|
void trace(const tp& object, const std::string& name, int width) override;
|
||||||
|
|
||||||
virtual void write_comment(const std::string&);
|
void write_comment(const std::string&) override;
|
||||||
virtual void trace(const unsigned int&, const std::string&, const char**);
|
void trace(const unsigned int&, const std::string&, const char**) override;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
// Formatting matches that of sc_trace.h
|
// Formatting matches that of sc_trace.h
|
||||||
@@ -90,9 +97,6 @@ private:
|
|||||||
DECL_TRACE_METHOD_B( unsigned short )
|
DECL_TRACE_METHOD_B( unsigned short )
|
||||||
DECL_TRACE_METHOD_B( unsigned int )
|
DECL_TRACE_METHOD_B( unsigned int )
|
||||||
DECL_TRACE_METHOD_B( unsigned long )
|
DECL_TRACE_METHOD_B( unsigned long )
|
||||||
#ifdef SYSTEMC_64BIT_PATCHES
|
|
||||||
DECL_TRACE_METHOD_B( unsigned long long)
|
|
||||||
#endif
|
|
||||||
DECL_TRACE_METHOD_B( char )
|
DECL_TRACE_METHOD_B( char )
|
||||||
DECL_TRACE_METHOD_B( short )
|
DECL_TRACE_METHOD_B( short )
|
||||||
DECL_TRACE_METHOD_B( int )
|
DECL_TRACE_METHOD_B( int )
|
||||||
|
|||||||
+116
-124
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -28,6 +28,8 @@
|
|||||||
#error "verilated_funcs.h should only be included by verilated.h"
|
#error "verilated_funcs.h should only be included by verilated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Extern functions -- User may override -- See verilated.cpp
|
// Extern functions -- User may override -- See verilated.cpp
|
||||||
|
|
||||||
@@ -43,12 +45,17 @@ extern void vl_finish(const char* filename, int linenum, const char* hier);
|
|||||||
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
|
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
|
||||||
extern void vl_stop(const char* filename, int linenum, const char* hier);
|
extern void vl_stop(const char* filename, int linenum, const char* hier);
|
||||||
|
|
||||||
/// Routine to call for a couple of fatal messages
|
/// Routine to call for fatal messages
|
||||||
/// User code may wish to replace this function, to do so, define VL_USER_FATAL.
|
/// User code may wish to replace this function, to do so, define VL_USER_FATAL.
|
||||||
/// This code does not have to be thread safe.
|
/// This code does not have to be thread safe.
|
||||||
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
|
/// Verilator internal code must call VL_FINISH_MT instead, which eventually calls this.
|
||||||
extern void vl_fatal(const char* filename, int linenum, const char* hier, const char* msg);
|
extern void vl_fatal(const char* filename, int linenum, const char* hier, const char* msg);
|
||||||
|
|
||||||
|
/// Routine to call for warning messages
|
||||||
|
/// User code may wish to replace this function, to do so, define VL_USER_WARN.
|
||||||
|
/// This code does not have to be thread safe.
|
||||||
|
extern void vl_warn(const char* filename, int linenum, const char* hier, const char* msg);
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Extern functions -- Slow path
|
// Extern functions -- Slow path
|
||||||
|
|
||||||
@@ -57,9 +64,12 @@ extern void VL_FINISH_MT(const char* filename, int linenum, const char* hier) VL
|
|||||||
/// Multithread safe wrapper for calls to $stop
|
/// Multithread safe wrapper for calls to $stop
|
||||||
extern void VL_STOP_MT(const char* filename, int linenum, const char* hier,
|
extern void VL_STOP_MT(const char* filename, int linenum, const char* hier,
|
||||||
bool maybe = true) VL_MT_SAFE;
|
bool maybe = true) VL_MT_SAFE;
|
||||||
/// Multithread safe wrapper to call for a couple of fatal messages
|
/// Multithread safe wrapper to call for fatal messages
|
||||||
extern void VL_FATAL_MT(const char* filename, int linenum, const char* hier,
|
extern void VL_FATAL_MT(const char* filename, int linenum, const char* hier,
|
||||||
const char* msg) VL_MT_SAFE;
|
const char* msg) VL_MT_SAFE;
|
||||||
|
/// Multithread safe wrapper to call for warning messages
|
||||||
|
extern void VL_WARN_MT(const char* filename, int linenum, const char* hier,
|
||||||
|
const char* msg) VL_MT_SAFE;
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
/// Print a string, multithread safe. Eventually VL_PRINTF will get called.
|
/// Print a string, multithread safe. Eventually VL_PRINTF will get called.
|
||||||
@@ -77,9 +87,10 @@ extern void VL_DBG_MSGF(const char* formatp, ...) VL_ATTR_PRINTF(1) VL_MT_SAFE;
|
|||||||
inline IData VL_RANDOM_I() VL_MT_SAFE { return vl_rand64(); }
|
inline IData VL_RANDOM_I() VL_MT_SAFE { return vl_rand64(); }
|
||||||
inline QData VL_RANDOM_Q() VL_MT_SAFE { return vl_rand64(); }
|
inline QData VL_RANDOM_Q() VL_MT_SAFE { return vl_rand64(); }
|
||||||
extern WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp);
|
extern WDataOutP VL_RANDOM_W(int obits, WDataOutP outwp);
|
||||||
extern IData VL_RANDOM_SEEDED_II(IData seed) VL_MT_SAFE;
|
extern IData VL_RANDOM_SEEDED_II(IData& seedr) VL_MT_SAFE;
|
||||||
|
extern IData VL_URANDOM_SEEDED_II(IData seed) VL_MT_SAFE;
|
||||||
inline IData VL_URANDOM_RANGE_I(IData hi, IData lo) {
|
inline IData VL_URANDOM_RANGE_I(IData hi, IData lo) {
|
||||||
const vluint64_t rnd = vl_rand64();
|
const uint64_t rnd = vl_rand64();
|
||||||
if (VL_LIKELY(hi > lo)) {
|
if (VL_LIKELY(hi > lo)) {
|
||||||
// (hi - lo + 1) can be zero when hi is UINT_MAX and lo is zero
|
// (hi - lo + 1) can be zero when hi is UINT_MAX and lo is zero
|
||||||
if (VL_UNLIKELY(hi - lo + 1 == 0)) return rnd;
|
if (VL_UNLIKELY(hi - lo + 1 == 0)) return rnd;
|
||||||
@@ -101,15 +112,6 @@ extern WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp);
|
|||||||
/// Zero reset a signal (slow - else use VL_ZERO_W)
|
/// Zero reset a signal (slow - else use VL_ZERO_W)
|
||||||
extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp);
|
extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp);
|
||||||
|
|
||||||
#if VL_THREADED
|
|
||||||
/// Return high-precision counter for profiling, or 0x0 if not available
|
|
||||||
inline QData VL_RDTSC_Q() {
|
|
||||||
vluint64_t val;
|
|
||||||
VL_RDTSC(val);
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void VL_PRINTTIMESCALE(const char* namep, const char* timeunitp,
|
extern void VL_PRINTTIMESCALE(const char* namep, const char* timeunitp,
|
||||||
const VerilatedContext* contextp) VL_MT_SAFE;
|
const VerilatedContext* contextp) VL_MT_SAFE;
|
||||||
|
|
||||||
@@ -144,17 +146,13 @@ extern IData VL_SYSTEM_IW(int lhswords, WDataInP const lhsp);
|
|||||||
extern IData VL_SYSTEM_IQ(QData lhs);
|
extern IData VL_SYSTEM_IQ(QData lhs);
|
||||||
inline IData VL_SYSTEM_II(IData lhs) VL_MT_SAFE { return VL_SYSTEM_IQ(lhs); }
|
inline IData VL_SYSTEM_II(IData lhs) VL_MT_SAFE { return VL_SYSTEM_IQ(lhs); }
|
||||||
|
|
||||||
extern IData VL_TESTPLUSARGS_I(const char* formatp);
|
extern IData VL_TESTPLUSARGS_I(const std::string& format);
|
||||||
extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish
|
extern const char* vl_mc_scan_plusargs(const char* prefixp); // PLIish
|
||||||
|
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Base macros
|
// Base macros
|
||||||
|
|
||||||
// Return true if data[bit] set; not 0/1 return, but 0/non-zero return.
|
// Return true if data[bit] set; not 0/1 return, but 0/non-zero return.
|
||||||
#define VL_BITISSET_I(data, bit) ((data) & (VL_UL(1) << VL_BITBIT_I(bit)))
|
|
||||||
#define VL_BITISSET_Q(data, bit) ((data) & (1ULL << VL_BITBIT_Q(bit)))
|
|
||||||
#define VL_BITISSET_E(data, bit) ((data) & (VL_EUL(1) << VL_BITBIT_E(bit)))
|
|
||||||
#define VL_BITISSET_W(data, bit) ((data)[VL_BITWORD_E(bit)] & (VL_EUL(1) << VL_BITBIT_E(bit)))
|
|
||||||
#define VL_BITISSETLIMIT_W(data, width, bit) (((bit) < (width)) && VL_BITISSET_W(data, bit))
|
#define VL_BITISSETLIMIT_W(data, width, bit) (((bit) < (width)) && VL_BITISSET_W(data, bit))
|
||||||
|
|
||||||
// Shift appropriate word by bit. Does not account for wrapping between two words
|
// Shift appropriate word by bit. Does not account for wrapping between two words
|
||||||
@@ -212,29 +210,27 @@ static inline QData VL_CVT_Q_D(double lhs) VL_PURE {
|
|||||||
// Return double from lhs (numeric) unsigned
|
// Return double from lhs (numeric) unsigned
|
||||||
double VL_ITOR_D_W(int lbits, WDataInP const lwp) VL_PURE;
|
double VL_ITOR_D_W(int lbits, WDataInP const lwp) VL_PURE;
|
||||||
static inline double VL_ITOR_D_I(int, IData lhs) VL_PURE {
|
static inline double VL_ITOR_D_I(int, IData lhs) VL_PURE {
|
||||||
return static_cast<double>(static_cast<vluint32_t>(lhs));
|
return static_cast<double>(static_cast<uint32_t>(lhs));
|
||||||
}
|
}
|
||||||
static inline double VL_ITOR_D_Q(int, QData lhs) VL_PURE {
|
static inline double VL_ITOR_D_Q(int, QData lhs) VL_PURE {
|
||||||
return static_cast<double>(static_cast<vluint64_t>(lhs));
|
return static_cast<double>(static_cast<uint64_t>(lhs));
|
||||||
}
|
}
|
||||||
// Return double from lhs (numeric) signed
|
// Return double from lhs (numeric) signed
|
||||||
double VL_ISTOR_D_W(int lbits, WDataInP const lwp) VL_PURE;
|
double VL_ISTOR_D_W(int lbits, WDataInP const lwp) VL_PURE;
|
||||||
static inline double VL_ISTOR_D_I(int lbits, IData lhs) VL_PURE {
|
static inline double VL_ISTOR_D_I(int lbits, IData lhs) VL_PURE {
|
||||||
if (lbits == 32) return static_cast<double>(static_cast<vlsint32_t>(lhs));
|
if (lbits == 32) return static_cast<double>(static_cast<int32_t>(lhs));
|
||||||
VlWide<VL_WQ_WORDS_E> lwp;
|
VlWide<VL_WQ_WORDS_E> lwp;
|
||||||
VL_SET_WI(lwp, lhs);
|
VL_SET_WI(lwp, lhs);
|
||||||
return VL_ISTOR_D_W(lbits, lwp);
|
return VL_ISTOR_D_W(lbits, lwp);
|
||||||
}
|
}
|
||||||
static inline double VL_ISTOR_D_Q(int lbits, QData lhs) VL_PURE {
|
static inline double VL_ISTOR_D_Q(int lbits, QData lhs) VL_PURE {
|
||||||
if (lbits == 64) return static_cast<double>(static_cast<vlsint64_t>(lhs));
|
if (lbits == 64) return static_cast<double>(static_cast<int64_t>(lhs));
|
||||||
VlWide<VL_WQ_WORDS_E> lwp;
|
VlWide<VL_WQ_WORDS_E> lwp;
|
||||||
VL_SET_WQ(lwp, lhs);
|
VL_SET_WQ(lwp, lhs);
|
||||||
return VL_ISTOR_D_W(lbits, lwp);
|
return VL_ISTOR_D_W(lbits, lwp);
|
||||||
}
|
}
|
||||||
// Return QData from double (numeric)
|
// Return QData from double (numeric)
|
||||||
static inline IData VL_RTOI_I_D(double lhs) VL_PURE {
|
static inline IData VL_RTOI_I_D(double lhs) VL_PURE { return static_cast<int32_t>(VL_TRUNC(lhs)); }
|
||||||
return static_cast<vlsint32_t>(VL_TRUNC(lhs));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sign extend such that if MSB set, we get ffff_ffff, else 0s
|
// Sign extend such that if MSB set, we get ffff_ffff, else 0s
|
||||||
// (Requires clean input)
|
// (Requires clean input)
|
||||||
@@ -260,51 +256,33 @@ extern void _vl_debug_print_w(int lbits, WDataInP const iwp);
|
|||||||
//=========================================================================
|
//=========================================================================
|
||||||
// Pli macros
|
// Pli macros
|
||||||
|
|
||||||
extern int VL_TIME_STR_CONVERT(const char* strp) VL_PURE;
|
|
||||||
|
|
||||||
// These are deprecated and used only to establish the default precision/units.
|
|
||||||
// Use Verilator timescale-override for better control.
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#ifndef VL_TIME_PRECISION
|
|
||||||
# ifdef VL_TIME_PRECISION_STR
|
|
||||||
# define VL_TIME_PRECISION VL_TIME_STR_CONVERT(VL_STRINGIFY(VL_TIME_PRECISION_STR))
|
|
||||||
# else
|
|
||||||
# define VL_TIME_PRECISION (-12) ///< Timescale default units if not in Verilog - picoseconds
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
#ifndef VL_TIME_UNIT
|
|
||||||
# ifdef VL_TIME_UNIT_STR
|
|
||||||
# define VL_TIME_UNIT VL_TIME_STR_CONVERT(VL_STRINGIFY(VL_TIME_PRECISION_STR))
|
|
||||||
# else
|
|
||||||
# define VL_TIME_UNIT (-12) ///< Timescale default units if not in Verilog - picoseconds
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(SYSTEMC_VERSION)
|
#if defined(SYSTEMC_VERSION)
|
||||||
/// Return current simulation time
|
/// Return current simulation time
|
||||||
// Already defined: extern sc_time sc_time_stamp();
|
// Already defined: extern sc_time sc_time_stamp();
|
||||||
inline vluint64_t vl_time_stamp64() { return sc_time_stamp().value(); }
|
inline uint64_t vl_time_stamp64() { return sc_time_stamp().value(); }
|
||||||
#else // Non-SystemC
|
#else // Non-SystemC
|
||||||
# if !defined(VL_TIME_CONTEXT) && !defined(VL_NO_LEGACY)
|
# if !defined(VL_TIME_CONTEXT) && !defined(VL_NO_LEGACY)
|
||||||
# ifdef VL_TIME_STAMP64
|
# ifdef VL_TIME_STAMP64
|
||||||
// vl_time_stamp64() may be optionally defined by the user to return time.
|
// vl_time_stamp64() may be optionally defined by the user to return time.
|
||||||
// On MSVC++ weak symbols are not supported so must be declared, or define
|
// On MSVC++ weak symbols are not supported so must be declared, or define
|
||||||
// VL_TIME_CONTEXT.
|
// VL_TIME_CONTEXT.
|
||||||
extern vluint64_t vl_time_stamp64() VL_ATTR_WEAK;
|
extern uint64_t vl_time_stamp64() VL_ATTR_WEAK;
|
||||||
# else
|
# else
|
||||||
// sc_time_stamp() may be optionally defined by the user to return time.
|
// sc_time_stamp() may be optionally defined by the user to return time.
|
||||||
// On MSVC++ weak symbols are not supported so must be declared, or define
|
// On MSVC++ weak symbols are not supported so must be declared, or define
|
||||||
// VL_TIME_CONTEXT.
|
// VL_TIME_CONTEXT.
|
||||||
extern double sc_time_stamp() VL_ATTR_WEAK; // Verilator 4.032 and newer
|
extern double sc_time_stamp() VL_ATTR_WEAK; // Verilator 4.032 and newer
|
||||||
inline vluint64_t vl_time_stamp64() {
|
inline uint64_t vl_time_stamp64() {
|
||||||
// clang9.0.1 requires & although we really do want the weak symbol value
|
// clang9.0.1 requires & although we really do want the weak symbol value
|
||||||
return VL_LIKELY(&sc_time_stamp) ? static_cast<vluint64_t>(sc_time_stamp()) : 0;
|
return VL_LIKELY(&sc_time_stamp) ? static_cast<uint64_t>(sc_time_stamp()) : 0;
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline vluint64_t VerilatedContext::time() const VL_MT_SAFE {
|
uint64_t VerilatedContext::time() const VL_MT_SAFE {
|
||||||
// When using non-default context, fastest path is return time
|
// When using non-default context, fastest path is return time
|
||||||
if (VL_LIKELY(m_s.m_time)) return m_s.m_time;
|
if (VL_LIKELY(m_s.m_time)) return m_s.m_time;
|
||||||
#if defined(SYSTEMC_VERSION) || (!defined(VL_TIME_CONTEXT) && !defined(VL_NO_LEGACY))
|
#if defined(SYSTEMC_VERSION) || (!defined(VL_TIME_CONTEXT) && !defined(VL_NO_LEGACY))
|
||||||
@@ -329,16 +307,22 @@ inline vluint64_t VerilatedContext::time() const VL_MT_SAFE {
|
|||||||
// Return time precision as multiplier of time units
|
// Return time precision as multiplier of time units
|
||||||
double vl_time_multiplier(int scale) VL_PURE;
|
double vl_time_multiplier(int scale) VL_PURE;
|
||||||
// Return power of 10. e.g. returns 100 if n==2
|
// Return power of 10. e.g. returns 100 if n==2
|
||||||
vluint64_t vl_time_pow10(int n) VL_PURE;
|
uint64_t vl_time_pow10(int n) VL_PURE;
|
||||||
|
|
||||||
#ifdef VL_DEBUG
|
#ifdef VL_DEBUG
|
||||||
/// Evaluate statement if Verilated::debug() enabled
|
/// Evaluate statement if VL_DEBUG defined
|
||||||
|
# define VL_DEBUG_IFDEF(stmt) \
|
||||||
|
do { \
|
||||||
|
stmt \
|
||||||
|
} while (false)
|
||||||
|
/// Evaluate statement if VL_DEBUG defined and Verilated::debug() enabled
|
||||||
# define VL_DEBUG_IF(stmt) \
|
# define VL_DEBUG_IF(stmt) \
|
||||||
do { \
|
do { \
|
||||||
if (VL_UNLIKELY(Verilated::debug())) {stmt} \
|
if (VL_UNLIKELY(Verilated::debug())) {stmt} \
|
||||||
} while (false)
|
} while (false)
|
||||||
#else
|
#else
|
||||||
// We intentionally do not compile the stmt to improve compile speed
|
// We intentionally do not compile the stmt to improve compile speed
|
||||||
|
# define VL_DEBUG_IFDEF(stmt) do {} while (false)
|
||||||
# define VL_DEBUG_IF(stmt) do {} while (false)
|
# define VL_DEBUG_IF(stmt) do {} while (false)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -464,10 +448,17 @@ static inline void VL_ASSIGNBIT_WO(int bit, WDataOutP owp) VL_MT_SAFE {
|
|||||||
{ \
|
{ \
|
||||||
const int words = VL_WORDS_I(obits); \
|
const int words = VL_WORDS_I(obits); \
|
||||||
sc_biguint<(obits)> _butemp = (svar).read(); \
|
sc_biguint<(obits)> _butemp = (svar).read(); \
|
||||||
for (int i = 0; i < words; ++i) { \
|
uint32_t* chunk = _butemp.get_raw(); \
|
||||||
int msb = ((i + 1) * VL_IDATASIZE) - 1; \
|
int32_t lsb = 0; \
|
||||||
msb = (msb >= (obits)) ? ((obits)-1) : msb; \
|
while (lsb < obits - BITS_PER_DIGIT) { \
|
||||||
(owp)[i] = _butemp.range(msb, i * VL_IDATASIZE).to_uint(); \
|
const uint32_t data = *chunk; \
|
||||||
|
++chunk; \
|
||||||
|
_vl_insert_WI(owp.data(), data, lsb + BITS_PER_DIGIT - 1, lsb); \
|
||||||
|
lsb += BITS_PER_DIGIT; \
|
||||||
|
} \
|
||||||
|
if (lsb < obits) { \
|
||||||
|
const uint32_t msb_data = *chunk; \
|
||||||
|
_vl_insert_WI(owp.data(), msb_data, obits - 1, lsb); \
|
||||||
} \
|
} \
|
||||||
(owp)[words - 1] &= VL_MASK_E(obits); \
|
(owp)[words - 1] &= VL_MASK_E(obits); \
|
||||||
}
|
}
|
||||||
@@ -508,13 +499,23 @@ static inline void VL_ASSIGNBIT_WO(int bit, WDataOutP owp) VL_MT_SAFE {
|
|||||||
{ (svar).write(rd); }
|
{ (svar).write(rd); }
|
||||||
#define VL_ASSIGN_SBQ(obits, svar, rd) \
|
#define VL_ASSIGN_SBQ(obits, svar, rd) \
|
||||||
{ (svar).write(rd); }
|
{ (svar).write(rd); }
|
||||||
|
#define VL_SC_BITS_PER_DIGIT 30 // This comes from sc_nbdefs.h BITS_PER_DIGIT
|
||||||
#define VL_ASSIGN_SBW(obits, svar, rwp) \
|
#define VL_ASSIGN_SBW(obits, svar, rwp) \
|
||||||
{ \
|
{ \
|
||||||
sc_biguint<(obits)> _butemp; \
|
sc_biguint<(obits)> _butemp; \
|
||||||
for (int i = 0; i < VL_WORDS_I(obits); ++i) { \
|
int32_t lsb = 0; \
|
||||||
int msb = ((i + 1) * VL_IDATASIZE) - 1; \
|
uint32_t* chunk = _butemp.get_raw(); \
|
||||||
msb = (msb >= (obits)) ? ((obits)-1) : msb; \
|
while (lsb + VL_SC_BITS_PER_DIGIT < (obits)) { \
|
||||||
_butemp.range(msb, i* VL_IDATASIZE) = (rwp)[i]; \
|
static_assert(std::is_same<IData, EData>::value, "IData and EData missmatch"); \
|
||||||
|
const uint32_t data = VL_SEL_IWII(lsb + VL_SC_BITS_PER_DIGIT + 1, (rwp).data(), lsb, \
|
||||||
|
VL_SC_BITS_PER_DIGIT); \
|
||||||
|
*chunk = data & VL_MASK_E(VL_SC_BITS_PER_DIGIT); \
|
||||||
|
++chunk; \
|
||||||
|
lsb += VL_SC_BITS_PER_DIGIT; \
|
||||||
|
} \
|
||||||
|
if (lsb < (obits)) { \
|
||||||
|
const uint32_t msb_data = VL_SEL_IWII((obits) + 1, (rwp).data(), lsb, (obits)-lsb); \
|
||||||
|
*chunk = msb_data & VL_MASK_E((obits)-lsb); \
|
||||||
} \
|
} \
|
||||||
(svar).write(_butemp); \
|
(svar).write(_butemp); \
|
||||||
}
|
}
|
||||||
@@ -869,46 +870,46 @@ static inline int _vl_cmp_w(int words, WDataInP const lwp, WDataInP const rwp) V
|
|||||||
static inline IData VL_GTS_III(int lbits, IData lhs, IData rhs) VL_PURE {
|
static inline IData VL_GTS_III(int lbits, IData lhs, IData rhs) VL_PURE {
|
||||||
// For lbits==32, this becomes just a single instruction, otherwise ~5.
|
// For lbits==32, this becomes just a single instruction, otherwise ~5.
|
||||||
// GCC 3.3.4 sign extension bugs on AMD64 architecture force us to use quad logic
|
// GCC 3.3.4 sign extension bugs on AMD64 architecture force us to use quad logic
|
||||||
const vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); // Q for gcc
|
const int64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); // Q for gcc
|
||||||
const vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); // Q for gcc
|
const int64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); // Q for gcc
|
||||||
return lhs_signed > rhs_signed;
|
return lhs_signed > rhs_signed;
|
||||||
}
|
}
|
||||||
static inline IData VL_GTS_IQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
static inline IData VL_GTS_IQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
||||||
const vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs);
|
const int64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs);
|
||||||
const vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs);
|
const int64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs);
|
||||||
return lhs_signed > rhs_signed;
|
return lhs_signed > rhs_signed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline IData VL_GTES_III(int lbits, IData lhs, IData rhs) VL_PURE {
|
static inline IData VL_GTES_III(int lbits, IData lhs, IData rhs) VL_PURE {
|
||||||
const vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); // Q for gcc
|
const int64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); // Q for gcc
|
||||||
const vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); // Q for gcc
|
const int64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); // Q for gcc
|
||||||
return lhs_signed >= rhs_signed;
|
return lhs_signed >= rhs_signed;
|
||||||
}
|
}
|
||||||
static inline IData VL_GTES_IQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
static inline IData VL_GTES_IQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
||||||
const vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs);
|
const int64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs);
|
||||||
const vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs);
|
const int64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs);
|
||||||
return lhs_signed >= rhs_signed;
|
return lhs_signed >= rhs_signed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline IData VL_LTS_III(int lbits, IData lhs, IData rhs) VL_PURE {
|
static inline IData VL_LTS_III(int lbits, IData lhs, IData rhs) VL_PURE {
|
||||||
const vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); // Q for gcc
|
const int64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); // Q for gcc
|
||||||
const vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); // Q for gcc
|
const int64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); // Q for gcc
|
||||||
return lhs_signed < rhs_signed;
|
return lhs_signed < rhs_signed;
|
||||||
}
|
}
|
||||||
static inline IData VL_LTS_IQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
static inline IData VL_LTS_IQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
||||||
const vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs);
|
const int64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs);
|
||||||
const vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs);
|
const int64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs);
|
||||||
return lhs_signed < rhs_signed;
|
return lhs_signed < rhs_signed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline IData VL_LTES_III(int lbits, IData lhs, IData rhs) VL_PURE {
|
static inline IData VL_LTES_III(int lbits, IData lhs, IData rhs) VL_PURE {
|
||||||
const vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); // Q for gcc
|
const int64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs); // Q for gcc
|
||||||
const vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); // Q for gcc
|
const int64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs); // Q for gcc
|
||||||
return lhs_signed <= rhs_signed;
|
return lhs_signed <= rhs_signed;
|
||||||
}
|
}
|
||||||
static inline IData VL_LTES_IQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
static inline IData VL_LTES_IQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
||||||
const vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs);
|
const int64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs);
|
||||||
const vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs);
|
const int64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs);
|
||||||
return lhs_signed <= rhs_signed;
|
return lhs_signed <= rhs_signed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1002,13 +1003,13 @@ static inline WDataOutP VL_MUL_W(int words, WDataOutP owp, WDataInP const lwp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline IData VL_MULS_III(int lbits, IData lhs, IData rhs) VL_PURE {
|
static inline IData VL_MULS_III(int lbits, IData lhs, IData rhs) VL_PURE {
|
||||||
const vlsint32_t lhs_signed = VL_EXTENDS_II(32, lbits, lhs);
|
const int32_t lhs_signed = VL_EXTENDS_II(32, lbits, lhs);
|
||||||
const vlsint32_t rhs_signed = VL_EXTENDS_II(32, lbits, rhs);
|
const int32_t rhs_signed = VL_EXTENDS_II(32, lbits, rhs);
|
||||||
return lhs_signed * rhs_signed;
|
return lhs_signed * rhs_signed;
|
||||||
}
|
}
|
||||||
static inline QData VL_MULS_QQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
static inline QData VL_MULS_QQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
||||||
const vlsint64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs);
|
const int64_t lhs_signed = VL_EXTENDS_QQ(64, lbits, lhs);
|
||||||
const vlsint64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs);
|
const int64_t rhs_signed = VL_EXTENDS_QQ(64, lbits, rhs);
|
||||||
return lhs_signed * rhs_signed;
|
return lhs_signed * rhs_signed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1054,30 +1055,30 @@ static inline IData VL_DIVS_III(int lbits, IData lhs, IData rhs) VL_PURE {
|
|||||||
if (VL_UNLIKELY(rhs == 0)) return 0;
|
if (VL_UNLIKELY(rhs == 0)) return 0;
|
||||||
// -MAX / -1 cannot be represented in twos complement, and will cause SIGFPE
|
// -MAX / -1 cannot be represented in twos complement, and will cause SIGFPE
|
||||||
if (VL_UNLIKELY(lhs == 0x80000000 && rhs == 0xffffffff)) return 0;
|
if (VL_UNLIKELY(lhs == 0x80000000 && rhs == 0xffffffff)) return 0;
|
||||||
const vlsint32_t lhs_signed = VL_EXTENDS_II(VL_IDATASIZE, lbits, lhs);
|
const int32_t lhs_signed = VL_EXTENDS_II(VL_IDATASIZE, lbits, lhs);
|
||||||
const vlsint32_t rhs_signed = VL_EXTENDS_II(VL_IDATASIZE, lbits, rhs);
|
const int32_t rhs_signed = VL_EXTENDS_II(VL_IDATASIZE, lbits, rhs);
|
||||||
return lhs_signed / rhs_signed;
|
return lhs_signed / rhs_signed;
|
||||||
}
|
}
|
||||||
static inline QData VL_DIVS_QQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
static inline QData VL_DIVS_QQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
||||||
if (VL_UNLIKELY(rhs == 0)) return 0;
|
if (VL_UNLIKELY(rhs == 0)) return 0;
|
||||||
// -MAX / -1 cannot be represented in twos complement, and will cause SIGFPE
|
// -MAX / -1 cannot be represented in twos complement, and will cause SIGFPE
|
||||||
if (VL_UNLIKELY(lhs == 0x8000000000000000ULL && rhs == 0xffffffffffffffffULL)) return 0;
|
if (VL_UNLIKELY(lhs == 0x8000000000000000ULL && rhs == 0xffffffffffffffffULL)) return 0;
|
||||||
const vlsint64_t lhs_signed = VL_EXTENDS_QQ(VL_QUADSIZE, lbits, lhs);
|
const int64_t lhs_signed = VL_EXTENDS_QQ(VL_QUADSIZE, lbits, lhs);
|
||||||
const vlsint64_t rhs_signed = VL_EXTENDS_QQ(VL_QUADSIZE, lbits, rhs);
|
const int64_t rhs_signed = VL_EXTENDS_QQ(VL_QUADSIZE, lbits, rhs);
|
||||||
return lhs_signed / rhs_signed;
|
return lhs_signed / rhs_signed;
|
||||||
}
|
}
|
||||||
static inline IData VL_MODDIVS_III(int lbits, IData lhs, IData rhs) VL_PURE {
|
static inline IData VL_MODDIVS_III(int lbits, IData lhs, IData rhs) VL_PURE {
|
||||||
if (VL_UNLIKELY(rhs == 0)) return 0;
|
if (VL_UNLIKELY(rhs == 0)) return 0;
|
||||||
if (VL_UNLIKELY(lhs == 0x80000000 && rhs == 0xffffffff)) return 0;
|
if (VL_UNLIKELY(lhs == 0x80000000 && rhs == 0xffffffff)) return 0;
|
||||||
const vlsint32_t lhs_signed = VL_EXTENDS_II(VL_IDATASIZE, lbits, lhs);
|
const int32_t lhs_signed = VL_EXTENDS_II(VL_IDATASIZE, lbits, lhs);
|
||||||
const vlsint32_t rhs_signed = VL_EXTENDS_II(VL_IDATASIZE, lbits, rhs);
|
const int32_t rhs_signed = VL_EXTENDS_II(VL_IDATASIZE, lbits, rhs);
|
||||||
return lhs_signed % rhs_signed;
|
return lhs_signed % rhs_signed;
|
||||||
}
|
}
|
||||||
static inline QData VL_MODDIVS_QQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
static inline QData VL_MODDIVS_QQQ(int lbits, QData lhs, QData rhs) VL_PURE {
|
||||||
if (VL_UNLIKELY(rhs == 0)) return 0;
|
if (VL_UNLIKELY(rhs == 0)) return 0;
|
||||||
if (VL_UNLIKELY(lhs == 0x8000000000000000ULL && rhs == 0xffffffffffffffffULL)) return 0;
|
if (VL_UNLIKELY(lhs == 0x8000000000000000ULL && rhs == 0xffffffffffffffffULL)) return 0;
|
||||||
const vlsint64_t lhs_signed = VL_EXTENDS_QQ(VL_QUADSIZE, lbits, lhs);
|
const int64_t lhs_signed = VL_EXTENDS_QQ(VL_QUADSIZE, lbits, lhs);
|
||||||
const vlsint64_t rhs_signed = VL_EXTENDS_QQ(VL_QUADSIZE, lbits, rhs);
|
const int64_t rhs_signed = VL_EXTENDS_QQ(VL_QUADSIZE, lbits, rhs);
|
||||||
return lhs_signed % rhs_signed;
|
return lhs_signed % rhs_signed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1408,8 +1409,8 @@ static inline IData VL_STREAML_FAST_III(int lbits, IData ld, IData rd_log2) VL_P
|
|||||||
// ret = 10324---
|
// ret = 10324---
|
||||||
IData ret = ld;
|
IData ret = ld;
|
||||||
if (rd_log2) {
|
if (rd_log2) {
|
||||||
const vluint32_t lbitsFloor = lbits & ~VL_MASK_I(rd_log2); // max multiple of rd <= lbits
|
const uint32_t lbitsFloor = lbits & ~VL_MASK_I(rd_log2); // max multiple of rd <= lbits
|
||||||
const vluint32_t lbitsRem = lbits - lbitsFloor; // number of bits in most-sig slice (MSS)
|
const uint32_t lbitsRem = lbits - lbitsFloor; // number of bits in most-sig slice (MSS)
|
||||||
const IData msbMask = VL_MASK_I(lbitsRem) << lbitsFloor; // mask to sel only bits in MSS
|
const IData msbMask = VL_MASK_I(lbitsRem) << lbitsFloor; // mask to sel only bits in MSS
|
||||||
ret = (ret & ~msbMask) | ((ret & msbMask) << ((VL_UL(1) << rd_log2) - lbitsRem));
|
ret = (ret & ~msbMask) | ((ret & msbMask) << ((VL_UL(1) << rd_log2) - lbitsRem));
|
||||||
}
|
}
|
||||||
@@ -1428,9 +1429,9 @@ static inline QData VL_STREAML_FAST_QQI(int lbits, QData ld, IData rd_log2) VL_P
|
|||||||
// Pre-shift bits in most-significant slice (see comment in VL_STREAML_FAST_III)
|
// Pre-shift bits in most-significant slice (see comment in VL_STREAML_FAST_III)
|
||||||
QData ret = ld;
|
QData ret = ld;
|
||||||
if (rd_log2) {
|
if (rd_log2) {
|
||||||
const vluint32_t lbitsFloor = lbits & ~VL_MASK_I(rd_log2);
|
const uint32_t lbitsFloor = lbits & ~VL_MASK_I(rd_log2);
|
||||||
const vluint32_t lbitsRem = lbits - lbitsFloor;
|
const uint32_t lbitsRem = lbits - lbitsFloor;
|
||||||
const QData msbMask = VL_MASK_Q(lbitsRem) << lbitsFloor;
|
const QData msbMask = lbitsFloor == 64 ? 0ULL : VL_MASK_Q(lbitsRem) << lbitsFloor;
|
||||||
ret = (ret & ~msbMask) | ((ret & msbMask) << ((1ULL << rd_log2) - lbitsRem));
|
ret = (ret & ~msbMask) | ((ret & msbMask) << ((1ULL << rd_log2) - lbitsRem));
|
||||||
}
|
}
|
||||||
switch (rd_log2) {
|
switch (rd_log2) {
|
||||||
@@ -1781,7 +1782,7 @@ static inline WDataOutP VL_SHIFTRS_WWW(int obits, int lbits, int rbits, WDataOut
|
|||||||
WDataInP const lwp, WDataInP const rwp) VL_MT_SAFE {
|
WDataInP const lwp, WDataInP const rwp) VL_MT_SAFE {
|
||||||
EData overshift = 0; // Huge shift 1>>32 or more
|
EData overshift = 0; // Huge shift 1>>32 or more
|
||||||
for (int i = 1; i < VL_WORDS_I(rbits); ++i) overshift |= rwp[i];
|
for (int i = 1; i < VL_WORDS_I(rbits); ++i) overshift |= rwp[i];
|
||||||
if (VL_UNLIKELY(overshift || rwp[0] >= obits)) {
|
if (VL_UNLIKELY(overshift || rwp[0] >= static_cast<IData>(obits))) {
|
||||||
const int lmsw = VL_WORDS_I(obits) - 1;
|
const int lmsw = VL_WORDS_I(obits) - 1;
|
||||||
const EData sign = VL_SIGNONES_E(lbits, lwp[lmsw]);
|
const EData sign = VL_SIGNONES_E(lbits, lwp[lmsw]);
|
||||||
for (int j = 0; j <= lmsw; ++j) owp[j] = sign;
|
for (int j = 0; j <= lmsw; ++j) owp[j] = sign;
|
||||||
@@ -1800,7 +1801,7 @@ static inline IData VL_SHIFTRS_IIW(int obits, int lbits, int rbits, IData lhs,
|
|||||||
WDataInP const rwp) VL_MT_SAFE {
|
WDataInP const rwp) VL_MT_SAFE {
|
||||||
EData overshift = 0; // Huge shift 1>>32 or more
|
EData overshift = 0; // Huge shift 1>>32 or more
|
||||||
for (int i = 1; i < VL_WORDS_I(rbits); ++i) overshift |= rwp[i];
|
for (int i = 1; i < VL_WORDS_I(rbits); ++i) overshift |= rwp[i];
|
||||||
if (VL_UNLIKELY(overshift || rwp[0] >= obits)) {
|
if (VL_UNLIKELY(overshift || rwp[0] >= static_cast<IData>(obits))) {
|
||||||
const IData sign = -(lhs >> (lbits - 1)); // ffff_ffff if negative
|
const IData sign = -(lhs >> (lbits - 1)); // ffff_ffff if negative
|
||||||
return VL_CLEAN_II(obits, obits, sign);
|
return VL_CLEAN_II(obits, obits, sign);
|
||||||
}
|
}
|
||||||
@@ -1810,7 +1811,7 @@ static inline QData VL_SHIFTRS_QQW(int obits, int lbits, int rbits, QData lhs,
|
|||||||
WDataInP const rwp) VL_MT_SAFE {
|
WDataInP const rwp) VL_MT_SAFE {
|
||||||
EData overshift = 0; // Huge shift 1>>32 or more
|
EData overshift = 0; // Huge shift 1>>32 or more
|
||||||
for (int i = 1; i < VL_WORDS_I(rbits); ++i) overshift |= rwp[i];
|
for (int i = 1; i < VL_WORDS_I(rbits); ++i) overshift |= rwp[i];
|
||||||
if (VL_UNLIKELY(overshift || rwp[0] >= obits)) {
|
if (VL_UNLIKELY(overshift || rwp[0] >= static_cast<IData>(obits))) {
|
||||||
const QData sign = -(lhs >> (lbits - 1)); // ffff_ffff if negative
|
const QData sign = -(lhs >> (lbits - 1)); // ffff_ffff if negative
|
||||||
return VL_CLEAN_QQ(obits, obits, sign);
|
return VL_CLEAN_QQ(obits, obits, sign);
|
||||||
}
|
}
|
||||||
@@ -1927,8 +1928,8 @@ static inline QData VL_RTOIROUND_Q_D(double lhs) VL_PURE {
|
|||||||
if (lhs == 0.0) return 0;
|
if (lhs == 0.0) return 0;
|
||||||
const QData q = VL_CVT_Q_D(lhs);
|
const QData q = VL_CVT_Q_D(lhs);
|
||||||
const int lsb = static_cast<int>((q >> 52ULL) & VL_MASK_Q(11)) - 1023 - 52;
|
const int lsb = static_cast<int>((q >> 52ULL) & VL_MASK_Q(11)) - 1023 - 52;
|
||||||
const vluint64_t mantissa = (q & VL_MASK_Q(52)) | (1ULL << 52);
|
const uint64_t mantissa = (q & VL_MASK_Q(52)) | (1ULL << 52);
|
||||||
vluint64_t out = 0;
|
uint64_t out = 0;
|
||||||
if (lsb < 0) {
|
if (lsb < 0) {
|
||||||
out = mantissa >> -lsb;
|
out = mantissa >> -lsb;
|
||||||
} else if (lsb < 64) {
|
} else if (lsb < 64) {
|
||||||
@@ -1948,7 +1949,7 @@ static inline WDataOutP VL_RTOIROUND_W_D(int obits, WDataOutP owp, double lhs) V
|
|||||||
if (lhs == 0.0) return owp;
|
if (lhs == 0.0) return owp;
|
||||||
const QData q = VL_CVT_Q_D(lhs);
|
const QData q = VL_CVT_Q_D(lhs);
|
||||||
const int lsb = static_cast<int>((q >> 52ULL) & VL_MASK_Q(11)) - 1023 - 52;
|
const int lsb = static_cast<int>((q >> 52ULL) & VL_MASK_Q(11)) - 1023 - 52;
|
||||||
const vluint64_t mantissa = (q & VL_MASK_Q(52)) | (1ULL << 52);
|
const uint64_t mantissa = (q & VL_MASK_Q(52)) | (1ULL << 52);
|
||||||
if (lsb < 0) {
|
if (lsb < 0) {
|
||||||
VL_SET_WQ(owp, mantissa >> -lsb);
|
VL_SET_WQ(owp, mantissa >> -lsb);
|
||||||
} else if (lsb < obits) {
|
} else if (lsb < obits) {
|
||||||
@@ -1962,42 +1963,33 @@ static inline WDataOutP VL_RTOIROUND_W_D(int obits, WDataOutP owp, double lhs) V
|
|||||||
// Range assignments
|
// Range assignments
|
||||||
|
|
||||||
// EMIT_RULE: VL_ASSIGNRANGE: rclean=dirty;
|
// EMIT_RULE: VL_ASSIGNRANGE: rclean=dirty;
|
||||||
static inline void VL_ASSIGNSEL_IIII(int rbits, int obits, int lsb, CData& lhsr,
|
static inline void VL_ASSIGNSEL_II(int rbits, int obits, int lsb, CData& lhsr, IData rhs) VL_PURE {
|
||||||
IData rhs) VL_PURE {
|
|
||||||
_vl_insert_II(lhsr, rhs, lsb + obits - 1, lsb, rbits);
|
_vl_insert_II(lhsr, rhs, lsb + obits - 1, lsb, rbits);
|
||||||
}
|
}
|
||||||
static inline void VL_ASSIGNSEL_IIII(int rbits, int obits, int lsb, SData& lhsr,
|
static inline void VL_ASSIGNSEL_II(int rbits, int obits, int lsb, SData& lhsr, IData rhs) VL_PURE {
|
||||||
IData rhs) VL_PURE {
|
|
||||||
_vl_insert_II(lhsr, rhs, lsb + obits - 1, lsb, rbits);
|
_vl_insert_II(lhsr, rhs, lsb + obits - 1, lsb, rbits);
|
||||||
}
|
}
|
||||||
static inline void VL_ASSIGNSEL_IIII(int rbits, int obits, int lsb, IData& lhsr,
|
static inline void VL_ASSIGNSEL_II(int rbits, int obits, int lsb, IData& lhsr, IData rhs) VL_PURE {
|
||||||
IData rhs) VL_PURE {
|
|
||||||
_vl_insert_II(lhsr, rhs, lsb + obits - 1, lsb, rbits);
|
_vl_insert_II(lhsr, rhs, lsb + obits - 1, lsb, rbits);
|
||||||
}
|
}
|
||||||
static inline void VL_ASSIGNSEL_QIII(int rbits, int obits, int lsb, QData& lhsr,
|
static inline void VL_ASSIGNSEL_QI(int rbits, int obits, int lsb, QData& lhsr, IData rhs) VL_PURE {
|
||||||
IData rhs) VL_PURE {
|
|
||||||
_vl_insert_QQ(lhsr, rhs, lsb + obits - 1, lsb, rbits);
|
_vl_insert_QQ(lhsr, rhs, lsb + obits - 1, lsb, rbits);
|
||||||
}
|
}
|
||||||
static inline void VL_ASSIGNSEL_QQII(int rbits, int obits, int lsb, QData& lhsr,
|
static inline void VL_ASSIGNSEL_QQ(int rbits, int obits, int lsb, QData& lhsr, QData rhs) VL_PURE {
|
||||||
QData rhs) VL_PURE {
|
|
||||||
_vl_insert_QQ(lhsr, rhs, lsb + obits - 1, lsb, rbits);
|
|
||||||
}
|
|
||||||
static inline void VL_ASSIGNSEL_QIIQ(int rbits, int obits, int lsb, QData& lhsr,
|
|
||||||
QData rhs) VL_PURE {
|
|
||||||
_vl_insert_QQ(lhsr, rhs, lsb + obits - 1, lsb, rbits);
|
_vl_insert_QQ(lhsr, rhs, lsb + obits - 1, lsb, rbits);
|
||||||
}
|
}
|
||||||
// static inline void VL_ASSIGNSEL_IIIW(int obits, int lsb, IData& lhsr, WDataInP const rwp)
|
// static inline void VL_ASSIGNSEL_IIIW(int obits, int lsb, IData& lhsr, WDataInP const rwp)
|
||||||
// VL_MT_SAFE { Illegal, as lhs width >= rhs width
|
// VL_MT_SAFE { Illegal, as lhs width >= rhs width
|
||||||
static inline void VL_ASSIGNSEL_WIII(int rbits, int obits, int lsb, WDataOutP owp,
|
static inline void VL_ASSIGNSEL_WI(int rbits, int obits, int lsb, WDataOutP owp,
|
||||||
IData rhs) VL_MT_SAFE {
|
IData rhs) VL_MT_SAFE {
|
||||||
_vl_insert_WI(owp, rhs, lsb + obits - 1, lsb, rbits);
|
_vl_insert_WI(owp, rhs, lsb + obits - 1, lsb, rbits);
|
||||||
}
|
}
|
||||||
static inline void VL_ASSIGNSEL_WIIQ(int rbits, int obits, int lsb, WDataOutP owp,
|
static inline void VL_ASSIGNSEL_WQ(int rbits, int obits, int lsb, WDataOutP owp,
|
||||||
QData rhs) VL_MT_SAFE {
|
QData rhs) VL_MT_SAFE {
|
||||||
_vl_insert_WQ(owp, rhs, lsb + obits - 1, lsb, rbits);
|
_vl_insert_WQ(owp, rhs, lsb + obits - 1, lsb, rbits);
|
||||||
}
|
}
|
||||||
static inline void VL_ASSIGNSEL_WIIW(int rbits, int obits, int lsb, WDataOutP owp,
|
static inline void VL_ASSIGNSEL_WW(int rbits, int obits, int lsb, WDataOutP owp,
|
||||||
WDataInP const rwp) VL_MT_SAFE {
|
WDataInP const rwp) VL_MT_SAFE {
|
||||||
_vl_insert_WW(owp, rwp, lsb + obits - 1, lsb, rbits);
|
_vl_insert_WW(owp, rwp, lsb + obits - 1, lsb, rbits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2036,40 +2028,40 @@ static inline WDataOutP VL_CONST_W_2X(int obits, WDataOutP o, EData d1, EData d0
|
|||||||
static inline WDataOutP VL_CONST_W_3X(int obits, WDataOutP o, EData d2, EData d1,
|
static inline WDataOutP VL_CONST_W_3X(int obits, WDataOutP o, EData d2, EData d1,
|
||||||
EData d0) VL_MT_SAFE {
|
EData d0) VL_MT_SAFE {
|
||||||
o[0] = d0; o[1] = d1; o[2] = d2;
|
o[0] = d0; o[1] = d1; o[2] = d2;
|
||||||
VL_C_END_(obits,3);
|
VL_C_END_(obits, 3);
|
||||||
}
|
}
|
||||||
static inline WDataOutP VL_CONST_W_4X(int obits, WDataOutP o,
|
static inline WDataOutP VL_CONST_W_4X(int obits, WDataOutP o,
|
||||||
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
||||||
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
||||||
VL_C_END_(obits,4);
|
VL_C_END_(obits, 4);
|
||||||
}
|
}
|
||||||
static inline WDataOutP VL_CONST_W_5X(int obits, WDataOutP o,
|
static inline WDataOutP VL_CONST_W_5X(int obits, WDataOutP o,
|
||||||
EData d4,
|
EData d4,
|
||||||
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
||||||
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
||||||
o[4] = d4;
|
o[4] = d4;
|
||||||
VL_C_END_(obits,5);
|
VL_C_END_(obits, 5);
|
||||||
}
|
}
|
||||||
static inline WDataOutP VL_CONST_W_6X(int obits, WDataOutP o,
|
static inline WDataOutP VL_CONST_W_6X(int obits, WDataOutP o,
|
||||||
EData d5, EData d4,
|
EData d5, EData d4,
|
||||||
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
||||||
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
||||||
o[4] = d4; o[5] = d5;
|
o[4] = d4; o[5] = d5;
|
||||||
VL_C_END_(obits,6);
|
VL_C_END_(obits, 6);
|
||||||
}
|
}
|
||||||
static inline WDataOutP VL_CONST_W_7X(int obits, WDataOutP o,
|
static inline WDataOutP VL_CONST_W_7X(int obits, WDataOutP o,
|
||||||
EData d6, EData d5, EData d4,
|
EData d6, EData d5, EData d4,
|
||||||
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
||||||
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
||||||
o[4] = d4; o[5] = d5; o[6] = d6;
|
o[4] = d4; o[5] = d5; o[6] = d6;
|
||||||
VL_C_END_(obits,7);
|
VL_C_END_(obits, 7);
|
||||||
}
|
}
|
||||||
static inline WDataOutP VL_CONST_W_8X(int obits, WDataOutP o,
|
static inline WDataOutP VL_CONST_W_8X(int obits, WDataOutP o,
|
||||||
EData d7, EData d6, EData d5, EData d4,
|
EData d7, EData d6, EData d5, EData d4,
|
||||||
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
EData d3, EData d2, EData d1, EData d0) VL_MT_SAFE {
|
||||||
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
o[0] = d0; o[1] = d1; o[2] = d2; o[3] = d3;
|
||||||
o[4] = d4; o[5] = d5; o[6] = d6; o[7] = d7;
|
o[4] = d4; o[5] = d5; o[6] = d6; o[7] = d7;
|
||||||
VL_C_END_(obits,8);
|
VL_C_END_(obits, 8);
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
static inline WDataOutP VL_CONSTHI_W_1X(int obits, int lsb, WDataOutP obase,
|
static inline WDataOutP VL_CONSTHI_W_1X(int obits, int lsb, WDataOutP obase,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2010-2021 by Wilson Snyder. This program is free software; you can
|
// Copyright 2010-2022 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
+41
-37
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2009-2021 by Wilson Snyder. This program is free software; you can
|
// Copyright 2009-2022 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -32,10 +32,15 @@
|
|||||||
#include "verilated.h"
|
#include "verilated.h"
|
||||||
#include "verilated_syms.h"
|
#include "verilated_syms.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <set>
|
#include <limits>
|
||||||
#include <vector>
|
#include <map>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
|
#include <set>
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
#ifdef VL_THREADED
|
#ifdef VL_THREADED
|
||||||
# include <functional>
|
# include <functional>
|
||||||
# include <queue>
|
# include <queue>
|
||||||
@@ -60,7 +65,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
vluint32_t m_mtaskId; // MTask that did enqueue
|
uint32_t m_mtaskId; // MTask that did enqueue
|
||||||
std::function<void()> m_cb; // Lambda to execute when message received
|
std::function<void()> m_cb; // Lambda to execute when message received
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
@@ -73,7 +78,7 @@ public:
|
|||||||
VerilatedMsg& operator=(const VerilatedMsg&) = default;
|
VerilatedMsg& operator=(const VerilatedMsg&) = default;
|
||||||
VerilatedMsg& operator=(VerilatedMsg&&) = default;
|
VerilatedMsg& operator=(VerilatedMsg&&) = default;
|
||||||
// METHODS
|
// METHODS
|
||||||
vluint32_t mtaskId() const { return m_mtaskId; }
|
uint32_t mtaskId() const { return m_mtaskId; }
|
||||||
// Execute the lambda function
|
// Execute the lambda function
|
||||||
void run() const { m_cb(); }
|
void run() const { m_cb(); }
|
||||||
};
|
};
|
||||||
@@ -84,9 +89,9 @@ public:
|
|||||||
class VerilatedEvalMsgQueue final {
|
class VerilatedEvalMsgQueue final {
|
||||||
using VerilatedThreadQueue = std::multiset<VerilatedMsg, VerilatedMsg::Cmp>;
|
using VerilatedThreadQueue = std::multiset<VerilatedMsg, VerilatedMsg::Cmp>;
|
||||||
|
|
||||||
std::atomic<vluint64_t> m_depth; // Current depth of queue (see comments below)
|
std::atomic<uint64_t> m_depth; // Current depth of queue (see comments below)
|
||||||
|
|
||||||
VerilatedMutex m_mutex; // Mutex protecting queue
|
mutable VerilatedMutex m_mutex; // Mutex protecting queue
|
||||||
VerilatedThreadQueue m_queue VL_GUARDED_BY(m_mutex); // Message queue
|
VerilatedThreadQueue m_queue VL_GUARDED_BY(m_mutex); // Message queue
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
@@ -138,11 +143,10 @@ class VerilatedThreadMsgQueue final {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// CONSTRUCTORS
|
// CONSTRUCTORS
|
||||||
VerilatedThreadMsgQueue() {}
|
VerilatedThreadMsgQueue() = default;
|
||||||
~VerilatedThreadMsgQueue() {
|
~VerilatedThreadMsgQueue() = default;
|
||||||
// The only call of this with a non-empty queue is a fatal error.
|
// The only call of destructor 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);
|
||||||
@@ -183,11 +187,11 @@ class VerilatedFpList final {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
using const_iterator = FILE* const*;
|
using const_iterator = FILE* const*;
|
||||||
explicit VerilatedFpList() {}
|
explicit VerilatedFpList() = default;
|
||||||
const_iterator begin() const { return m_fp; }
|
const_iterator begin() const { return m_fp; }
|
||||||
const_iterator end() const { return m_fp + m_sz; }
|
const_iterator end() const { return m_fp + m_sz; }
|
||||||
std::size_t size() const { return m_sz; }
|
std::size_t size() const { return m_sz; }
|
||||||
std::size_t capacity() const { return 31; }
|
static std::size_t capacity() { return 31; }
|
||||||
void push_back(FILE* fd) {
|
void push_back(FILE* fd) {
|
||||||
if (VL_LIKELY(size() < capacity())) m_fp[m_sz++] = fd;
|
if (VL_LIKELY(size() < capacity())) m_fp[m_sz++] = fd;
|
||||||
}
|
}
|
||||||
@@ -231,17 +235,16 @@ class VerilatedContextImp final : VerilatedContext {
|
|||||||
return s_s;
|
return s_s;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
public: // But only for verilated*.cpp
|
||||||
// CONSTRUCTORS - no data can live here, use only VerilatedContext
|
// CONSTRUCTORS - no data can live here, use only VerilatedContext
|
||||||
VerilatedContextImp() = delete;
|
VerilatedContextImp() = delete;
|
||||||
~VerilatedContextImp() = delete;
|
~VerilatedContextImp() = delete;
|
||||||
|
|
||||||
public: // But only for verilated*.cpp
|
|
||||||
// METHODS - extending into VerilatedContext, call via impp()->
|
// METHODS - extending into VerilatedContext, call via impp()->
|
||||||
|
|
||||||
// Random seed handling
|
// Random seed handling
|
||||||
vluint64_t randSeedDefault64() const VL_MT_SAFE;
|
uint64_t randSeedDefault64() const VL_MT_SAFE;
|
||||||
static vluint32_t randSeedEpoch() VL_MT_SAFE { return s().s_randSeedEpoch; }
|
static uint32_t randSeedEpoch() VL_MT_SAFE { return s().s_randSeedEpoch; }
|
||||||
|
|
||||||
// METHODS - timeformat
|
// METHODS - timeformat
|
||||||
int timeFormatUnits() const VL_MT_SAFE {
|
int timeFormatUnits() const VL_MT_SAFE {
|
||||||
@@ -267,13 +270,12 @@ public: // But only for verilated*.cpp
|
|||||||
std::string argPlusMatch(const char* prefixp) VL_MT_SAFE_EXCLUDES(m_argMutex);
|
std::string argPlusMatch(const char* prefixp) VL_MT_SAFE_EXCLUDES(m_argMutex);
|
||||||
std::pair<int, char**> argc_argv() VL_MT_SAFE_EXCLUDES(m_argMutex);
|
std::pair<int, char**> argc_argv() VL_MT_SAFE_EXCLUDES(m_argMutex);
|
||||||
|
|
||||||
public: // But only for verilated*.cpp
|
// METHODS - scope name - INTERNAL only for verilated*.cpp
|
||||||
// METHODS - scope name
|
|
||||||
void scopeInsert(const VerilatedScope* scopep) VL_MT_SAFE;
|
void scopeInsert(const VerilatedScope* scopep) VL_MT_SAFE;
|
||||||
void scopeErase(const VerilatedScope* scopep) VL_MT_SAFE;
|
void scopeErase(const VerilatedScope* scopep) VL_MT_SAFE;
|
||||||
|
|
||||||
public: // But only for verilated*.cpp
|
// METHODS - file IO - INTERNAL only for verilated*.cpp
|
||||||
// METHODS - file IO
|
|
||||||
IData fdNewMcd(const char* filenamep) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
IData fdNewMcd(const char* filenamep) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
||||||
const VerilatedLockGuard lock{m_fdMutex};
|
const VerilatedLockGuard lock{m_fdMutex};
|
||||||
if (m_fdFreeMct.empty()) return 0;
|
if (m_fdFreeMct.empty()) return 0;
|
||||||
@@ -293,7 +295,7 @@ public: // But only for verilated*.cpp
|
|||||||
const std::size_t start = std::max<std::size_t>(31UL + 1UL + 3UL, m_fdps.size());
|
const std::size_t start = std::max<std::size_t>(31UL + 1UL + 3UL, m_fdps.size());
|
||||||
const std::size_t excess = 10;
|
const std::size_t excess = 10;
|
||||||
m_fdps.resize(start + excess);
|
m_fdps.resize(start + excess);
|
||||||
std::fill(m_fdps.begin() + start, m_fdps.end(), (FILE*)0);
|
std::fill(m_fdps.begin() + start, m_fdps.end(), static_cast<FILE*>(nullptr));
|
||||||
m_fdFree.resize(excess);
|
m_fdFree.resize(excess);
|
||||||
for (std::size_t i = 0, id = start; i < m_fdFree.size(); ++i, ++id) {
|
for (std::size_t i = 0, id = start; i < m_fdFree.size(); ++i, ++id) {
|
||||||
m_fdFree[i] = id;
|
m_fdFree[i] = id;
|
||||||
@@ -312,14 +314,14 @@ public: // But only for verilated*.cpp
|
|||||||
IData fdSeek(IData fdi, IData offset, IData origin) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
IData fdSeek(IData fdi, IData offset, IData origin) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
||||||
const VerilatedLockGuard lock{m_fdMutex};
|
const VerilatedLockGuard lock{m_fdMutex};
|
||||||
const VerilatedFpList fdlist = fdToFpList(fdi);
|
const VerilatedFpList fdlist = fdToFpList(fdi);
|
||||||
if (VL_UNLIKELY(fdlist.size() != 1)) return 0;
|
if (VL_UNLIKELY(fdlist.size() != 1)) return ~0U; // -1
|
||||||
return static_cast<IData>(
|
return static_cast<IData>(
|
||||||
std::fseek(*fdlist.begin(), static_cast<long>(offset), static_cast<int>(origin)));
|
std::fseek(*fdlist.begin(), static_cast<long>(offset), static_cast<int>(origin)));
|
||||||
}
|
}
|
||||||
IData fdTell(IData fdi) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
IData fdTell(IData fdi) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
||||||
const VerilatedLockGuard lock{m_fdMutex};
|
const VerilatedLockGuard lock{m_fdMutex};
|
||||||
const VerilatedFpList fdlist = fdToFpList(fdi);
|
const VerilatedFpList fdlist = fdToFpList(fdi);
|
||||||
if (VL_UNLIKELY(fdlist.size() != 1)) return 0;
|
if (VL_UNLIKELY(fdlist.size() != 1)) return ~0U; // -1
|
||||||
return static_cast<IData>(std::ftell(*fdlist.begin()));
|
return static_cast<IData>(std::ftell(*fdlist.begin()));
|
||||||
}
|
}
|
||||||
void fdWrite(IData fdi, const std::string& output) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
void fdWrite(IData fdi, const std::string& output) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
||||||
@@ -339,7 +341,7 @@ public: // But only for verilated*.cpp
|
|||||||
if (VL_UNLIKELY(idx <= 2)) return; // stdout/stdin/stderr
|
if (VL_UNLIKELY(idx <= 2)) return; // stdout/stdin/stderr
|
||||||
if (VL_UNLIKELY(!m_fdps[idx])) return; // Already free
|
if (VL_UNLIKELY(!m_fdps[idx])) return; // Already free
|
||||||
std::fclose(m_fdps[idx]);
|
std::fclose(m_fdps[idx]);
|
||||||
m_fdps[idx] = (FILE*)0;
|
m_fdps[idx] = nullptr;
|
||||||
m_fdFree.push_back(idx);
|
m_fdFree.push_back(idx);
|
||||||
} else {
|
} else {
|
||||||
// MCD case
|
// MCD case
|
||||||
@@ -354,7 +356,7 @@ public: // But only for verilated*.cpp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline FILE* fdToFp(IData fdi) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
FILE* fdToFp(IData fdi) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
||||||
const VerilatedLockGuard lock{m_fdMutex};
|
const VerilatedLockGuard lock{m_fdMutex};
|
||||||
const VerilatedFpList fdlist = fdToFpList(fdi);
|
const VerilatedFpList fdlist = fdToFpList(fdi);
|
||||||
if (VL_UNLIKELY(fdlist.size() != 1)) return nullptr;
|
if (VL_UNLIKELY(fdlist.size() != 1)) return nullptr;
|
||||||
@@ -390,7 +392,11 @@ protected:
|
|||||||
// METHODS - protected
|
// METHODS - protected
|
||||||
void commandArgsAddGuts(int argc, const char** argv);
|
void commandArgsAddGuts(int argc, const char** argv);
|
||||||
void commandArgVl(const std::string& arg);
|
void commandArgVl(const std::string& arg);
|
||||||
bool commandArgVlValue(const std::string& arg, const std::string& prefix, std::string& valuer);
|
bool commandArgVlString(const std::string& arg, const std::string& prefix,
|
||||||
|
std::string& valuer);
|
||||||
|
bool commandArgVlUint64(const std::string& arg, const std::string& prefix, uint64_t& valuer,
|
||||||
|
uint64_t min = std::numeric_limits<uint64_t>::min(),
|
||||||
|
uint64_t max = std::numeric_limits<uint64_t>::max());
|
||||||
void commandArgDump() const VL_MT_SAFE_EXCLUDES(m_argMutex);
|
void commandArgDump() const VL_MT_SAFE_EXCLUDES(m_argMutex);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -455,13 +461,12 @@ public:
|
|||||||
// METHODS - debug
|
// METHODS - debug
|
||||||
static void versionDump() VL_MT_SAFE;
|
static void versionDump() VL_MT_SAFE;
|
||||||
|
|
||||||
public:
|
|
||||||
// METHODS - user scope tracking
|
// METHODS - user scope tracking
|
||||||
// We implement this as a single large map instead of one map per scope.
|
// We implement this as a single large map instead of one map per scope.
|
||||||
// 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.
|
||||||
// As scopep's are pointers, this implicitly handles multiple Context's
|
// As scopep's are pointers, this implicitly handles multiple Context's
|
||||||
static inline void userInsert(const void* scopep, void* userKey, void* userData) VL_MT_SAFE {
|
static void userInsert(const void* scopep, void* userKey, void* userData) VL_MT_SAFE {
|
||||||
const VerilatedLockGuard lock{s().m_userMapMutex};
|
const VerilatedLockGuard lock{s().m_userMapMutex};
|
||||||
const auto it = s().m_userMap.find(std::make_pair(scopep, userKey));
|
const auto it = s().m_userMap.find(std::make_pair(scopep, userKey));
|
||||||
if (it != s().m_userMap.end()) {
|
if (it != s().m_userMap.end()) {
|
||||||
@@ -470,17 +475,18 @@ public:
|
|||||||
s().m_userMap.emplace(std::make_pair(scopep, userKey), userData);
|
s().m_userMap.emplace(std::make_pair(scopep, userKey), userData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static inline void* userFind(const void* scopep, void* userKey) VL_MT_SAFE {
|
static void* userFind(const void* scopep, void* userKey) VL_MT_SAFE {
|
||||||
const VerilatedLockGuard lock{s().m_userMapMutex};
|
const VerilatedLockGuard lock{s().m_userMapMutex};
|
||||||
const auto& it = vlstd::as_const(s().m_userMap).find(std::make_pair(scopep, userKey));
|
const auto& it = vlstd::as_const(s().m_userMap).find(std::make_pair(scopep, userKey));
|
||||||
if (VL_UNLIKELY(it == s().m_userMap.end())) return nullptr;
|
if (VL_UNLIKELY(it == s().m_userMap.end())) return nullptr;
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
public: // But only for verilated.cpp
|
// METHODS - But only for verilated.cpp
|
||||||
|
|
||||||
// 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 only iterate.
|
||||||
const VerilatedLockGuard lock{s().m_userMapMutex};
|
const VerilatedLockGuard lock{s().m_userMapMutex};
|
||||||
for (auto it = s().m_userMap.begin(); it != s().m_userMap.end();) {
|
for (auto it = s().m_userMap.begin(); it != s().m_userMap.end();) {
|
||||||
if (it->first.first == scopep) {
|
if (it->first.first == scopep) {
|
||||||
@@ -503,8 +509,7 @@ public: // But only for verilated.cpp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public: // But only for verilated*.cpp
|
// METHODS - hierarchy - only for verilated*.cpp
|
||||||
// METHODS - hierarchy
|
|
||||||
static void hierarchyAdd(const VerilatedScope* fromp, const VerilatedScope* top) VL_MT_SAFE {
|
static void hierarchyAdd(const VerilatedScope* fromp, const VerilatedScope* top) VL_MT_SAFE {
|
||||||
// Slow ok - called at construction for VPI accessible elements
|
// Slow ok - called at construction for VPI accessible elements
|
||||||
const VerilatedLockGuard lock{s().m_hierMapMutex};
|
const VerilatedLockGuard lock{s().m_hierMapMutex};
|
||||||
@@ -525,8 +530,7 @@ public: // But only for verilated*.cpp
|
|||||||
return &s().m_hierMap;
|
return &s().m_hierMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
public: // But only for verilated*.cpp
|
// METHODS - export names - only for verilated*.cpp
|
||||||
// METHODS - export names
|
|
||||||
|
|
||||||
// Each function prototype is converted to a function number which we
|
// Each function prototype is converted to a function number which we
|
||||||
// then use to index a 2D table also indexed by scope number, because we
|
// then use to index a 2D table also indexed by scope number, because we
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
|
|||||||
@@ -0,0 +1,225 @@
|
|||||||
|
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||||
|
//=============================================================================
|
||||||
|
//
|
||||||
|
// Code available from: https://verilator.org
|
||||||
|
//
|
||||||
|
// Copyright 2012-2022 by Wilson Snyder. This program is free software; you can
|
||||||
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
|
// Version 2.0.
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||||
|
//
|
||||||
|
//=============================================================================
|
||||||
|
///
|
||||||
|
/// \file
|
||||||
|
/// \brief Verilated run-time profiling implementation code
|
||||||
|
///
|
||||||
|
//=============================================================================
|
||||||
|
|
||||||
|
#include "verilatedos.h"
|
||||||
|
|
||||||
|
#include "verilated_profiler.h"
|
||||||
|
|
||||||
|
#if VL_THREADED
|
||||||
|
#include "verilated_threads.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Globals
|
||||||
|
|
||||||
|
// Internal note: Globals may multi-construct, see verilated.cpp top.
|
||||||
|
|
||||||
|
VL_THREAD_LOCAL VlExecutionProfiler::ExecutionTrace VlExecutionProfiler::t_trace;
|
||||||
|
|
||||||
|
constexpr const char* const VlExecutionRecord::s_ascii[];
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// VlPgoProfiler implementation
|
||||||
|
|
||||||
|
uint16_t VlExecutionRecord::getcpu() {
|
||||||
|
#if defined(__linux)
|
||||||
|
return sched_getcpu(); // TODO: this is a system call. Not exactly cheap.
|
||||||
|
#elif defined(__APPLE__) && !defined(__arm64__)
|
||||||
|
uint32_t info[4];
|
||||||
|
__cpuid_count(1, 0, info[0], info[1], info[2], info[3]);
|
||||||
|
// info[1] is EBX, bits 24-31 are APIC ID
|
||||||
|
if ((info[3] & (1 << 9)) == 0) {
|
||||||
|
return -1; // no APIC on chip
|
||||||
|
} else {
|
||||||
|
return (unsigned)info[1] >> 24;
|
||||||
|
}
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
return GetCurrentProcessorNumber();
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// VlExecutionProfiler implementation
|
||||||
|
|
||||||
|
template <size_t N>
|
||||||
|
static size_t roundUptoMultipleOf(size_t value) {
|
||||||
|
static_assert((N & (N - 1)) == 0, "'N' must be a power of 2");
|
||||||
|
size_t mask = N - 1;
|
||||||
|
return (value + mask) & ~mask;
|
||||||
|
}
|
||||||
|
|
||||||
|
VlExecutionProfiler::VlExecutionProfiler(VerilatedContext& context)
|
||||||
|
: m_context{context} {
|
||||||
|
// Setup profiling on main thread
|
||||||
|
setupThread(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void VlExecutionProfiler::configure() {
|
||||||
|
|
||||||
|
if (VL_UNLIKELY(m_enabled)) {
|
||||||
|
--m_windowCount;
|
||||||
|
if (VL_UNLIKELY(m_windowCount == m_context.profExecWindow())) {
|
||||||
|
VL_DEBUG_IF(VL_DBG_MSGF("+ profile start collection\n"););
|
||||||
|
clear(); // Clear the profile after the cache warm-up cycles.
|
||||||
|
m_tickBegin = VL_CPU_TICK();
|
||||||
|
} else if (VL_UNLIKELY(m_windowCount == 0)) {
|
||||||
|
const uint64_t tickEnd = VL_CPU_TICK();
|
||||||
|
VL_DEBUG_IF(VL_DBG_MSGF("+ profile end\n"););
|
||||||
|
const std::string& fileName = m_context.profExecFilename();
|
||||||
|
dump(fileName.c_str(), tickEnd);
|
||||||
|
m_enabled = false;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint64_t startReq = m_context.profExecStart() + 1; // + 1, so we can start at time 0
|
||||||
|
|
||||||
|
if (VL_UNLIKELY(m_lastStartReq < startReq && VL_TIME_Q() >= m_context.profExecStart())) {
|
||||||
|
VL_DEBUG_IF(VL_DBG_MSGF("+ profile start warmup\n"););
|
||||||
|
VL_DEBUG_IF(assert(m_windowCount == 0););
|
||||||
|
m_enabled = true;
|
||||||
|
m_windowCount = m_context.profExecWindow() * 2;
|
||||||
|
m_lastStartReq = startReq;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VerilatedVirtualBase* VlExecutionProfiler::construct(VerilatedContext& context) {
|
||||||
|
VlExecutionProfiler* const selfp = new VlExecutionProfiler{context};
|
||||||
|
#if VL_THREADED
|
||||||
|
if (VlThreadPool* const threadPoolp = static_cast<VlThreadPool*>(context.threadPoolp())) {
|
||||||
|
for (int i = 0; i < threadPoolp->numThreads(); ++i) {
|
||||||
|
// Data to pass to worker thread initialization
|
||||||
|
struct Data {
|
||||||
|
VlExecutionProfiler* const selfp;
|
||||||
|
const uint32_t threadId;
|
||||||
|
} data{selfp, static_cast<uint32_t>(i + 1)};
|
||||||
|
|
||||||
|
// Initialize worker thread
|
||||||
|
threadPoolp->workerp(i)->addTask(
|
||||||
|
[](void* userp, bool) {
|
||||||
|
Data* const datap = static_cast<Data*>(userp);
|
||||||
|
datap->selfp->setupThread(datap->threadId);
|
||||||
|
},
|
||||||
|
&data);
|
||||||
|
|
||||||
|
// Wait until initializationis complete
|
||||||
|
threadPoolp->workerp(i)->wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return selfp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VlExecutionProfiler::setupThread(uint32_t threadId) {
|
||||||
|
// Reserve some space in the thread-local profiling buffer, in order to try to avoid malloc
|
||||||
|
// while profiling.
|
||||||
|
t_trace.reserve(RESERVED_TRACE_CAPACITY);
|
||||||
|
// Register thread-local buffer in list of all buffers
|
||||||
|
bool exists;
|
||||||
|
{
|
||||||
|
const VerilatedLockGuard lock{m_mutex};
|
||||||
|
exists = !m_traceps.emplace(threadId, &t_trace).second;
|
||||||
|
}
|
||||||
|
if (VL_UNLIKELY(exists)) {
|
||||||
|
VL_FATAL_MT(__FILE__, __LINE__, "", "multiple initialization of profiler on some thread");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VlExecutionProfiler::clear() VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||||
|
const VerilatedLockGuard lock{m_mutex};
|
||||||
|
for (const auto& pair : m_traceps) {
|
||||||
|
ExecutionTrace* const tracep = pair.second;
|
||||||
|
const size_t reserve = roundUptoMultipleOf<RESERVED_TRACE_CAPACITY>(tracep->size());
|
||||||
|
tracep->clear();
|
||||||
|
tracep->reserve(reserve);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VlExecutionProfiler::dump(const char* filenamep, uint64_t tickEnd)
|
||||||
|
VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||||
|
const VerilatedLockGuard lock{m_mutex};
|
||||||
|
VL_DEBUG_IF(VL_DBG_MSGF("+prof+exec writing to '%s'\n", filenamep););
|
||||||
|
|
||||||
|
FILE* const fp = std::fopen(filenamep, "w");
|
||||||
|
if (VL_UNLIKELY(!fp)) { VL_FATAL_MT(filenamep, 0, "", "+prof+exec+file file not writable"); }
|
||||||
|
|
||||||
|
// TODO Perhaps merge with verilated_coverage output format, so can
|
||||||
|
// have a common merging and reporting tool, etc.
|
||||||
|
fprintf(fp, "VLPROFVERSION 2.0 # Verilator execution profile version 2.0\n");
|
||||||
|
fprintf(fp, "VLPROF arg +verilator+prof+exec+start+%" PRIu64 "\n",
|
||||||
|
Verilated::threadContextp()->profExecStart());
|
||||||
|
fprintf(fp, "VLPROF arg +verilator+prof+exec+window+%u\n",
|
||||||
|
Verilated::threadContextp()->profExecWindow());
|
||||||
|
const unsigned threads = static_cast<unsigned>(m_traceps.size());
|
||||||
|
fprintf(fp, "VLPROF stat threads %u\n", threads);
|
||||||
|
#ifdef VL_THREADED
|
||||||
|
fprintf(fp, "VLPROF stat yields %" PRIu64 "\n", VlMTaskVertex::yields());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Copy /proc/cpuinfo into this output so verilator_gantt can be run on
|
||||||
|
// a different machine
|
||||||
|
{
|
||||||
|
const std::unique_ptr<std::ifstream> ifp{new std::ifstream("/proc/cpuinfo")};
|
||||||
|
if (!ifp->fail()) {
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(*ifp, line)) { fprintf(fp, "VLPROFPROC %s\n", line.c_str()); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& pair : m_traceps) {
|
||||||
|
const uint32_t threadId = pair.first;
|
||||||
|
ExecutionTrace* const tracep = pair.second;
|
||||||
|
fprintf(fp, "VLPROFTHREAD %" PRIu32 "\n", threadId);
|
||||||
|
|
||||||
|
for (const VlExecutionRecord& er : *tracep) {
|
||||||
|
const char* const name = VlExecutionRecord::s_ascii[static_cast<uint8_t>(er.m_type)];
|
||||||
|
const uint64_t time = er.m_tick - m_tickBegin;
|
||||||
|
fprintf(fp, "VLPROFEXEC %s %" PRIu64, name, time);
|
||||||
|
|
||||||
|
switch (er.m_type) {
|
||||||
|
case VlExecutionRecord::Type::EVAL_BEGIN:
|
||||||
|
case VlExecutionRecord::Type::EVAL_END:
|
||||||
|
case VlExecutionRecord::Type::EVAL_LOOP_BEGIN:
|
||||||
|
case VlExecutionRecord::Type::EVAL_LOOP_END:
|
||||||
|
// No payload
|
||||||
|
fprintf(fp, "\n");
|
||||||
|
break;
|
||||||
|
case VlExecutionRecord::Type::MTASK_BEGIN: {
|
||||||
|
const auto& payload = er.m_payload.mtaskBegin;
|
||||||
|
fprintf(fp, " id %u predictStart %u cpu %u\n", payload.m_id,
|
||||||
|
payload.m_predictStart, payload.m_cpu);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case VlExecutionRecord::Type::MTASK_END: {
|
||||||
|
const auto& payload = er.m_payload.mtaskEnd;
|
||||||
|
fprintf(fp, " id %u predictCost %u\n", payload.m_id, payload.m_predictCost);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: abort(); // LCOV_EXCL_LINE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(fp, "VLPROF stat ticks %" PRIu64 "\n", tickEnd - m_tickBegin);
|
||||||
|
|
||||||
|
std::fclose(fp);
|
||||||
|
}
|
||||||
+190
-45
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2012-2021 by Wilson Snyder. This program is free software; you
|
// Copyright 2012-2022 by Wilson Snyder. This program is free software; you
|
||||||
// can redistribute it and/or modify it under the terms of either the GNU
|
// 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
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -12,7 +12,7 @@
|
|||||||
//=============================================================================
|
//=============================================================================
|
||||||
///
|
///
|
||||||
/// \file
|
/// \file
|
||||||
/// \brief Verilated general profiling header
|
/// \brief Verilated run-time profiling header
|
||||||
///
|
///
|
||||||
/// This file is not part of the Verilated public-facing API.
|
/// This file is not part of the Verilated public-facing API.
|
||||||
/// It is only for internal use by Verilated library routines.
|
/// It is only for internal use by Verilated library routines.
|
||||||
@@ -23,55 +23,206 @@
|
|||||||
#define VERILATOR_VERILATED_PROFILER_H_
|
#define VERILATOR_VERILATED_PROFILER_H_
|
||||||
|
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
#include "verilated.h" // for VerilatedMutex and clang annotations
|
|
||||||
|
|
||||||
// Profile record, private class used only by this header
|
#include "verilated.h"
|
||||||
class VerilatedProfilerRec final {
|
|
||||||
const std::string m_name; // Hashed name of mtask/etc
|
#include <array>
|
||||||
const size_t m_counterNumber = 0; // Which counter has data
|
#include <atomic>
|
||||||
|
#include <cassert>
|
||||||
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class VlExecutionProfiler;
|
||||||
|
class VlThreadPool;
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Macros to simplify generated code
|
||||||
|
|
||||||
|
#define VL_EXEC_TRACE_ADD_RECORD(vlSymsp) \
|
||||||
|
if (VL_UNLIKELY((vlSymsp)->__Vm_executionProfilerp->enabled())) \
|
||||||
|
(vlSymsp)->__Vm_executionProfilerp->addRecord()
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Return high-precision counter for profiling, or 0x0 if not available
|
||||||
|
VL_ATTR_ALWINLINE QData VL_CPU_TICK() {
|
||||||
|
uint64_t val;
|
||||||
|
VL_GET_CPU_TICK(val);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// Private class used by VlExecutionProfiler
|
||||||
|
|
||||||
|
#define _VL_FOREACH_APPLY(macro, arg) macro(arg, #arg)
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
#define FOREACH_VlExecutionRecord_TYPE(macro) \
|
||||||
|
_VL_FOREACH_APPLY(macro, EVAL_BEGIN) \
|
||||||
|
_VL_FOREACH_APPLY(macro, EVAL_END) \
|
||||||
|
_VL_FOREACH_APPLY(macro, EVAL_LOOP_BEGIN) \
|
||||||
|
_VL_FOREACH_APPLY(macro, EVAL_LOOP_END) \
|
||||||
|
_VL_FOREACH_APPLY(macro, MTASK_BEGIN) \
|
||||||
|
_VL_FOREACH_APPLY(macro, MTASK_END)
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
class VlExecutionRecord final {
|
||||||
|
friend class VlExecutionProfiler;
|
||||||
|
|
||||||
|
// TYPES
|
||||||
|
enum class Type : uint8_t {
|
||||||
|
#define VL_FOREACH_MACRO(id, name) id,
|
||||||
|
FOREACH_VlExecutionRecord_TYPE(VL_FOREACH_MACRO)
|
||||||
|
#undef VL_FOREACH_MACRO
|
||||||
|
};
|
||||||
|
|
||||||
|
static constexpr const char* const s_ascii[] = {
|
||||||
|
#define VL_FOREACH_MACRO(id, name) name,
|
||||||
|
FOREACH_VlExecutionRecord_TYPE(VL_FOREACH_MACRO)
|
||||||
|
#undef VL_FOREACH_MACRO
|
||||||
|
};
|
||||||
|
|
||||||
|
union Payload {
|
||||||
|
struct {
|
||||||
|
uint32_t m_id; // MTask id
|
||||||
|
uint32_t m_predictStart; // Time scheduler predicted would start
|
||||||
|
uint32_t m_cpu; // Executing CPU id
|
||||||
|
} mtaskBegin;
|
||||||
|
struct {
|
||||||
|
uint32_t m_id; // MTask id
|
||||||
|
uint32_t m_predictCost; // How long scheduler predicted would take
|
||||||
|
} mtaskEnd;
|
||||||
|
};
|
||||||
|
|
||||||
|
// STATE
|
||||||
|
// Layout below allows efficient packing.
|
||||||
|
const uint64_t m_tick = VL_CPU_TICK(); // Tick at construction
|
||||||
|
Payload m_payload; // The record payload
|
||||||
|
Type m_type; // The record type
|
||||||
|
static_assert(alignof(uint64_t) >= alignof(Payload), "Padding not allowed");
|
||||||
|
static_assert(alignof(Payload) >= alignof(Type), "Padding not allowed");
|
||||||
|
|
||||||
|
static uint16_t getcpu(); // Return currently executing CPU id
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// CONSTRUCTOR
|
||||||
|
VlExecutionRecord() = default;
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
VerilatedProfilerRec(size_t counterNumber, const std::string& name)
|
void evalBegin() { m_type = Type::EVAL_BEGIN; }
|
||||||
: m_name{name}
|
void evalEnd() { m_type = Type::EVAL_END; }
|
||||||
, m_counterNumber{counterNumber} {}
|
void evalLoopBegin() { m_type = Type::EVAL_LOOP_BEGIN; }
|
||||||
VerilatedProfilerRec() = default;
|
void evalLoopEnd() { m_type = Type::EVAL_LOOP_END; }
|
||||||
size_t counterNumber() const { return m_counterNumber; }
|
void mtaskBegin(uint32_t id, uint32_t predictStart) {
|
||||||
std::string name() const { return m_name; }
|
m_payload.mtaskBegin.m_id = id;
|
||||||
|
m_payload.mtaskBegin.m_predictStart = predictStart;
|
||||||
|
m_payload.mtaskBegin.m_cpu = getcpu();
|
||||||
|
m_type = Type::MTASK_BEGIN;
|
||||||
|
}
|
||||||
|
void mtaskEnd(uint32_t id, uint32_t predictCost) {
|
||||||
|
m_payload.mtaskEnd.m_id = id;
|
||||||
|
m_payload.mtaskEnd.m_predictCost = predictCost;
|
||||||
|
m_type = Type::MTASK_END;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create some number of bucketed profilers
|
static_assert(std::is_trivially_destructible<VlExecutionRecord>::value,
|
||||||
template <std::size_t T_Entries> class VerilatedProfiler final {
|
"VlExecutionRecord should be trivially destructible for fast buffer clearing");
|
||||||
// Counters are stored packed, all together, versus in VerilatedProfilerRec to
|
|
||||||
// reduce cache effects
|
//=============================================================================
|
||||||
std::array<vluint64_t, T_Entries> m_counters{}; // Time spent on this record
|
// VlExecutionProfiler is for collecting profiling data about model execution
|
||||||
std::deque<VerilatedProfilerRec> m_records; // Record information
|
|
||||||
|
class VlExecutionProfiler final : public VerilatedVirtualBase {
|
||||||
|
// CONSTANTS
|
||||||
|
|
||||||
|
// In order to try to avoid dynamic memory allocations during the actual profiling phase,
|
||||||
|
// trace buffers are pre-allocated to be able to hold [a multiple] of this many records.
|
||||||
|
static constexpr size_t RESERVED_TRACE_CAPACITY = 4096;
|
||||||
|
|
||||||
|
// TYPES
|
||||||
|
|
||||||
|
// Execution traces are recorded into thread local vectors. We can append records of profiling
|
||||||
|
// events to this vector with very low overhead, and then dump them out later. This prevents
|
||||||
|
// the overhead of printf/malloc/IO from corrupting the profiling data. It's super cheap to
|
||||||
|
// append a VlProfileRec struct on the end of a pre-allocated vector; this is the only cost we
|
||||||
|
// pay in real-time during a profiling cycle. Internal note: Globals may multi-construct, see
|
||||||
|
// verilated.cpp top.
|
||||||
|
using ExecutionTrace = std::vector<VlExecutionRecord>;
|
||||||
|
|
||||||
|
// STATE
|
||||||
|
VerilatedContext& m_context; // The context this profiler is under
|
||||||
|
static VL_THREAD_LOCAL ExecutionTrace t_trace; // thread-local trace buffers
|
||||||
|
mutable VerilatedMutex m_mutex;
|
||||||
|
// Map from thread id to &t_trace of given thread
|
||||||
|
std::map<uint32_t, ExecutionTrace*> m_traceps VL_GUARDED_BY(m_mutex);
|
||||||
|
|
||||||
|
bool m_enabled = false; // Is profiling currently enabled
|
||||||
|
|
||||||
|
uint64_t m_tickBegin = 0; // Sample time (rdtsc() on x86) at beginning of collection
|
||||||
|
uint64_t m_lastStartReq = 0; // Last requested profiling start (in simulation time)
|
||||||
|
uint32_t m_windowCount = 0; // Track our position in the cache warmup and profile window
|
||||||
|
|
||||||
|
public:
|
||||||
|
// CONSTRUCTOR
|
||||||
|
explicit VlExecutionProfiler(VerilatedContext& context);
|
||||||
|
~VlExecutionProfiler() override = default;
|
||||||
|
|
||||||
|
// METHODS
|
||||||
|
|
||||||
|
// Is profiling enabled
|
||||||
|
bool enabled() const { return m_enabled; }
|
||||||
|
// Append a trace record to the trace buffer of the current thread
|
||||||
|
static VlExecutionRecord& addRecord() {
|
||||||
|
t_trace.emplace_back();
|
||||||
|
return t_trace.back();
|
||||||
|
}
|
||||||
|
// Configure profiler (called in beginning of 'eval')
|
||||||
|
void configure();
|
||||||
|
// Setup profiling on a particular thread;
|
||||||
|
void setupThread(uint32_t threadId);
|
||||||
|
// Clear all profiling data
|
||||||
|
void clear() VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||||
|
// Write profiling data into file
|
||||||
|
void dump(const char* filenamep, uint64_t tickEnd) VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||||
|
|
||||||
|
// Passed to VerilatedContext to create the VlExecutionProfiler profiler instance
|
||||||
|
static VerilatedVirtualBase* construct(VerilatedContext& context);
|
||||||
|
};
|
||||||
|
|
||||||
|
//=============================================================================
|
||||||
|
// VlPgoProfiler is for collecting profiling data for PGO
|
||||||
|
|
||||||
|
template <std::size_t T_Entries>
|
||||||
|
class VlPgoProfiler final {
|
||||||
|
// TYPES
|
||||||
|
struct Record final {
|
||||||
|
const std::string m_name; // Hashed name of mtask/etc
|
||||||
|
const size_t m_counterNumber = 0; // Which counter has data
|
||||||
|
};
|
||||||
|
|
||||||
|
// Counters are stored packed, all together to reduce cache effects
|
||||||
|
std::array<uint64_t, T_Entries> m_counters; // Time spent on this record
|
||||||
|
std::vector<Record> m_records; // Record information
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// METHODS
|
// METHODS
|
||||||
VerilatedProfiler() = default;
|
VlPgoProfiler() = default;
|
||||||
~VerilatedProfiler() = default;
|
~VlPgoProfiler() = default;
|
||||||
void write(const char* modelp, const std::string& filename) VL_MT_SAFE;
|
void write(const char* modelp, const std::string& filename) VL_MT_SAFE;
|
||||||
void addCounter(size_t counter, const std::string& name) {
|
void addCounter(size_t counter, const std::string& name) {
|
||||||
VL_DEBUG_IF(assert(counter < T_Entries););
|
VL_DEBUG_IF(assert(counter < T_Entries););
|
||||||
m_records.emplace_back(VerilatedProfilerRec{counter, name});
|
m_records.emplace_back(Record{name, counter});
|
||||||
}
|
}
|
||||||
void startCounter(size_t counter) {
|
void startCounter(size_t counter) {
|
||||||
vluint64_t val;
|
// -= so when we add end time in stopCounter, the net effect is adding the difference,
|
||||||
VL_RDTSC(val);
|
// without needing to hold onto a temporary
|
||||||
// -= so when we add end time in stopCounter, we already subtracted
|
m_counters[counter] -= VL_CPU_TICK();
|
||||||
// out, without needing to hold another temporary
|
|
||||||
m_counters[counter] -= val;
|
|
||||||
}
|
|
||||||
void stopCounter(size_t counter) {
|
|
||||||
vluint64_t val;
|
|
||||||
VL_RDTSC(val);
|
|
||||||
m_counters[counter] += val;
|
|
||||||
}
|
}
|
||||||
|
void stopCounter(size_t counter) { m_counters[counter] += VL_CPU_TICK(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <std::size_t T_Entries>
|
template <std::size_t T_Entries>
|
||||||
void VerilatedProfiler<T_Entries>::write(const char* modelp,
|
void VlPgoProfiler<T_Entries>::write(const char* modelp, const std::string& filename) VL_MT_SAFE {
|
||||||
const std::string& filename) VL_MT_SAFE {
|
|
||||||
static VerilatedMutex s_mutex;
|
static VerilatedMutex s_mutex;
|
||||||
const VerilatedLockGuard lock{s_mutex};
|
const VerilatedLockGuard lock{s_mutex};
|
||||||
|
|
||||||
@@ -79,20 +230,15 @@ void VerilatedProfiler<T_Entries>::write(const char* modelp,
|
|||||||
// So when we have multiple models in an executable, possibly even
|
// So when we have multiple models in an executable, possibly even
|
||||||
// running on different threads, each will have a different symtab so
|
// running on different threads, each will have a different symtab so
|
||||||
// each will collect is own data correctly. However when each is
|
// each will collect is own data correctly. However when each is
|
||||||
// destroid we need to get all the data, not keep overwriting and only
|
// destroyed we need to get all the data, not keep overwriting and only
|
||||||
// get the last model's data.
|
// get the last model's data.
|
||||||
static bool s_firstCall = true;
|
static bool s_firstCall = true;
|
||||||
|
|
||||||
VL_DEBUG_IF(VL_DBG_MSGF("+prof+vlt+file writing to '%s'\n", filename.c_str()););
|
VL_DEBUG_IF(VL_DBG_MSGF("+prof+vlt+file writing to '%s'\n", filename.c_str()););
|
||||||
|
|
||||||
FILE* fp = nullptr;
|
FILE* const fp = std::fopen(filename.c_str(), s_firstCall ? "w" : "a");
|
||||||
if (!s_firstCall) fp = std::fopen(filename.c_str(), "a");
|
|
||||||
if (VL_UNLIKELY(!fp))
|
|
||||||
fp = std::fopen(filename.c_str(), "w"); // firstCall, or doesn't exist yet
|
|
||||||
if (VL_UNLIKELY(!fp)) {
|
if (VL_UNLIKELY(!fp)) {
|
||||||
VL_FATAL_MT(filename.c_str(), 0, "", "+prof+vlt+file file not writable");
|
VL_FATAL_MT(filename.c_str(), 0, "", "+prof+vlt+file file not writable");
|
||||||
// cppcheck-suppress resourceLeak // bug, doesn't realize fp is nullptr
|
|
||||||
return; // LCOV_EXCL_LINE
|
|
||||||
}
|
}
|
||||||
s_firstCall = false;
|
s_firstCall = false;
|
||||||
|
|
||||||
@@ -101,10 +247,9 @@ void VerilatedProfiler<T_Entries>::write(const char* modelp,
|
|||||||
fprintf(fp, "// Verilated model profile-guided optimization data dump file\n");
|
fprintf(fp, "// Verilated model profile-guided optimization data dump file\n");
|
||||||
fprintf(fp, "`verilator_config\n");
|
fprintf(fp, "`verilator_config\n");
|
||||||
|
|
||||||
for (const auto& it : m_records) {
|
for (const Record& rec : m_records) {
|
||||||
const std::string& name = it.name();
|
fprintf(fp, "profile_data -model \"%s\" -mtask \"%s\" -cost 64'd%" PRIu64 "\n", modelp,
|
||||||
fprintf(fp, "profile_data -model \"%s\" -mtask \"%s\" -cost 64'd%" VL_PRI64 "u\n", modelp,
|
rec.m_name.c_str(), m_counters[rec.m_counterNumber]);
|
||||||
name.c_str(), m_counters[it.counterNumber()]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::fclose(fp);
|
std::fclose(fp);
|
||||||
|
|||||||
+12
-10
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||||
// can redistribute it and/or modify it under the terms of either the GNU
|
// 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
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -24,8 +24,10 @@
|
|||||||
#define VERILATOR_VERILATED_SAVE_CPP_
|
#define VERILATOR_VERILATED_SAVE_CPP_
|
||||||
|
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
#include "verilated.h"
|
|
||||||
#include "verilated_save.h"
|
#include "verilated_save.h"
|
||||||
|
|
||||||
|
#include "verilated.h"
|
||||||
#include "verilated_imp.h"
|
#include "verilated_imp.h"
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
@@ -38,13 +40,13 @@
|
|||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef O_LARGEFILE // For example on WIN32
|
#ifndef O_LARGEFILE // WIN32 headers omit this
|
||||||
# define O_LARGEFILE 0
|
# define O_LARGEFILE 0
|
||||||
#endif
|
#endif
|
||||||
#ifndef O_NONBLOCK
|
#ifndef O_NONBLOCK // WIN32 headers omit this
|
||||||
# define O_NONBLOCK 0
|
# define O_NONBLOCK 0
|
||||||
#endif
|
#endif
|
||||||
#ifndef O_CLOEXEC
|
#ifndef O_CLOEXEC // WIN32 headers omit this
|
||||||
# define O_CLOEXEC 0
|
# define O_CLOEXEC 0
|
||||||
#endif
|
#endif
|
||||||
// clang-format on
|
// clang-format on
|
||||||
@@ -63,8 +65,8 @@ static const char* const VLTSAVE_TRAILER_STR = "vltsaved";
|
|||||||
bool VerilatedDeserialize::readDiffers(const void* __restrict datap,
|
bool VerilatedDeserialize::readDiffers(const void* __restrict datap,
|
||||||
size_t size) VL_MT_UNSAFE_ONE {
|
size_t size) VL_MT_UNSAFE_ONE {
|
||||||
bufferCheck();
|
bufferCheck();
|
||||||
const vluint8_t* __restrict dp = static_cast<const vluint8_t* __restrict>(datap);
|
const uint8_t* __restrict dp = static_cast<const uint8_t* __restrict>(datap);
|
||||||
vluint8_t miss = 0;
|
uint8_t miss = 0;
|
||||||
while (size--) miss |= (*dp++ ^ *m_cp++);
|
while (size--) miss |= (*dp++ ^ *m_cp++);
|
||||||
return (miss != 0);
|
return (miss != 0);
|
||||||
}
|
}
|
||||||
@@ -192,7 +194,7 @@ void VerilatedRestore::close() VL_MT_UNSAFE_ONE {
|
|||||||
void VerilatedSave::flush() VL_MT_UNSAFE_ONE {
|
void VerilatedSave::flush() VL_MT_UNSAFE_ONE {
|
||||||
m_assertOne.check();
|
m_assertOne.check();
|
||||||
if (VL_UNLIKELY(!isOpen())) return;
|
if (VL_UNLIKELY(!isOpen())) return;
|
||||||
const vluint8_t* wp = m_bufp;
|
const uint8_t* wp = m_bufp;
|
||||||
while (true) {
|
while (true) {
|
||||||
const ssize_t remaining = (m_cp - wp);
|
const ssize_t remaining = (m_cp - wp);
|
||||||
if (remaining == 0) break;
|
if (remaining == 0) break;
|
||||||
@@ -219,8 +221,8 @@ void VerilatedRestore::fill() VL_MT_UNSAFE_ONE {
|
|||||||
m_assertOne.check();
|
m_assertOne.check();
|
||||||
if (VL_UNLIKELY(!isOpen())) return;
|
if (VL_UNLIKELY(!isOpen())) return;
|
||||||
// Move remaining characters down to start of buffer. (No memcpy, overlaps allowed)
|
// Move remaining characters down to start of buffer. (No memcpy, overlaps allowed)
|
||||||
vluint8_t* rp = m_bufp;
|
uint8_t* rp = m_bufp;
|
||||||
for (vluint8_t* sp = m_cp; sp < m_endp; *rp++ = *sp++) {} // Overlaps
|
for (uint8_t* sp = m_cp; sp < m_endp; *rp++ = *sp++) {} // Overlaps
|
||||||
m_endp = m_bufp + (m_endp - m_cp);
|
m_endp = m_bufp + (m_endp - m_cp);
|
||||||
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
|
||||||
|
|||||||
+36
-34
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2000-2021 by Wilson Snyder. This program is free software; you
|
// Copyright 2000-2022 by Wilson Snyder. This program is free software; you
|
||||||
// can redistribute it and/or modify it under the terms of either the GNU
|
// 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
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
#define VERILATOR_VERILATED_SAVE_C_H_
|
#define VERILATOR_VERILATED_SAVE_C_H_
|
||||||
|
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
|
|
||||||
#include "verilated.h"
|
#include "verilated.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -40,8 +41,8 @@ class VerilatedSerialize VL_NOT_FINAL {
|
|||||||
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
|
uint8_t* m_cp; // Current pointer into m_bufp buffer
|
||||||
vluint8_t* m_bufp; // Output buffer
|
uint8_t* m_bufp; // Output buffer
|
||||||
bool m_isOpen = false; // True indicates open file/stream
|
bool m_isOpen = false; // 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
|
||||||
@@ -58,7 +59,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
/// Construct
|
/// Construct
|
||||||
VerilatedSerialize() {
|
VerilatedSerialize() {
|
||||||
m_bufp = new vluint8_t[bufferSize()];
|
m_bufp = new uint8_t[bufferSize()];
|
||||||
m_cp = m_bufp;
|
m_cp = m_bufp;
|
||||||
}
|
}
|
||||||
/// Flish, close, and destruct
|
/// Flish, close, and destruct
|
||||||
@@ -77,12 +78,12 @@ public:
|
|||||||
virtual void flush() VL_MT_UNSAFE_ONE {}
|
virtual void flush() VL_MT_UNSAFE_ONE {}
|
||||||
/// Write data to stream
|
/// Write data to stream
|
||||||
VerilatedSerialize& write(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
VerilatedSerialize& write(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
||||||
const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap;
|
const uint8_t* __restrict dp = static_cast<const uint8_t* __restrict>(datap);
|
||||||
while (size) {
|
while (size) {
|
||||||
bufferCheck();
|
bufferCheck();
|
||||||
size_t blk = size;
|
size_t blk = size;
|
||||||
if (blk > bufferInsertSize()) blk = bufferInsertSize();
|
if (blk > bufferInsertSize()) blk = bufferInsertSize();
|
||||||
const vluint8_t* __restrict maxp = dp + blk;
|
const uint8_t* __restrict maxp = dp + blk;
|
||||||
for (; dp < maxp; *m_cp++ = *dp++) {}
|
for (; dp < maxp; *m_cp++ = *dp++) {}
|
||||||
size -= blk;
|
size -= blk;
|
||||||
}
|
}
|
||||||
@@ -111,9 +112,9 @@ class VerilatedDeserialize VL_NOT_FINAL {
|
|||||||
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
|
uint8_t* m_cp; // Current pointer into m_bufp buffer
|
||||||
vluint8_t* m_bufp; // Output buffer
|
uint8_t* m_bufp; // Output buffer
|
||||||
vluint8_t* m_endp = nullptr; // Last valid byte in m_bufp buffer
|
uint8_t* m_endp = nullptr; // Last valid byte in m_bufp buffer
|
||||||
bool m_isOpen = false; // True indicates open file/stream
|
bool m_isOpen = false; // 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
|
||||||
@@ -131,7 +132,7 @@ protected:
|
|||||||
public:
|
public:
|
||||||
/// Construct
|
/// Construct
|
||||||
VerilatedDeserialize() {
|
VerilatedDeserialize() {
|
||||||
m_bufp = new vluint8_t[bufferSize()];
|
m_bufp = new uint8_t[bufferSize()];
|
||||||
m_cp = m_bufp;
|
m_cp = m_bufp;
|
||||||
}
|
}
|
||||||
/// Destruct
|
/// Destruct
|
||||||
@@ -150,12 +151,12 @@ public:
|
|||||||
virtual void flush() VL_MT_UNSAFE_ONE {}
|
virtual void flush() VL_MT_UNSAFE_ONE {}
|
||||||
/// Read data from stream
|
/// Read data from stream
|
||||||
VerilatedDeserialize& read(void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
VerilatedDeserialize& read(void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
||||||
vluint8_t* __restrict dp = static_cast<vluint8_t* __restrict>(datap);
|
uint8_t* __restrict dp = static_cast<uint8_t* __restrict>(datap);
|
||||||
while (size) {
|
while (size) {
|
||||||
bufferCheck();
|
bufferCheck();
|
||||||
size_t blk = size;
|
size_t blk = size;
|
||||||
if (blk > bufferInsertSize()) blk = bufferInsertSize();
|
if (blk > bufferInsertSize()) blk = bufferInsertSize();
|
||||||
const vluint8_t* __restrict maxp = dp + blk;
|
const uint8_t* __restrict maxp = dp + blk;
|
||||||
for (; dp < maxp; *dp++ = *m_cp++) {}
|
for (; dp < maxp; *dp++ = *m_cp++) {}
|
||||||
size -= blk;
|
size -= blk;
|
||||||
}
|
}
|
||||||
@@ -165,7 +166,7 @@ public:
|
|||||||
// Internal use:
|
// Internal use:
|
||||||
// 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;
|
||||||
VerilatedDeserialize& readAssert(vluint64_t data) VL_MT_UNSAFE_ONE {
|
VerilatedDeserialize& readAssert(uint64_t data) VL_MT_UNSAFE_ONE {
|
||||||
return readAssert(&data, sizeof(data));
|
return readAssert(&data, sizeof(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,16 +195,16 @@ public:
|
|||||||
/// Construct new object
|
/// Construct new object
|
||||||
VerilatedSave() = default;
|
VerilatedSave() = default;
|
||||||
/// Flush, close and destruct
|
/// Flush, close and destruct
|
||||||
virtual ~VerilatedSave() override { close(); }
|
~VerilatedSave() override { close(); }
|
||||||
// METHODS
|
// METHODS
|
||||||
/// Open the file; call isOpen() to see if errors
|
/// Open the file; call isOpen() to see if errors
|
||||||
void open(const char* filenamep) VL_MT_UNSAFE_ONE;
|
void open(const char* filenamep) VL_MT_UNSAFE_ONE;
|
||||||
/// Open the file; call isOpen() to see if errors
|
/// Open the file; call isOpen() to see if errors
|
||||||
void open(const std::string& filename) VL_MT_UNSAFE_ONE { open(filename.c_str()); }
|
void open(const std::string& filename) VL_MT_UNSAFE_ONE { open(filename.c_str()); }
|
||||||
/// Flush and close the file
|
/// Flush and close the file
|
||||||
virtual void close() override VL_MT_UNSAFE_ONE;
|
void close() override VL_MT_UNSAFE_ONE;
|
||||||
/// Flush data to file
|
/// Flush data to file
|
||||||
virtual void flush() override VL_MT_UNSAFE_ONE;
|
void flush() override VL_MT_UNSAFE_ONE;
|
||||||
};
|
};
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
@@ -221,7 +222,7 @@ public:
|
|||||||
/// Construct new object
|
/// Construct new object
|
||||||
VerilatedRestore() = default;
|
VerilatedRestore() = default;
|
||||||
/// Flush, close and destruct
|
/// Flush, close and destruct
|
||||||
virtual ~VerilatedRestore() override { close(); }
|
~VerilatedRestore() override { close(); }
|
||||||
|
|
||||||
// METHODS
|
// METHODS
|
||||||
/// Open the file; call isOpen() to see if errors
|
/// Open the file; call isOpen() to see if errors
|
||||||
@@ -229,35 +230,35 @@ public:
|
|||||||
/// Open the file; call isOpen() to see if errors
|
/// Open the file; call isOpen() to see if errors
|
||||||
void open(const std::string& filename) VL_MT_UNSAFE_ONE { open(filename.c_str()); }
|
void open(const std::string& filename) VL_MT_UNSAFE_ONE { open(filename.c_str()); }
|
||||||
/// Close the file
|
/// Close the file
|
||||||
virtual void close() override VL_MT_UNSAFE_ONE;
|
void close() override VL_MT_UNSAFE_ONE;
|
||||||
virtual void flush() override VL_MT_UNSAFE_ONE {}
|
void flush() override VL_MT_UNSAFE_ONE {}
|
||||||
virtual void fill() override VL_MT_UNSAFE_ONE;
|
void fill() override VL_MT_UNSAFE_ONE;
|
||||||
};
|
};
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, const vluint64_t& rhs) {
|
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, const uint64_t& rhs) {
|
||||||
return os.write(&rhs, sizeof(rhs));
|
return os.write(&rhs, sizeof(rhs));
|
||||||
}
|
}
|
||||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint64_t& rhs) {
|
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, uint64_t& rhs) {
|
||||||
return os.read(&rhs, sizeof(rhs));
|
return os.read(&rhs, sizeof(rhs));
|
||||||
}
|
}
|
||||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, const vluint32_t& rhs) {
|
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, const uint32_t& rhs) {
|
||||||
return os.write(&rhs, sizeof(rhs));
|
return os.write(&rhs, sizeof(rhs));
|
||||||
}
|
}
|
||||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint32_t& rhs) {
|
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, uint32_t& rhs) {
|
||||||
return os.read(&rhs, sizeof(rhs));
|
return os.read(&rhs, sizeof(rhs));
|
||||||
}
|
}
|
||||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, const vluint16_t& rhs) {
|
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, const uint16_t& rhs) {
|
||||||
return os.write(&rhs, sizeof(rhs));
|
return os.write(&rhs, sizeof(rhs));
|
||||||
}
|
}
|
||||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint16_t& rhs) {
|
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, uint16_t& rhs) {
|
||||||
return os.read(&rhs, sizeof(rhs));
|
return os.read(&rhs, sizeof(rhs));
|
||||||
}
|
}
|
||||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, const vluint8_t& rhs) {
|
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, const uint8_t& rhs) {
|
||||||
return os.write(&rhs, sizeof(rhs));
|
return os.write(&rhs, sizeof(rhs));
|
||||||
}
|
}
|
||||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint8_t& rhs) {
|
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, uint8_t& rhs) {
|
||||||
return os.read(&rhs, sizeof(rhs));
|
return os.read(&rhs, sizeof(rhs));
|
||||||
}
|
}
|
||||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, const bool& rhs) {
|
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, const bool& rhs) {
|
||||||
@@ -279,15 +280,16 @@ inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, float& rhs) {
|
|||||||
return os.read(&rhs, sizeof(rhs));
|
return os.read(&rhs, sizeof(rhs));
|
||||||
}
|
}
|
||||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, const std::string& rhs) {
|
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, const std::string& rhs) {
|
||||||
const vluint32_t len = rhs.length();
|
const uint32_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;
|
uint32_t len = 0;
|
||||||
os >> len;
|
os >> len;
|
||||||
rhs.resize(len);
|
rhs.resize(len);
|
||||||
return os.read((void*)rhs.data(), len);
|
// C cast is required below
|
||||||
|
return os.read((void*)(rhs.data()), len);
|
||||||
}
|
}
|
||||||
VerilatedSerialize& operator<<(VerilatedSerialize& os, VerilatedContext* rhsp);
|
VerilatedSerialize& operator<<(VerilatedSerialize& os, VerilatedContext* rhsp);
|
||||||
VerilatedDeserialize& operator>>(VerilatedDeserialize& os, VerilatedContext* rhsp);
|
VerilatedDeserialize& operator>>(VerilatedDeserialize& os, VerilatedContext* rhsp);
|
||||||
@@ -295,7 +297,7 @@ VerilatedDeserialize& operator>>(VerilatedDeserialize& os, VerilatedContext* rhs
|
|||||||
template <class T_Key, class T_Value>
|
template <class T_Key, class T_Value>
|
||||||
VerilatedSerialize& operator<<(VerilatedSerialize& os, VlAssocArray<T_Key, T_Value>& rhs) {
|
VerilatedSerialize& operator<<(VerilatedSerialize& os, VlAssocArray<T_Key, T_Value>& rhs) {
|
||||||
os << rhs.atDefault();
|
os << rhs.atDefault();
|
||||||
const vluint32_t len = rhs.size();
|
const uint32_t len = rhs.size();
|
||||||
os << len;
|
os << len;
|
||||||
for (const auto& i : rhs) {
|
for (const auto& i : rhs) {
|
||||||
const T_Key index = i.first; // Copy to get around const_iterator
|
const T_Key index = i.first; // Copy to get around const_iterator
|
||||||
@@ -307,10 +309,10 @@ VerilatedSerialize& operator<<(VerilatedSerialize& os, VlAssocArray<T_Key, T_Val
|
|||||||
template <class T_Key, class T_Value>
|
template <class T_Key, class T_Value>
|
||||||
VerilatedDeserialize& operator>>(VerilatedDeserialize& os, VlAssocArray<T_Key, T_Value>& rhs) {
|
VerilatedDeserialize& operator>>(VerilatedDeserialize& os, VlAssocArray<T_Key, T_Value>& rhs) {
|
||||||
os >> rhs.atDefault();
|
os >> rhs.atDefault();
|
||||||
vluint32_t len = 0;
|
uint32_t len = 0;
|
||||||
os >> len;
|
os >> len;
|
||||||
rhs.clear();
|
rhs.clear();
|
||||||
for (vluint32_t i = 0; i < len; ++i) {
|
for (uint32_t i = 0; i < len; ++i) {
|
||||||
T_Key index;
|
T_Key index;
|
||||||
T_Value value;
|
T_Value value;
|
||||||
os >> index;
|
os >> index;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2009-2021 by Wilson Snyder. This program is free software; you can
|
// Copyright 2009-2022 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -39,10 +39,10 @@
|
|||||||
// This class is thread safe (though most of SystemC is not).
|
// This class is thread safe (though most of SystemC is not).
|
||||||
class VlScBvExposer final : public sc_bv_base {
|
class VlScBvExposer final : public sc_bv_base {
|
||||||
public:
|
public:
|
||||||
static const vluint32_t* sp_datap(const sc_bv_base& base) VL_MT_SAFE {
|
static const uint32_t* sp_datap(const sc_bv_base& base) VL_MT_SAFE {
|
||||||
return static_cast<const VlScBvExposer*>(&base)->sp_datatp();
|
return static_cast<const VlScBvExposer*>(&base)->sp_datatp();
|
||||||
}
|
}
|
||||||
const vluint32_t* sp_datatp() const { return reinterpret_cast<vluint32_t*>(m_data); }
|
const uint32_t* sp_datatp() const { return reinterpret_cast<uint32_t*>(m_data); }
|
||||||
// Above reads this protected element in sc_bv_base:
|
// Above reads this protected element in sc_bv_base:
|
||||||
// sc_digit* m_data; // data array
|
// sc_digit* m_data; // data array
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -69,9 +69,9 @@ public:
|
|||||||
|
|
||||||
class VerilatedVarProps VL_NOT_FINAL {
|
class VerilatedVarProps VL_NOT_FINAL {
|
||||||
// TYPES
|
// TYPES
|
||||||
static constexpr vluint32_t MAGIC = 0xddc4f829UL;
|
static constexpr uint32_t MAGIC = 0xddc4f829UL;
|
||||||
// MEMBERS
|
// MEMBERS
|
||||||
const vluint32_t m_magic; // Magic number
|
const uint32_t m_magic; // Magic number
|
||||||
const VerilatedVarType m_vltype; // Data type
|
const VerilatedVarType m_vltype; // Data type
|
||||||
const VerilatedVarFlags m_vlflags; // Direction
|
const VerilatedVarFlags m_vlflags; // Direction
|
||||||
const int m_pdims; // Packed dimensions, 0 = none
|
const int m_pdims; // Packed dimensions, 0 = none
|
||||||
@@ -134,7 +134,6 @@ public:
|
|||||||
initUnpacked(ulims);
|
initUnpacked(ulims);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
|
||||||
~VerilatedVarProps() = default;
|
~VerilatedVarProps() = default;
|
||||||
// METHODS
|
// METHODS
|
||||||
bool magicOk() const { return m_magic == MAGIC; }
|
bool magicOk() const { return m_magic == MAGIC; }
|
||||||
@@ -142,7 +141,7 @@ public:
|
|||||||
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);
|
||||||
}
|
}
|
||||||
vluint32_t entSize() const;
|
uint32_t entSize() const;
|
||||||
bool isPublicRW() const { return ((m_vlflags & VLVF_PUB_RW) != 0); }
|
bool isPublicRW() const { return ((m_vlflags & VLVF_PUB_RW) != 0); }
|
||||||
// DPI compatible C standard layout
|
// DPI compatible C standard layout
|
||||||
bool isDpiCLayout() const { return ((m_vlflags & VLVF_DPI_CLAY) != 0); }
|
bool isDpiCLayout() const { return ((m_vlflags & VLVF_DPI_CLAY) != 0); }
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
|
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -30,6 +30,7 @@
|
|||||||
#define VERILATOR_VERILATED_SYMS_H_
|
#define VERILATOR_VERILATED_SYMS_H_
|
||||||
|
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
|
|
||||||
#include "verilated.h"
|
#include "verilated.h"
|
||||||
#include "verilated_sym_props.h"
|
#include "verilated_sym_props.h"
|
||||||
|
|
||||||
|
|||||||
+44
-158
@@ -3,7 +3,7 @@
|
|||||||
//
|
//
|
||||||
// Code available from: https://verilator.org
|
// Code available from: https://verilator.org
|
||||||
//
|
//
|
||||||
// Copyright 2012-2021 by Wilson Snyder. This program is free software; you can
|
// Copyright 2012-2022 by Wilson Snyder. This program is free software; you can
|
||||||
// redistribute it and/or modify it under the terms of either the GNU
|
// redistribute it and/or modify it under the terms of either the GNU
|
||||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
// Version 2.0.
|
// Version 2.0.
|
||||||
@@ -22,24 +22,24 @@
|
|||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
#include "verilatedos.h"
|
#include "verilatedos.h"
|
||||||
|
|
||||||
#include "verilated_threads.h"
|
#include "verilated_threads.h"
|
||||||
|
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <fstream>
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// Globals
|
// Globals
|
||||||
|
|
||||||
// Internal note: Globals may multi-construct, see verilated.cpp top.
|
// Internal note: Globals may multi-construct, see verilated.cpp top.
|
||||||
|
|
||||||
std::atomic<vluint64_t> VlMTaskVertex::s_yields;
|
std::atomic<uint64_t> VlMTaskVertex::s_yields;
|
||||||
|
|
||||||
VL_THREAD_LOCAL VlThreadPool::ProfileTrace* VlThreadPool::t_profilep = nullptr;
|
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// VlMTaskVertex
|
// VlMTaskVertex
|
||||||
|
|
||||||
VlMTaskVertex::VlMTaskVertex(vluint32_t upstreamDepCount)
|
VlMTaskVertex::VlMTaskVertex(uint32_t upstreamDepCount)
|
||||||
: m_upstreamDepsDone{0}
|
: m_upstreamDepsDone{0}
|
||||||
, m_upstreamDepCount{upstreamDepCount} {
|
, m_upstreamDepCount{upstreamDepCount} {
|
||||||
assert(atomic_is_lock_free(&m_upstreamDepsDone));
|
assert(atomic_is_lock_free(&m_upstreamDepsDone));
|
||||||
@@ -48,176 +48,62 @@ VlMTaskVertex::VlMTaskVertex(vluint32_t upstreamDepCount)
|
|||||||
//=============================================================================
|
//=============================================================================
|
||||||
// VlWorkerThread
|
// VlWorkerThread
|
||||||
|
|
||||||
VlWorkerThread::VlWorkerThread(VlThreadPool* poolp, VerilatedContext* contextp, bool profiling)
|
VlWorkerThread::VlWorkerThread(VerilatedContext* contextp)
|
||||||
: m_ready_size{0}
|
: m_ready_size{0}
|
||||||
, m_poolp{poolp}
|
, m_cthread{startWorker, this, contextp} {}
|
||||||
, m_profiling{profiling} // Must init this last -- after setting up fields that it might read:
|
|
||||||
, m_exiting{false}
|
|
||||||
, m_cthread{startWorker, this}
|
|
||||||
, m_contextp{contextp} {}
|
|
||||||
|
|
||||||
VlWorkerThread::~VlWorkerThread() {
|
VlWorkerThread::~VlWorkerThread() {
|
||||||
m_exiting.store(true, std::memory_order_release);
|
shutdown();
|
||||||
wakeUp();
|
|
||||||
// The thread should exit; join it.
|
// The thread should exit; join it.
|
||||||
m_cthread.join();
|
m_cthread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VlWorkerThread::workerLoop() {
|
static void shutdownTask(void*, bool) {
|
||||||
if (VL_UNLIKELY(m_profiling)) m_poolp->setupProfilingClientThread();
|
// Deliberately empty, we use the address of this function as a magic number
|
||||||
|
|
||||||
ExecRec work;
|
|
||||||
work.m_fnp = nullptr;
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (VL_LIKELY(!work.m_fnp)) dequeWork(&work);
|
|
||||||
|
|
||||||
// Do this here, not above, to avoid a race with the destructor.
|
|
||||||
if (VL_UNLIKELY(m_exiting.load(std::memory_order_acquire))) break;
|
|
||||||
|
|
||||||
if (VL_LIKELY(work.m_fnp)) {
|
|
||||||
work.m_fnp(work.m_selfp, work.m_evenCycle);
|
|
||||||
work.m_fnp = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (VL_UNLIKELY(m_profiling)) m_poolp->tearDownProfilingClientThread();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VlWorkerThread::startWorker(VlWorkerThread* workerp) {
|
void VlWorkerThread::shutdown() { addTask(shutdownTask, nullptr); }
|
||||||
Verilated::threadContextp(workerp->m_contextp);
|
|
||||||
|
void VlWorkerThread::wait() {
|
||||||
|
// Enqueue a task that sets this flag. Execution is in-order so this ensures completion.
|
||||||
|
std::atomic<bool> flag{false};
|
||||||
|
addTask([](void* flagp, bool) { static_cast<std::atomic<bool>*>(flagp)->store(true); }, &flag);
|
||||||
|
// Spin wait
|
||||||
|
for (unsigned i = 0; i < VL_LOCK_SPINS; ++i) {
|
||||||
|
if (flag.load()) return;
|
||||||
|
VL_CPU_RELAX();
|
||||||
|
}
|
||||||
|
// Yield wait
|
||||||
|
while (!flag.load()) std::this_thread::yield();
|
||||||
|
}
|
||||||
|
|
||||||
|
void VlWorkerThread::workerLoop() {
|
||||||
|
ExecRec work;
|
||||||
|
|
||||||
|
// Wait for the first task without spinning, in case the thread is never actually used.
|
||||||
|
dequeWork</* SpinWait: */ false>(&work);
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
if (VL_UNLIKELY(work.m_fnp == shutdownTask)) break;
|
||||||
|
work.m_fnp(work.m_selfp, work.m_evenCycle);
|
||||||
|
// Wait for next task with spinning.
|
||||||
|
dequeWork</* SpinWait: */ true>(&work);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void VlWorkerThread::startWorker(VlWorkerThread* workerp, VerilatedContext* contextp) {
|
||||||
|
Verilated::threadContextp(contextp);
|
||||||
workerp->workerLoop();
|
workerp->workerLoop();
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// VlThreadPool
|
// VlThreadPool
|
||||||
|
|
||||||
VlThreadPool::VlThreadPool(VerilatedContext* contextp, int nThreads, bool profiling)
|
VlThreadPool::VlThreadPool(VerilatedContext* contextp, unsigned nThreads) {
|
||||||
: m_profiling{profiling} {
|
for (unsigned i = 0; i < nThreads; ++i) m_workers.push_back(new VlWorkerThread{contextp});
|
||||||
// --threads N passes nThreads=N-1, as the "main" threads counts as 1
|
|
||||||
const unsigned cpus = std::thread::hardware_concurrency();
|
|
||||||
if (cpus < nThreads + 1) {
|
|
||||||
static int warnedOnce = 0;
|
|
||||||
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
|
|
||||||
for (int i = 0; i < nThreads; ++i) {
|
|
||||||
m_workers.push_back(new VlWorkerThread{this, contextp, profiling});
|
|
||||||
}
|
|
||||||
// Set up a profile buffer for the current thread too -- on the
|
|
||||||
// assumption that it's the same thread that calls eval and may be
|
|
||||||
// donated to run mtasks during the eval.
|
|
||||||
if (VL_UNLIKELY(m_profiling)) setupProfilingClientThread();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VlThreadPool::~VlThreadPool() {
|
VlThreadPool::~VlThreadPool() {
|
||||||
// Each ~WorkerThread will wait for its thread to exit.
|
// Each ~WorkerThread will wait for its thread to exit.
|
||||||
for (auto& i : m_workers) delete i;
|
for (auto& i : m_workers) delete i;
|
||||||
if (VL_UNLIKELY(m_profiling)) tearDownProfilingClientThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
void VlThreadPool::tearDownProfilingClientThread() {
|
|
||||||
assert(t_profilep);
|
|
||||||
delete t_profilep;
|
|
||||||
t_profilep = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VlThreadPool::setupProfilingClientThread() VL_MT_SAFE_EXCLUDES(m_mutex) {
|
|
||||||
assert(!t_profilep);
|
|
||||||
t_profilep = new ProfileTrace;
|
|
||||||
// Reserve some space in the thread-local profiling buffer;
|
|
||||||
// try not to malloc while collecting profiling.
|
|
||||||
t_profilep->reserve(4096);
|
|
||||||
{
|
|
||||||
const VerilatedLockGuard lock{m_mutex};
|
|
||||||
m_allProfiles.insert(t_profilep);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VlThreadPool::profileAppendAll(const VlProfileRec& rec) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
|
||||||
const VerilatedLockGuard lock{m_mutex};
|
|
||||||
for (const auto& profilep : m_allProfiles) {
|
|
||||||
// Every thread's profile trace gets a copy of rec.
|
|
||||||
profilep->emplace_back(rec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void VlThreadPool::profileDump(const char* filenamep, vluint64_t tickStart, vluint64_t tickEnd)
|
|
||||||
VL_MT_SAFE_EXCLUDES(m_mutex) {
|
|
||||||
const VerilatedLockGuard lock{m_mutex};
|
|
||||||
VL_DEBUG_IF(VL_DBG_MSGF("+prof+threads writing to '%s'\n", filenamep););
|
|
||||||
|
|
||||||
FILE* const fp = std::fopen(filenamep, "w");
|
|
||||||
if (VL_UNLIKELY(!fp)) {
|
|
||||||
VL_FATAL_MT(filenamep, 0, "", "+prof+threads+file file not writable");
|
|
||||||
// cppcheck-suppress resourceLeak // bug, doesn't realize fp is nullptr
|
|
||||||
return; // LCOV_EXCL_LINE
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Perhaps merge with verilated_coverage output format, so can
|
|
||||||
// have a common merging and reporting tool, etc.
|
|
||||||
fprintf(fp, "VLPROFTHREAD 1.1 # Verilator thread profile dump version 1.1\n");
|
|
||||||
fprintf(fp, "VLPROF arg --threads %" VL_PRI64 "u\n", vluint64_t(m_workers.size() + 1));
|
|
||||||
fprintf(fp, "VLPROF arg +verilator+prof+threads+start+%" VL_PRI64 "u\n",
|
|
||||||
Verilated::threadContextp()->profThreadsStart());
|
|
||||||
fprintf(fp, "VLPROF arg +verilator+prof+threads+window+%u\n",
|
|
||||||
Verilated::threadContextp()->profThreadsWindow());
|
|
||||||
fprintf(fp, "VLPROF stat yields %" VL_PRI64 "u\n", VlMTaskVertex::yields());
|
|
||||||
|
|
||||||
// Copy /proc/cpuinfo into this output so verilator_gantt can be run on
|
|
||||||
// a different machine
|
|
||||||
{
|
|
||||||
const std::unique_ptr<std::ifstream> ifp{new std::ifstream("/proc/cpuinfo")};
|
|
||||||
if (!ifp->fail()) {
|
|
||||||
std::string line;
|
|
||||||
while (std::getline(*ifp, line)) { fprintf(fp, "VLPROFPROC %s\n", line.c_str()); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vluint32_t thread_id = 0;
|
|
||||||
for (const auto& pi : m_allProfiles) {
|
|
||||||
++thread_id;
|
|
||||||
|
|
||||||
bool printing = false; // False while in warmup phase
|
|
||||||
for (const auto& ei : *pi) {
|
|
||||||
switch (ei.m_type) {
|
|
||||||
case VlProfileRec::TYPE_BARRIER: //
|
|
||||||
printing = true;
|
|
||||||
break;
|
|
||||||
case VlProfileRec::TYPE_EVAL:
|
|
||||||
if (!printing) break;
|
|
||||||
fprintf(fp,
|
|
||||||
"VLPROF eval start %" VL_PRI64 "u elapsed %" VL_PRI64 "u"
|
|
||||||
" cpu %u on thread %u\n",
|
|
||||||
ei.m_startTime - tickStart, (ei.m_endTime - ei.m_startTime), ei.m_cpu,
|
|
||||||
thread_id);
|
|
||||||
break;
|
|
||||||
case VlProfileRec::TYPE_EVAL_LOOP:
|
|
||||||
if (!printing) break;
|
|
||||||
fprintf(fp,
|
|
||||||
"VLPROF eval_loop start %" VL_PRI64 "u elapsed %" VL_PRI64 "u"
|
|
||||||
" cpu %u on thread %u\n",
|
|
||||||
ei.m_startTime - tickStart, (ei.m_endTime - ei.m_startTime), ei.m_cpu,
|
|
||||||
thread_id);
|
|
||||||
break;
|
|
||||||
case VlProfileRec::TYPE_MTASK_RUN:
|
|
||||||
if (!printing) break;
|
|
||||||
fprintf(fp,
|
|
||||||
"VLPROF mtask %d"
|
|
||||||
" start %" VL_PRI64 "u elapsed %" VL_PRI64 "u"
|
|
||||||
" predict_start %u predict_cost %u cpu %u on thread %u\n",
|
|
||||||
ei.m_mtaskId, ei.m_startTime - tickStart, (ei.m_endTime - ei.m_startTime),
|
|
||||||
ei.m_predictStart, ei.m_predictCost, ei.m_cpu, thread_id);
|
|
||||||
break;
|
|
||||||
default: assert(false); break; // LCOV_EXCL_LINE
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf(fp, "VLPROF stat ticks %" VL_PRI64 "u\n", tickEnd - tickStart);
|
|
||||||
|
|
||||||
std::fclose(fp);
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user