mirror of
https://github.com/verilator/verilator.git
synced 2026-10-05 09:33:41 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ca45df9c7 | ||
|
|
8db9c1d227 | ||
|
|
930f35acc9 | ||
|
|
13e0fc7c27 | ||
|
|
a730daabef | ||
|
|
3c28b72897 | ||
|
|
05e5f1955e | ||
|
|
378800ee4a | ||
|
|
43a57da950 | ||
|
|
99a43b7695 | ||
|
|
59d2eea302 | ||
|
|
6f3f64e63f | ||
|
|
48c71ef76c | ||
|
|
563faeb33f | ||
|
|
9c5c77c69c | ||
|
|
4573e04488 | ||
|
|
6cb0a41857 | ||
|
|
124e3463fc | ||
|
|
1b15509a9c | ||
|
|
eb3f10399a | ||
|
|
4660806c8f | ||
|
|
6f5d1037b4 | ||
|
|
24b097b228 | ||
|
|
a0ea96b355 | ||
|
|
a663da7393 | ||
|
|
c812a9b18f | ||
|
|
367249ec84 | ||
|
|
f4acc59b82 | ||
|
|
d1da1664f0 | ||
|
|
b100615726 | ||
|
|
ec0815e9ac | ||
|
|
97e9996f0b | ||
|
|
b7af859ba3 | ||
|
|
701fa5438a | ||
|
|
004865a8b2 | ||
|
|
3e5859e5da | ||
|
|
78555b683c | ||
|
|
c2e44dbd99 | ||
|
|
18fc3e6089 | ||
|
|
f4f8ea0dcf | ||
|
|
f78c4e8490 | ||
|
|
e6fe367bdb | ||
|
|
3426ee5170 | ||
|
|
a32b8d80f9 | ||
|
|
3b81654c72 | ||
|
|
6abd556f5a | ||
|
|
31c1df638b | ||
|
|
f4cb2c8cf2 | ||
|
|
7d5e19365e | ||
|
|
6fa1ade4e0 | ||
|
|
99c619a4c9 | ||
|
|
37a4002098 | ||
|
|
45ee949cc4 | ||
|
|
54f9f4b6a9 | ||
|
|
a61178bd89 | ||
|
|
2f5c58b345 | ||
|
|
403a197e23 | ||
|
|
3a659d460d | ||
|
|
8707c88787 | ||
|
|
167cba723e | ||
|
|
7f40dd8b5b | ||
|
|
1609c23fea | ||
|
|
216fc8a212 | ||
|
|
5136ea1082 | ||
|
|
5b931faf2b | ||
|
|
a2496e041e | ||
|
|
fab268f772 | ||
|
|
550d47b7f4 | ||
|
|
a01a21db86 | ||
|
|
2082f1aa9e | ||
|
|
50a5a1ff5b | ||
|
|
1600cc01a4 | ||
|
|
b9e1d55262 | ||
|
|
0d43c14b93 | ||
|
|
87d1c10fa7 | ||
|
|
a2506a6f96 | ||
|
|
20dba7464d | ||
|
|
cb5d03ff0b | ||
|
|
2727c33219 | ||
|
|
0419ed0430 | ||
|
|
1e3c7a5496 | ||
|
|
d2dfcbca53 | ||
|
|
e779934443 | ||
|
|
a3b255b054 | ||
|
|
f5caa4b7dc | ||
|
|
8f4490628f | ||
|
|
df566bdf4d | ||
|
|
981d3ce782 | ||
|
|
b7345eb5d5 | ||
|
|
2bd2b9324f | ||
|
|
298faa84ee | ||
|
|
43377ed8b0 | ||
|
|
b18037b7e7 | ||
|
|
095b1ccb67 | ||
|
|
2a30a87580 | ||
|
|
e11bc6beeb | ||
|
|
0a9b31bb30 | ||
|
|
34e37d7bd0 | ||
|
|
164a7a7c5d | ||
|
|
67ea819d82 | ||
|
|
60f9e21d8c | ||
|
|
dc037db1cd | ||
|
|
0658af90f5 | ||
|
|
131623de34 | ||
|
|
74ae879c2f | ||
|
|
8c3b754bac | ||
|
|
e080f5c0cb | ||
|
|
2284cf595d | ||
|
|
b1cc0c54c1 | ||
|
|
4cf017d7fe | ||
|
|
25f5db4b5f | ||
|
|
3cf9606ea9 | ||
|
|
6882f8c55e | ||
|
|
2696a9a5bd | ||
|
|
abb46c9cb2 | ||
|
|
bbb223f217 | ||
|
|
570e1bc35a | ||
|
|
11da07d3b9 | ||
|
|
2cfec0ecc3 | ||
|
|
e3e7b3f2b5 | ||
|
|
fe0b210a0c | ||
|
|
c383f4868f | ||
|
|
b66fdd7421 | ||
|
|
83878325a7 | ||
|
|
490bc63eb5 | ||
|
|
947b6fd23f | ||
|
|
de44ca8df3 | ||
|
|
3cee54dfdf | ||
|
|
dace2c0a9a | ||
|
|
ca4858eb7f | ||
|
|
a6d438d111 | ||
|
|
955ed3f193 | ||
|
|
8bffb8c391 | ||
|
|
85356f464f | ||
|
|
72993ec3dd | ||
|
|
d6a294b784 | ||
|
|
864a852bca | ||
|
|
b0992406aa | ||
|
|
9e2c8aefc8 | ||
|
|
4c584c17e6 | ||
|
|
3315a6e431 | ||
|
|
ba0183131c | ||
|
|
e1580b9c3d | ||
|
|
aadd5ea509 | ||
|
|
833df6d9ea | ||
|
|
607c19a67d | ||
|
|
d5cfe1a379 | ||
|
|
6e557791c8 | ||
|
|
cd693ce02b | ||
|
|
2641bc98aa | ||
|
|
ad2862ce3f | ||
|
|
4695967185 | ||
|
|
f96e99542c | ||
|
|
7de193c2e9 | ||
|
|
442c9bc316 | ||
|
|
3203019408 | ||
|
|
bc853e260b | ||
|
|
d6e5703298 | ||
|
|
a9e50327fd | ||
|
|
6f0a36318e | ||
|
|
221fecad0b | ||
|
|
fd1e4d9e45 | ||
|
|
920ed5ca3d | ||
|
|
2537431273 | ||
|
|
13114f2efe | ||
|
|
e9f59e44a5 | ||
|
|
d4c3e35f97 | ||
|
|
02dd33b60e | ||
|
|
2bc883f3b3 | ||
|
|
29db25b70e | ||
|
|
d6bc0c712a | ||
|
|
962efa3691 | ||
|
|
4babba16d6 | ||
|
|
5363d89870 | ||
|
|
44acb08ea9 | ||
|
|
6584b4d426 | ||
|
|
9ff06c1664 | ||
|
|
1537c9badc | ||
|
|
708f875b31 | ||
|
|
0d3cb86a44 | ||
|
|
5c2b9d55b2 | ||
|
|
1dbf1be3e6 | ||
|
|
3f886f7c61 | ||
|
|
7c9fa8647c | ||
|
|
dbf68a99e8 | ||
|
|
53c2e416f4 | ||
|
|
e834b5be2d | ||
|
|
bd7689f59a | ||
|
|
3496eb80a5 | ||
|
|
839c3bf444 | ||
|
|
d4b3583307 | ||
|
|
ee130cb20d | ||
|
|
552a146f9c | ||
|
|
913679f261 | ||
|
|
d9078df650 | ||
|
|
f84592af49 | ||
|
|
5f85c89425 | ||
|
|
94f789b677 | ||
|
|
739be2f782 | ||
|
|
25b9a16bc7 | ||
|
|
9a8e68928d | ||
|
|
19cccd170e | ||
|
|
d99c8f5d44 | ||
|
|
cf111d2e1f | ||
|
|
45eb5b8a5c | ||
|
|
ce5cad17a8 | ||
|
|
ed01befc25 | ||
|
|
69a2bfee68 | ||
|
|
1cc37ad6ce | ||
|
|
2a9f29912c | ||
|
|
298e0f24d1 | ||
|
|
80b08b71aa | ||
|
|
64ba569f0d | ||
|
|
3cb4033c97 | ||
|
|
6509bac59e | ||
|
|
ec45a77d93 | ||
|
|
8044833c74 | ||
|
|
3f89bdcfac | ||
|
|
c99364b81a | ||
|
|
d841a791e6 | ||
|
|
b5b937e2f2 | ||
|
|
4a41f69293 | ||
|
|
8fd038f88e | ||
|
|
4982f63da2 | ||
|
|
71bc60fb91 | ||
|
|
0da7ecf753 | ||
|
|
25ca1af8b3 | ||
|
|
5d54fa8e6f | ||
|
|
e8c5b9faad | ||
|
|
8e0301c287 | ||
|
|
3f625fc359 | ||
|
|
72b96d5069 | ||
|
|
d1b45b8d32 | ||
|
|
5601056ed0 | ||
|
|
8ed269c77f | ||
|
|
27b7e70218 | ||
|
|
97680656d3 | ||
|
|
4202ec2ab2 | ||
|
|
4f3a816fb0 | ||
|
|
25fd8ef5c0 | ||
|
|
a9664b8d16 | ||
|
|
26a5729514 | ||
|
|
5b839699ac | ||
|
|
1315aa31ed | ||
|
|
5d8da6b4ac | ||
|
|
aac2563a07 | ||
|
|
8e44487354 | ||
|
|
1012c054e6 | ||
|
|
a8b5738b44 | ||
|
|
72845167e6 | ||
|
|
7ca2d6470a | ||
|
|
33e999e01a | ||
|
|
522bead374 | ||
|
|
030286142f | ||
|
|
8a4ceb5717 | ||
|
|
63fa6accc4 | ||
|
|
28718f964a | ||
|
|
1d486e3a59 | ||
|
|
9b396f7125 | ||
|
|
e16cbce52e | ||
|
|
840970e8f7 | ||
|
|
e390d6779d | ||
|
|
39ee522f92 | ||
|
|
9526efcf72 | ||
|
|
d397e0d838 | ||
|
|
8301fdc6d3 | ||
|
|
f645382f11 | ||
|
|
1ed5557d2d | ||
|
|
28b9216f8a | ||
|
|
0114cb67ca | ||
|
|
ea8f86dd30 | ||
|
|
0ff77fc352 | ||
|
|
341963e820 | ||
|
|
db60b92613 | ||
|
|
98206a4f04 | ||
|
|
4df9e2e0e5 | ||
|
|
34e4cffb62 | ||
|
|
71d76c993c | ||
|
|
e67bdb4c08 | ||
|
|
23f013f2d7 | ||
|
|
9b729b80e0 | ||
|
|
38ad328956 | ||
|
|
f767f0cfaa | ||
|
|
1c79df8630 | ||
|
|
248573205b | ||
|
|
88831ca21b | ||
|
|
26f15e11c4 | ||
|
|
5c0a7e06dc | ||
|
|
290b313dc0 | ||
|
|
93e5ca3f6d | ||
|
|
6ffff8565f | ||
|
|
494e05b326 | ||
|
|
a24f61403a | ||
|
|
292cc54768 | ||
|
|
e8a9662eb5 | ||
|
|
0262819c20 | ||
|
|
d3b93a1113 | ||
|
|
5f8c06c805 | ||
|
|
a5ad26cd28 | ||
|
|
5802818b9a | ||
|
|
df519ff16e | ||
|
|
bf8a88a0ad | ||
|
|
878204db73 | ||
|
|
08c76b1da6 | ||
|
|
e82c9db6da | ||
|
|
65c3cb4708 | ||
|
|
0cab076b86 | ||
|
|
3a28ed24ea | ||
|
|
71775eae4c | ||
|
|
953249aa43 | ||
|
|
229dbbb100 | ||
|
|
4a439beae5 | ||
|
|
49022c3e73 | ||
|
|
c92ced4ac7 | ||
|
|
ba47da6587 | ||
|
|
2c27f22900 | ||
|
|
c0391990ad | ||
|
|
2247e1e345 | ||
|
|
e4847464d4 | ||
|
|
7694a7bf41 | ||
|
|
a686e547cf | ||
|
|
1481d34959 | ||
|
|
04512e5d04 | ||
|
|
9a3aed57b1 | ||
|
|
5a69321be3 | ||
|
|
5ee938fd1c | ||
|
|
f78783e187 | ||
|
|
11bfe7a7bb | ||
|
|
8ba494c71f | ||
|
|
acb63c929b | ||
|
|
26dd5d4550 | ||
|
|
32f288084a | ||
|
|
6db149c588 | ||
|
|
0fed5f8b3e | ||
|
|
a30930bdcc | ||
|
|
3a1355fb54 | ||
|
|
97db128d66 | ||
|
|
3d57256070 | ||
|
|
5dc8fb5b4f | ||
|
|
3f0d434f82 | ||
|
|
2cdc5ea48b | ||
|
|
745605efe3 | ||
|
|
0fbd4313b2 | ||
|
|
9f8f61ef2f | ||
|
|
4b1f4938b8 | ||
|
|
5f1dc73a1b | ||
|
|
5e1fc6e24d | ||
|
|
0ec32ee404 | ||
|
|
97b21b3849 | ||
|
|
214173c6b8 | ||
|
|
3786f59e03 | ||
|
|
fa7234ff68 | ||
|
|
91dd3c5fac | ||
|
|
a378dbd9b2 | ||
|
|
da9521a351 | ||
|
|
af51107587 | ||
|
|
e60f652a64 | ||
|
|
a4813ec677 | ||
|
|
01dadb0a8d | ||
|
|
9dcb7ea6a9 | ||
|
|
adfe072b89 | ||
|
|
b12f8b3d73 | ||
|
|
f56f318217 | ||
|
|
3af0eb7fa0 | ||
|
|
a69cb9b044 | ||
|
|
b68a696859 | ||
|
|
e320b0b581 | ||
|
|
42041f2403 | ||
|
|
881c6ee655 | ||
|
|
d8b2993974 | ||
|
|
30e711aa5c | ||
|
|
51ae8e13fb | ||
|
|
0892b39ad2 | ||
|
|
5964d5cf63 | ||
|
|
2162a31d3a | ||
|
|
e00e4d4245 | ||
|
|
4b9532fe24 | ||
|
|
c3ff52208a | ||
|
|
cfb73923bd | ||
|
|
a951446f9b | ||
|
|
a187a16e56 | ||
|
|
d1dec38f38 | ||
|
|
65b632a7dd | ||
|
|
ec0787015e | ||
|
|
cbc76a7816 | ||
|
|
d667b73e8d | ||
|
|
248de2be2e | ||
|
|
365537d8e3 | ||
|
|
a23cf1ceea | ||
|
|
be471e9ccc | ||
|
|
d0e7eaafc9 | ||
|
|
13b7cce8be | ||
|
|
efff630763 | ||
|
|
e2e0795538 | ||
|
|
c20634e4f8 | ||
|
|
715dce546f | ||
|
|
07d86bf91d | ||
|
|
fe8c7c5a94 | ||
|
|
7ada5195d8 | ||
|
|
a6ad85244f | ||
|
|
f13f2296de | ||
|
|
b1d901f100 | ||
|
|
8ab576f7e6 | ||
|
|
6f92c9c974 | ||
|
|
7425037db6 | ||
|
|
6ca60429ce | ||
|
|
c702fc944e | ||
|
|
999c9ae21c | ||
|
|
c715cfc254 | ||
|
|
22687a6901 | ||
|
|
eecdf4b0f3 | ||
|
|
e3e5f30ba1 | ||
|
|
ce174743bb | ||
|
|
a84be1844f | ||
|
|
9ccef4180f | ||
|
|
3bf896f7db | ||
|
|
e4a0e5aad6 | ||
|
|
d6f8ccd20b | ||
|
|
94460867d3 | ||
|
|
5b70325e52 | ||
|
|
3aece189ac | ||
|
|
188f0eb4ad | ||
|
|
d4c8a15407 | ||
|
|
354a534d68 | ||
|
|
c8a40e0b52 | ||
|
|
771cb5f60b | ||
|
|
23836ee8d0 | ||
|
|
8a7f36c34b | ||
|
|
31262e81f9 | ||
|
|
3d006afacc | ||
|
|
74ec50f933 | ||
|
|
21e85f87bc | ||
|
|
0b8daf4ae4 | ||
|
|
6c0c88cfc4 | ||
|
|
f0d010d9c5 | ||
|
|
2989e54eaa | ||
|
|
1a2c9ca813 | ||
|
|
e3f3e3399f | ||
|
|
6b8531f0a6 | ||
|
|
50df902b54 | ||
|
|
3a5248a919 | ||
|
|
1a92502788 | ||
|
|
a38fea1f9e | ||
|
|
d595d4c7ac | ||
|
|
a43fd06f85 | ||
|
|
375a121377 | ||
|
|
fef0502d50 | ||
|
|
c30b9d04a8 | ||
|
|
89cfa0737f | ||
|
|
8b03f2d47b | ||
|
|
f80c167d65 | ||
|
|
db3ce29b36 | ||
|
|
6f96c6763d | ||
|
|
372cdf1fc8 | ||
|
|
54922c036a | ||
|
|
2e999a5441 | ||
|
|
5073f208af | ||
|
|
c9d7486d16 | ||
|
|
27d906a6b3 | ||
|
|
21bf2d62d2 | ||
|
|
fcdd8e5da6 | ||
|
|
ab47fc6656 | ||
|
|
5f52c066e5 | ||
|
|
19cb366e5d | ||
|
|
55d1b87b34 | ||
|
|
eec41fd039 | ||
|
|
69043549d6 | ||
|
|
68e4eeb53e | ||
|
|
0ca90257a5 | ||
|
|
7507c5f56c | ||
|
|
acbbb2594a | ||
|
|
5294140753 | ||
|
|
a36a07c297 | ||
|
|
47b129bf07 | ||
|
|
1a0c8f1573 | ||
|
|
2be6f03848 | ||
|
|
4172c0f29e | ||
|
|
ec01008fe3 | ||
|
|
8ea814e4b4 | ||
|
|
0195fe9dfd | ||
|
|
e430ea13f4 | ||
|
|
719954a24a | ||
|
|
3adb31f53b | ||
|
|
3eaed3b6f5 | ||
|
|
22de598456 |
+1
-1
@@ -1,4 +1,4 @@
|
||||
Checks: '*,-hicpp*,-android-cloexec-fopen,-cert-dcl50-cpp,-cert-env33-c,-cert-err34-c,-cert-err58-cpp,-clang-analyzer-core.UndefinedBinaryOperatorResult,-clang-analyzer-security*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-no-malloc,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-special-member-functions,-fuchsia-*,-google-default-arguments,-google-readability-todo,-google-runtime-references,-llvm-header-guard,-llvm-include-order,-misc-string-integer-assignment,-misc-string-literal-with-embedded-nul,-modernize-use-auto,-modernize-use-trailing-return-type,-readability-braces-around-statements,-readability-container-size-empty,-readability-delete-null-pointer,-readability-else-after-return,-readability-implicit-bool-conversion,-readability-named-parameter,-readability-static-accessed-through-instance'
|
||||
Checks: '*,-hicpp*,-android-cloexec-fopen,-cert-dcl50-cpp,-cert-env33-c,-cert-err34-c,-cert-err58-cpp,-clang-analyzer-core.UndefinedBinaryOperatorResult,-clang-analyzer-security*,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-no-malloc,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-special-member-functions,-fuchsia-*,-google-default-arguments,-google-readability-todo,-google-runtime-references,-llvm-header-guard,-llvm-include-order,-misc-string-integer-assignment,-misc-string-literal-with-embedded-nul,-modernize-use-auto,-modernize-use-trailing-return-type,-readability-braces-around-statements,-readability-container-size-empty,-readability-delete-null-pointer,-readability-else-after-return,-readability-implicit-bool-conversion,-readability-named-parameter,-readability-static-accessed-through-instance,-llvmlibc-*,-altera-*'
|
||||
WarningsAsErrors: ''
|
||||
HeaderFilterRegex: ''
|
||||
FormatStyle: none
|
||||
|
||||
@@ -18,3 +18,5 @@ What 'verilator --version' are you using? Did you try it with the git master ve
|
||||
What OS and distribution are you using?
|
||||
|
||||
May we assist you in trying to fix this in Verilator yourself?
|
||||
|
||||
(Please avoid attaching screenshots that show text - you can convert images to text using e.g. https://ocr.space)
|
||||
|
||||
@@ -11,6 +11,8 @@ Thanks for taking the time to report this.
|
||||
|
||||
What would you like added/supported?
|
||||
|
||||
What 'verilator --version' are you using? Did you try it with the git master version?
|
||||
|
||||
Can you attach an example that runs on other simulators? (Must be openly licensed, ideally in test_regress format.)
|
||||
|
||||
May we assist you in trying to fix this in Verilator yourself?
|
||||
|
||||
@@ -8,3 +8,5 @@ assignees: ''
|
||||
---
|
||||
|
||||
How may we help - what is your question?
|
||||
|
||||
(If reporting a bug or requesting a feature please use one of the other issue templates.)
|
||||
|
||||
+32
-47
@@ -17,6 +17,8 @@ env:
|
||||
CCACHE_COMPRESS: 1
|
||||
CCACHE_DIR: ${{ github.workspace }}/.ccache
|
||||
CCACHE_LIMIT_MULTIPLE: 0.95
|
||||
INSTALL_DIR: ${{ github.workspace }}/install
|
||||
RELOC_DIR: ${{ github.workspace }}/relloc
|
||||
|
||||
defaults:
|
||||
run:
|
||||
@@ -37,43 +39,29 @@ jobs:
|
||||
compiler:
|
||||
- { cc: clang, cxx: clang++ }
|
||||
- { cc: gcc, cxx: g++ }
|
||||
# m32 1 is deprecated, not here to speed up regressions
|
||||
m32: [0]
|
||||
exclude:
|
||||
# Build pull requests only with ubuntu-22.04 and without m32
|
||||
# - os: ${{ github.event_name == 'pull_request' && 'ubuntu-18.04' || 'do-not-exclude' }}
|
||||
# - os: ${{ github.event_name == 'pull_request' && 'ubuntu-20.04' || 'do-not-exclude' }}
|
||||
# - m32: ${{ github.event_name == 'pull_request' && 1 || 'do-not-exclude' }}
|
||||
# Build -m32 only on ubuntu-22.04 clang++
|
||||
- {os: ubuntu-18.04, m32: 1}
|
||||
- {os: ubuntu-20.04, m32: 1}
|
||||
- compiler: { cc: gcc, cxx: g++ }
|
||||
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 }}
|
||||
name: Build | ${{ matrix.os }} | ${{ matrix.compiler.cc }} ${{ matrix.m32 && '| -m32' || '' }}
|
||||
name: Build | ${{ matrix.os }} | ${{ matrix.compiler.cc }}
|
||||
env:
|
||||
CI_BUILD_STAGE_NAME: build
|
||||
CI_RUNS_ON: ${{ matrix.os }}
|
||||
CI_M32: ${{ matrix.m32 }}
|
||||
CC: ${{ matrix.compiler.cc }}
|
||||
CXX: ${{ matrix.compiler.cxx }}
|
||||
CACHE_BASE_KEY: build-${{ matrix.os }}-${{ matrix.compiler.cc }}-m32=${{ matrix.m32 }}
|
||||
CACHE_BASE_KEY: build-${{ matrix.os }}-${{ matrix.compiler.cc }}
|
||||
CCACHE_MAXSIZE: 1000M # Per build matrix entry (* 5 = 5000M 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 }}.tar.gz
|
||||
steps:
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: repo
|
||||
|
||||
- name: Cache $CCACHE_DIR
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
CACHE_KEY: ${{ env.CACHE_BASE_KEY }}-ccache
|
||||
with:
|
||||
@@ -93,7 +81,7 @@ jobs:
|
||||
run: tar --posix -c -z -f ${{ env.VERILATOR_ARCHIVE }} repo
|
||||
|
||||
- name: Upload tar archive
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/${{ env.VERILATOR_ARCHIVE }}
|
||||
name: ${{ env.VERILATOR_ARCHIVE }}
|
||||
@@ -108,40 +96,38 @@ jobs:
|
||||
compiler:
|
||||
- { cc: clang, cxx: clang++ }
|
||||
- { cc: gcc, cxx: g++ }
|
||||
m32: [0]
|
||||
suite: [dist-vlt-0, dist-vlt-1, dist-vlt-2, vltmt-0, vltmt-1]
|
||||
exclude:
|
||||
# Build pull requests only with ubuntu-22.04 and without m32
|
||||
# - os: ${{ github.event_name == 'pull_request' && 'ubuntu-18.04' || 'do-not-exclude' }}
|
||||
# - os: ${{ github.event_name == 'pull_request' && 'ubuntu-20.04' || 'do-not-exclude' }}
|
||||
# - m32: ${{ github.event_name == 'pull_request' && 1 || 'do-not-exclude' }}
|
||||
# Build -m32 only on ubuntu-22.04
|
||||
- {os: ubuntu-18.04, m32: 1}
|
||||
- {os: ubuntu-20.04, m32: 1}
|
||||
- compiler: { cc: gcc, cxx: g++ }
|
||||
m32: 1
|
||||
reloc: [0]
|
||||
suite: [dist-vlt-0, dist-vlt-1, dist-vlt-2, dist-vlt-3, vltmt-0, vltmt-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}
|
||||
# Test with GCC 10 on ubuntu-20.04
|
||||
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: dist-vlt-0}
|
||||
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: dist-vlt-1}
|
||||
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: dist-vlt-2}
|
||||
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: dist-vlt-3}
|
||||
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: vltmt-0}
|
||||
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, suite: vltmt-1}
|
||||
# Test relocated installation - on most common platform only
|
||||
- {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: dist-vlt-0}
|
||||
- {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: dist-vlt-1}
|
||||
- {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: dist-vlt-2}
|
||||
- {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: dist-vlt-3}
|
||||
- {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: vltmt-0}
|
||||
- {os: ubuntu-22.04, compiler: { cc: gcc, cxx: g++ }, reloc: 1, suite: vltmt-1}
|
||||
runs-on: ${{ matrix.os }}
|
||||
name: Test | ${{ matrix.os }} | ${{ matrix.compiler.cc }} | ${{ matrix.suite }} ${{ matrix.m32 && '| -m32' || '' }}
|
||||
name: Test | ${{ matrix.os }} | ${{ matrix.compiler.cc }} | ${{ matrix.reloc && 'reloc | ' || '' }} ${{ matrix.suite }}
|
||||
env:
|
||||
CI_BUILD_STAGE_NAME: test
|
||||
CI_RUNS_ON: ${{ matrix.os }}
|
||||
CI_M32: ${{ matrix.m32 }}
|
||||
CI_RELOC: ${{ matrix.reloc }}
|
||||
CC: ${{ matrix.compiler.cc }}
|
||||
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 }}-${{ matrix.reloc }}-${{ matrix.suite }}
|
||||
CCACHE_MAXSIZE: 100M # Per build per suite (* 5 * 5 = 2500M 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 }}.tar.gz
|
||||
steps:
|
||||
|
||||
- name: Download tar archive
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ${{ env.VERILATOR_ARCHIVE }}
|
||||
path: ${{ github.workspace }}
|
||||
@@ -151,9 +137,9 @@ jobs:
|
||||
run: tar -x -z -f ${{ env.VERILATOR_ARCHIVE }}
|
||||
|
||||
- name: Cache $CCACHE_DIR
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
env:
|
||||
CACHE_KEY: ${{ env.CACHE_BASE_KEY }}-ccache
|
||||
CACHE_KEY: ${{ env.CACHE_BASE_KEY }}-ccache2
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: ${{ env.CACHE_KEY }}-${{ github.sha }}
|
||||
@@ -174,10 +160,9 @@ jobs:
|
||||
env:
|
||||
CI_BUILD_STAGE_NAME: build
|
||||
CI_RUNS_ON: ubuntu-22.04
|
||||
CI_M32: 0
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: repo
|
||||
|
||||
|
||||
@@ -13,5 +13,5 @@ jobs:
|
||||
name: "'docs/CONTRIBUTORS' was signed"
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
- run: test_regress/t/t_dist_contributors.pl
|
||||
|
||||
@@ -11,7 +11,6 @@ on:
|
||||
env:
|
||||
CI_OS_NAME: linux
|
||||
CI_COMMIT: ${{ github.sha }}
|
||||
CI_M32: 0
|
||||
COVERAGE: 1
|
||||
VERILATOR_ARCHIVE: verilator-coverage-${{ github.sha }}.tar.gz
|
||||
|
||||
@@ -31,7 +30,7 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
path: repo
|
||||
|
||||
@@ -46,7 +45,7 @@ jobs:
|
||||
run: tar --posix -c -z -f ${{ env.VERILATOR_ARCHIVE }} repo
|
||||
|
||||
- name: Upload tar archive
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/${{ env.VERILATOR_ARCHIVE }}
|
||||
name: ${{ env.VERILATOR_ARCHIVE }}
|
||||
@@ -81,7 +80,7 @@ jobs:
|
||||
steps:
|
||||
|
||||
- name: Download tar archive
|
||||
uses: actions/download-artifact@v3
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: ${{ env.VERILATOR_ARCHIVE }}
|
||||
path: ${{ github.workspace }}
|
||||
@@ -97,3 +96,10 @@ jobs:
|
||||
env:
|
||||
TESTS: coverage-${{ matrix.test }}${{ matrix.num }}
|
||||
run: ./ci/ci-script.bash
|
||||
|
||||
- name: Upload coverage data to Codecov
|
||||
env:
|
||||
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
||||
run: |
|
||||
find . -name '*.gcno' -exec rm {} \;
|
||||
./ci/codecov -v upload-process -Z --sha ${{ github.sha }} -f nodist/obj_dir/coverage/app_total.info
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Extract context variables
|
||||
run: |
|
||||
|
||||
@@ -16,10 +16,9 @@ jobs:
|
||||
CI_OS_NAME: linux
|
||||
CI_RUNS_ON: ubuntu-22.04
|
||||
CI_COMMIT: ${{ github.sha }}
|
||||
CI_M32: 0
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
- name: Install packages for build
|
||||
|
||||
@@ -32,11 +32,11 @@ jobs:
|
||||
name: run on windows
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
path: repo
|
||||
- name: Cache $CCACHE_DIR
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ env.CCACHE_DIR }}
|
||||
key: msbuild-msvc-cmake
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
- name: Zip up repository
|
||||
run: Compress-Archive -LiteralPath install -DestinationPath verilator.zip
|
||||
- name: Upload zip archive
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
path: ${{ github.workspace }}/repo/verilator.zip
|
||||
name: verilator-win.zip
|
||||
|
||||
@@ -44,3 +44,8 @@ verilator-config-version.cmake
|
||||
/.idea/
|
||||
/cmake-build-*/
|
||||
/test_regress/snapshot/
|
||||
xmverilog.*
|
||||
xrun.history
|
||||
|
||||
# Normal CMake build directory
|
||||
/build
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
# See https://citation-file-format.github.io/
|
||||
cff-version: 1.2.0
|
||||
title: Verilator
|
||||
message: >-
|
||||
If you use this software, please cite it using the
|
||||
metadata from this file.
|
||||
type: software
|
||||
authors:
|
||||
- given-names: Wilson
|
||||
family-names: Snyder
|
||||
email: [email protected]
|
||||
affiliation: Veripool
|
||||
- given-names: Paul
|
||||
family-names: Wasson
|
||||
- given-names: Duane
|
||||
family-names: Galbi
|
||||
- name: 'et al'
|
||||
repository-code: 'https://github.com/verilator/verilator'
|
||||
url: 'https://verilator.org'
|
||||
abstract: >-
|
||||
The Verilator package converts Verilog and SystemVerilog hardware
|
||||
description language (HDL) designs into a fast C++ or SystemC model
|
||||
that, after compiling, can be executed. Verilator is not a
|
||||
traditional simulator but a compiler.
|
||||
license:
|
||||
- LGPL-3.0-only
|
||||
- Artistic-2.0
|
||||
+8
-3
@@ -15,7 +15,7 @@
|
||||
cmake_minimum_required(VERSION 3.15)
|
||||
cmake_policy(SET CMP0091 NEW) # Use MSVC_RUNTIME_LIBRARY to select the runtime
|
||||
project(Verilator
|
||||
VERSION 5.020
|
||||
VERSION 5.028
|
||||
HOMEPAGE_URL https://verilator.org
|
||||
LANGUAGES CXX
|
||||
)
|
||||
@@ -24,12 +24,13 @@ option(DEBUG_AND_RELEASE_AND_COVERAGE
|
||||
"Builds both the debug and release binaries, overriding CMAKE_BUILD_TYPE. Not supported under MSBuild.")
|
||||
|
||||
find_package(Python3 COMPONENTS Interpreter)
|
||||
set(PYTHON3 Python3::Interpreter)
|
||||
set(PYTHON3 ${Python3_EXECUTABLE})
|
||||
set(CMAKE_INSTALL_DATADIR ${CMAKE_INSTALL_PREFIX})
|
||||
include(GNUInstallDirs)
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(CheckStructHasMember)
|
||||
include(ExternalProject)
|
||||
include(FindThreads)
|
||||
|
||||
if (NOT WIN32)
|
||||
message(WARNING "CMake support on Linux/OSX is experimental.")
|
||||
@@ -95,10 +96,14 @@ endif()
|
||||
|
||||
set(PACKAGE_NAME ${PROJECT_NAME})
|
||||
set(PACKAGE_VERSION ${PROJECT_VERSION})
|
||||
set(CXX ${CMAKE_CXX_COMPILER})
|
||||
set(AR ${CMAKE_AR})
|
||||
|
||||
configure_file(include/verilated_config.h.in include/verilated_config.h @ONLY)
|
||||
configure_file(include/verilated.mk.in include/verilated.mk @ONLY)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/verilated_config.h DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/verilated.mk DESTINATION ${CMAKE_INSTALL_PREFIX}/include)
|
||||
|
||||
configure_package_config_file(verilator-config.cmake.in verilator-config.cmake
|
||||
INSTALL_DESTINATION ${CMAKE_INSTALL_PREFIX}
|
||||
@@ -118,6 +123,7 @@ foreach (program
|
||||
verilator_ccache_report
|
||||
verilator_difftree
|
||||
verilator_profcfunc
|
||||
verilator_includer
|
||||
)
|
||||
install(PROGRAMS bin/${program} TYPE BIN)
|
||||
endforeach()
|
||||
@@ -130,7 +136,6 @@ install(DIRECTORY examples TYPE DATA FILES_MATCHING
|
||||
|
||||
install(DIRECTORY include TYPE DATA FILES_MATCHING
|
||||
PATTERN "include/verilated_config.h"
|
||||
PATTERN "include/verilated.mk"
|
||||
PATTERN "include/*.[chv]"
|
||||
PATTERN "include/*.cpp"
|
||||
PATTERN "include/*.sv"
|
||||
|
||||
@@ -8,12 +8,273 @@ The changes in each Verilator version are described below. The
|
||||
contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
|
||||
Verilator 5.028 2024-08-21
|
||||
==========================
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Support state-dependent constraints (#5217). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Support cross-module clocking variable access (#5184). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Support inline constraints for class randomization methods (#5234). [Krzysztof Boroński]
|
||||
* Support clocking blocks in virtual interfaces (#5235). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Support `$assertcontrol` assertion_type (#5236). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Support conditional constraints (#5245). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Support`--compiler-include` headers in user-supplied cpp files (#5271). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Support `rand_mode` (#5273). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Support `this.randomize with` (#5282). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Support foreach constraints (#5302). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Support `parameter type` in hierarchical blocks (#5309) (#5333). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Support assertcontrol directive type (#5310). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Support inline random variable control (#5317). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Support streaming operator on arrays and wide data (#5326). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Support streams to/from arrays of wide data (#5334). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Support `constraint_mode` (#5338). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Support constraining AstSel (#5344). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Support default value on module input (#5358) (#5373). [Drew Ranck]
|
||||
* Add `--compiler-include` for additional C++ includes (#5139) (#5202). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Add `--emit-accessors` (#5182) (#5227). [Ryan Ziegler]
|
||||
* Add suggestions on misspelled PLI functions.
|
||||
* Add warning on dist in constraints (#5264). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Add more `rand_mode` unsupported errors (#5329). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Add parsing but otherwise ignore std::randomize (#5354). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Add Verilated cc define when `--timing` used (#5383). [Kaleb Barrett]
|
||||
* Improve emitted code to use a reference for VlSelf (#5254). [Yangyu Chen]
|
||||
* Fix monitor block sensitivity items (#4400) (#5294). [Udaya Raj Subedi]
|
||||
* Fix fusing macro arguments to not ignore whitespace (#5061). [Tudor Timi]
|
||||
* Fix optimized-out sensitivity trees with `--timing` (#5080) (#5349). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix classes/modules of case-similar names (#5109). [Arkadiusz Kozdra]
|
||||
* Fix mis-removing $value$plusargs calls (#5127) (#5137). [Seth Pellegrino]
|
||||
* Fix incorrect result of width mismatch (#5186) (#5189). [Yutetsu TAKATSUKASA]
|
||||
* Fix compiler coroutine check (#5190) (#5300). [Ricardo Barbedo]
|
||||
* Fix shortened module names when searching for files (#5196) (#5246). [Tim Hutt]
|
||||
* Fix `--x-assign` to be independent from `+verilator+rand+reset` (#5214). [Andrew Nolte]
|
||||
* Fix splitting if statements with impure conditions (#5219). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Fix unknown conversion on queues (#5220). [Alex Solomatnikov]
|
||||
* Fix top-level unpacked structure resets (#5221).
|
||||
* Fix concurrency for mailbox and semaphores (#5222). [Liam Braun]
|
||||
* Fix forks capturing non-input ports in tasks (#5237) (#5343). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix toggle coverage aggregation on same line (#5248). [Krzysztof Obłonczek]
|
||||
* Fix error on empty generate with -O0 (#5250).
|
||||
* Fix unconstrained randomization of unpacked structs (#5252). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix inlining of variables driven from forced vars (#5259). [Geza Lore]
|
||||
* Fix tracing with `--main-top-name -` (#5261). [Ethan Sifferman]
|
||||
* Fix randomization when used with inheritance (#5268). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix inline constraints creating class random generator (#5280). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix WIDTHEXPAND on left shift of intuitive amount (#5284). [Greg Taylor]
|
||||
* Fix elaborating foreach loops (#5285). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Fix initializing static array in dynamic arrays and queues (#5287). [Baruch Sterin]
|
||||
* Fix static variable initializers in procedures (#5296). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Fix randomizing current object with `rand` class instance member (#5292). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix handling of rand fields not referenced in constraints (#5305). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix Python3 path discovery in make flows to avoid mixing system and user python interpreters (#5307) [Markus Krause]
|
||||
* Fix make flows to pass PYTHON3 (like PERL) (#5307) (#5308). [Markus Krause]
|
||||
* Fix assert on wide expression (#5319) (#5324). [Varun Koyyalagunta]
|
||||
* Fix output clock variable overwriting signal (#5320) (#5347). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix stringify in nested preprocessor macros (#5323). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix $sformat with array arguments (#5330). [Abe Jordan]
|
||||
* Fix -Wunused-but-set-variable clang warning (#5331). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Fix purity of functions with AstJumpBlock or AstStmtExpr (#5332). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix compilation error on unreachable disable fork / wait fork (#5339). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Fix missing type coercion in 'inside {array}' (#5340). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Fix +: and -: unpacked array slicing when array has nonzero low index (#5345) (#5387). [James Bailey]
|
||||
* Fix tracing_{on,off} in the presence of non-inlined modules (#5346). [Geza Lore]
|
||||
* Fix NBAs in suspendables (#5348). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix lint_off on Errors (#5351) (#5363). [Ethan Sifferman]
|
||||
* Fix cache config file resolution performance (#5369). [Geza Lore]
|
||||
* Fix capturing fields from superclass in `randomize() with` (#5389). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix virtual interface null checks (#5391). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix ==? and !=? with X values.
|
||||
* Fix CPU time being zero.
|
||||
* Fix inline function ref port persistence.
|
||||
|
||||
|
||||
Verilator 5.026 2024-06-15
|
||||
==========================
|
||||
|
||||
**Major:**
|
||||
|
||||
* Support constrained randomization with external solvers (#4947). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Support `$psprintf` system function (#4314) (#5169). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Support 2D dynamic array initialization (#4700) (#5122). [Valentin Atepalikhin]
|
||||
* Support __en/__out signals on top level inout ports (#4812) (#4856). [Paul Wright]
|
||||
* Support empty queue as dynarray default value (#5055). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Support vpiInertialDelay (#5087). [Todd Strader]
|
||||
* Support NBAs to arrays inside loops (#5092). [Geza Lore]
|
||||
* Support parsing and otherwise ignoring inline constraints (#5126). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Support `inout` clocking items (#5160). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Support StructSel in unpacked array assignments (#5176). [Geza Lore]
|
||||
* Add error on zero width select (#5028).
|
||||
* Add CITATION.cff (#5057) (#5058). [Gijs Burghoorn]
|
||||
* Add VPI eval needed tracking (#5065). [Todd Strader]
|
||||
* Add `--localize-max-size` option and optimization (#5072).
|
||||
* Add parameterless assert control system tasks (#5010). [Bartłomiej Chmiel]
|
||||
* Add traceCapable indication to model header (#5053). [Vito Gamberini]
|
||||
* Add increasing of stack size when possible (#5071) (#5104). [Yinan Xu]
|
||||
* Add assertion on reusing VerilatedContext (#5167).
|
||||
* Add `--pins-sc-uint-bool` to force SystemC uint type (#5192). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Improve DFG regularization in cyclic graphs (#5142). [Geza Lore]
|
||||
* Improve VerilatedVpiPutHolder storage requirements (#5144). [Kaleb Barrett]
|
||||
* Fix coroutines without awaits to have a co_return (#4208) (#5175). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Fix missing flex include path variable (#4970) (#4971). [Christopher Taylor]
|
||||
* Fix missing parameters with comma to be errors (#4979) (#5012). [Paul Swirhun]
|
||||
* Fix 'experimental/coroutine' file not found on MacOS (#5030) (#5031) (#5151). [Paul Bowen-Huggett]
|
||||
* Fix bound queue printing (#5032). [Aleksander Kiryk, Antmicro Ltd.]
|
||||
* Fix consecutive zero-delays (#5038). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix attempted to destroy locked thread pool error (#5040). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Fix `$system` with string argument (#5042).
|
||||
* Fix width extension on delays (#5043).
|
||||
* Fix `$typename` on array.min and others (#5049). [Gökçe Aydos]
|
||||
* Fix `make $(info)` which cannot be silenced (#5059). [Gökçe Aydos]
|
||||
* Fix CMake builds to export VERILATOR_ROOT (#5063). [Michael Bikovitsky]
|
||||
* Fix false ASSIGNIN on functions with explicit port map (#5069).
|
||||
* Fix 4-state value support for $readmem (#5070) (#5078). [Ethan Sifferman]
|
||||
* Fix DFG assertion with SystemC (#5076). [Geza Lore]
|
||||
* Fix `$typename` string to be more standard (#5082) (#5083). [Andrew Nolte]
|
||||
* Fix missed optimization in V3Delayed (#5089). [Geza Lore]
|
||||
* Fix macro expansion in strings per 1800-2023 (#5094). [Geza Lore]
|
||||
* Fix width extension of unpacked array select (#5095). [Varun Koyyalagunta]
|
||||
* Fix MacOS missing <type_traits> header (#5096) (#5097). [Vito Gamberini]
|
||||
* Fix assertion failure in V3Gate (#5101). [Yutetsu TAKATSUKASA]
|
||||
* Fix aliases for forced port signals (#5105). [Geza Lore]
|
||||
* Fix tracing interface functions (#5108). [Alex Solomatnikov]
|
||||
* Fix method calls parsing in constraints (#5110). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Fix vpiInertialDelay for memories (#5113). [Todd Strader]
|
||||
* Fix hierarchical compilation with nested -F (#5114) (#5124). [Alex Solomatnikov]
|
||||
* Fix references to ports in forks (#5123). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix output C++ type error on change detect of I/O arrays (#5125) (#5131). [Pawel Jewstafjew]
|
||||
* Fix x-valued parameters with `--x-assign unique` (#5129). [Ethan Sifferman]
|
||||
* Fix overflow of string on VPI reads (#5145) (#5146). [Kaleb Barrett]
|
||||
* Fix VerilatedVpiPutHolder class (#5156). [Kaleb Barrett]
|
||||
* Fix extending out-of-range select (#5159) (#5164). [Geza Lore]
|
||||
* Fix radix in width warnings (#5166). [Geza Lore]
|
||||
* Fix SystemC BITS_PER_DIGIT in VL_ASSIGN_SBW (#5170). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Fix non-constant replication in concats (#5171). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Fix table optimization when applied on real data type (#5172) (#5173). [Arthur Rosa]
|
||||
* Fix signed types emitted in hierarchical Verilation (#5178). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Fix DPI import of null C-string (#5179).
|
||||
* Fix CMake installation missing verilated.mk (#5187) (#5188). [Philip Axer]
|
||||
* Fix linking with pthreads on CMake (#5194). [Tim Hutt]
|
||||
* Fix clang-17 coroutines configuration with -std=gnu++20 (#5200). [Gus Smith]
|
||||
|
||||
|
||||
Verilator 5.024 2024-04-05
|
||||
==========================
|
||||
|
||||
**Major:**
|
||||
|
||||
* Add printing summary reports, use `--quiet` or `+verilator+quiet` to suppress (#4909).
|
||||
* Support 1800-2023 keywords, and parsing with UNDEFINED warnings.
|
||||
* Support 1800-2023 preprocessor ifdef expressions.
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Change 1800-2023 to be default language version.
|
||||
* Add DFG 'regularize' pass, and improve variable removal (#4937). [Geza Lore]
|
||||
* Add error when pass net to function argument (#4132) (#4966). [Fuad Ismail]
|
||||
* Add `UNUSEDLOOP` when unused loop is removed (#4926). [Bartłomiej Chmiel, Antmicro Ltd.]
|
||||
* Add custom version for verilator --version packaging (#4954). [Nolan Poe]
|
||||
* Add error on missing pure virtual functions (#4961).
|
||||
* Add error on calling static function without object (#4962).
|
||||
* Add JSON AST dumps (#5020). [Szymon Gizler]
|
||||
* Support 1800-2023 DPI headers, svGetTime/svgGetTimeUnit/svGetTimePrecision methods.
|
||||
* Support 1800-2023 class and function :initial, :extends, :final virtual overrides (#5025).
|
||||
* Support public packed struct / union (#860) (#4878). [Kefa Chen]
|
||||
* Support stream operation on unpacked array (#4714) (#5006). [Fuad Ismail]
|
||||
* Support implicitly-typed variable definitions in for-loop initializers (#4945) (#4986). [Kevin Nygaard]
|
||||
* Support inside range with implicit type conversion (#5026). [Arkadiusz Kozdra, Antmicro Ltd.]
|
||||
* Improve installation to be relocatable (#4927). [Geza Lore]
|
||||
* Improve internal ordering code (#4957) (#4990) (#4994) et al. [Geza Lore]
|
||||
* Fix generate blocks in vpi_iterate (#3609) (#4913). [Andrew Nolte]
|
||||
* Fix __Vlip undefined error in --freloop (#4824). [Justin Yao Du]
|
||||
* Fix missing VPI scopes (#4918). [Andrew Nolte]
|
||||
* Fix invalid cast on string structure creation (#4921).
|
||||
* Fix try-lock spuriously fails (#4931) (#4938). [Kamil Rakoczy]
|
||||
* Fix V3Unknown unpacked struct x-assign (#4934). [Yan Xu]
|
||||
* Fix DFG removing forceable signals (#4942). [Geza Lore]
|
||||
* Fix null characters in shortened identifiers (#4946). [Abdul Hameed]
|
||||
* Fix assignment of null into struct member (#4952).
|
||||
* Fix VPI missing scopes 2 (#4965). [Andrew Nolte]
|
||||
* Fix object assignment from conditionals (#4968).
|
||||
* Fix GCC14 warnings on template specialization syntax (#4974) (#4975). [Nolan Poe]
|
||||
* Fix unpacked structure upper bit cleaning (#4978).
|
||||
* Fix tests on MacOS (#4984) (#4985). [Kevin Nygaard]
|
||||
* Fix `--prof-exec` predicted time values (#4988). [Geza Lore]
|
||||
* Fix class type as an associative array parameter (#4997).
|
||||
* Fix inout ports of unpacked struct type (#5000). [Ryszard Rozak, Antmicro Ltd.]
|
||||
* Fix `unique {}` constraints missing semicolon (#5001).
|
||||
* Fix preprocessor to respect strings in joins (#5007).
|
||||
* Fix tracing class parameters (#5014).
|
||||
* Fix memory leaks (#5016). [Geza Lore]
|
||||
* Fix $readmem with missing newline (#5019). [Josse Van Delm]
|
||||
* Fix internal error on missing pattern key (#5023).
|
||||
* Fix tracing replicated hierarchical models (#5027).
|
||||
|
||||
|
||||
Verilator 5.022 2024-02-24
|
||||
==========================
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Add predicted stack overflow warning (#4799).
|
||||
* Add `+verilator+coverage+file` runtime option.
|
||||
* Add `--assert-case` option (#4919). [Yutetsu TAKATSUKASA]
|
||||
* Add `--decorations node` for inserting debug comments into emitted code.
|
||||
* Add `--json-only` and related JSON dumping (#4715) (#4831). [Szymon Gizler, Antmicro Ltd.]
|
||||
* Add `--[no]-stop-fail` option for continuing after assertions (#4904). [Yutetsu TAKATSUKASA]
|
||||
* Add `--runtime-debug` for Verilated executable runtime debugging.
|
||||
* Add `--valgrind` switch (#4828). [Szymon Gizler]
|
||||
* Add `unroll_disable` and `unroll_full` loop control metacomments (#3260). [Jiaxun Yang]
|
||||
* Remove deprecated 32-bit pointer mode (`gcc -m32`).
|
||||
* Deprecate --xml-only and XML dumping (#4715) (#4831).
|
||||
* Change zero replication width error to ZEROREPL warning (#4753) (#4762). [Pengcheng Xu]
|
||||
* Improve message for priority case assertion failure (#4905). [Yutetsu TAKATSUKASA]
|
||||
* Support dumping coverage with `--main`.
|
||||
* Support dumping DFG patterns with `--stats` (#4889). [Geza Lore]
|
||||
* Support `vpiConstType` in `vpi_get_str()` (#4797). [Marlon James]
|
||||
* Support SystemC 3.0.0 public review version (#4805) (#4807). [Anthony Donlon]
|
||||
* Support parsing anonymous primitive instantiations (#4809). [Anthony Donlon]
|
||||
* Fix to not emit already waived warnings in waiver output (#4574) (#4818). [Jonathan Schröter]
|
||||
* Fix `this` in member initialization (#4710). [eliasphanna]
|
||||
* Fix localparam elaboration (#3858) (#4794). [Andrew Nolte]
|
||||
* Fix lint_off disables on preprocessor warnings (#4703). [Srinivasan Venkataramanan]
|
||||
* Fix $time not rounding up (#4790) (#4792). [Paul Wright]
|
||||
* Fix `vpi_get()` and `vpi_get64()` to return vpiUndefined on errors (#4795). [Marlon James]
|
||||
* Fix VPI parameter iteration (#4798). [Marlon James]
|
||||
* Fix delays using wrong timeunit when modules inlined (#4806). [Paul Wright]
|
||||
* Fix warnings in verilated_sc_trace.h for Clang. (#4807) (#4827). [Anthony Donlon]
|
||||
* Fix null pointer dereference (#4810) (#4825). [Adrian Sampson]
|
||||
* Fix compilation error on multi-inherited interface class usage (#4819).
|
||||
* Fix maybe-uninitialized compiler warning (#4820) (#4822). [Larry Doolittle]
|
||||
* Fix mis-splitting of dump control functions (#4821). [Fan Shupei]
|
||||
* Fix wrong utimes() parameter (#4829). [Szymon Gizler]
|
||||
* Fix incorrect bit-op-tree NOT optimization (#4832) (#4847). [Yutetsu TAKATSUKASA]
|
||||
* Fix width calculation in replaceShiftOp (#4837) (#4841) (#4849). [Yutetsu TAKATSUKASA]
|
||||
* Fix unsafe write in wide array insertion (#4850) (#4855). [Paul Swirhun]
|
||||
* Fix NOT when checking EQ/NEQ under AND/OR tree (#4857) (#4863). [Yutetsu TAKATSUKASA]
|
||||
* Fix tracing chandles (#4860). [Nathan Graybeal]
|
||||
* Fix $fwrite of null (#4862). [Jose Tejada]
|
||||
* Fix -fno-const-bit-op-tree wrong runtime result (#4864) (#4867). [Yutetsu TAKATSUKASA]
|
||||
* Fix SystemC biguint sign desynchronization (#4870). [Bartłomiej Chmiel]
|
||||
* Fix incorrect temporary insertion in loop conditions with statements (#4873). [Geza Lore]
|
||||
* Fix timing with expr on assign LHS (#4880). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix assertion for unique case (#4892). [Yutetsu TAKATSUKASA]
|
||||
* Fix GCC tautological-compare warnings.
|
||||
* Fix compile error on structs with queues (and ignore toggle coverage on queues).
|
||||
* Fix toggle coverage error on multi-edge driven signals.
|
||||
* Fix whitespace in `pragma protect version` (#4902) (#4914). [Paul Swirhun]
|
||||
* Fix incorrect code generation for change expression on typedefed unpacked array (#4915). [Geza Lore]
|
||||
* Fix inconsistent driver resolution with typedefs (#4917). [Geza Lore]
|
||||
|
||||
|
||||
Verilator 5.020 2024-01-01
|
||||
==========================
|
||||
|
||||
**Major:**
|
||||
|
||||
* Support compilation with precompiled headers with Make and GCC or CLang.
|
||||
* Support compilation with precompiled headers with Make, and GCC or CLang.
|
||||
* Change include to systemc instead of systemc.h (#4622) (#4623). [Chih-Mao Chen]
|
||||
This may require that SystemC programs add 'using namespace sc_core', 'using namespace sc_dt'.
|
||||
|
||||
@@ -71,6 +332,7 @@ Verilator 5.020 2024-01-01
|
||||
* Fix dynamic NBA conditions (#4773). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix `V3Fork` stage to run only if `--timing` is set (#4778). [Krzysztof Bieganski, Antmicro Ltd.]
|
||||
* Fix max multiply width and add runtime assertions if too small. (#4781)
|
||||
* Fix select value too wide (#5148) (#5153). [Dercury]
|
||||
|
||||
|
||||
Verilator 5.018 2023-10-30
|
||||
@@ -271,7 +533,7 @@ Verilator 5.012 2023-06-13
|
||||
* Optimize VPI callValueCbs (#4155). [Hennadii Chernyshchyk]
|
||||
* Configure for faster C++ linking using 'mold', if it is installed.
|
||||
* Fix crash on duplicate imported modules (#3231). [Robert Balas]
|
||||
* Fix false WIDTHEXPAND on array declarations (#3959). [JOTEGO]
|
||||
* Fix false WIDTHEXPAND on array declarations (#3959). [Jose Tejada]
|
||||
* Fix marking overridden methods as coroutines (#4120) (#4169). [Krzysztof Bieganski, Antmicro Ltd]
|
||||
* Fix SystemC signal copy macro use (#4135). [Josep Sans]
|
||||
* Fix duplicate static names in blocks in functions (#4144) (#4160). [Stefan Wallentowitz]
|
||||
@@ -443,7 +705,7 @@ Verilator 5.006 2023-01-22
|
||||
**Minor:**
|
||||
|
||||
* Support clocking blocks (#3674). [Krzysztof Bieganski, Antmicro Ltd]
|
||||
* Support packed structs (#3802). [Aleksander Kiryk, Antmicro Ltd]
|
||||
* Support unpacked structs (#3802). [Aleksander Kiryk, Antmicro Ltd]
|
||||
* Support Windows-native builds using cmake (#3814). [Kritik Bhimani]
|
||||
* Support p format for UnpackArray (#3877). [Aleksander Kiryk, Antmicro Ltd]
|
||||
* Support property calls without parenthesis (#3879) (#3893). [Ryszard Rozak, Antmicro Ltd]
|
||||
@@ -1334,6 +1596,7 @@ Verilator 4.026 2020-01-11
|
||||
* Fix expand optimization slowing --lint-only. Closes #2091. [Thomas Watts]
|
||||
* Fix %{number}s with strings. #2093. [agrobman]
|
||||
* Fix shebang breaking some shells. Closes #2067. [zdave]
|
||||
* Fix errors on using string in incorrect format (#5240). [John Demme]
|
||||
|
||||
|
||||
Verilator 4.024 2019-12-08
|
||||
|
||||
+57
-26
@@ -91,6 +91,7 @@ datarootdir = @datarootdir@
|
||||
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
|
||||
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
|
||||
CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
|
||||
CFG_WITH_SOLVER = @CFG_WITH_SOLVER@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
|
||||
#### End of system configuration section. ####
|
||||
@@ -112,7 +113,7 @@ SUBDIRS = docs src test_regress \
|
||||
examples/make_tracing_c \
|
||||
examples/make_tracing_sc \
|
||||
examples/make_protect_lib \
|
||||
examples/xml_py \
|
||||
examples/json_py \
|
||||
|
||||
INFOS = verilator.html verilator.pdf
|
||||
|
||||
@@ -203,11 +204,21 @@ verilator.html:
|
||||
verilator.pdf: Makefile
|
||||
$(MAKE) -C docs verilator.pdf
|
||||
|
||||
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
|
||||
VL_INST_BIN_FILES = verilator verilator_bin$(EXEEXT) verilator_bin_dbg$(EXEEXT) verilator_coverage_bin_dbg$(EXEEXT) \
|
||||
verilator_ccache_report verilator_coverage verilator_difftree verilator_gantt verilator_includer verilator_profcfunc
|
||||
# Some scripts go into both the search path and pkgdatadir,
|
||||
# so they can be found by the user, and under $VERILATOR_ROOT.
|
||||
# Public executables intended to be invoked directly by the user
|
||||
# Don't put wildcards in these variables, it might cause an uninstall of other stuff
|
||||
VL_INST_PUBLIC_SCRIPT_FILES = verilator \
|
||||
verilator_coverage \
|
||||
verilator_gantt \
|
||||
verilator_profcfunc \
|
||||
|
||||
VL_INST_PUBLIC_BIN_FILES = verilator_bin$(EXEEXT) \
|
||||
verilator_bin_dbg$(EXEEXT) \
|
||||
verilator_coverage_bin_dbg$(EXEEXT) \
|
||||
|
||||
# Private executabels intended to be invoked by internals
|
||||
# Don't put wildcards in these variables, it might cause an uninstall of other stuff
|
||||
VL_INST_PRIVATE_SCRIPT_FILES = verilator_ccache_report \
|
||||
verilator_includer \
|
||||
|
||||
VL_INST_INC_BLDDIR_FILES = \
|
||||
include/verilated_config.h \
|
||||
@@ -226,19 +237,34 @@ VL_INST_DATA_SRCDIR_FILES = \
|
||||
examples/*/Makefile* \
|
||||
examples/*/vl_* \
|
||||
|
||||
installbin:
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(bindir)
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator $(DESTDIR)$(bindir)/verilator )
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_coverage $(DESTDIR)$(bindir)/verilator_coverage )
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_gantt $(DESTDIR)$(bindir)/verilator_gantt )
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_profcfunc $(DESTDIR)$(bindir)/verilator_profcfunc )
|
||||
( cd bin ; $(INSTALL_PROGRAM) verilator_bin$(EXEEXT) $(DESTDIR)$(bindir)/verilator_bin$(EXEEXT) )
|
||||
( cd bin ; $(INSTALL_PROGRAM) verilator_bin_dbg$(EXEEXT) $(DESTDIR)$(bindir)/verilator_bin_dbg$(EXEEXT) )
|
||||
( cd bin ; $(INSTALL_PROGRAM) verilator_coverage_bin_dbg$(EXEEXT) $(DESTDIR)$(bindir)/verilator_coverage_bin_dbg$(EXEEXT) )
|
||||
mkbindirs:
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/bin
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(pkgdatadir)/bin/verilator_includer )
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_ccache_report $(DESTDIR)$(pkgdatadir)/bin/verilator_ccache_report )
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_difftree $(DESTDIR)$(pkgdatadir)/bin/verilator_difftree )
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(bindir)
|
||||
|
||||
installbin: | mkbindirs
|
||||
cd $(srcdir)/bin; \
|
||||
for p in $(VL_INST_PUBLIC_SCRIPT_FILES) ; do \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkgdatadir)/bin/$$p; \
|
||||
done
|
||||
cd bin; \
|
||||
for p in $(VL_INST_PUBLIC_BIN_FILES) ; do \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkgdatadir)/bin/$$p; \
|
||||
done
|
||||
cd $(srcdir)/bin; \
|
||||
for p in $(VL_INST_PRIVATE_SCRIPT_FILES) ; do \
|
||||
$(INSTALL_PROGRAM) $$p $(DESTDIR)$(pkgdatadir)/bin/$$p; \
|
||||
done
|
||||
|
||||
installredirect: installbin | mkbindirs
|
||||
cp ${srcdir}/bin/redirect ${srcdir}/bin/redirect.tmp
|
||||
perl -p -i -e 'use File::Spec;' \
|
||||
-e' $$path = File::Spec->abs2rel("$(realpath $(DESTDIR)$(pkgdatadir)/bin)", "$(realpath $(DESTDIR)$(bindir))");' \
|
||||
-e 's/RELPATH.*/"$$path";/g' -- "${srcdir}/bin/redirect.tmp"
|
||||
cd $(srcdir)/bin; \
|
||||
for p in $(VL_INST_PUBLIC_SCRIPT_FILES) $(VL_INST_PUBLIC_BIN_FILES) ; do \
|
||||
$(INSTALL_PROGRAM) redirect.tmp $(DESTDIR)$(bindir)/$$p; \
|
||||
done
|
||||
rm ${srcdir}/bin/redirect.tmp
|
||||
|
||||
# Man files can either be part of the original kit, or built in current directory
|
||||
# So important we use $^ so VPATH is searched
|
||||
@@ -269,7 +295,7 @@ installdata:
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_c
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_sc
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_protect_lib
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/xml_py
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/json_py
|
||||
cd $(srcdir) \
|
||||
; for p in $(VL_INST_DATA_SRCDIR_FILES) ; do \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
|
||||
@@ -281,8 +307,11 @@ installdata:
|
||||
|
||||
# We don't trust rm -rf, so rmdir instead as it will fail if user put in other files
|
||||
uninstall:
|
||||
-cd $(DESTDIR)$(bindir) && rm -f $(VL_INST_BIN_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir)/bin && rm -f $(VL_INST_BIN_FILES)
|
||||
-cd $(DESTDIR)$(bindir) && rm -f $(VL_INST_PUBLIC_SCRIPT_FILES)
|
||||
-cd $(DESTDIR)$(bindir) && rm -f $(VL_INST_PUBLIC_BIN_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir)/bin && rm -f $(VL_INST_PUBLIC_SCRIPT_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir)/bin && rm -f $(VL_INST_PUBLIC_BIN_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir)/bin && rm -f $(VL_INST_PRIVATE_SCRIPT_FILES)
|
||||
-cd $(DESTDIR)$(mandir)/man1 && rm -f $(VL_INST_MAN_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_BLDDIR_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_SRCDIR_FILES)
|
||||
@@ -305,13 +334,13 @@ uninstall:
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_c
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_sc
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_protect_lib
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/xml_py
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/json_py
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)
|
||||
-rmdir $(DESTDIR)$(pkgconfigdir)
|
||||
|
||||
install: all_nomsg install-all
|
||||
install-all: installbin installman installdata install-msg
|
||||
install-all: installbin installredirect installman installdata install-msg
|
||||
|
||||
install-here: installman info
|
||||
|
||||
@@ -340,7 +369,7 @@ CPPCHECK_FLAGS = --enable=all --inline-suppr \
|
||||
--suppress=useStlAlgorithm
|
||||
CPPCHECK_FLAGS += --xml
|
||||
CPPCHECK_DEP = $(subst .cpp,.cppcheck,$(CHECK_CPP))
|
||||
CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/src/obj_dbg -I$(srcdir)/src
|
||||
CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/include/gtkwave -I$(srcdir)/include/vltstd -I$(srcdir)/src/obj_dbg -I$(srcdir)/src
|
||||
|
||||
cppcheck: cppcheck-1 cppcheck-2 cppcheck-3 cppcheck-4 cppcheck-5 cppcheck-6 cppcheck-7 cppcheck-8
|
||||
cppcheck-1:
|
||||
@@ -399,8 +428,8 @@ PY_PROGRAMS = \
|
||||
bin/verilator_gantt \
|
||||
bin/verilator_includer \
|
||||
bin/verilator_profcfunc \
|
||||
examples/xml_py/vl_file_copy \
|
||||
examples/xml_py/vl_hier_graph \
|
||||
examples/json_py/vl_file_copy \
|
||||
examples/json_py/vl_hier_graph \
|
||||
docs/guide/conf.py \
|
||||
docs/bin/vl_sphinx_extract \
|
||||
docs/bin/vl_sphinx_fix \
|
||||
@@ -410,6 +439,7 @@ PY_PROGRAMS = \
|
||||
src/cppcheck_filtered \
|
||||
src/flexfix \
|
||||
src/vlcovgen \
|
||||
src/.gdbinit.py \
|
||||
test_regress/t/*.pf \
|
||||
nodist/clang_check_attributes \
|
||||
nodist/code_coverage \
|
||||
@@ -417,6 +447,7 @@ PY_PROGRAMS = \
|
||||
nodist/fuzzer/actual_fail \
|
||||
nodist/fuzzer/generate_dictionary \
|
||||
nodist/install_test \
|
||||
nodist/log_changes \
|
||||
|
||||
PY_FILES = \
|
||||
$(PY_PROGRAMS) \
|
||||
|
||||
+18
-17
@@ -1,21 +1,23 @@
|
||||
.. Github doesn't render images unless absolute URL
|
||||
.. Do not know of a conditional tag, "only: github" nor "github display" works
|
||||
|
||||
.. image:: https://img.shields.io/badge/Website-Verilator.org-181717.svg
|
||||
|badge1| |badge2| |badge3| |badge4| |badge5| |badge6| |badge7| |badge8|
|
||||
|
||||
.. |badge1| image:: https://img.shields.io/badge/Website-Verilator.org-181717.svg
|
||||
:target: https://verilator.org
|
||||
.. image:: https://img.shields.io/badge/License-LGPL%20v3-blue.svg
|
||||
.. |badge2| image:: https://img.shields.io/badge/License-LGPL%20v3-blue.svg
|
||||
:target: https://www.gnu.org/licenses/lgpl-3.0
|
||||
.. image:: https://img.shields.io/badge/License-Artistic%202.0-0298c3.svg
|
||||
.. |badge3| image:: https://img.shields.io/badge/License-Artistic%202.0-0298c3.svg
|
||||
:target: https://opensource.org/licenses/Artistic-2.0
|
||||
.. image:: https://repology.org/badge/tiny-repos/verilator.svg?header=distro%20packages
|
||||
.. |badge4| image:: https://repology.org/badge/tiny-repos/verilator.svg?header=distro%20packages
|
||||
:target: https://repology.org/project/verilator/versions
|
||||
.. image:: https://img.shields.io/docker/pulls/verilator/verilator
|
||||
.. |badge5| image:: https://img.shields.io/docker/pulls/verilator/verilator
|
||||
:target: https://hub.docker.com/r/verilator/verilator
|
||||
.. image:: https://api.codacy.com/project/badge/Grade/fa78caa433c84a4ab9049c43e9debc6f
|
||||
.. |badge6| image:: https://api.codacy.com/project/badge/Grade/fa78caa433c84a4ab9049c43e9debc6f
|
||||
:target: https://www.codacy.com/gh/verilator/verilator
|
||||
.. image:: https://codecov.io/gh/verilator/verilator/branch/master/graph/badge.svg
|
||||
.. |badge7| image:: https://codecov.io/gh/verilator/verilator/branch/master/graph/badge.svg
|
||||
:target: https://codecov.io/gh/verilator/verilator
|
||||
.. image:: https://github.com/verilator/verilator/workflows/build/badge.svg
|
||||
.. |badge8| image:: https://github.com/verilator/verilator/workflows/build/badge.svg
|
||||
:target: https://github.com/verilator/verilator/actions?query=workflow%3Abuild
|
||||
|
||||
|
||||
@@ -66,9 +68,9 @@ executable performs the design simulation. Verilator also supports linking
|
||||
Verilated generated libraries, optionally encrypted, into other simulators.
|
||||
|
||||
Verilator may not be the best choice if you are expecting a full-featured
|
||||
replacement for a closed-source Verilog simulator, needs SDF annotation,
|
||||
replacement for a closed-source Verilog simulator, need SDF annotation,
|
||||
mixed-signal simulation, or are doing a quick class project (we recommend
|
||||
`Icarus Verilog`_ for classwork.) However, if you are looking for a path
|
||||
`Icarus Verilog`_ for classwork). However, if you are looking for a path
|
||||
to migrate SystemVerilog to C++/SystemC, or want high-speed simulation of
|
||||
designs, Verilator is the tool for you.
|
||||
|
||||
@@ -80,17 +82,16 @@ Verilator does not directly translate Verilog HDL to C++ or SystemC. Rather,
|
||||
Verilator compiles your code into a much faster optimized and optionally
|
||||
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
|
||||
single-thread over 10x faster than standalone SystemC, and on a single
|
||||
single thread over 10x faster than standalone SystemC, and on a single
|
||||
thread is about 100 times faster than interpreted Verilog simulators such
|
||||
as `Icarus Verilog`_. Another 2-10x speedup might be gained from
|
||||
multithreading (yielding 200-1000x total over interpreted simulators).
|
||||
|
||||
Verilator has typically similar or better performance versus the
|
||||
closed-source Verilog simulators (e.g., Carbon Design Systems Carbonator,
|
||||
Modelsim/Questa, Cadence Incisive/NC-Verilog, Synopsys VCS, VTOC, and
|
||||
Pragmatic CVer/CVC). But, Verilator is open-sourced, so you can spend on
|
||||
computes rather than licenses. Thus, Verilator gives you the best
|
||||
simulation cycles/dollar.
|
||||
Verilator has typically similar or better performance versus closed-source
|
||||
Verilog simulators (e.g., Aldec Riviera-Pro, Cadence Incisive/NC-Verilog,
|
||||
Mentor ModelSim/Questa, Synopsys VCS, VTOC, and Pragmatic CVer/CVC). But,
|
||||
Verilator is open-sourced, so you can spend on computes rather than
|
||||
licenses. Thus, Verilator gives you the best simulation cycles/dollar.
|
||||
|
||||
|
||||
Installation & Documentation
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
#!/usr/bin/env perl
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2003-2024 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
|
||||
#
|
||||
######################################################################
|
||||
|
||||
require 5.006_001;
|
||||
use warnings;
|
||||
use FindBin qw($RealBin $RealScript);
|
||||
use strict;
|
||||
|
||||
my $relpath = RELPATH; # Substituted during Verilator 'make install'
|
||||
|
||||
unshift @ARGV, $RealScript;
|
||||
|
||||
exec { "$RealBin/$relpath/$RealScript" } @ARGV;
|
||||
die "%Error: Exec failed,";
|
||||
+74
-38
@@ -15,6 +15,7 @@ use Getopt::Long;
|
||||
use FindBin qw($RealBin $RealScript);
|
||||
use IO::File;
|
||||
use Pod::Usage;
|
||||
use Cwd qw(realpath);
|
||||
|
||||
use strict;
|
||||
use vars qw($Debug @Opt_Verilator_Sw);
|
||||
@@ -32,6 +33,7 @@ my $opt_rr;
|
||||
my $opt_gdbbt;
|
||||
my $opt_quiet_exit;
|
||||
my $opt_unlimited_stack = 1;
|
||||
my $opt_valgrind;
|
||||
|
||||
# No arguments can't do anything useful. Give help
|
||||
if ($#ARGV < 0) {
|
||||
@@ -56,15 +58,29 @@ if (! GetOptions(
|
||||
# Switches
|
||||
"gdb!" => \$opt_gdb,
|
||||
"gdbbt!" => \$opt_gdbbt,
|
||||
"quiet!" => \$opt_quiet_exit, # As -quiet implies -quiet-exit
|
||||
"quiet-exit!" => \$opt_quiet_exit,
|
||||
"rr!" => \$opt_rr,
|
||||
"unlimited-stack!" => \$opt_unlimited_stack,
|
||||
"valgrind!" => \$opt_valgrind,
|
||||
# Additional parameters
|
||||
"<>" => sub {}, # Ignored
|
||||
)) {
|
||||
pod2usage(-exitstatus => 2, -verbose => 0);
|
||||
}
|
||||
|
||||
my $verilator_root = realpath("$RealBin/..");
|
||||
if (defined $ENV{VERILATOR_ROOT}) {
|
||||
if ((!-d $ENV{VERILATOR_ROOT}) || $verilator_root ne realpath($ENV{VERILATOR_ROOT})) {
|
||||
warn "%Error: verilator: VERILATOR_ROOT is set to inconsistent path. Suggest leaving it unset.\n";
|
||||
warn "%Error: VERILATOR_ROOT=$ENV{VERILATOR_ROOT}\n";
|
||||
exit 1;
|
||||
}
|
||||
} else {
|
||||
print "export VERILATOR_ROOT='$verilator_root'\n" if $Debug;
|
||||
$ENV{VERILATOR_ROOT} = $verilator_root;
|
||||
}
|
||||
|
||||
if ($opt_gdbbt && !gdb_works()) {
|
||||
warn "-Info: --gdbbt ignored: gdb doesn't seem to be working\n" if $Debug;
|
||||
$opt_gdbbt = 0;
|
||||
@@ -109,6 +125,18 @@ if ($opt_gdb) {
|
||||
. " -ex \"run " . join(' ', @quoted_sw)."\""
|
||||
. " -ex 'set width 0'"
|
||||
. " -ex 'bt' -ex 'quit'");
|
||||
} elsif ($opt_valgrind) {
|
||||
# Run under valgrind
|
||||
my $valgrind_bin = ($ENV{VERILATOR_VALGRIND} || "valgrind --error-exitcode=1 --max-stackframe=2815880"
|
||||
# Magic number sugested by valgrind, may need to be increased in future
|
||||
# if you get warnings. See: https://valgrind.org/docs/manual/manual-core.html#opt.max-stackframe
|
||||
);
|
||||
|
||||
run (ulimit_stack_unlimited()
|
||||
. aslr_off()
|
||||
. $valgrind_bin
|
||||
. " " . verilator_bin()
|
||||
. " " . join(' ', @quoted_sw));
|
||||
} elsif ($Debug) {
|
||||
# Debug
|
||||
run(ulimit_stack_unlimited()
|
||||
@@ -137,30 +165,13 @@ sub debug {
|
||||
# Builds
|
||||
|
||||
sub verilator_bin {
|
||||
my $bin = "";
|
||||
# Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
|
||||
my $basename = ($ENV{VERILATOR_BIN}
|
||||
|| ($Debug ? "verilator_bin_dbg" : "verilator_bin"));
|
||||
if (defined($ENV{VERILATOR_ROOT})) {
|
||||
my $dir = $ENV{VERILATOR_ROOT};
|
||||
if (-x "$dir/bin/$basename"
|
||||
|| -x "$dir/bin/$basename.exe") { # From a "make install" into VERILATOR_ROOT
|
||||
$bin = "$dir/bin/$basename";
|
||||
} else {
|
||||
$bin = "$dir/$basename"; # From pointing to kit directory
|
||||
}
|
||||
if (-x "$RealBin/$basename" || -x "$RealBin/$basename.exe") {
|
||||
return "$RealBin/$basename";
|
||||
} else {
|
||||
if (-x "$RealBin/$basename"
|
||||
|| -x "$RealBin/$basename.exe") {
|
||||
$bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
|
||||
} else {
|
||||
$bin = $basename; # Find in PATH
|
||||
}
|
||||
# Note we don't look under bin/$basename which would be right if running
|
||||
# in the kit dir. Running that would likely break, since
|
||||
# VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
|
||||
return $basename; # Find in PATH
|
||||
}
|
||||
return $bin;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
@@ -298,7 +309,9 @@ detailed descriptions of these arguments.
|
||||
+1800-2009ext+<ext> Use SystemVerilog 2009 with file extension <ext>
|
||||
+1800-2012ext+<ext> Use SystemVerilog 2012 with file extension <ext>
|
||||
+1800-2017ext+<ext> Use SystemVerilog 2017 with file extension <ext>
|
||||
+1800-2023ext+<ext> Use SystemVerilog 2023 with file extension <ext>
|
||||
--assert Enable all assertions
|
||||
--assert-case Enable unique/unique0/priority case related checks
|
||||
--autoflush Flush streams after all $displays
|
||||
--bbox-sys Blackbox unknown $system calls
|
||||
--bbox-unsup Blackbox unsupported language features
|
||||
@@ -307,11 +320,11 @@ detailed descriptions of these arguments.
|
||||
--build-dep-bin <filename> Override build dependency Verilator binary
|
||||
--build-jobs <jobs> Parallelism for --build
|
||||
--cc Create C++ output
|
||||
--cdc Clock domain crossing analysis
|
||||
-CFLAGS <flags> C++ compiler arguments for makefile
|
||||
--clk <signal-name> Mark specified signal as clock
|
||||
--no-clk <signal-name> Prevent marking specified signal as clock
|
||||
--compiler <compiler-name> Tune for specified C++ compiler
|
||||
--compiler-include Include additional header in the precompiled one
|
||||
--converge-limit <loops> Tune convergence settle time
|
||||
--coverage Enable all coverage
|
||||
--coverage-line Enable line coverage
|
||||
@@ -325,7 +338,8 @@ detailed descriptions of these arguments.
|
||||
--no-debug-leak Disable leaking memory in --debug mode
|
||||
--debugi <level> Enable debugging at a specified level
|
||||
--debugi-<srcfile> <level> Enable debugging a source file at a level
|
||||
--no-decoration Disable comments and symbol decorations
|
||||
--decorations <level> Set output comment and spacing level
|
||||
--no-decoration Disable comments and lower spacing level
|
||||
--default-language <lang> Default language to parse
|
||||
+define+<var>=<value> Set preprocessor define
|
||||
--dpi-hdr-only Only produce the DPI header file
|
||||
@@ -334,12 +348,16 @@ detailed descriptions of these arguments.
|
||||
--dump-graph Enable dumping V3Graphs to .dot files
|
||||
--dump-tree Enable dumping Ast .tree files
|
||||
--dump-tree-addrids Use short identifiers instead of addresses
|
||||
--dump-tree-dot Enable dumping Ast .tree.dot debug files
|
||||
--dump-tree-json Enable dumping Ast .tree.json files and .tree.meta.json file
|
||||
--dump-<srcfile> Enable dumping everything in source file
|
||||
--dumpi-dfg <level> Enable dumping DfgGraphs to .dot files at level
|
||||
--dumpi-graph <level> Enable dumping V3Graphs to .dot files at level
|
||||
--dumpi-tree <level> Enable dumping Ast .tree files at level
|
||||
--dumpi-tree-json <level> Enable dumping Ast .tree.json files at level
|
||||
--dumpi-<srcfile> <level> Enable dumping everything in source file at level
|
||||
-E Preprocess, but do not compile
|
||||
--emit-accessors Emit getter and setter methods for model top class
|
||||
--error-limit <value> Abort after this number of errors
|
||||
--exe Link to create executable
|
||||
--expand-limit <value> Set expand optimization limit
|
||||
@@ -347,6 +365,8 @@ detailed descriptions of these arguments.
|
||||
-f <file> Parse arguments from a file
|
||||
-FI <file> Force include of a file
|
||||
--flatten Force inlining of all modules, tasks and functions
|
||||
--future0 <option> Ignore an option for compatibility
|
||||
--future1 <option> Ignore an option with argument for compatibility
|
||||
-fno-<optimization> Disable internal optimization stage
|
||||
-G<name>=<value> Overwrite top-level parameter
|
||||
--gate-stmts <value> Tune gate optimizer depth
|
||||
@@ -355,8 +375,9 @@ detailed descriptions of these arguments.
|
||||
--generate-key Create random key for --protect-key
|
||||
--getenv <var> Get environment variable with defaults
|
||||
--get-supported <feature> Get if feature is supported
|
||||
--help Display this help
|
||||
--help Show this help
|
||||
--hierarchical Enable hierarchical Verilation
|
||||
--hierarchical-params-file <name> Internal option that specifies parameters file for hier blocks
|
||||
-I<dir> Directory to search for includes
|
||||
--if-depth <value> Tune IFDEPTH warning
|
||||
+incdir+<dir> Directory to search for includes
|
||||
@@ -369,6 +390,7 @@ detailed descriptions of these arguments.
|
||||
--lib-create <name> Create a DPI library
|
||||
+libext+<ext>+[ext]... Extensions for finding modules
|
||||
--lint-only Lint, but do not make output
|
||||
--localize-max-size <value> Tune localize optimization variable size
|
||||
--make <build-tool> Generate scripts for specified build tool
|
||||
-MAKEFLAGS <flags> Arguments to pass to make during --build
|
||||
--main Generate C++ main() file
|
||||
@@ -383,14 +405,15 @@ detailed descriptions of these arguments.
|
||||
-O3 High-performance optimizations
|
||||
-O<optimization-letter> Selectable optimizations
|
||||
-o <executable> Name of final executable
|
||||
--no-order-clock-delay Disable ordering clock enable assignments
|
||||
--output-split <statements> Split .cpp files into pieces
|
||||
--output-split-cfuncs <statements> Split model functions
|
||||
--output-split-ctrace <statements> Split tracing functions
|
||||
-P Disable line numbers and blanks with -E
|
||||
--pins-bv <bits> Specify types for top-level ports
|
||||
--pins-inout-enables Specify that __en and __out signals be created for inouts
|
||||
--pins-sc-biguint Specify types for top-level ports
|
||||
--pins-sc-uint Specify types for top-level ports
|
||||
--pins-sc-uint-bool 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
|
||||
@@ -404,24 +427,29 @@ detailed descriptions of these arguments.
|
||||
--protect-ids Hash identifier names for obscurity
|
||||
--protect-key <key> Key for symbol protection
|
||||
--protect-lib <name> Create a DPI protected library
|
||||
--public Debugging; see docs
|
||||
--public Mark signals as public; see docs
|
||||
--public-depth <level> Mark public to specified module depth
|
||||
--public-params Mark all parameters as public_flat
|
||||
--public-flat-rw Mark all variables, etc as public_flat_rw
|
||||
-pvalue+<name>=<value> Overwrite toplevel parameter
|
||||
--quiet Minimize additional printing
|
||||
--quiet-exit Don't print the command on failure
|
||||
--quiet-stats Don't print statistics
|
||||
--relative-includes Resolve includes relative to current file
|
||||
--reloop-limit Minimum iterations for forming loops
|
||||
--report-unoptflat Extra diagnostics for UNOPTFLAT
|
||||
--rr Run Verilator and record with rr
|
||||
--runtime-debug Enable model runtime debugging
|
||||
--savable Enable model save-restore
|
||||
--sc Create SystemC output
|
||||
--no-skip-identical Disable skipping identical output
|
||||
--stats Create statistics file
|
||||
--stats-vars Provide statistics on variables
|
||||
--no-std Prevent parsing standard library
|
||||
--no-stop-fail Do not call $stop when assertion fails
|
||||
--structs-packed Convert all unpacked structures to packed structures
|
||||
-sv Enable SystemVerilog parsing
|
||||
+systemverilogext+<ext> Synonym for +1800-2017ext+<ext>
|
||||
+systemverilogext+<ext> Synonym for +1800-2023ext+<ext>
|
||||
--threads <threads> Enable multithreading
|
||||
--threads-dpi <mode> Enable multithreaded DPI
|
||||
--threads-max-mtasks <mtasks> Tune maximum mtask partitioning
|
||||
@@ -435,8 +463,8 @@ detailed descriptions of these arguments.
|
||||
--trace-coverage Enable tracing of coverage
|
||||
--trace-depth <levels> Depth of tracing
|
||||
--trace-fst Enable FST waveform creation
|
||||
--trace-max-array <depth> Maximum bit width for tracing
|
||||
--trace-max-width <width> Maximum array depth for tracing
|
||||
--trace-max-array <depth> Maximum array depth for tracing
|
||||
--trace-max-width <width> Maximum bit width for tracing
|
||||
--trace-params Enable tracing of parameters
|
||||
--trace-structs Enable tracing structure names
|
||||
--trace-threads <threads> Enable FST waveform creation on separate threads
|
||||
@@ -449,11 +477,12 @@ detailed descriptions of these arguments.
|
||||
--unused-regexp <regexp> Tune UNUSED lint signals
|
||||
-V Verbose version and config
|
||||
-v <filename> Verilog library
|
||||
--valgrind Run Verilator under valgrind
|
||||
--verilate-jobs Job threads for Verilation stage
|
||||
--no-verilate Skip Verilation and just compile previously Verilated code
|
||||
+verilog1995ext+<ext> Synonym for +1364-1995ext+<ext>
|
||||
+verilog2001ext+<ext> Synonym for +1364-2001ext+<ext>
|
||||
--version Displays program version and exits
|
||||
--version Show program version and exits
|
||||
--vpi Enable VPI compiles
|
||||
--waiver-output <filename> Create a waiver file based on the linter warnings
|
||||
-Wall Enable all style warnings
|
||||
@@ -471,6 +500,11 @@ detailed descriptions of these arguments.
|
||||
--x-assign <mode> Assign non-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
|
||||
--no-json-edit-nums Don't dump editNum in .tree.json files
|
||||
--no-json-ids Don't use short identifiers instead of adresses/paths in .tree.json
|
||||
--json-only Create JSON parser output (.tree.json and .meta.json)
|
||||
--json-only-output .tree.json output filename
|
||||
--json-only-meta-output .tree.meta.json output filename
|
||||
--xml-only Create XML parser output
|
||||
--xml-output XML output filename
|
||||
-y <dir> Directory to search for modules
|
||||
@@ -482,19 +516,21 @@ description of these arguments.
|
||||
|
||||
=for VL_SPHINX_EXTRACT "_build/gen/args_verilated.rst"
|
||||
|
||||
+verilator+debug Enable debugging
|
||||
+verilator+debugi+<value> Enable debugging at a level
|
||||
+verilator+error+limit+<value> Set error limit
|
||||
+verilator+help Display help
|
||||
+verilator+noassert Disable assert checking
|
||||
+verilator+debug Enable debugging
|
||||
+verilator+debugi+<value> Enable debugging at a level
|
||||
+verilator+coverage+file+<filename> Set coverage output filename
|
||||
+verilator+error+limit+<value> Set error limit
|
||||
+verilator+help Show help
|
||||
+verilator+noassert Disable assert checking
|
||||
+verilator+prof+exec+file+<filename> Set execution profile filename
|
||||
+verilator+prof+exec+start+<value> Set execution profile starting point
|
||||
+verilator+prof+exec+window+<value> Set execution profile duration
|
||||
+verilator+prof+vlt+file+<filename> Set PGO profile filename
|
||||
+verilator+rand+reset+<value> Set random reset technique
|
||||
+verilator+seed+<value> Set random seed
|
||||
+verilator+V Verbose version and config
|
||||
+verilator+version Show version and exit
|
||||
+verilator+quiet Minimize additional printing
|
||||
+verilator+rand+reset+<value> Set random reset technique
|
||||
+verilator+seed+<value> Set random seed
|
||||
+verilator+V Show verbose version and config
|
||||
+verilator+version Show version and exit
|
||||
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
@@ -154,9 +154,9 @@ verilator_coverage - Verilator coverage analyzer
|
||||
|
||||
verilator_coverage --annotate <obj>
|
||||
|
||||
verilator_coverage -write merged.dat -read <datafiles>...
|
||||
verilator_coverage -write merged.dat <datafiles>...
|
||||
|
||||
verilator_coverage -write-info merged.info -read <datafiles>...
|
||||
verilator_coverage -write-info merged.info <datafiles>...
|
||||
|
||||
Verilator_coverage processes Verilated model-generated coverage reports.
|
||||
|
||||
@@ -177,12 +177,12 @@ L<https://verilator.org/guide/latest/exe_verilator_coverage.html>.
|
||||
--write <filename> Write aggregate coverage results.
|
||||
--write-info <filename.info> Write lcov .info.
|
||||
|
||||
+libext+I<ext>+I<ext>... Extensions for Verilog files.
|
||||
+define+I<var>+I<value> Defines the given variable.
|
||||
-DI<var>=I<value> Defines the given variable.
|
||||
+incdir+I<dir> Add directory for finding include files.
|
||||
-II<dir> Add directory for finding include files.
|
||||
-y I<dir> Specifies module search directory.
|
||||
+libext+<ext>+<ext>... Extensions for Verilog files.
|
||||
+define+<var>+<value> Defines the given variable.
|
||||
-D<var>=<value> Defines the given variable.
|
||||
+incdir+<dir> Add directory for finding include files.
|
||||
-I<dir> Add directory for finding include files.
|
||||
-y <dir> Specifies module search directory.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
|
||||
+8
-21
@@ -27,12 +27,6 @@ fatal() {
|
||||
echo "ERROR: $(basename "$0"): $1" >&2; exit 1;
|
||||
}
|
||||
|
||||
if [ "$CI_M32" = "0" ]; then
|
||||
unset CI_M32
|
||||
elif [ "$CI_M32" != "1" ]; then
|
||||
fatal "\$CI_M32 must be '0' or '1'";
|
||||
fi
|
||||
|
||||
if [ "$CI_OS_NAME" = "linux" ]; then
|
||||
MAKE=make
|
||||
elif [ "$CI_OS_NAME" = "osx" ]; then
|
||||
@@ -77,10 +71,6 @@ if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then
|
||||
if [ "$COVERAGE" = 1 ]; then
|
||||
yes yes | sudo cpan -fi Parallel::Forker
|
||||
fi
|
||||
if [ "$CI_M32" = 1 ]; then
|
||||
sudo apt-get install gcc-multilib g++-multilib ||
|
||||
sudo apt-get install gcc-multilib g++-multilib
|
||||
fi
|
||||
elif [ "$CI_OS_NAME" = "osx" ]; then
|
||||
brew update
|
||||
brew install ccache perl gperftools
|
||||
@@ -102,29 +92,24 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
|
||||
sudo apt-get update ||
|
||||
sudo apt-get update
|
||||
# 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
|
||||
sudo apt-get install gdb gtkwave lcov libfl-dev ccache jq z3 ||
|
||||
sudo apt-get install gdb gtkwave lcov libfl-dev ccache jq z3
|
||||
# Required for test_regress/t/t_dist_attributes.pl
|
||||
if [ "$CI_RUNS_ON" = "ubuntu-22.04" ]; then
|
||||
sudo apt-get install libclang-dev mold ||
|
||||
sudo apt-get install libclang-dev mold
|
||||
pip3 install clang==14.0
|
||||
sudo apt-get install python3-clang mold ||
|
||||
sudo apt-get install python3-clang mold
|
||||
fi
|
||||
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
|
||||
if [ "$CI_M32" = 1 ]; then
|
||||
sudo apt-get install lib32z1-dev gcc-multilib g++-multilib ||
|
||||
sudo apt-get install lib32z1-dev gcc-multilib g++-multilib
|
||||
fi
|
||||
elif [ "$CI_OS_NAME" = "osx" ]; then
|
||||
brew update
|
||||
# brew cask install gtkwave # fst2vcd hangs at launch, so don't bother
|
||||
brew install ccache perl
|
||||
brew install ccache perl jq z3
|
||||
elif [ "$CI_OS_NAME" = "freebsd" ]; then
|
||||
# fst2vcd fails with "Could not open '<input file>', exiting."
|
||||
sudo pkg install -y ccache gmake perl5 python3
|
||||
sudo pkg install -y ccache gmake perl5 python3 jq z3
|
||||
else
|
||||
fatal "Unknown os: '$CI_OS_NAME'"
|
||||
fi
|
||||
@@ -134,6 +119,8 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
|
||||
fi
|
||||
yes yes | sudo cpan -M $CI_CPAN_REPO -fi Parallel::Forker
|
||||
install-vcddiff
|
||||
# Workaround -fsanitize=address crash
|
||||
sudo sysctl -w vm.mmap_rnd_bits=28
|
||||
else
|
||||
##############################################################################
|
||||
# Unknown build stage
|
||||
|
||||
+25
-17
@@ -21,12 +21,6 @@ fatal() {
|
||||
echo "ERROR: $(basename "$0"): $1" >&2; exit 1;
|
||||
}
|
||||
|
||||
if [ "$CI_M32" = "0" ]; then
|
||||
unset CI_M32
|
||||
elif [ "$CI_M32" != "1" ]; then
|
||||
fatal "\$CI_M32 must be '0' or '1'";
|
||||
fi
|
||||
|
||||
if [ "$CI_OS_NAME" = "linux" ]; then
|
||||
export MAKE=make
|
||||
NPROC=$(nproc)
|
||||
@@ -46,7 +40,7 @@ if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then
|
||||
|
||||
if [ "$COVERAGE" != 1 ]; then
|
||||
autoconf
|
||||
./configure --enable-longtests --enable-ccwarn ${CI_M32:+--enable-m32}
|
||||
./configure --enable-longtests --enable-ccwarn --prefix="$INSTALL_DIR"
|
||||
ccache -z
|
||||
"$MAKE" -j "$NPROC" -k
|
||||
# 22.04: ccache -s -v
|
||||
@@ -91,25 +85,42 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
|
||||
fi
|
||||
|
||||
# Run sanitize on Ubuntu 22.04 only
|
||||
[ "$CI_RUNS_ON" = 'ubuntu-22.04' ] && [ "$CI_M32" = "" ] && sanitize='--sanitize' || sanitize=''
|
||||
[ "$CI_RUNS_ON" = 'ubuntu-22.04' ] && sanitize='--sanitize' || sanitize=''
|
||||
|
||||
TEST_REGRESS=test_regress
|
||||
if [ "$CI_RELOC" == 1 ]; then
|
||||
# Testing that the installation is relocatable.
|
||||
"$MAKE" install
|
||||
mkdir -p "$RELOC_DIR"
|
||||
mv "$INSTALL_DIR" "$RELOC_DIR/relocated-install"
|
||||
export VERILATOR_ROOT="$RELOC_DIR/relocated-install/share/verilator"
|
||||
TEST_REGRESS="$RELOC_DIR/test_regress"
|
||||
mv test_regress "$TEST_REGRESS"
|
||||
# Feeling brave?
|
||||
find . -delete
|
||||
ls -la .
|
||||
fi
|
||||
|
||||
# Run the specified test
|
||||
ccache -z
|
||||
case $TESTS in
|
||||
dist-vlt-0)
|
||||
"$MAKE" -C test_regress SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=0/3
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=0/4
|
||||
;;
|
||||
dist-vlt-1)
|
||||
"$MAKE" -C test_regress SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=1/3
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=1/4
|
||||
;;
|
||||
dist-vlt-2)
|
||||
"$MAKE" -C test_regress SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=2/3
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=2/4
|
||||
;;
|
||||
dist-vlt-3)
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS="--dist --vlt $sanitize" DRIVER_HASHSET=--hashset=3/4
|
||||
;;
|
||||
vltmt-0)
|
||||
"$MAKE" -C test_regress SCENARIOS=--vltmt DRIVER_HASHSET=--hashset=0/2
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS=--vltmt DRIVER_HASHSET=--hashset=0/2
|
||||
;;
|
||||
vltmt-1)
|
||||
"$MAKE" -C test_regress SCENARIOS=--vltmt DRIVER_HASHSET=--hashset=1/2
|
||||
"$MAKE" -C "$TEST_REGRESS" SCENARIOS=--vltmt DRIVER_HASHSET=--hashset=1/2
|
||||
;;
|
||||
coverage-all)
|
||||
nodist/code_coverage --stages 1-
|
||||
@@ -181,13 +192,10 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
|
||||
fatal "Unknown test: $TESTS"
|
||||
;;
|
||||
esac
|
||||
|
||||
# 22.04: ccache -s -v
|
||||
ccache -s
|
||||
|
||||
# Upload coverage data
|
||||
if [[ $TESTS == coverage-* ]]; then
|
||||
bash <(cat ci/coverage-upload.sh) -f nodist/obj_dir/coverage/app_total.info
|
||||
fi
|
||||
else
|
||||
##############################################################################
|
||||
# Unknown build stage
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
# DESCRIPTION: Verilator: CI Windows Power Shell - Compile Verilator
|
||||
#
|
||||
# Copyright 2024 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
|
||||
################################################################################
|
||||
|
||||
Set-PSDebug -Trace 1
|
||||
|
||||
if (-Not (Test-Path $PWD/../.ccache/win_bison.exe)) {
|
||||
git clone --depth 1 https://github.com/lexxmark/winflexbison
|
||||
cd winflexbison
|
||||
@@ -8,6 +20,7 @@ if (-Not (Test-Path $PWD/../.ccache/win_bison.exe)) {
|
||||
cmake --install . --prefix $PWD/../../../.ccache
|
||||
cd ../..
|
||||
}
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. --install-prefix $PWD/../install
|
||||
|
||||
+17
-1
@@ -1,3 +1,16 @@
|
||||
# DESCRIPTION: Verilator: CI Windows Power Shell - Verilate a test
|
||||
#
|
||||
# Copyright 2024 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
|
||||
################################################################################
|
||||
|
||||
|
||||
Set-PSDebug -Trace 1
|
||||
|
||||
cd install
|
||||
$Env:VERILATOR_ROOT=$PWD
|
||||
cd examples/cmake_tracing_c
|
||||
@@ -5,6 +18,9 @@ mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
cmake --build . --config Release -j 3
|
||||
Release/example.exe
|
||||
|
||||
# TODO put this back in, see issue# 5163
|
||||
# Release/example.exe
|
||||
|
||||
cd ..
|
||||
Remove-Item -path build -recurse
|
||||
|
||||
Executable
BIN
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@@ -43,6 +43,7 @@ RUN apt-get update \
|
||||
perl \
|
||||
python3 \
|
||||
wget \
|
||||
z3 \
|
||||
zlib1g \
|
||||
zlib1g-dev \
|
||||
&& apt-get clean \
|
||||
|
||||
@@ -11,10 +11,11 @@ easily as a docker image, e.g.:
|
||||
|
||||
docker run -ti verilator/verilator:latest --version
|
||||
|
||||
This will install the container, run the latest Verilator and print
|
||||
This will pull the container from `docker hub
|
||||
<https://hub.docker.com/r/verilator/verilator>`_, run the latest Verilator and print
|
||||
Verilator's version.
|
||||
|
||||
Containers are automatically built for all released versions, so you may
|
||||
Containers are automatically built and pushed to docker hub for all released versions, so you may
|
||||
easily compare results across versions, e.g.:
|
||||
|
||||
::
|
||||
|
||||
+69
-51
@@ -5,12 +5,12 @@
|
||||
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
# When releasing, also update header of Changes file, and CmakeLists.txt,
|
||||
# When releasing, also update header of Changes file, and CMakeLists.txt,
|
||||
# and commit using "devel release" or "Version bump" message
|
||||
# Then 'make maintainer-dist'
|
||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[5.020 2024-01-01],
|
||||
AC_INIT([Verilator],[5.028 2024-08-21],
|
||||
[https://verilator.org],
|
||||
[verilator],[https://verilator.org])
|
||||
|
||||
@@ -67,20 +67,6 @@ AC_ARG_ENABLE([tcmalloc],
|
||||
[CFG_WITH_TCMALLOC=check;])
|
||||
AC_MSG_RESULT($CFG_WITH_TCMALLOC)
|
||||
|
||||
# Flag to enable -m32 build
|
||||
AC_MSG_CHECKING(whether to use -m32)
|
||||
AC_ARG_ENABLE([m32],
|
||||
[AS_HELP_STRING([--enable-m32],
|
||||
[Use -m32 for all compilation and link,
|
||||
including Verilator and generated models.])],
|
||||
[case "${enableval}" in
|
||||
yes) CFG_ENABLE_M32=yes ;;
|
||||
no) CFG_ENABLE_M32=no ;;
|
||||
*) AC_MSG_ERROR([bad value '${enableval}' for --enable-m32]) ;;
|
||||
esac],
|
||||
CFG_ENABLE_M32=no)
|
||||
AC_MSG_RESULT($CFG_ENABLE_M32)
|
||||
|
||||
# Flag to enable coverage build
|
||||
AC_MSG_CHECKING(whether to build for coverage collection)
|
||||
AC_ARG_ENABLE([coverage],
|
||||
@@ -148,6 +134,28 @@ AC_ARG_ENABLE([longtests],
|
||||
AC_SUBST(CFG_WITH_LONGTESTS)
|
||||
AC_MSG_RESULT($CFG_WITH_LONGTESTS)
|
||||
|
||||
AC_CHECK_PROG(HAVE_Z3,z3,yes)
|
||||
AC_CHECK_PROG(HAVE_CVC5,cvc5,yes)
|
||||
AC_CHECK_PROG(HAVE_CVC4,cvc4,yes)
|
||||
|
||||
# Special Substitutions - CFG_WITH_SOLVER
|
||||
AC_MSG_CHECKING(for SMT solver)
|
||||
AC_ARG_WITH([solver],
|
||||
[AS_HELP_STRING([--with-solver='z3 --in'],
|
||||
[set default SMT solver for constrained randomization])],
|
||||
[CFG_WITH_SOLVER="${withval}"],
|
||||
[CFG_WITH_SOLVER=no
|
||||
if test "x$HAVE_Z3" = "xyes"; then
|
||||
CFG_WITH_SOLVER="z3 --in"
|
||||
elif test "x$HAVE_CVC5" = "xyes"; then
|
||||
CFG_WITH_SOLVER="cvc5 --incremental"
|
||||
elif test "x$HAVE_CVC4" = "xyes"; then
|
||||
CFG_WITH_SOLVER="cvc4 --lang=smt2 --incremental"
|
||||
fi]
|
||||
)
|
||||
AC_SUBST(CFG_WITH_SOLVER)
|
||||
AC_MSG_RESULT($CFG_WITH_SOLVER)
|
||||
|
||||
# Compiler flags (ensure they are not empty to avoid configure defaults)
|
||||
CFLAGS="$CFLAGS "
|
||||
CPPFLAGS="$CPPFLAGS "
|
||||
@@ -280,6 +288,43 @@ AC_DEFUN([_MY_CXX_CHECK_OPT],
|
||||
_MY_CXX_CHECK_IFELSE($2, $1="$$1 $2")
|
||||
])
|
||||
|
||||
AC_DEFUN([_MY_CXX_CHECK_CORO_SET],
|
||||
[# _MY_CXX_CHECK_CORO_SET(variable,option)
|
||||
# Check if compiler supports coroutines with specific option. If it does,
|
||||
# set variable to option, only if not previously set.
|
||||
# Define HAVE_COROUTINES if supported.
|
||||
if test "$$1" = ""; then
|
||||
if test "$2" != ""; then
|
||||
_my_msg_opt=" with $2"
|
||||
else
|
||||
_my_msg_opt=""
|
||||
fi
|
||||
AC_MSG_CHECKING([whether coroutines are supported by $CXX$_my_msg_opt])
|
||||
ACO_SAVE_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $2"
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([
|
||||
#if defined(__clang__) && !defined(__cpp_impl_coroutine)
|
||||
#define __cpp_impl_coroutine 1
|
||||
#endif
|
||||
#include <coroutine>
|
||||
],[[std::coroutine_handle<> h;]])],
|
||||
[_my_result=yes],
|
||||
[AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM(
|
||||
[#include <experimental/coroutine>],
|
||||
[[std::experimental::coroutine_handle<> h;]])],
|
||||
[_my_result=yes],
|
||||
[_my_result=no])])
|
||||
AC_MSG_RESULT($_my_result)
|
||||
CXXFLAGS="$ACO_SAVE_CXXFLAGS"
|
||||
if test "$_my_result" = "yes" ; then
|
||||
$1="$2"
|
||||
AC_DEFINE([HAVE_COROUTINES],[1],[Defined if coroutines are supported by $CXX])
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([_MY_LDLIBS_CHECK_FLAG],
|
||||
[# _MY_LDLIBS_CHECK_FLAG(flag) -- Check if linker supports specific options
|
||||
# Set $_my_result appropriately
|
||||
@@ -319,15 +364,7 @@ AC_DEFUN([_MY_LDLIBS_CHECK_OPT],
|
||||
_MY_LDLIBS_CHECK_IFELSE($2, $1="$$1 $2")
|
||||
])
|
||||
|
||||
# When using -m32. Check this first as later checks may fail with the -m32 flag.
|
||||
if test "$CFG_ENABLE_M32" = "yes"; then
|
||||
_MY_CXX_CHECK_IFELSE(
|
||||
-m32,
|
||||
[CXX="$CXX -m32"],
|
||||
[AC_MSG_ERROR([--enable-m32 was given but compiler does not support -m32])])
|
||||
fi
|
||||
|
||||
# Similarly, add the coverage flags early as they influence later checks.
|
||||
# Add the coverage flags early as they influence later checks.
|
||||
if test "$CFG_ENABLE_COVERAGE" = "yes"; then
|
||||
_MY_CXX_CHECK_OPT(CXX,--coverage)
|
||||
# Otherwise inline may not show as uncovered
|
||||
@@ -373,32 +410,12 @@ _MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wthread-safety)
|
||||
AC_SUBST(CFG_CXXFLAGS_WEXTRA)
|
||||
|
||||
# Flags for coroutine support for dynamic scheduling
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_COROUTINES,-fcoroutines-ts)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_COROUTINES,-fcoroutines)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_COROUTINES,-fcoroutines-ts -Wno-deprecated-experimental-coroutine)
|
||||
_MY_CXX_CHECK_CORO_SET(CFG_CXXFLAGS_COROUTINES, "")
|
||||
_MY_CXX_CHECK_CORO_SET(CFG_CXXFLAGS_COROUTINES,-fcoroutines-ts)
|
||||
_MY_CXX_CHECK_CORO_SET(CFG_CXXFLAGS_COROUTINES,-fcoroutines)
|
||||
_MY_CXX_CHECK_CORO_SET(CFG_CXXFLAGS_COROUTINES,-fcoroutines-ts -Wno-deprecated-experimental-coroutine)
|
||||
_MY_CXX_CHECK_CORO_SET(CFG_CXXFLAGS_COROUTINES,-std=gnu++20)
|
||||
AC_SUBST(CFG_CXXFLAGS_COROUTINES)
|
||||
|
||||
# HAVE_COROUTINES
|
||||
# Check if coroutines are supported at all
|
||||
AC_MSG_CHECKING([whether coroutines are supported by $CXX])
|
||||
ACO_SAVE_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $CFG_CXXFLAGS_COROUTINES"
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([
|
||||
#ifdef __clang__
|
||||
#define __cpp_impl_coroutine 1
|
||||
#endif
|
||||
#include <coroutine>
|
||||
],[[]])],
|
||||
[_my_result=yes
|
||||
AC_DEFINE([HAVE_COROUTINES],[1],[Defined if coroutines are supported by $CXX])],
|
||||
[AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([#include <experimental/coroutine>],[[]])],
|
||||
[_my_result=yes
|
||||
AC_DEFINE([HAVE_COROUTINES],[1],[Defined if coroutines are supported by $CXX])],
|
||||
[_my_result=no])])
|
||||
AC_MSG_RESULT($_my_result)
|
||||
CXXFLAGS="$ACO_SAVE_CXXFLAGS"
|
||||
AC_SUBST(HAVE_COROUTINES)
|
||||
|
||||
# Flags for compiling Verilator internals including parser always
|
||||
@@ -446,11 +463,11 @@ m4_foreach([cflag],[
|
||||
[-Wno-c++11-narrowing],
|
||||
[-Wno-constant-logical-operand],
|
||||
[-Wno-non-pod-varargs],
|
||||
[-Wno-overloaded-virtual],
|
||||
[-Wno-parentheses-equality],
|
||||
[-Wno-shadow],
|
||||
[-Wno-sign-compare],
|
||||
[-Wno-tautological-bitwise-compare],
|
||||
[-Wno-tautological-compare],
|
||||
[-Wno-uninitialized],
|
||||
[-Wno-unused-but-set-parameter],
|
||||
[-Wno-unused-but-set-variable],
|
||||
@@ -497,6 +514,7 @@ AC_SUBST(CFG_LDFLAGS_VERILATED)
|
||||
# pthreads is harmless otherwise.
|
||||
CFG_LIBS="$LIBS $CFG_LIBS"
|
||||
_MY_LDLIBS_CHECK_OPT(CFG_LIBS, -lpthread)
|
||||
_MY_LDLIBS_CHECK_OPT(CFG_LIBS, -latomic)
|
||||
|
||||
# Check libraries for MingW
|
||||
_MY_LDLIBS_CHECK_OPT(CFG_LIBS, -lbcrypt)
|
||||
|
||||
@@ -4,24 +4,32 @@ under the Developer Certificate of Origin (https://developercertificate.org/).
|
||||
Please see the Verilator manual for 200+ additional contributors. Thanks to all.
|
||||
|
||||
Adam Bagley
|
||||
Adrian Sampson
|
||||
Adrien Le Masle
|
||||
Ahmed El-Mahmoudy
|
||||
Aleksander Kiryk
|
||||
Alex Chadwick
|
||||
Alex Solomatnikov
|
||||
Àlex Torregrosa
|
||||
Aliaksei Chapyzhenka
|
||||
Ameya Vikram Singh
|
||||
Andrea Calabrese
|
||||
Andreas Kuster
|
||||
Andrei Kostovski
|
||||
Andrew Miloradovsky
|
||||
Andrew Nolte
|
||||
Anthony Donlon
|
||||
Arkadiusz Kozdra
|
||||
Arthur Rosa
|
||||
Aylon Chaim Porat
|
||||
Bartłomiej Chmiel
|
||||
Cameron Kirk
|
||||
Chih-Mao Chen
|
||||
Chris Bachhuber
|
||||
Chris Randall
|
||||
Christopher Taylor
|
||||
Chuxuan Wang
|
||||
Chykon
|
||||
Conor McCullough
|
||||
Dan Petrisko
|
||||
Daniel Bates
|
||||
@@ -30,6 +38,7 @@ David Ledger
|
||||
David Metz
|
||||
David Stanford
|
||||
David Turner
|
||||
Dercury
|
||||
Don Williamson
|
||||
Drew Ranck
|
||||
Drew Taussig
|
||||
@@ -43,10 +52,12 @@ february cozzocrea
|
||||
Felix Neumärker
|
||||
Felix Yan
|
||||
Frans Skarman
|
||||
Fuad Ismail
|
||||
G-A. Kamendje
|
||||
Garrett Smith
|
||||
Geza Lore
|
||||
Gianfranco Costamagna
|
||||
Gijs Burghoorn
|
||||
Glen Gibb
|
||||
Gökçe Aydos
|
||||
Graham Rushton
|
||||
@@ -66,6 +77,7 @@ Iru Cai
|
||||
Ivan Vnučec
|
||||
Iztok Jeras
|
||||
Jake Merdich
|
||||
James Bailey
|
||||
James Hanlon
|
||||
James Hutchinson
|
||||
James Pallister
|
||||
@@ -73,6 +85,7 @@ James Shi
|
||||
Jamey Hicks
|
||||
Jamie Iles
|
||||
Jan Van Winkel
|
||||
Jiangjie Weng
|
||||
Jean Berniolles
|
||||
Jeremy Bennett
|
||||
Jesse Taube
|
||||
@@ -86,6 +99,7 @@ John Coiner
|
||||
John Demme
|
||||
John Wehle
|
||||
Jonathan Drolet
|
||||
Jonathan Schröter
|
||||
Jordan McConnon
|
||||
Jose Loyola
|
||||
Josep Sans
|
||||
@@ -98,14 +112,19 @@ Justin Thiel
|
||||
Kaleb Barrett
|
||||
Kamil Rakoczy
|
||||
Kanad Kanhere
|
||||
Kefa Chen
|
||||
Keith Colbert
|
||||
Kevin Kiningham
|
||||
Kevin Nygaard
|
||||
Kritik Bhimani
|
||||
Krzysztof Bieganski
|
||||
Krzysztof Boronski
|
||||
Krzysztof Boroński
|
||||
Krzysztof Obłonczek
|
||||
Kuba Ober
|
||||
Larry Doolittle
|
||||
Liam Braun
|
||||
Luca Colagrande
|
||||
Ludwig Rogiers
|
||||
Lukasz Dalek
|
||||
Maarten De Braekeleer
|
||||
@@ -119,6 +138,7 @@ Marshal Qiao
|
||||
Martin Schmidt
|
||||
Martin Stadler
|
||||
Matthew Ballance
|
||||
Michael Bikovitsky
|
||||
Michael Killough
|
||||
Michaël Lefebvre
|
||||
Michal Czyz
|
||||
@@ -130,13 +150,19 @@ Mostafa Gamal
|
||||
Nandu Raj
|
||||
Nathan Kohagen
|
||||
Nathan Myers
|
||||
Nolan Poe
|
||||
Oleh Maksymenko
|
||||
Patrick Stewart
|
||||
Paul Bowen-Huggett
|
||||
Paul Swirhun
|
||||
Paul Wright
|
||||
Pawel Jewstafjew
|
||||
Pawel Sagan
|
||||
Pengcheng Xu
|
||||
Peter Debacker
|
||||
Peter Horvath
|
||||
Peter Monsson
|
||||
Philip Axer
|
||||
Philipp Wagner
|
||||
Pierre-Henri Horrein
|
||||
Pieter Kapsenberg
|
||||
@@ -146,19 +172,23 @@ Quentin Corradi
|
||||
Rafal Kapuscik
|
||||
Rasfunk
|
||||
Raynard Qiao
|
||||
Ricardo Barbedo
|
||||
Richard Myers
|
||||
Risto Pejašinović
|
||||
Robert Balas
|
||||
Rupert Swarbrick
|
||||
Ryan Ziegler
|
||||
Ryszard Rozak
|
||||
Samuel Riedel
|
||||
Sean Cross
|
||||
Sebastien Van Cauwenberghe
|
||||
Sergi Granell
|
||||
Seth Pellegrino
|
||||
Srinivasan Venkataramanan
|
||||
Stefan Wallentowitz
|
||||
Stephen Henry
|
||||
Steven Hugg
|
||||
Szymon Gizler
|
||||
Sören Tempel
|
||||
Teng Huang
|
||||
Tim Hutt
|
||||
@@ -173,6 +203,8 @@ Tudor Timi
|
||||
Tymoteusz Blazejczyk
|
||||
Udi Finkelstein
|
||||
Unai Martinez-Corral
|
||||
Udaya Raj Subedi
|
||||
Valentin Atepalikhin
|
||||
Varun Koyyalagunta
|
||||
Vassilis Papaefstathiou
|
||||
Veripool API Bot
|
||||
@@ -181,6 +213,8 @@ Vito Gamberini
|
||||
William D. Jones
|
||||
Wilson Snyder
|
||||
Xi Zhang
|
||||
Yan Xu
|
||||
Yangyu Chen
|
||||
Yinan Xu
|
||||
Yoda Lee
|
||||
Yossi Nivin
|
||||
@@ -192,3 +226,4 @@ Zhanglei Wang
|
||||
Zhou Shen
|
||||
Zixi Li
|
||||
أحمد المحمودي
|
||||
404allen404
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. comment: generated by t_lint_multidriven_bad
|
||||
.. code-block::
|
||||
|
||||
%Warning-MULTIDRIVEN: example.v:1:22 Signal has multiple driving blocks with different clocking: 'out2'
|
||||
%Warning-MULTIDRIVEN: example.v:1:22 Signal has multiple driving blocks with different clocking: 't.mem'
|
||||
example.v:1:7 ... Location of first driving block
|
||||
example.v:1:7 ... Location of other driving block
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
.. comment: generated by t_lint_pinmissing_bad
|
||||
.. code-block:: sv
|
||||
:linenos:
|
||||
:emphasize-lines: 2
|
||||
|
||||
module t;
|
||||
sub sub(); // <--- Warning
|
||||
endmodule
|
||||
module sub
|
||||
(output port);
|
||||
endmodule
|
||||
@@ -0,0 +1,4 @@
|
||||
.. comment: generated by t_lint_pinmissing_bad
|
||||
.. code-block::
|
||||
|
||||
%Warning-PINMISSING: example.v:1:8 Cell has missing pin: 'port'
|
||||
@@ -0,0 +1,11 @@
|
||||
.. comment: generated by t_lint_pkgnodecl_bad
|
||||
.. code-block:: sv
|
||||
:linenos:
|
||||
:emphasize-lines: 2
|
||||
|
||||
module t;
|
||||
initial Pkg::hello(); //<--- Warning
|
||||
endmodule
|
||||
package Pkg;
|
||||
function void hello(); endfunction
|
||||
endpackage
|
||||
@@ -0,0 +1,4 @@
|
||||
.. comment: generated by t_lint_pkgnodecl_bad
|
||||
.. code-block::
|
||||
|
||||
%Error-PKGNODECL: example.v:1:12 Package/class 'Pkg' not found, and needs to be predeclared (IEEE 1800-2023 26.3)
|
||||
+1
-1
@@ -45,7 +45,7 @@ def setup(app):
|
||||
# -- Project information
|
||||
|
||||
project = 'Verilator'
|
||||
copyright = '2022 by Wilson Snyder, under LGPL-3.0 or Artistic-2.0'
|
||||
copyright = '2024 by Wilson Snyder, under LGPL-3.0 or Artistic-2.0'
|
||||
author = 'Wilson Snyder'
|
||||
|
||||
# The master toctree document.
|
||||
|
||||
@@ -407,6 +407,16 @@ only a couple of instructions.
|
||||
For signal callbacks to work the main loop of the program must call
|
||||
:code:`VerilatedVpi::callValueCbs()`.
|
||||
|
||||
Verilator also tracks when the model state has been modified via the VPI with
|
||||
an :code:`evalNeeded` flag. This flag can be checked with :code:`VerilatedVpi::evalNeeded()`
|
||||
and it can be cleared with :code:`VerilatedVpi::clearEvalNeeded()`. Used together
|
||||
it is possible to skip :code:`eval()` calls if no model state has been changed
|
||||
since the last :code:`eval()`.
|
||||
|
||||
Any data written via :code:`vpi_put_value` with :code:`vpiInertialDelay` will
|
||||
be deferred for later. These delayed values can be flushed to the model with
|
||||
:code:`VerilatedVpi::doInertialPuts()`.
|
||||
|
||||
|
||||
.. _VPI Example:
|
||||
|
||||
@@ -500,7 +510,7 @@ the user should call:
|
||||
any delayed events pending,
|
||||
* :code:`designp->nextTimeSlot()`, which returns the simulation time of the
|
||||
next delayed event. This method can only be called if
|
||||
:code:`designp->nextTimeSlot()` returned :code:`true`.
|
||||
:code:`designp->eventsPending()` returned :code:`true`.
|
||||
|
||||
Call :code:`eventsPending()` to check if you should continue with the
|
||||
simulation, and then :code:`nextTimeSlot()` to move simulation time forward.
|
||||
|
||||
@@ -6,7 +6,7 @@ Deprecations
|
||||
|
||||
The following deprecated items are scheduled for future removal:
|
||||
|
||||
C++11 compiler support
|
||||
C++14 compiler support
|
||||
Verilator currently requires a C++20 or newer compiler for timing, and a
|
||||
C++14 or newer compiler for both compiling Verilator and compiling
|
||||
Verilated models with --no-timing.
|
||||
@@ -14,7 +14,6 @@ C++11 compiler support
|
||||
Verilator will require C++20 or newer compilers for both compiling
|
||||
Verilator and compiling all Verilated models no sooner than January 2025.
|
||||
|
||||
32-bit compiler support
|
||||
Verilator currently regresses both 64-bit and 32-bit pointer modes (GCC's
|
||||
`-m64` and `-m32`). Support for 32-bit `-m32` mode will be deprecated no
|
||||
sooner than January 2024.
|
||||
XML output
|
||||
Verilator currently supports XML parser output (enabled with `--xml-only`).
|
||||
Support for `--xml-*` options will be deprecated no sooner than January 2025.
|
||||
|
||||
@@ -118,6 +118,17 @@ associated programs.
|
||||
|
||||
See :ref:`Installation` for more details.
|
||||
|
||||
.. option:: VERILATOR_SOLVER
|
||||
|
||||
If set, the command to run as a constrained randomization backend, such
|
||||
as :command:`cvc4 --lang=smt2 --incremental`. If not specified, it will use
|
||||
the one supplied or found during configure, or :command:`z3 --in` if empty.
|
||||
|
||||
.. option:: VERILATOR_VALGRIND
|
||||
|
||||
If set, the command to run when using the :vlopt:`--valgrind` option, such as
|
||||
"valgrind --tool=callgrind". If not specified, it will use "valgrind".
|
||||
|
||||
|
||||
Make Variables
|
||||
==============
|
||||
|
||||
@@ -9,6 +9,7 @@ Examples
|
||||
|
||||
This section covers the following examples:
|
||||
|
||||
* :ref:`Example Create-Binary Execution`
|
||||
* :ref:`Example C++ Execution`
|
||||
* :ref:`Example SystemC Execution`
|
||||
* :ref:`Examples in the Distribution`
|
||||
|
||||
@@ -19,11 +19,20 @@ Summary:
|
||||
.. include:: ../_build/gen/args_verilated.rst
|
||||
|
||||
|
||||
.. option:: +verilator+coverage+file+<filename>
|
||||
|
||||
When a model was Verilated using :vlopt:`--coverage`, sets the filename
|
||||
to write coverage data into. Defaults to :file:`coverage.dat`.
|
||||
|
||||
.. option:: +verilator+debug
|
||||
|
||||
Enable simulation runtime debugging. Equivalent to
|
||||
:vlopt:`+verilator+debugi+4 <+verilator+debugi+\<value\>>`.
|
||||
|
||||
To be useful, the model typically must first be compiled with debug
|
||||
capabilities by Verilating with :vlopt:`--runtime-debug` or `-CFLAGS
|
||||
-DVL_DEBUG=1`.
|
||||
|
||||
.. option:: +verilator+debugi+<value>
|
||||
|
||||
Enable simulation runtime debugging at the provided level.
|
||||
@@ -83,6 +92,11 @@ Summary:
|
||||
profile-guided optimization data runtime filename to dump to. Defaults
|
||||
to :file:`profile.vlt`.
|
||||
|
||||
.. option:: +verilator+quiet
|
||||
|
||||
Disable printing the simulation summary report, see :ref:`Simulation
|
||||
Summary Report`.
|
||||
|
||||
.. option:: +verilator+rand+reset+<value>
|
||||
|
||||
When a model was Verilated using
|
||||
|
||||
+206
-20
@@ -51,6 +51,8 @@ Summary:
|
||||
|
||||
.. option:: +1800-2017ext+<ext>
|
||||
|
||||
.. option:: +1800-2023ext+<ext>
|
||||
|
||||
Specifies the language standard to be used with a specific filename
|
||||
extension, <ext>.
|
||||
|
||||
@@ -85,7 +87,11 @@ Summary:
|
||||
|
||||
.. option:: --assert
|
||||
|
||||
Enable all assertions.
|
||||
Enable all assertions. Implies :vlopt:`--assert-case`.
|
||||
|
||||
.. option:: --assert-case
|
||||
|
||||
Enable unique/unique0/priority case related checks.
|
||||
|
||||
.. option:: --autoflush
|
||||
|
||||
@@ -195,9 +201,10 @@ Summary:
|
||||
|
||||
.. option:: --compiler <compiler-name>
|
||||
|
||||
Enables workarounds for the specified C++ compiler (list below).
|
||||
This does not change any performance tuning options, but it may
|
||||
in the future.
|
||||
Enables workarounds for the specified C++ compiler (list below). This
|
||||
does not change any performance tuning options, but it may in the
|
||||
future. This also does not change default compiler flags; these are
|
||||
determined when Verilator was configured.
|
||||
|
||||
clang
|
||||
Tune for clang. This may reduce execution speed as it enables several
|
||||
@@ -215,6 +222,13 @@ Summary:
|
||||
expressions into sub-expressions to avoid error C1009, and breaking
|
||||
deep blocks into functions to avoid error C1061.
|
||||
|
||||
.. option:: --compiler-include <header-path>
|
||||
|
||||
Specifies additional headers to be included in the final PCH header.
|
||||
It is required to add them to this header, due to compilers'
|
||||
limitation that allow only one precompiled header per compilation.
|
||||
Use this instead of ::vlopt:`-CFLAGS` with `-include <header-path>`.
|
||||
|
||||
.. option:: --converge-limit <loops>
|
||||
|
||||
Rarely needed. Specifies the maximum number of runtime iterations
|
||||
@@ -304,19 +318,47 @@ Summary:
|
||||
detailed messages. See :vlopt:`--debug` for other implications of
|
||||
enabling debug.
|
||||
|
||||
.. option:: --decorations none
|
||||
|
||||
.. option:: --decorations medium
|
||||
|
||||
.. option:: --decorations node
|
||||
|
||||
When creating output Verilated code, set level of comment and whitespace
|
||||
decoration.
|
||||
|
||||
With "--decorations none",
|
||||
Minimize comments, white space, symbol names, and other decorative
|
||||
items, at the cost of reduced readability. This may assist C++ compile
|
||||
times. This will not typically change the ultimate model's
|
||||
performance, but may in some cases. See also :vlopt:`--no-decoration`
|
||||
option.
|
||||
|
||||
With "--decorations medium",
|
||||
The default, put a small amount of comments and white space, for
|
||||
typical level of readability.
|
||||
|
||||
With "--decorations node",
|
||||
Include comments indicating what caused generation of the following
|
||||
text, including what node pointer (corresponding to
|
||||
:vlopt:`--dump-tree` .tree printed data), and the source Verilog
|
||||
filename and line number. If subsequent following statements etc have
|
||||
the same filename/line number these comments are omitted. This
|
||||
enables easy debug when looking at the C++ code to determine what
|
||||
Verilog source may be related. As node pointers are not stable
|
||||
between different Verilator runs, this may harm compile caching and
|
||||
should only be used for debug.
|
||||
|
||||
.. option:: --no-decoration
|
||||
|
||||
When creating output Verilated code, minimize comments, white space,
|
||||
symbol names, and other decorative items, at the cost of reduced
|
||||
readability. This may assist C++ compile times. This will not typically
|
||||
change the ultimate model's performance, but may in some cases.
|
||||
Alias for ``--decorations none``.
|
||||
|
||||
.. option:: --default-language <value>
|
||||
|
||||
Select the language used by default when first processing each
|
||||
Verilog file. The language value must be "VAMS", "1364-1995",
|
||||
"1364-2001", "1364-2001-noconfig", "1364-2005", "1800-2005",
|
||||
"1800-2009", "1800-2012", "1800-2017", or "1800+VAMS".
|
||||
"1800-2009", "1800-2012", "1800-2017", "1800-2023", or "1800+VAMS".
|
||||
|
||||
Any language associated with a particular file extension (see the
|
||||
various +<lang>*\ ext+ options) will be used in preference to the
|
||||
@@ -329,7 +371,7 @@ Summary:
|
||||
``+<lang>ext+`` options should be used.
|
||||
|
||||
If no language is specified, either by this option or ``+<lang>ext+``
|
||||
options, then the latest SystemVerilog language (IEEE 1800-2017) is
|
||||
options, then the latest SystemVerilog language (IEEE 1800-2023) is
|
||||
used.
|
||||
|
||||
.. option:: +define+<var>=<value>
|
||||
@@ -378,6 +420,12 @@ Summary:
|
||||
:vlopt:`--debug --no-dump-tree <--dump-tree>` may be useful if the dump
|
||||
files are large and not desired.
|
||||
|
||||
.. option:: --dump-tree-json
|
||||
|
||||
Rarely needed. Enable dumping Ast .json.tree debug files with dumping level 3,
|
||||
which dumps the standard critical stages. For details on the format, see
|
||||
the Verilator Internals manual.
|
||||
|
||||
.. option:: --dump-tree-dot
|
||||
|
||||
Rarely needed. Enable dumping Ast .tree.dot debug files in Graphviz
|
||||
@@ -413,6 +461,11 @@ Summary:
|
||||
Rarely needed - for developer use. Set internal Ast dumping level
|
||||
globally to the specified value.
|
||||
|
||||
.. option:: --dumpi-tree-json <level>
|
||||
|
||||
Rarely needed - for developer use. Set internal Ast JSON dumping level
|
||||
globally to the specified value.
|
||||
|
||||
.. option:: --dumpi-<srcfile> <level>
|
||||
|
||||
Rarely needed - for developer use. Set the dumping level in the
|
||||
@@ -430,6 +483,12 @@ Summary:
|
||||
See also :vlopt:`--dump-defines`, :vlopt:`-P`, and
|
||||
:vlopt:`--pp-comments` options.
|
||||
|
||||
.. option:: --emit-accessors
|
||||
|
||||
Emit getter and setter methods for each top-level signal in the
|
||||
model top class. Signals are still available as public members,
|
||||
but with the `__Vm_sig_` prefix.
|
||||
|
||||
.. option:: --error-limit <value>
|
||||
|
||||
After this number of errors are encountered during Verilator run, exit.
|
||||
@@ -664,6 +723,13 @@ Summary:
|
||||
:option:`/*verilator&32;hier_block*/` metacomment is ignored. See
|
||||
:ref:`Hierarchical Verilation`.
|
||||
|
||||
.. option:: --hierarchical-params-file <filename>
|
||||
|
||||
Internal flag inserted used during :vlopt:`--hierarchical`; specifies
|
||||
name of hierarchical parameters file for deparametrized modules with
|
||||
:option:`/*verilator&32;hier_block*/` metacomment. See
|
||||
:ref:`Hierarchical Verilation`.
|
||||
|
||||
.. option:: -I<dir>
|
||||
|
||||
See :vlopt:`-y`.
|
||||
@@ -771,6 +837,11 @@ Summary:
|
||||
If the design is not to be completely Verilated, see also the
|
||||
:vlopt:`--bbox-sys` and :vlopt:`--bbox-unsup` options.
|
||||
|
||||
.. option:: --localize-max-size <value>
|
||||
|
||||
Rarely needed. Set the maximum variable size in bytes for it to be
|
||||
subject to localizing-to-stack optimization. Defaults to 1024.
|
||||
|
||||
.. option:: --make <build-tool>
|
||||
|
||||
Generates a script for the specified build tool.
|
||||
@@ -939,6 +1010,13 @@ Summary:
|
||||
:option:`/*verilator&32;sc_bv*/` metacomment to select specific ports to
|
||||
be sc_bv.
|
||||
|
||||
.. option:: --pins-inout-enables
|
||||
|
||||
Specifies that the __en and __out outputs will always be created for
|
||||
inouts in the top-level module. The __en variable has a one in a bit
|
||||
position to indicate the corresponding bit of the __out variable has
|
||||
a value being driven from within the Verilated model.
|
||||
|
||||
.. option:: --pins-sc-uint
|
||||
|
||||
Specifies SystemC inputs/outputs greater than 2 bits wide should use
|
||||
@@ -946,6 +1024,10 @@ Summary:
|
||||
:vlopt:`--pins-sc-biguint` combination, it results in sc_uint being used
|
||||
between 2 and 64 and sc_biguint being used between 65 and 512.
|
||||
|
||||
.. option:: --pins-sc-uint-bool
|
||||
|
||||
Specifies SystemC inputs/outputs one bit wide should use sc_uint<1>.
|
||||
|
||||
.. option:: --pins-sc-biguint
|
||||
|
||||
Specifies SystemC inputs/outputs greater than 65 bits wide should use
|
||||
@@ -1128,11 +1210,20 @@ Summary:
|
||||
Overwrites the given parameter(s) of the top-level module. See
|
||||
:vlopt:`-G <-G<name>>` for a detailed description.
|
||||
|
||||
.. option:: --quiet
|
||||
|
||||
Alias for :vlopt:`--quiet-exit` :vlopt:`--quiet-stats`.
|
||||
|
||||
.. option:: --quiet-exit
|
||||
|
||||
When exiting due to an error, do not display the "Exiting due to Errors"
|
||||
nor "Command Failed" messages.
|
||||
|
||||
.. option:: --quiet-stats
|
||||
|
||||
Disable printing the Verilation statistics report, see :ref:`Verilation
|
||||
Summary Report`.
|
||||
|
||||
.. option:: --relative-includes
|
||||
|
||||
When a file references an include file, resolve the filename relative to
|
||||
@@ -1183,6 +1274,40 @@ Summary:
|
||||
Run Verilator and record with the :command:`rr` command. See
|
||||
`https://rr-project.org <https://rr-project.org>`_.
|
||||
|
||||
.. option:: --runtime-debug
|
||||
|
||||
Enable including debug assertions in the generated model. This may
|
||||
significantly decrease model performance. This option will only work
|
||||
with gcc/clang.
|
||||
|
||||
This option has the same effect as the following flags:
|
||||
|
||||
:vlopt:`--decorations node <--decorations>`
|
||||
Instructs Verilator to add comments to the Verilated C++ code to
|
||||
assist determining what Verilog code was responsible for each C++
|
||||
statement.
|
||||
|
||||
``-CFLAGS -ggdb -LDFLAGS -ggdb``
|
||||
Instructs the compiler and linker to enable debugger symbols.
|
||||
|
||||
``-CFLAGS -fsanitize=address,undefined -LDFLAGS -fsanitize=address,undefined``
|
||||
Instructs the compiler and linker to enable the address sanitizer, and
|
||||
undefined behavior sanitizer.
|
||||
|
||||
``-CFLAGS -D_GLIBCXX_DEBUG``
|
||||
Instructs the compiler to enable C++ library (glibc) internal
|
||||
assertions to find library-misuse issues.
|
||||
|
||||
``-CFLAGS -DVL_DEBUG=1``
|
||||
Instructs the compiler to enable Verilator's runtime assertions and
|
||||
debug capabilities. To enable debug print messages at runtime, see
|
||||
:vlopt:`+verilator+debug`.
|
||||
|
||||
The :vlopt:`-CFLAGS` and/or :vlopt:`-LDFLAGS` options used here pass the
|
||||
following argument into the generated Makefile for use as compiler or
|
||||
linker options respectively. If you are using your own Makefiles, adapt
|
||||
appropriately to pass the suggested flags to the compiler and linker.
|
||||
|
||||
.. option:: --savable
|
||||
|
||||
Enable including save and restore functions in the generated model. See
|
||||
@@ -1205,6 +1330,8 @@ Summary:
|
||||
|
||||
Creates a dump file with statistics on the design in
|
||||
:file:`<prefix>__stats.txt`.
|
||||
Also dumps DFG patterns to
|
||||
:file:`<prefix>__stats_dfg_patterns__*.txt`.
|
||||
|
||||
.. option:: --stats-vars
|
||||
|
||||
@@ -1216,6 +1343,10 @@ Summary:
|
||||
|
||||
Prevents parsing standard library.
|
||||
|
||||
.. option:: --no-stop-fail
|
||||
|
||||
Don't call $stop when assertion fails. Simulation will continue.
|
||||
|
||||
.. option:: --structs-packed
|
||||
|
||||
Converts all unpacked structures to packed structures, and issues an
|
||||
@@ -1226,12 +1357,12 @@ Summary:
|
||||
.. option:: -sv
|
||||
|
||||
Specifies SystemVerilog language features should be enabled; equivalent
|
||||
to :vlopt:`--language 1800-2017 <--language>`. This option is selected
|
||||
to :vlopt:`--language 1800-2023 <--language>`. This option is selected
|
||||
by default; it exists for compatibility with other simulators.
|
||||
|
||||
.. option:: +systemverilogext+<ext>
|
||||
|
||||
A synonym for :vlopt:`+1800-2017ext+\<ext\>`.
|
||||
A synonym for :vlopt:`+1800-2023ext+\<ext\>`.
|
||||
|
||||
.. option:: --threads <threads>
|
||||
|
||||
@@ -1424,13 +1555,17 @@ Summary:
|
||||
|
||||
.. option:: --unroll-count <loops>
|
||||
|
||||
Rarely needed. Specifies the maximum number of loop iterations that may be
|
||||
unrolled. See also :option:`BLKLOOPINIT` warning.
|
||||
Rarely needed. Specifies the maximum number of loop iterations that may
|
||||
be unrolled. See also :option:`BLKLOOPINIT` warning, and
|
||||
:option:`/*verilator&32;unroll_disable*/` and
|
||||
:option:`/*verilator&32;unroll_full*/` metacomments.
|
||||
|
||||
.. option:: --unroll-stmts <statements>
|
||||
|
||||
Rarely needed. Specifies the maximum number of statements in a loop for
|
||||
that loop to be unrolled. See also :option:`BLKLOOPINIT` warning.
|
||||
that loop to be unrolled. See also :option:`BLKLOOPINIT` warning, and
|
||||
:option:`/*verilator&32;unroll_disable*/` and
|
||||
:option:`/*verilator&32;unroll_full*/` metacomments.
|
||||
|
||||
.. option:: --unused-regexp <regexp>
|
||||
|
||||
@@ -1450,6 +1585,11 @@ Summary:
|
||||
used to resolve instances in the top-level module, otherwise, they are
|
||||
ignored. Note "-v" is relatively standard across Verilog tools.
|
||||
|
||||
.. option:: --valgrind
|
||||
|
||||
Run Verilator under `Valgrind <https://valgrind.org/>`_. The command may be
|
||||
changed with :option:`VERILATOR_VALGRIND`.
|
||||
|
||||
.. option:: --no-verilate
|
||||
|
||||
When using :vlopt:`--build`, disable the generation of C++/SystemC code, and
|
||||
@@ -1628,9 +1768,9 @@ Summary:
|
||||
|
||||
.. note::
|
||||
|
||||
This option applies only to values explicitly written as X
|
||||
in modules (not classes) in the Verilog source code. Initial values
|
||||
of clocks are set to 0 unless `--x-initial-edge` is
|
||||
This option applies only to values explicitly written as X in modules
|
||||
(not classes, nor parameters) in the Verilog source code. Initial
|
||||
values of clocks are set to 0 unless `--x-initial-edge` is
|
||||
specified. Initial values of all other state holding variables are
|
||||
controlled with `--x-initial`.
|
||||
|
||||
@@ -1695,19 +1835,58 @@ Summary:
|
||||
iterations. This may be another indication of problems with the
|
||||
modeled design that should be addressed.
|
||||
|
||||
.. option:: --json-only
|
||||
|
||||
Create JSON output only, do not create any other output.
|
||||
|
||||
The JSON format is intended to be used to leverage Verilator's parser and
|
||||
elaboration to feed to other downstream tools. For details on the format, see
|
||||
the Verilator Internals manual. Be aware that the JSON
|
||||
format is still evolving; there will be some changes in future versions.
|
||||
|
||||
This option disables some more aggressive transformations and dumps only
|
||||
the final state of the AST. For more granular and unaltered dumps, meant
|
||||
mainly for debugging see :vlopt:`--dump-tree-json`.
|
||||
|
||||
.. option:: --json-only-meta-output <filename>
|
||||
|
||||
Specifies the filename for the metadata output file (`.tree.meta.json`) of --json-only.
|
||||
Using this option automatically sets :vlopt:`--json-only`.
|
||||
|
||||
.. option:: --json-only-output <filename>
|
||||
|
||||
Specifies the filename for the main output file (`.tree.json`) of --json-only.
|
||||
Using this option automatically sets :vlopt:`--json-only`.
|
||||
|
||||
.. option:: --no-json-edit-nums
|
||||
|
||||
Don't dump edit number in .tree.json files. This may make the file more
|
||||
run-to-run stable for easier comparison.
|
||||
|
||||
.. option:: --no-json-ids
|
||||
|
||||
Don't use short identifiers instead of addresses/paths in .tree.json.
|
||||
|
||||
.. option:: --xml-only
|
||||
|
||||
Create XML output only, do not create any other output.
|
||||
|
||||
The XML format is intended to be used to leverage Verilator's parser and
|
||||
elaboration to feed to other downstream tools. Be aware that the XML
|
||||
format is still evolving; there will be some changes in future versions.
|
||||
elaboration to feed to other downstream tools.
|
||||
|
||||
.. note::
|
||||
|
||||
This feature is deprecated in favor of :vlopt:`--json-only`.
|
||||
|
||||
.. option:: --xml-output <filename>
|
||||
|
||||
Specifies the filename for the XML output file. Using this option
|
||||
automatically sets :vlopt:`--xml-only`.
|
||||
|
||||
.. note::
|
||||
|
||||
This feature is deprecated in favor of :vlopt:`--json-only`.
|
||||
|
||||
.. option:: -y <dir>
|
||||
|
||||
Add the directory to the list of directories that should be searched to find
|
||||
@@ -1824,6 +2003,13 @@ The grammar of configuration commands is as follows:
|
||||
that the setting is ignored unless the :vlopt:`--hierarchical` option is
|
||||
specified. See :ref:`Hierarchical Verilation`.
|
||||
|
||||
.. option:: hier_params -module "<modulename>"
|
||||
|
||||
Specifies that the module contains parameters a :vlopt:`--hierarchical` block. This option
|
||||
is used internally to specify parameters for deparametrized hier block instances.
|
||||
This option should not be used directly.
|
||||
See :ref:`Hierarchical Verilation`.
|
||||
|
||||
.. option:: inline -module "<modulename>"
|
||||
|
||||
Specifies the module may be inlined into any modules that use this
|
||||
|
||||
@@ -37,9 +37,9 @@ verilator_coverage Example Usage
|
||||
|
||||
verilator_coverage --annotate <obj>
|
||||
|
||||
verilator_coverage -write merged.dat -read <datafiles>...
|
||||
verilator_coverage -write merged.dat <datafiles>...
|
||||
|
||||
verilator_coverage -write-info merged.info -read <datafiles>...
|
||||
verilator_coverage -write-info merged.info <datafiles>...
|
||||
|
||||
|
||||
verilator_coverage Arguments
|
||||
|
||||
@@ -36,8 +36,7 @@ or "`ifdef`"'s may break other tools.
|
||||
.. option:: """ [string] """
|
||||
|
||||
A triple-quoted block specifies a string that may include newlines and
|
||||
single quotes. This extension is experimental and may be removed
|
||||
without deprecation.
|
||||
single quotes. This extension was standardized in IEEE 1800-2023.
|
||||
|
||||
.. option:: $c([string], ...);
|
||||
|
||||
@@ -577,6 +576,10 @@ or "`ifdef`"'s may break other tools.
|
||||
|
||||
.. option:: /*verilator&32;trace_init_task*/
|
||||
|
||||
Removed.
|
||||
|
||||
In versions before 5.024:
|
||||
|
||||
Attached to a DPI import to indicate that function should be called when
|
||||
initializing tracing. This attribute is indented only to be used
|
||||
internally in code that Verilator generates when :vlopt:`--lib-create`
|
||||
@@ -594,6 +597,23 @@ or "`ifdef`"'s may break other tools.
|
||||
Re-enable waveform tracing for all future signals or instances that are
|
||||
declared.
|
||||
|
||||
.. option:: /*verilator&32;unroll_disable*/
|
||||
|
||||
Used in a statement position to indicate the immediately following loop
|
||||
at the same statement level should not be unrolled by Verilator,
|
||||
ignoring :vlopt:`--unroll-count`. This is similar to clang's ``#pragma
|
||||
clang loop unroll(disable)``.
|
||||
|
||||
This option does not currently disable the C++ compiler's unrolling (or
|
||||
not) of any loops that make it through to the Verilated C++ code.
|
||||
|
||||
.. option:: /*verilator&32;unroll_full*/
|
||||
|
||||
Rarely needed. Used in a statement position to indicate the immediately
|
||||
following loop at the same statement level should always be fully
|
||||
unrolled by Verilator, ignoring :vlopt:`--unroll-count`. This is
|
||||
similar to clang's ``#pragma clang loop unroll(full)``.
|
||||
|
||||
.. option:: $stacktrace
|
||||
|
||||
Called as a task, print a stack trace. Called as a function, return a
|
||||
@@ -602,4 +622,4 @@ or "`ifdef`"'s may break other tools.
|
||||
symbols. Also, the data represents the C++ stack; the SystemVerilog
|
||||
functions/tasks involved may be renamed and/or inlined before becoming
|
||||
the C++ functions that may be visible in the stack trace. This
|
||||
extension is experimental and may be removed without deprecation.
|
||||
extension was standardized in IEEE 1800-2023.
|
||||
|
||||
+20
-13
@@ -128,10 +128,13 @@ How do I generate waveforms (traces) in C++?
|
||||
|
||||
See also the next question for tracing in SystemC mode.
|
||||
|
||||
A. Pass the :vlopt:`--trace` option to Verilator, and in your top-level C
|
||||
code, call ``Verilated::traceEverOn(true)``. Then you may use
|
||||
``$dumpfile`` and ``$dumpvars`` to enable traces, the same as with any
|
||||
Verilog simulator. See ``examples/make_tracing_c`` in the distribution.
|
||||
A. Pass the :vlopt:`--trace` option to Verilator. Then you may use ``$dumpfile`` and
|
||||
``$dumpvars`` to enable traces, the same as with any Verilog simulator,
|
||||
although Verilator ignores the arguments to ``$dumpvars``. See
|
||||
``examples/make_tracing_c`` in the distribution.
|
||||
|
||||
If writing the top-level C code, call ``Verilated::traceEverOn(true)``;
|
||||
this is done for you if using :vlopt:`--binary`.
|
||||
|
||||
B. Or, for finer-grained control, or C++ files with multiple Verilated
|
||||
modules, you may also create the trace purely from C++. Create a
|
||||
@@ -226,12 +229,14 @@ How do I generate FST waveforms (traces) in C++ or SystemC?
|
||||
|
||||
FST is a trace file format developed by GTKWave. Verilator provides basic
|
||||
FST support. To dump traces in FST format, add the :vlopt:`--trace-fst`
|
||||
option to Verilator and either A. use :code:`$dumpfile & $dumpvars` in
|
||||
Verilog as described in the VCD example above,
|
||||
option to Verilator and either:
|
||||
|
||||
Use :code:`$dumpfile & $dumpvars` in Verilog as described in the VCD
|
||||
example above,
|
||||
|
||||
Or, in C++ change the include described in the VCD example above:
|
||||
|
||||
.. code-block:: C++
|
||||
.. code-block:: C++
|
||||
|
||||
#include "verilated_fst_c.h"
|
||||
VerilatedFstC* tfp = new VerilatedFstC;
|
||||
@@ -239,14 +244,14 @@ Or, in C++ change the include described in the VCD example above:
|
||||
|
||||
Or, in SystemC, change the include described in the VCD example above:
|
||||
|
||||
.. code-block:: C++
|
||||
.. code-block:: C++
|
||||
|
||||
#include "verilated_fst_sc.h"
|
||||
VerilatedFstC* tfp = new VerilatedFstSc;
|
||||
|
||||
|
||||
Currently, supporting FST and VCD in a single simulation is impossible, but
|
||||
such requirement should be rare. You can however ifdef around the trace
|
||||
Currently, supporting FST and VCD in a single simulation is not supported,
|
||||
but such usage should be unlikely. You can however ifdef around the trace
|
||||
format in your C++ main loop, and select VCD or FST at compile time.
|
||||
|
||||
|
||||
@@ -254,9 +259,11 @@ How do I view waveforms (aka dumps or traces)?
|
||||
""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
Verilator creates standard VCD (Value Change Dump) and FST files. VCD
|
||||
files are viewable with the open-source GTKWave (recommended), or Dinotrace
|
||||
(legacy) programs, or any of the many closed-source offerings; FST is
|
||||
supported only by GTKWave.
|
||||
files are viewable with the open-source
|
||||
`GTKWave <http://gtkwave.sourceforge.net/>`_,
|
||||
`Surfer <https://surfer-project.org/>`_, Dinotrace (legacy), or any of the
|
||||
many closed-source viewer offerings; FST is supported only by GTKWave and
|
||||
Surfer.
|
||||
|
||||
|
||||
How do I speed up writing large waveform (trace) files?
|
||||
|
||||
+16
-10
@@ -48,12 +48,6 @@ For --cc/--sc, it creates:
|
||||
- Make include file for compiling (from --make gmake)
|
||||
* - *{prefix}*\ _classes.mk
|
||||
- Make include file with class names (from --make gmake)
|
||||
* - *{prefix}*\ _hier.mk
|
||||
- Make file for hierarchy blocks (from --make gmake)
|
||||
* - *{prefix}*\ __hierMkArgs.f
|
||||
- Arguments for hierarchical Verilation (from --make gmake)
|
||||
* - *{prefix}*\ __hierCMakeArgs.f
|
||||
- Arguments for hierarchical Verilation (from --make cmake)
|
||||
* - *{prefix}*\ .h
|
||||
- Model header
|
||||
* - *{prefix}*\ .cpp
|
||||
@@ -95,16 +89,24 @@ For --cc/--sc, it creates:
|
||||
* - *{prefix}{each_verilog_module}{__DepSet_hash__n}*\ .cpp
|
||||
- Additional lower C++ files (hashed to reduce build times)
|
||||
|
||||
For --hierarchy mode, it creates:
|
||||
For --hierarchical mode, it creates:
|
||||
|
||||
.. list-table::
|
||||
|
||||
* - V\ *{hier_block}*\ /
|
||||
- Directory to Verilate each hierarchy block (from --hierarchy)
|
||||
- Directory to Verilate each hierarchical block (from --hierarchical)
|
||||
* - *{prefix}*\ __hierVer.d
|
||||
- Make dependencies of the top module (from --hierarchy)
|
||||
- Make dependencies of the top module (from --hierarchical)
|
||||
* - *{prefix}*\ _hier.mk
|
||||
- Make file for hierarchical blocks (from --make gmake)
|
||||
* - *{prefix}*\ __hierCMakeArgs.f
|
||||
- Arguments for hierarchical Verilation (from --make cmake)
|
||||
* - *{prefix}*\ __hierMkArgs.f
|
||||
- Arguments for hierarchical Verilation (from --make gmake)
|
||||
* - *{prefix}*\ __hierParameters.v
|
||||
- Module parameters for hierarchical blocks
|
||||
* - *{prefix}*\ __hier.dir
|
||||
- Directory to store .dot, .vpp, .tree of top module (from --hierarchy)
|
||||
- Directory to store .dot, .vpp, .tree of top module (from --hierarchical)
|
||||
|
||||
In specific debug and other modes, it also creates:
|
||||
|
||||
@@ -112,6 +114,10 @@ In specific debug and other modes, it also creates:
|
||||
|
||||
* - *{prefix}*\ .xml
|
||||
- XML tree information (from --xml)
|
||||
* - *{prefix}*\ .tree.json
|
||||
- JSON tree information (from --json-only)
|
||||
* - *{prefix}*\ .tree.meta.json
|
||||
- JSON tree metadata (from --json-only)
|
||||
* - *{prefix}*\ __cdc.txt
|
||||
- Clock Domain Crossing checks (from --cdc)
|
||||
* - *{prefix}*\ __stats.txt
|
||||
|
||||
+17
-4
@@ -126,8 +126,9 @@ Those developing Verilator itself may also want these (see internals.rst):
|
||||
::
|
||||
|
||||
sudo apt-get install clang clang-format-14 cmake gdb gprof graphviz lcov
|
||||
sudo apt-get install libclang-dev yapf3 bear
|
||||
sudo pip3 install clang sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe ruff
|
||||
sudo apt-get install python3-clang yapf3 bear jq
|
||||
sudo pip3 install sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe ruff
|
||||
sudo pip3 install git+https://github.com/antmicro/astsee.git
|
||||
cpan install Pod::Perldoc
|
||||
cpan install Parallel::Forker
|
||||
|
||||
@@ -151,6 +152,17 @@ To make use of Verilator FST tracing you will want `GTKwave
|
||||
required at Verilator build time.
|
||||
|
||||
|
||||
Install Z3
|
||||
^^^^^^^^^^
|
||||
|
||||
In order to use constrained randomization the `Z3 Theorem Prover
|
||||
<https://github.com/z3prover/z3#readme>`__ must be installed, however this is
|
||||
not required at Verilator build time. There are other compatible SMT solvers,
|
||||
like CVC5/CVC4, but they are not guaranteed to work. Since different solvers are
|
||||
faster for different scenarios, the solver to use at run-time can be specified
|
||||
by the environment variable :option:`VERILATOR_SOLVER`.
|
||||
|
||||
|
||||
.. _Obtain Sources:
|
||||
|
||||
Obtain Sources
|
||||
@@ -192,8 +204,9 @@ Eventual Installation Options
|
||||
Before configuring the build, you must decide how you're going to
|
||||
eventually install Verilator onto your system. Verilator will be compiling
|
||||
the current value of the environment variables :option:`VERILATOR_ROOT`,
|
||||
:option:`SYSTEMC_INCLUDE`, and :option:`SYSTEMC_LIBDIR` as defaults into
|
||||
the executable, so they must be correct before configuring.
|
||||
:option:`VERILATOR_SOLVER`, :option:`SYSTEMC_INCLUDE`, and
|
||||
:option:`SYSTEMC_LIBDIR` as defaults into the executable, so they must be
|
||||
correct before configuring.
|
||||
|
||||
These are the installation options:
|
||||
|
||||
|
||||
@@ -62,12 +62,23 @@ Verilator supports the 2017 "for" loop constructs and several cleanups IEEE
|
||||
made in 1800-2017.
|
||||
|
||||
|
||||
SystemVerilog 2023 (IEEE 1800-2023) Support
|
||||
-------------------------------------------
|
||||
|
||||
Verilator supports some of the 2023 improvements, including triple-quoted
|
||||
string blocks that may include newlines and single quotes.
|
||||
|
||||
Verilator implements a full IEEE 1800-2023 compliant preprocessor,
|
||||
including triple-quoted strings, and \`ifdef expressions.
|
||||
|
||||
|
||||
Verilog AMS Support
|
||||
-------------------
|
||||
|
||||
Verilator implements a very small subset of Verilog AMS (Verilog Analog and
|
||||
Mixed-Signal Extensions) with the subset corresponding to those VMS
|
||||
keywords with near-equivalents in Verilog 2005 or SystemVerilog 2017.
|
||||
keywords with near-equivalents in Verilog IEEE 1364 or SystemVerilog
|
||||
IEEE 1800.
|
||||
|
||||
AMS parsing is enabled with :vlopt:`--language VAMS <--language>` or
|
||||
:vlopt:`--language 1800+VAMS <--language>`.
|
||||
|
||||
@@ -23,12 +23,12 @@ resulting model's C++ or SystemC code is output as .cpp and .h files. This
|
||||
is referred to as "Verilating", and the process is "to Verilate"; the
|
||||
output is a "Verilated" model.
|
||||
|
||||
2. For simulation, a small-user written C++ wrapper file is required, the
|
||||
2. For simulation, a small user-written C++ wrapper file is required, the
|
||||
"wrapper". This wrapper defines the C++ standard function "main()", which
|
||||
instantiates the Verilated model as a C++/SystemC object.
|
||||
|
||||
3. The user C++ wrapper, the files created by Verilator, a "runtime
|
||||
library" provided by Verilator, and, if applicable SystemC libraries are
|
||||
library" provided by Verilator, and, if applicable, SystemC libraries are
|
||||
then compiled using a C++ compiler to create a simulation executable.
|
||||
|
||||
4. The resulting executable will perform the actual simulation during
|
||||
@@ -50,6 +50,6 @@ The best place to get started is to try the :ref:`Examples`.
|
||||
.. [#] SystemVerilog is defined by the `Institute of Electrical and
|
||||
Electronics Engineers (IEEE) Standard for SystemVerilog - Unified
|
||||
Hardware Design, Specification, and Verification Language`, Standard
|
||||
1800, released in 2005, 2009, 2012, and 2017. The Verilator
|
||||
documentation uses the shorthand e.g., "IEEE 1800-2017", to refer to
|
||||
the, e.g., 2017 version of this standard.
|
||||
1800, released in 2005, 2009, 2012, 2017, and 2023. The Verilator
|
||||
documentation uses the shorthand e.g., "IEEE 1800-2023", to refer to
|
||||
the, e.g., 2023 version of this standard.
|
||||
|
||||
+101
-20
@@ -12,6 +12,60 @@ Verilated model's executable. For the runtime arguments to a simulated
|
||||
model, see :ref:`Simulation Runtime Arguments`.
|
||||
|
||||
|
||||
.. _Simulation Summary Report:
|
||||
|
||||
Simulation Summary Report
|
||||
=========================
|
||||
|
||||
When simulation finishes, it will print a report to stdout summarizing the
|
||||
simulation. This requires the model being Verilated with :vlopt:`--main`.
|
||||
The report may be disabled with :vlopt:`+verilator+quiet`.
|
||||
|
||||
For example:
|
||||
|
||||
.. code-block::
|
||||
|
||||
- S i m u l a t i o n R e p o r t: Verilator ...
|
||||
- Verilator: End at simtime 123 ns; walltime 1234.001 s; speed 123 ns/s
|
||||
- Verilator: cpu 22.001 s on 4 threads; alloced 123 MB
|
||||
|
||||
The information in this report is:
|
||||
|
||||
.. describe:: "Verilator ..."
|
||||
|
||||
Program version.
|
||||
|
||||
.. describe:: "End at simtime 123 ns"
|
||||
|
||||
Verilog $time at which the model finished or stopped.
|
||||
|
||||
.. describe:: "walltime 1234.001 s"
|
||||
|
||||
Real elapsed wall time in seconds.
|
||||
|
||||
.. describe:: "speed 123.1 ns/s"
|
||||
|
||||
Simulated time (if non-zero) divided by wall time. e.g. `123 ns/s` means
|
||||
123 simulated nanoseconds took 1 second of wall time; for a model with
|
||||
only a 1 GHz clock that would be equivalent to 123.1 cycles per
|
||||
second. The units are automatically selected to give a number between 1
|
||||
and 1000. The wall time includes initialization, initial and final
|
||||
process blocks, so indicates a slower speed than if the model had a
|
||||
longer runtime.
|
||||
|
||||
.. describe:: "cpu 22 s"
|
||||
|
||||
CPU time used total across all CPU threads in seconds.
|
||||
|
||||
.. describe:: "4 threads"
|
||||
|
||||
Number of simultaneous threads used.
|
||||
|
||||
.. describe:: "alloced 123 MB"
|
||||
|
||||
Total memory used during simulation in megabytes.
|
||||
|
||||
|
||||
.. _Benchmarking & Optimization:
|
||||
|
||||
Benchmarking & Optimization
|
||||
@@ -230,14 +284,20 @@ Coverage Collection
|
||||
When any coverage flag is used to Verilate, Verilator will add appropriate
|
||||
coverage point insertions into the model and collect the coverage data.
|
||||
|
||||
To get the coverage data from the model, in the user wrapper code,
|
||||
typically at the end once a test passes, call
|
||||
:code:`Verilated::threadContextp()->coveragep()->write` with an argument of the filename for
|
||||
the coverage data file to write coverage data to (typically
|
||||
"logs/coverage.dat").
|
||||
To get the coverage data from the model, write the coverage with either:
|
||||
|
||||
1. Using :vlopt:`--binary` or :vlopt:`--main`, and Verilator will dump
|
||||
coverage when the test completes to the filename specified with
|
||||
:vlopt:`+verilator+coverage+file+\<filename\>`.
|
||||
|
||||
2. In the user wrapper code, typically at the end once a test passes, call
|
||||
:code:`Verilated::threadContextp()->coveragep()->write` with an argument
|
||||
of the filename for the coverage data file to write coverage data to
|
||||
(typically "logs/coverage.dat").
|
||||
|
||||
Run each of your tests in different directories, potentially in parallel.
|
||||
Each test will create a :file:`logs/coverage.dat` file.
|
||||
Each test will create the file specified above,
|
||||
e.g. :file:`logs/coverage.dat`.
|
||||
|
||||
After running all of the tests, execute the :command:`verilator_coverage`
|
||||
command, passing arguments pointing to the filenames of all the
|
||||
@@ -273,13 +333,17 @@ profiled C++ code functions.
|
||||
|
||||
To use profiling:
|
||||
|
||||
#. Use Verilator's :vlopt:`--prof-cfuncs`.
|
||||
#. Make sure the Verilog code will call `$finish` at the end of simulation
|
||||
(otherwise the C library may not correctly create the `gmon.out` file in
|
||||
the later steps below).
|
||||
#. Run Verilator, adding the :vlopt:`--prof-cfuncs` option.
|
||||
#. Build and run the simulation model.
|
||||
#. The model will create gmon.out.
|
||||
#. Run :command:`gprof` to see where in the C++ code the time is spent.
|
||||
#. Run the gprof output through the :command:`verilator_profcfunc` program,
|
||||
and it will tell you what Verilog line numbers on which most of the time
|
||||
is being spent.
|
||||
#. The model will create `gmon.out`.
|
||||
#. Run :command:`gprof gmon.out > gprof.log` to see where in the C++ code
|
||||
the time is spent.
|
||||
#. Run :command:`verilator_profcfunc gprof.log > profcfunc.log` to take the
|
||||
gprof output and translate into output showing the Verilog line numbers
|
||||
on which most of the time is being spent.
|
||||
|
||||
|
||||
.. _Execution Profiling:
|
||||
@@ -505,13 +569,30 @@ documentation.
|
||||
Runtime Debugging
|
||||
=================
|
||||
|
||||
To debug a Verilated executable, use the standard GNU debugger ``gdb`` or a
|
||||
similar tool. Typically you will want to have debugger symbols inserted by
|
||||
the compiler, assertions enabled in the C library, and assertions enabled
|
||||
in the Verilated library. (These options slow down the executable, so do
|
||||
this only when debugging.) To enable this, Verilate with:
|
||||
To debug a Verilated executable, Verilate with :vlopt:`--runtime-debug`.
|
||||
This will instruct the compiler to insert debugger, and enable various
|
||||
library assertions. These options slow down the executable, so do this
|
||||
only when debugging.
|
||||
|
||||
-CFLAGS -ggdb -LDFLAGS -ggdb -CFLAGS -DVL_DEBUG=1 -CFLAGS -D_GLIBCXX_DEBUG
|
||||
If you are using your own Makefiles, adapt appropriately to pass the
|
||||
options documented under :vlopt:`--runtime-debug` to the compiler and
|
||||
linker.
|
||||
|
||||
The :vlopt:`-CFLAGS` and/or :vlopt:`-LDFLAGS` options pass arguments
|
||||
directly to the compiler or linker.
|
||||
Once you have a debugging-enabled executable, run it using the the standard
|
||||
GNU debugger ``gdb`` or a similar tool, and create a backtrace; e.g.:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
gdb obj_dir/Vtop
|
||||
run {Vtop_command_arguments}
|
||||
{Vtop prints output, perhaps a segmentation faults}
|
||||
bt
|
||||
|
||||
Rarely the bug may disappear with :vlopt:`--runtime-debug`; if so, try
|
||||
instead using the sub-options that :vlopt:`--runtime-debug` documents, to
|
||||
find the maximum subset that still shows the issue. E.g. it is likely that
|
||||
using `-CFLAGS -D_GLIBCXX_DEBUG` will not hide any bug, so may be used.
|
||||
|
||||
Using :vlopt:`--runtime-debug` or `-CFLAGS -DVL_DEBUG=1` will only print a
|
||||
message if something goes wrong. To enable debug print messages at
|
||||
runtime, additionally use the :vlopt:`+verilator+debug` runtime option.
|
||||
|
||||
@@ -304,9 +304,9 @@ GNU Make
|
||||
========
|
||||
|
||||
Verilator defaults to creating GNU Make makefiles for the model. Verilator
|
||||
will call make automatically when the :vlopt:'--build' option is used.
|
||||
will call make automatically when the :vlopt:`--build` option is used.
|
||||
|
||||
If calling Verilator from a makefile, the :vlopt:'-MMD' option will create
|
||||
If calling Verilator from a makefile, the :vlopt:`--MMD` option will create
|
||||
a dependency file, allowing Make to only run Verilator if input Verilog
|
||||
files change.
|
||||
|
||||
@@ -498,3 +498,78 @@ The search paths can be configured by setting some variables:
|
||||
|
||||
Sets the installation prefix of an installed SystemC library. (Same as
|
||||
SYSTEMC_ROOT).
|
||||
|
||||
|
||||
.. _Verilation Summary Report:
|
||||
|
||||
Verilation Summary Report
|
||||
=========================
|
||||
|
||||
When Verilator generates code, unless :vlopt:`--quiet-stats` is used, it
|
||||
will print a report to stdout summarizing the build. For example:
|
||||
|
||||
.. code-block::
|
||||
|
||||
- V e r i l a t i o n R e p o r t: Verilator ....
|
||||
- Verilator: Built from 354 MB sources in 247 modules,
|
||||
into 74 MB in 89 C++ files needing 0.192 MB
|
||||
- Verilator: Walltime 26.580 s (elab=2.096, cvt=18.268,
|
||||
bld=2.100); cpu 26.548 s on 1 threads; alloced 2894.672 MB
|
||||
|
||||
The information in this report is:
|
||||
|
||||
.. describe:: "Verilator ..."
|
||||
|
||||
Program version.
|
||||
|
||||
.. describe:: "234 MB sources"
|
||||
|
||||
Characters of post-preprocessed text in all input
|
||||
Verilog and Verilator Control files in megabytes.
|
||||
|
||||
.. describe:: "247 modules"
|
||||
|
||||
Number of interfaces/modules/classes/packages in design before
|
||||
elaboration.
|
||||
|
||||
.. describe:: "into 74 MB"
|
||||
|
||||
Characters of output C++ code, including comments in megabytes.
|
||||
|
||||
.. describe:: "89 C++ files"
|
||||
|
||||
Number of .cpp files created.
|
||||
|
||||
.. describe:: "needing 192MB"
|
||||
|
||||
Verilation-time minimum-bound estimate of memory needed to run model in
|
||||
megabytes. (Expect to need significantly more.)
|
||||
|
||||
.. describe:: "Walltime 26.580 s"
|
||||
|
||||
Real elapsed wall time for Verilation and build.
|
||||
|
||||
.. describe:: "elab=2.096"
|
||||
|
||||
Wall time to read in files and complete elaboration.
|
||||
|
||||
.. describe:: "cvt=18.268"
|
||||
|
||||
Wall time for Verilator to process and write output.
|
||||
|
||||
.. describe:: "bld=2.1"
|
||||
|
||||
Wall time to compile gcc/clang (if using :vlopt:`--build`).
|
||||
|
||||
.. describe:: "cpu 22.548 s"
|
||||
|
||||
CPU time used, total across all CPU threads.
|
||||
|
||||
.. describe:: "4 threads"
|
||||
|
||||
Number of simultaneous threads used.
|
||||
|
||||
.. describe:: "alloced 123 MB"
|
||||
|
||||
Total memory used during build by Verilator executable (excludes
|
||||
:vlopt:`--build` compiler's usage) in megabytes.
|
||||
|
||||
+164
-40
@@ -161,8 +161,8 @@ List Of Warnings
|
||||
.. option:: BADSTDPRAGMA
|
||||
|
||||
An error that a pragma is badly formed, for pragmas defined by IEEE
|
||||
1800-2017. For example, an empty pragma line, or an incorrectly used
|
||||
'pragma protect'. Third-party pragmas not defined by IEEE 1800-2017 are
|
||||
1800-2023. For example, an empty pragma line, or an incorrectly used
|
||||
'pragma protect'. Third-party pragmas not defined by IEEE 1800-2023 are
|
||||
ignored.
|
||||
|
||||
|
||||
@@ -210,22 +210,35 @@ List Of Warnings
|
||||
|
||||
.. option:: BLKLOOPINIT
|
||||
|
||||
.. TODO better example
|
||||
|
||||
This indicates that the initialization of an array needs to use
|
||||
non-delayed assignments. This is done in the interest of speed; if
|
||||
delayed assignments were used, the simulator would have to copy large
|
||||
arrays every cycle. (In smaller loops, loop unrolling allows the
|
||||
delayed assignment to work, though it's a bit slower than a non-delayed
|
||||
assignment.) Here's an example
|
||||
Indicates certain constructs where non-blocking assignments to unpacked
|
||||
arrays (memories) are not supported inside loops. These typically appear in
|
||||
initialization/reset code:
|
||||
|
||||
.. code-block:: sv
|
||||
|
||||
always @(posedge clk)
|
||||
if (~reset_l)
|
||||
for (i=0; i<`ARRAY_SIZE; i++)
|
||||
array[i] = 0; // Non-delayed for verilator
|
||||
array[i] <= 0; // Non-blocking assignment inside loop
|
||||
else
|
||||
array[address] <= data;
|
||||
|
||||
While this is supported in typical synthesizeable code (including the
|
||||
example above), some complicated cases are not supported. Namely:
|
||||
|
||||
1. If the above loop is inside a suspendable process or fork statement.
|
||||
|
||||
2. If the variable is also the target of a '<=' non-blocking assignment
|
||||
in a suspendable process or fork statement (in addition to a synthesizable
|
||||
loop).
|
||||
|
||||
3. If the element type of the array is a compound type.
|
||||
|
||||
4. In versions before 5.026, any delayed assignment to an array.
|
||||
|
||||
It might slightly improve run-time performance if you change the
|
||||
non-blocking assignment inside the loop into a blocking assignment
|
||||
(that is: use '=' instead of '<='), if possible.
|
||||
|
||||
This message is only seen on large or complicated loops because
|
||||
Verilator generally unrolls small loops. You may want to try increasing
|
||||
@@ -283,7 +296,7 @@ List Of Warnings
|
||||
Unique case statements that select on an enumerated variable, where all
|
||||
of the enumerated values are covered by case items, are considered
|
||||
complete even if the case statement does not cover illegal
|
||||
non-enumerated values (IEEE 1800-2017 12.5.3). To check that illegal
|
||||
non-enumerated values (IEEE 1800-2023 12.5.3). To check that illegal
|
||||
values are not hit, use :vlopt:`--assert`.
|
||||
|
||||
Ignoring this warning will only suppress the lint check; it will
|
||||
@@ -406,9 +419,9 @@ List Of Warnings
|
||||
|
||||
.. option:: CONSTRAINTIGN
|
||||
|
||||
Warns that Verilator does not support :code:`constraint`,
|
||||
:code:`constraint_mode`, or :code:`rand_mode`, and the construct was are
|
||||
ignored.
|
||||
Warns that Verilator does not support certain forms of
|
||||
:code:`constraint`, :code:`constraint_mode`, or :code:`rand_mode`, and
|
||||
the construct was are ignored.
|
||||
|
||||
Ignoring this warning may make Verilator randomize() simulations differ
|
||||
from other simulators.
|
||||
@@ -479,7 +492,7 @@ List Of Warnings
|
||||
|
||||
.. code-block::
|
||||
|
||||
%Warning-DEFPARAM: example.v:5:15: defparam is deprecated (IEEE 1800-2017 C.4.1)
|
||||
%Warning-DEFPARAM: example.v:5:15: defparam is deprecated (IEEE 1800-2023 C.4.1)
|
||||
: ... Suggest use instantiation with #(.MY_PARAM(...etc...))
|
||||
|
||||
To repair use :code:`#(.PARAMETER(...))` syntax. Repaired Example:
|
||||
@@ -707,7 +720,7 @@ List Of Warnings
|
||||
|
||||
.. code-block::
|
||||
|
||||
%Warning-GENUNNAMED: example.v:2:9: Unnamed generate block (IEEE 1800-2017 27.6)
|
||||
%Warning-GENUNNAMED: example.v:2:9: Unnamed generate block (IEEE 1800-2023 27.6)
|
||||
|
||||
To fix this assign a label (often with the naming convention prefix of
|
||||
:code:`gen_` or :code:`g_`), for example:
|
||||
@@ -763,7 +776,7 @@ List Of Warnings
|
||||
|
||||
.. code-block::
|
||||
|
||||
%Warning-IGNOREDRETURN: example.v:5:9: Ignoring return value of non-void function (IEEE 1800-2017 13.4.1)
|
||||
%Warning-IGNOREDRETURN: example.v:5:9: Ignoring return value of non-void function (IEEE 1800-2023 13.4.1)
|
||||
|
||||
The portable way to suppress this warning (in SystemVerilog) is to use a
|
||||
void cast, for example:
|
||||
@@ -1204,6 +1217,14 @@ List Of Warnings
|
||||
:vlopt:`--no-timing` option.
|
||||
|
||||
|
||||
.. option:: NONSTD
|
||||
|
||||
Warns when a non-standard language feature is used that has a standard
|
||||
equivalent, which might behave differently in corner cases. For example
|
||||
:code:`$psprintf` system function is replaced by its standard equivalent
|
||||
:code:`$sformatf`.
|
||||
|
||||
|
||||
.. option:: NULLPORT
|
||||
|
||||
Warns that a null port was detected in the module definition port
|
||||
@@ -1243,7 +1264,7 @@ List Of Warnings
|
||||
|
||||
.. option:: PINMISSING
|
||||
|
||||
.. TODO better example
|
||||
.. TODO better example (frequent)
|
||||
|
||||
Warns that a module has a pin that is not mentioned in an instance. If
|
||||
a pin is not missing it should still be specified on the instance
|
||||
@@ -1252,6 +1273,22 @@ List Of Warnings
|
||||
Ignoring this warning will only suppress the lint check; it will
|
||||
simulate correctly.
|
||||
|
||||
Faulty example:
|
||||
|
||||
.. include:: ../../docs/gen/ex_PKGNODECL_faulty.rst
|
||||
|
||||
Results in:
|
||||
|
||||
.. include:: ../../docs/gen/ex_PKGNODECL_msg.rst
|
||||
|
||||
Repaired example:
|
||||
|
||||
.. code-block:: sv
|
||||
:emphasize-lines: 2
|
||||
|
||||
sub sub (
|
||||
.port());
|
||||
|
||||
Other tools with similar warnings: Icarus Verilog's portbind, "warning:
|
||||
Instantiating module ... with dangling input port (...)". Slang's
|
||||
unconnected-port, "port '...' has no connection".
|
||||
@@ -1283,7 +1320,7 @@ List Of Warnings
|
||||
generate
|
||||
if (A==0) begin
|
||||
b b_inst1 (.x(1'b0)); //<--- error nonexistent port
|
||||
b #(.PX(1'b0)) b_inst2 (); //<--- error nonexistent parameter
|
||||
b #(.PX(1'b0)) b_inst2 (); //<--- error nonexistent parameter
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
@@ -1325,11 +1362,47 @@ List Of Warnings
|
||||
|
||||
.. option:: PKGNODECL
|
||||
|
||||
.. TODO better example
|
||||
An error that a package/class appears to have been referenced that has
|
||||
not yet been declared. According to IEEE 1800-2023 26.3, all packages
|
||||
must be declared before being used.
|
||||
|
||||
An error that a package/class appears to have been referenced that has not
|
||||
yet been declared. According to IEEE 1800-2017 26.3, all packages must
|
||||
be declared before being used.
|
||||
Faulty example:
|
||||
|
||||
.. include:: ../../docs/gen/ex_PKGNODECL_faulty.rst
|
||||
|
||||
Results in:
|
||||
|
||||
.. include:: ../../docs/gen/ex_PKGNODECL_msg.rst
|
||||
|
||||
Often the package is declared in its own header file. In this case add
|
||||
an include of that package header file to the referencing file. (And
|
||||
make sure you have header guards in the package's header file to prevent
|
||||
multiple declarations of the package.)
|
||||
|
||||
|
||||
.. option:: PREPROCZERO
|
||||
|
||||
Warns that a preprocessor \`ifdef/\`ifndef expression (added in IEEE
|
||||
1800-2023) evaluates a define value which has a value of :code:`0`.
|
||||
This will evaluate in the expression as :code:`1` because the define has
|
||||
a definition, unlike in the C preprocessor, which evaluates using the
|
||||
define's value (of :code:`1`).
|
||||
|
||||
Referring to a define with an empty value does not give this warning, as
|
||||
in C, the preprocessor will give an error on a preprocessor expression
|
||||
of a define that is empty.
|
||||
|
||||
.. code-block:: sv
|
||||
:linenos:
|
||||
:emphasize-lines: 2
|
||||
|
||||
`define ZERO 0
|
||||
`ifdef (ZERO || ZERO) //<--- warning PREPROCZERO
|
||||
`error This_will_error_which_might_be_not_the_intent
|
||||
`endif
|
||||
|
||||
The portable way to suppress this warning is to use a define value other
|
||||
than zero, when it is to be used in a preprocessor expression.
|
||||
|
||||
|
||||
.. option:: PROCASSWIRE
|
||||
@@ -1707,7 +1780,7 @@ List Of Warnings
|
||||
|
||||
.. code-block::
|
||||
|
||||
%Warning-TIMESCALEMOD: example.v:1:8: Timescale missing on this module as other modules have it (IEEE 1800-2017 3.14.2.3)
|
||||
%Warning-TIMESCALEMOD: example.v:1:8: Timescale missing on this module as other modules have it (IEEE 1800-2023 3.14.2.3)
|
||||
|
||||
Recommend using :vlopt:`--timescale` argument, or in front of all
|
||||
modules use:
|
||||
@@ -1851,7 +1924,8 @@ List Of Warnings
|
||||
|
||||
.. option:: UNPACKED
|
||||
|
||||
Warns that unpacked structs and unions are not supported.
|
||||
Warns that unpacked structs and unions are not supported because
|
||||
:vlopt:`--structs-packed` was used, or by up through version 5.004.
|
||||
|
||||
Ignoring this warning will make Verilator treat the structure as packed,
|
||||
which may make Verilator simulations differ from other simulators. This
|
||||
@@ -1902,14 +1976,16 @@ List Of Warnings
|
||||
|
||||
.. TODO better example
|
||||
|
||||
Warns that the specified genvar is never used/consumed.
|
||||
Warns that the specified genvar is never used/consumed. See similar
|
||||
:option:`UNUSEDSIGNAL`.
|
||||
|
||||
|
||||
.. option:: UNUSEDPARAM
|
||||
|
||||
.. TODO better example
|
||||
|
||||
Warns that the specified parameter is never used/consumed.
|
||||
Warns that the specified parameter is never used/consumed. See similar
|
||||
:option:`UNUSEDSIGNAL`.
|
||||
|
||||
|
||||
.. option:: UNUSEDSIGNAL
|
||||
@@ -1949,7 +2025,7 @@ List Of Warnings
|
||||
.. option:: USERERROR
|
||||
|
||||
A SystemVerilog elaboration-time assertion error was executed.
|
||||
IEEE 1800-2017 20.11 requires this error.
|
||||
IEEE 1800-2023 20.11 requires this error.
|
||||
|
||||
Faulty example:
|
||||
|
||||
@@ -1965,7 +2041,7 @@ List Of Warnings
|
||||
.. option:: USERFATAL
|
||||
|
||||
A SystemVerilog elaboration-time assertion fatal was executed.
|
||||
IEEE 1800-2017 20.11 requires this error.
|
||||
IEEE 1800-2023 20.11 requires this error.
|
||||
|
||||
Faulty example:
|
||||
|
||||
@@ -1981,7 +2057,7 @@ List Of Warnings
|
||||
.. option:: USERINFO
|
||||
|
||||
A SystemVerilog elaboration-time assertion print was executed. This is
|
||||
not an error or warning, and IEEE 1800-2017 20.11 requires this
|
||||
not an error or warning, and IEEE 1800-2023 20.11 requires this
|
||||
behavior.
|
||||
|
||||
Example:
|
||||
@@ -1996,7 +2072,7 @@ List Of Warnings
|
||||
.. option:: USERWARN
|
||||
|
||||
A SystemVerilog elaboration-time assertion warning was executed.
|
||||
IEEE 1800-2017 20.11 requires this warning.
|
||||
IEEE 1800-2023 20.11 requires this warning.
|
||||
|
||||
Faulty example:
|
||||
|
||||
@@ -2032,10 +2108,6 @@ List Of Warnings
|
||||
|
||||
.. option:: WAITCONST
|
||||
|
||||
.. code-block:: sv
|
||||
|
||||
wait(1); // Blocks forever
|
||||
|
||||
Warns that a `wait` statement awaits a constant condition, which means it
|
||||
either blocks forever or never blocks.
|
||||
|
||||
@@ -2043,6 +2115,12 @@ List Of Warnings
|
||||
something that elaborates to zero), does not warn, as it is presumed the
|
||||
code is making the intent clear.
|
||||
|
||||
Faulty example:
|
||||
|
||||
.. code-block:: sv
|
||||
|
||||
wait(1); // Blocks forever
|
||||
|
||||
|
||||
.. option:: WIDTH
|
||||
|
||||
@@ -2079,7 +2157,7 @@ List Of Warnings
|
||||
|
||||
.. include:: ../../docs/gen/ex_WIDTHEXPAND_1_faulty.rst
|
||||
|
||||
Results in a WIDTHEXPAND warning:
|
||||
Results in a :option:`WIDTHEXPAND` warning:
|
||||
|
||||
.. include:: ../../docs/gen/ex_WIDTHEXPAND_1_msg.rst
|
||||
|
||||
@@ -2090,15 +2168,18 @@ List Of Warnings
|
||||
|
||||
.. option:: WIDTHTRUNC
|
||||
|
||||
A more granular WIDTH warning, for when a value is truncated.
|
||||
A more granular :option:`WIDTH` warning, for when a value is
|
||||
truncated. See :option:`WIDTH`.
|
||||
|
||||
.. option:: WIDTHEXPAND
|
||||
|
||||
A more granular WIDTH warning, for when a value is zero expanded.
|
||||
A more granular :option:`WIDTH` warning, for when a value is zero
|
||||
expanded. See :option:`WIDTH`.
|
||||
|
||||
.. option:: WIDTHXZEXPAND
|
||||
|
||||
A more granular WIDTH warning, for when a value is X/Z expanded.
|
||||
A more granular :option:`WIDTH` warning, for when a value is X/Z
|
||||
expanded. See :option:`WIDTH`.
|
||||
|
||||
.. option:: WIDTHCONCAT
|
||||
|
||||
@@ -2131,3 +2212,46 @@ List Of Warnings
|
||||
Inactive region. Such processes do get resumed in the same time slot
|
||||
somewhere in the Active region. Issued only if Verilator is run with the
|
||||
:vlopt:`--timing` option.
|
||||
|
||||
.. option:: ZEROREPL
|
||||
|
||||
Warns that zero is used as the replication value in the replication
|
||||
operator. This is specified as an error by IEEE 1800-2023 11.4.12.1.
|
||||
|
||||
Faulty example:
|
||||
|
||||
.. code-block:: sv
|
||||
:linenos:
|
||||
:emphasize-lines: 5
|
||||
|
||||
module dut
|
||||
#(parameter int MY_PARAM = 0);
|
||||
reg [7:0] data;
|
||||
always @* begin
|
||||
data = {MY_PARAM{1'b1}}; //<--- Warning
|
||||
end
|
||||
endmodule
|
||||
|
||||
Results in the following error:
|
||||
|
||||
.. code-block::
|
||||
|
||||
%Error-ZEROREPL: test.v:5:22: Replication value of 0 is only legal under a concatenation (IEEE 1800-2023 11.4.12.1)
|
||||
|
||||
Note that in some cases, this warning may be false, when a condition
|
||||
upstream or downstream of the access means the zero replication will
|
||||
never execute or be used.
|
||||
|
||||
Repaired example:
|
||||
|
||||
.. code-block:: sv
|
||||
:linenos:
|
||||
:emphasize-lines: 2
|
||||
|
||||
module dut
|
||||
#(parameter int MY_PARAM = 1); //<--- REPAIRED
|
||||
reg [7:0] data;
|
||||
always @* begin
|
||||
data = {MY_PARAM{1'b1}};
|
||||
end
|
||||
endmodule
|
||||
|
||||
+202
-11
@@ -224,7 +224,7 @@ Scheduling
|
||||
----------
|
||||
|
||||
Verilator implements the Active and NBA regions of the SystemVerilog scheduling
|
||||
model as described in IEEE 1800-2017 chapter 4, and in particular sections
|
||||
model as described in IEEE 1800-2023 chapter 4, and in particular sections
|
||||
4.5 and Figure 4.1. The static (Verilation time) scheduling of SystemVerilog
|
||||
processes is performed by code in the ``V3Sched`` namespace. The single
|
||||
entry point to the scheduling algorithm is ``V3Sched::schedule``. Some
|
||||
@@ -312,7 +312,7 @@ Scheduling of clocked and combinational logic
|
||||
For performance, clocked and combinational logic needs to be ordered.
|
||||
Conceptually this minimizes the iterations through the evaluation loop
|
||||
presented in the reference algorithm in the SystemVerilog standard (IEEE
|
||||
1800-2017 section 4.5), by evaluating logic constructs in data-flow order.
|
||||
1800-2023 section 4.5), by evaluating logic constructs in data-flow order.
|
||||
Without going into a lot of detail here, accept that well thought out ordering
|
||||
is crucial to good simulation performance, and also enables further
|
||||
optimizations later on.
|
||||
@@ -407,7 +407,7 @@ triggered due to a combinational signal change from the previous evaluation
|
||||
pass, and a combinational loop settling due to hybrid logic, if the clocked
|
||||
logic reads the not yet settled combinationally driven signal. Such a race
|
||||
is indeed possible, but our evaluation is consistent with the SystemVerilog
|
||||
scheduling semantics (IEEE 1800-2017 chapter 4), and therefore any program
|
||||
scheduling semantics (IEEE 1800-2023 chapter 4), and therefore any program
|
||||
that exhibits such a race has non-deterministic behavior according to the
|
||||
SystemVerilog semantics, so we accept this.
|
||||
|
||||
@@ -1031,6 +1031,91 @@ the evaluation process records a bitmask of variables that might have
|
||||
changed; if clear, checking those signals for changes may be skipped.
|
||||
|
||||
|
||||
Constrained randomization
|
||||
-------------------------
|
||||
|
||||
Because general constrained randomization is a co-NP-hard problem, not all
|
||||
cases are implemented in Verilator, and an external specialized SMT solver is
|
||||
used for any non-obvious ones.
|
||||
|
||||
The ``randomize()`` method spawns an SMT solver in a sub-process. Then the
|
||||
solver gets a setup query, then the definition of variables, then all the
|
||||
constraints (SMT assertions) about the variables. Since the solver has no
|
||||
information about the class' PRNG state, if the problem is satisfiable,
|
||||
the solution space is further constrained by adding extra random constraints,
|
||||
and querying the values satisfying the problem statement.
|
||||
The constraint is currently constructed as fixing a simple xor of randomly
|
||||
chosen bits of the variables being randomized.
|
||||
|
||||
The runtime classes used for handling the randomization are defined in
|
||||
``verilated_random.h`` and ``verilated_random.cpp``.
|
||||
|
||||
|
||||
``VlSubprocess``
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Subprocess handle, responsible for keeping track of the resources like child
|
||||
PID, read and write file descriptors, and presenting them as a C++ iostream.
|
||||
|
||||
|
||||
``VlRandomizer``
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Randomizer class, responsible for keeping track of variables and constraints,
|
||||
and communicating with the solver subprocess.
|
||||
|
||||
The solver gets the constraints in `SMT-LIB2
|
||||
<https://smtlib.cs.uiowa.edu/>`__ textual format in the following syntax:
|
||||
|
||||
::
|
||||
|
||||
(set-info :smt-lib-version 2.0)
|
||||
(set-option :produce-models true)
|
||||
(set-logic QF_BV)
|
||||
|
||||
(declare-fun v () (_ BitVec 16))
|
||||
(declare-fun w () (_ BitVec 64))
|
||||
(declare-fun x () (_ BitVec 48))
|
||||
(declare-fun z () (_ BitVec 24))
|
||||
(declare-fun t () (_ BitVec 23))
|
||||
(assert (or (= v #x0003) (= v #x0008)))
|
||||
(assert (= w #x0000000000000009))
|
||||
(assert (or (or (= x #x000000000001) (= x #x000000000002)) (or (= x #x000000000004) (= x #x000000000009))))
|
||||
(assert (bvult ((_ zero_extend 8) z) #x00000015))
|
||||
(assert (bvugt ((_ zero_extend 8) z) #x0000000d))
|
||||
|
||||
(check-sat)
|
||||
|
||||
The solver responds with either ``sat`` or ``unsat``. Then the initial solution
|
||||
is queried with:
|
||||
|
||||
::
|
||||
|
||||
(get-value (v w x z t ))
|
||||
|
||||
The solver then responds with e.g.:
|
||||
|
||||
::
|
||||
|
||||
((v #x0008)
|
||||
(w #x0000000000000005)
|
||||
(x #x000000000002)
|
||||
(z #x000010)
|
||||
(t #b00000000000000000000000))
|
||||
|
||||
And then a follow-up query (or a series thereof) is asked, and the solver gets
|
||||
reset, so that it can be reused by subsequent randomization attempts:
|
||||
|
||||
::
|
||||
|
||||
(assert (= (bvxor (bvxor <...> (bvxor ((_ extract 21 21) z) ((_ extract 39 39) x)) ((_ extract 5 5) w)) <...> ((_ extract 10 10) w)) #b0))
|
||||
(check-sat)
|
||||
(get-value)
|
||||
...
|
||||
(reset)
|
||||
|
||||
|
||||
|
||||
Coding Conventions
|
||||
==================
|
||||
|
||||
@@ -1696,6 +1781,84 @@ Similarly, the ``NETLIST`` has a list of modules referred to by its
|
||||
``op1p()`` pointer.
|
||||
|
||||
|
||||
.tree.json Output
|
||||
-----------------
|
||||
|
||||
``.tree.json``` is an alternative dump format to ``.tree`` that is meant for
|
||||
programmatic processing (e.g. with `astsee <https://github.com/antmicro/astsee>`_).
|
||||
To enable this dump format, use :vlopt:`--dump-tree-json` or :vlopt:`--json-only`.
|
||||
|
||||
Structure:
|
||||
::
|
||||
|
||||
{
|
||||
/* Attributes that are common to all types of nodes */
|
||||
"type": "VAR",
|
||||
"name": "cyc",
|
||||
/* By default addresses and filenames use short/stable ids rather than real value */
|
||||
"addr": "(H)",
|
||||
"loc": "a,25:12,26:15", /* "fileid,firstLine:firstCol,lastLine:endCol" (endCol is right exclusive) */
|
||||
"editNum": 602,
|
||||
/* Fields that are specific to AstVar nodes: */
|
||||
"origName": "cyc",
|
||||
"isSc": false,
|
||||
"ioDirection": "NONE",
|
||||
"isConst": false,
|
||||
"isPullup": false,
|
||||
"isPulldown": false,
|
||||
"isUsedClock": false,
|
||||
"isSigPublic": false,
|
||||
"isLatched": false,
|
||||
"isUsedLoopIdx": false,
|
||||
"noReset": false,
|
||||
"attrIsolateAssign": false,
|
||||
"attrFileDescr": false,
|
||||
"isDpiOpenArray": false,
|
||||
"isFuncReturn": false,
|
||||
"isFuncLocal": false,
|
||||
"attrClocker": "UNKNOWN",
|
||||
"lifetime": "NONE",
|
||||
"varType": "VAR",
|
||||
/* Lists of child nodes (which use similar structure as their parent): */
|
||||
"childDTypep": [ /* ... */ ],
|
||||
"delayp": [ /* ... */ ],
|
||||
"valuep": [ /* ... */ ],
|
||||
"attrsp": [ /* ... */ ]
|
||||
}
|
||||
|
||||
.tree.meta.json Output
|
||||
----------------
|
||||
.tree.meta.json contains metadata that is common across the whole AST tree
|
||||
(in case of --dump-tree-json, multiple trees share one meta file).
|
||||
|
||||
Besides de-duplication of data shared between multiple stages, .meta.json enables offloading
|
||||
unstable data (that can vary from machine-to-machine or run-to-run) from main .tree.json.
|
||||
This offloading allows, for example, to use byte-to-byte comparisons of AST dumps in tests.
|
||||
|
||||
::
|
||||
|
||||
{"files": {
|
||||
/* Map id to filename, and other metadata */
|
||||
"d": {"filename":"/home/ant/tmp/verilator/include/verilated_std.sv", "realpath":"/home/ant/tmp/verilator/include/verilated_std.sv", "language":"1800-2023"},
|
||||
"a": {"filename":"<built-in>", "realpath":"<built-in>", "language":"1800-2023"},
|
||||
"b": {"filename":"<command-line>", "realpath":"<command-line>", "language":"1800-2023"},
|
||||
"c": {"filename":"input.vc", "realpath":"/home/ant/tmp/verilator/test_regress/input.vc", "language":"1800-2023"},
|
||||
"e": {"filename":"t/t_EXAMPLE.v", "realpath":"/home/ant/tmp/verilator/test_regress/t/t_EXAMPLE.v", "language":"1800-2023"}
|
||||
},"pointers": {
|
||||
/* Map id to real address */
|
||||
"(AG)": "0x562997289180",
|
||||
"(YF)": "0x5629971c50b0",
|
||||
"(WF)": "0x5629971e7ae0",
|
||||
/* ... /*
|
||||
},"ptrFieldNames": [
|
||||
/* List of fields that are used for storing pointers */
|
||||
"aboveScopep",
|
||||
"voidp",
|
||||
"addr",
|
||||
/* ... */
|
||||
]}
|
||||
|
||||
|
||||
.tree.dot Output
|
||||
----------------
|
||||
|
||||
@@ -1768,6 +1931,20 @@ To print a node:
|
||||
pnt nodep
|
||||
# or: call dumpTreeGdb(nodep) # aliased to "pnt" in src/.gdbinit
|
||||
|
||||
``src/.gdbinit`` and ``src/.gdbinit.py`` define handy utilities for working with
|
||||
JSON AST dumps. For example:
|
||||
|
||||
* ``jstash nodep`` - Perform a JSON AST dump and save it into GDB value history (e.g. ``$1``)
|
||||
* ``jtree nodep`` - Perform a JSON AST dump and pretty print it using ``astsee_verilator``.
|
||||
* ``jtree $1`` - Pretty print a dump that was previously saved by ``jstash``.
|
||||
* ``jtree nodep -d '.file, .timeunit'`` - Perform a JSON AST dump, filter out some fields and pretty print it.
|
||||
* ``jtree 0x55555613dca0`` - Pretty print using address literal (rather than actual pointer).
|
||||
* ``jtree $1 nodep`` - Diff ``nodep`` against an older dump.
|
||||
|
||||
A detailed description of ``jstash`` and ``jtree`` can be displayed using ``gdb``'s ``help`` command.
|
||||
|
||||
These commands require `astsee <https://github.com/antmicro/astsee>`_ to be installed.
|
||||
|
||||
When GDB halts, it is useful to understand that the backtrace will commonly
|
||||
show the iterator functions between each invocation of ``visit`` in the
|
||||
backtrace. You will typically see a frame sequence something like:
|
||||
@@ -1829,21 +2006,21 @@ 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
|
||||
anticipated to be ever implemented for the reasons indicated.
|
||||
|
||||
IEEE 1800-2017 3.3 modules within modules
|
||||
IEEE 1800-2023 3.3 modules within modules
|
||||
Little/no tool support, and arguably not a good practice.
|
||||
IEEE 1800-2017 6.12 "shortreal"
|
||||
IEEE 1800-2023 6.12 "shortreal"
|
||||
Little/no tool support, and easily promoted to real.
|
||||
IEEE 1800-2017 11.11 Min, typ, max
|
||||
IEEE 1800-2023 11.11 Min, typ, max
|
||||
No SDF support, so will always use typical.
|
||||
IEEE 1800-2017 20.16 Stochastic analysis
|
||||
IEEE 1800-2023 20.16 Stochastic analysis
|
||||
Little industry use.
|
||||
IEEE 1800-2017 20.17 PLA modeling
|
||||
IEEE 1800-2023 20.17 PLA modeling
|
||||
Little industry use and outdated technology.
|
||||
IEEE 1800-2017 31 Timing checks
|
||||
IEEE 1800-2023 31 Timing checks
|
||||
No longer relevant with static timing analysis tools.
|
||||
IEEE 1800-2017 32 SDF annotation
|
||||
IEEE 1800-2023 32 SDF annotation
|
||||
No longer relevant with static timing analysis tools.
|
||||
IEEE 1800-2017 33 Config
|
||||
IEEE 1800-2023 33 Config
|
||||
Little industry use.
|
||||
|
||||
|
||||
@@ -1884,6 +2061,10 @@ driver.pl Non-Scenario Arguments
|
||||
files with dumping level 3, which dumps the standard critical stages.
|
||||
For details on the format see `.tree Output`.
|
||||
|
||||
--fail-max <numtests>
|
||||
Set the number of failing tests, after which the driver will stop running
|
||||
additional tests. Defaults to 20, 0 disables.
|
||||
|
||||
--gdb
|
||||
Same as ``verilator --gdb``: Run Verilator under the debugger.
|
||||
|
||||
@@ -1937,6 +2118,9 @@ driver.pl Non-Scenario Arguments
|
||||
--trace
|
||||
Set the simulator specific flags to request waveform tracing.
|
||||
|
||||
--valgrind
|
||||
Same as ``verilator --valgrind``: Run Verilator under `Valgrind <https://valgrind.org/>`_.
|
||||
|
||||
--verbose
|
||||
Compile and run the test in verbose mode. This means ``TEST_VERBOSE``
|
||||
will be defined for the test (Verilog and any C++/SystemC wrapper).
|
||||
@@ -1980,6 +2164,9 @@ simultaneously.
|
||||
--vltmt
|
||||
Run Verilator tests in multithreaded mode.
|
||||
|
||||
--xrun
|
||||
Run Cadence Xcelium simulator tests.
|
||||
|
||||
--xsim
|
||||
Run Xilinx XSim simulator tests.
|
||||
|
||||
@@ -2023,6 +2210,10 @@ VERILATOR_ROOT
|
||||
Standard path to Verilator distribution root; see primary Verilator
|
||||
documentation.
|
||||
|
||||
VERILATOR_SOLVER
|
||||
SMT solver command for constrained randomization; see primary Verilator
|
||||
documentation.
|
||||
|
||||
VERILATOR_TESTS_SITE
|
||||
Used with ``--site``, a colon-separated list of directories with tests to
|
||||
be added to testlist.
|
||||
|
||||
@@ -40,6 +40,7 @@ Brej
|
||||
Briquet
|
||||
Brownlee
|
||||
Buckenmaier
|
||||
Burghoorn
|
||||
Bybell
|
||||
CLang
|
||||
CMake
|
||||
@@ -71,6 +72,7 @@ Deadman
|
||||
Debacker
|
||||
Deepa
|
||||
Defparams
|
||||
Delm
|
||||
Denio
|
||||
Deprecations
|
||||
Deroo
|
||||
@@ -130,6 +132,7 @@ Gernot
|
||||
Gerst
|
||||
Gielda
|
||||
Gigerl
|
||||
Gijs
|
||||
Gileadi
|
||||
Giri
|
||||
Gisselquist
|
||||
@@ -146,6 +149,7 @@ Grulfen
|
||||
Gu
|
||||
Gunter
|
||||
Guo
|
||||
Hameed
|
||||
Hao
|
||||
Haojin
|
||||
Harboe
|
||||
@@ -162,6 +166,7 @@ Homebrew
|
||||
Hornung
|
||||
Hossell
|
||||
Hsu
|
||||
Huggett
|
||||
Hutt
|
||||
Hyperthreading
|
||||
Ibrahim
|
||||
@@ -180,9 +185,11 @@ Jannis
|
||||
Jasen
|
||||
Jens
|
||||
Jeras
|
||||
Jiaxun
|
||||
Jiuyang
|
||||
Joannou
|
||||
Joly
|
||||
Josse
|
||||
Jullien
|
||||
Junji
|
||||
Junyi
|
||||
@@ -372,6 +379,7 @@ Srini
|
||||
Srinivasan
|
||||
Stamness
|
||||
Stephane
|
||||
Sterin
|
||||
Stoddard
|
||||
Stroebel
|
||||
Strouble
|
||||
@@ -437,6 +445,7 @@ Verilog
|
||||
Vighnesh
|
||||
Viktor
|
||||
Vilp
|
||||
Vlip
|
||||
Vm
|
||||
Vukobratovic
|
||||
Wai
|
||||
@@ -453,6 +462,7 @@ Wojciech
|
||||
Wolfel
|
||||
Wouters
|
||||
Wpedantic
|
||||
Wunused
|
||||
Wwarn
|
||||
XSim
|
||||
Xcelium
|
||||
@@ -460,6 +470,7 @@ Xiaoliang
|
||||
Xiaoyi
|
||||
Xuan
|
||||
Xuanqi
|
||||
Yao
|
||||
Yazdanbakhsh
|
||||
Yernagula
|
||||
Yi
|
||||
@@ -488,6 +499,7 @@ architected
|
||||
args
|
||||
arrarys
|
||||
assertOn
|
||||
assertcontrol
|
||||
astgen
|
||||
async
|
||||
atClone
|
||||
@@ -519,6 +531,7 @@ buildenv
|
||||
bv
|
||||
bvs
|
||||
callValueCbs
|
||||
callgrind
|
||||
casex
|
||||
casez
|
||||
casted
|
||||
@@ -579,10 +592,12 @@ defname
|
||||
defparam
|
||||
demangling
|
||||
dep
|
||||
deparametrized
|
||||
der
|
||||
dereference
|
||||
desassign
|
||||
destructor
|
||||
desynchronization
|
||||
detections
|
||||
dev
|
||||
devcontainer
|
||||
@@ -613,6 +628,7 @@ dut
|
||||
dx
|
||||
dynarray
|
||||
elab
|
||||
eliasphanna
|
||||
elike
|
||||
elsif
|
||||
endcase
|
||||
@@ -635,6 +651,7 @@ envvar
|
||||
eof
|
||||
errae
|
||||
erroring
|
||||
esynr
|
||||
et
|
||||
eval
|
||||
evals
|
||||
@@ -666,6 +683,7 @@ foreach
|
||||
fprintf
|
||||
fprofile
|
||||
fread
|
||||
freloop
|
||||
frewind
|
||||
fs
|
||||
fscanf
|
||||
@@ -687,7 +705,9 @@ genvar
|
||||
genvars
|
||||
getenv
|
||||
getline
|
||||
getter
|
||||
ggdb
|
||||
glibc
|
||||
gmake
|
||||
gmon
|
||||
gotFinish
|
||||
@@ -699,6 +719,7 @@ hh
|
||||
hier
|
||||
hierCMakeArgs
|
||||
hierMkArgs
|
||||
hierParameters
|
||||
hierVer
|
||||
hx
|
||||
hyperthreading
|
||||
@@ -732,6 +753,7 @@ ish
|
||||
isunbounded
|
||||
isunknown
|
||||
jobserver
|
||||
json
|
||||
jwoutersymatra
|
||||
killua
|
||||
lang
|
||||
@@ -829,6 +851,8 @@ parallelized
|
||||
param
|
||||
parameterization
|
||||
parameterized
|
||||
parameterized
|
||||
parameterless
|
||||
params
|
||||
parens
|
||||
pawel
|
||||
@@ -872,7 +896,9 @@ profcfunc
|
||||
profiler
|
||||
prototyptes
|
||||
ps
|
||||
psprintf
|
||||
pthread
|
||||
pthreads
|
||||
ptr
|
||||
pulldown
|
||||
pulldowns
|
||||
@@ -902,6 +928,7 @@ recrem
|
||||
redeclaring
|
||||
regs
|
||||
reloop
|
||||
replaceShiftOp
|
||||
resetall
|
||||
respecified
|
||||
rodata
|
||||
@@ -940,6 +967,7 @@ stdin
|
||||
stdout
|
||||
stime
|
||||
stmts
|
||||
str
|
||||
strcasecmp
|
||||
stringification
|
||||
stringified
|
||||
@@ -953,13 +981,20 @@ submakes
|
||||
submodule
|
||||
submodules
|
||||
substring
|
||||
superclass
|
||||
suspendable
|
||||
suspendables
|
||||
sv
|
||||
svBitVal
|
||||
svBitVecVal
|
||||
svGet
|
||||
svGetTime
|
||||
svGetTimePrecision
|
||||
svLogicVal
|
||||
svdpi
|
||||
svgGetTimeUnit
|
||||
swrite
|
||||
synthesizeable
|
||||
sys
|
||||
systemc
|
||||
tenghtt
|
||||
@@ -978,6 +1013,7 @@ toolchain
|
||||
topcell
|
||||
toplevel
|
||||
toupper
|
||||
traceCapable
|
||||
traceEverOn
|
||||
tran
|
||||
treei
|
||||
@@ -1014,8 +1050,10 @@ unsup
|
||||
untyped
|
||||
urandom
|
||||
uselib
|
||||
utimes
|
||||
uwire
|
||||
uwires
|
||||
valgrind
|
||||
vc
|
||||
vcd
|
||||
vcddiff
|
||||
@@ -1040,6 +1078,7 @@ vluint
|
||||
vpi
|
||||
vpiConstType
|
||||
vpiDefName
|
||||
vpiInertialDelay
|
||||
vpiInstance
|
||||
vpiLeftRange
|
||||
vpiModule
|
||||
@@ -1047,6 +1086,7 @@ vpiSize
|
||||
vpiSuppressVal
|
||||
vpiTimeUnit
|
||||
vpiType
|
||||
vpiUndefined
|
||||
vpm
|
||||
vpp
|
||||
warmup
|
||||
@@ -1072,3 +1112,4 @@ zdave
|
||||
Øyvind
|
||||
Алексеевич
|
||||
Исаак
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ endif()
|
||||
|
||||
# Create a new executable target that will contain all your sources
|
||||
add_executable(example ../make_hello_c/sim_main.cpp)
|
||||
target_compile_features(example PUBLIC cxx_std_14)
|
||||
|
||||
# Add the Verilated circuit to the target
|
||||
verilate(example
|
||||
|
||||
@@ -31,7 +31,7 @@ endif
|
||||
ifeq ($(shell which cmake),)
|
||||
TARGET := nocmake
|
||||
else
|
||||
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
|
||||
CMAKE_VERSION := $(shell cmake --version | grep -o '[0-9][.0-9]\+')
|
||||
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
|
||||
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
|
||||
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
|
||||
|
||||
@@ -37,6 +37,7 @@ find_package(SystemCLanguage QUIET)
|
||||
|
||||
# Create a new executable target that will contain all your sources
|
||||
add_executable(example ../make_hello_sc/sc_main.cpp)
|
||||
target_compile_features(example PUBLIC cxx_std_14)
|
||||
|
||||
set_property(
|
||||
TARGET example
|
||||
|
||||
@@ -31,7 +31,7 @@ endif
|
||||
ifeq ($(shell which cmake),)
|
||||
TARGET := nocmake
|
||||
else
|
||||
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
|
||||
CMAKE_VERSION := $(shell cmake --version | grep -o '[0-9][.0-9]\+')
|
||||
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
|
||||
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
|
||||
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
|
||||
|
||||
@@ -30,9 +30,12 @@ endif()
|
||||
|
||||
# Create the main executable target
|
||||
add_executable(example ../make_protect_lib/sim_main.cpp)
|
||||
target_compile_features(example PUBLIC cxx_std_14)
|
||||
|
||||
# Create a secret library
|
||||
add_library(verilated_secret STATIC) # or SHARED for a shared library
|
||||
target_compile_features(verilated_secret PUBLIC cxx_std_14)
|
||||
|
||||
target_link_libraries(example PRIVATE verilated_secret)
|
||||
# To create both libraries on CMake >= 3.12 replace the above 2 lines with the following:
|
||||
# add_library(verilated_secret OBJECT)
|
||||
|
||||
@@ -31,7 +31,7 @@ endif
|
||||
ifeq ($(shell which cmake),)
|
||||
TARGET := nocmake
|
||||
else
|
||||
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
|
||||
CMAKE_VERSION := $(shell cmake --version | grep -o '[0-9][.0-9]\+')
|
||||
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
|
||||
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
|
||||
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
|
||||
|
||||
@@ -30,6 +30,7 @@ endif()
|
||||
|
||||
# Create a new executable target that will contain all your sources
|
||||
add_executable(example ../make_tracing_c/sim_main.cpp)
|
||||
target_compile_features(example PUBLIC cxx_std_14)
|
||||
|
||||
# Add the Verilated circuit to the target
|
||||
verilate(example COVERAGE TRACE
|
||||
|
||||
@@ -31,7 +31,7 @@ endif
|
||||
ifeq ($(shell which cmake),)
|
||||
TARGET := nocmake
|
||||
else
|
||||
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
|
||||
CMAKE_VERSION := $(shell cmake --version | grep -o '[0-9][.0-9]\+')
|
||||
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
|
||||
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
|
||||
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
|
||||
|
||||
@@ -38,6 +38,7 @@ find_package(SystemCLanguage QUIET)
|
||||
|
||||
# Create a new executable target that will contain all your sources
|
||||
add_executable(example ../make_tracing_sc/sc_main.cpp)
|
||||
target_compile_features(example PUBLIC cxx_std_14)
|
||||
|
||||
set_property(
|
||||
TARGET example
|
||||
|
||||
@@ -31,7 +31,7 @@ endif
|
||||
ifeq ($(shell which cmake),)
|
||||
TARGET := nocmake
|
||||
else
|
||||
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
|
||||
CMAKE_VERSION := $(shell cmake --version | grep -o '[0-9][.0-9]\+')
|
||||
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
|
||||
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
|
||||
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- Python -*- See copyright, etc below
|
||||
# pylint: disable=C0114,C0115,C0209,R0903
|
||||
# pylint: disable=C0103,C0114,C0115,C0209,R0903
|
||||
######################################################################
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import tempfile
|
||||
import xml.etree.ElementTree as ET
|
||||
from shutil import copy2
|
||||
from tempfile import NamedTemporaryFile
|
||||
# from pprint import pprint, pformat
|
||||
|
||||
#######################################################################
|
||||
@@ -25,29 +25,30 @@ class VlFileCopy:
|
||||
|
||||
self.debug = debug
|
||||
|
||||
with tempfile.NamedTemporaryFile() as xml_temp:
|
||||
with NamedTemporaryFile() as tree_temp, NamedTemporaryFile(
|
||||
) as meta_temp:
|
||||
vargs = [
|
||||
'--xml-output',
|
||||
xml_temp.name,
|
||||
'--json-only-output',
|
||||
tree_temp.name,
|
||||
'--json-only-meta-output',
|
||||
meta_temp.name,
|
||||
'--bbox-sys', # Parse some stuff can't translate
|
||||
'--bbox-unsup',
|
||||
'--prefix vlxml'
|
||||
] # So we know name of .xml output
|
||||
'--prefix vljson'
|
||||
]
|
||||
vargs += verilator_args
|
||||
self.run_verilator(vargs)
|
||||
self.tree = ET.parse(xml_temp.name)
|
||||
self.tree = json.load(tree_temp)
|
||||
self.meta = json.load(meta_temp)
|
||||
|
||||
os.makedirs(output_dir, 0o777, True)
|
||||
|
||||
# Find and copy the files
|
||||
root = self.tree.getroot()
|
||||
xfiles = root.find('files')
|
||||
for xfile in xfiles.findall('file'):
|
||||
filename = xfile.get('filename')
|
||||
if not re.match('^<', filename): # e.g. <built-in>
|
||||
for file_id in self.meta['files']:
|
||||
path = self.meta['files'][file_id]['realpath']
|
||||
if not re.match('^<', path): # e.g. <built-in>
|
||||
if self.debug:
|
||||
print("\tcp %s %s" % (filename, output_dir))
|
||||
copy2(filename, output_dir)
|
||||
print("\tcp %s %s" % (path, output_dir))
|
||||
copy2(path, output_dir)
|
||||
|
||||
def run_verilator(self, vargs):
|
||||
"""Run Verilator command, check errors"""
|
||||
@@ -71,7 +72,7 @@ if __name__ == '__main__':
|
||||
allow_abbrev=False,
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
description=
|
||||
"""Example of using Verilator XML output to copy a list of files to an
|
||||
"""Example of using Verilator JSON output to copy a list of files to an
|
||||
output directory (-odir, defaults to 'copied'), e.g. to easily create a
|
||||
tarball of the design to pass to others.
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
######################################################################
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import tempfile
|
||||
import xml.etree.ElementTree as ET
|
||||
from tempfile import NamedTemporaryFile
|
||||
# from pprint import pprint, pformat
|
||||
|
||||
#######################################################################
|
||||
@@ -22,19 +22,23 @@ class VlHierGraph:
|
||||
output_filename='graph.dot'): # output filename
|
||||
self.debug = debug
|
||||
self.next_vertex_number = 0
|
||||
self.name_to_number = {}
|
||||
self.addr_to_number = {}
|
||||
|
||||
with tempfile.NamedTemporaryFile() as xml_temp:
|
||||
with NamedTemporaryFile() as tree_temp, NamedTemporaryFile(
|
||||
) as meta_temp:
|
||||
vargs = [
|
||||
'--xml-output',
|
||||
xml_temp.name,
|
||||
'--json-only-output',
|
||||
tree_temp.name,
|
||||
'--json-only-meta-output',
|
||||
meta_temp.name,
|
||||
'--bbox-sys', # Parse some stuff can't translate
|
||||
'--bbox-unsup',
|
||||
'--prefix vlxml'
|
||||
] # So we know name of .xml output
|
||||
'--prefix vljson'
|
||||
]
|
||||
vargs += verilator_args
|
||||
self.run_verilator(vargs)
|
||||
self.tree = ET.parse(xml_temp.name)
|
||||
self.tree = json.load(tree_temp)
|
||||
self.meta = json.load(meta_temp)
|
||||
|
||||
with open(output_filename, "w", encoding="utf8") as fh:
|
||||
# For more serious purposes, use the python graphviz package instead
|
||||
@@ -46,31 +50,45 @@ class VlHierGraph:
|
||||
)
|
||||
fh.write(" edge [fontsize=6]")
|
||||
# Find cells
|
||||
root = self.tree.getroot()
|
||||
netlist = root.find('netlist')
|
||||
for module in netlist.findall('module'):
|
||||
modules = self.flatten(self.tree, lambda n: n['type'] == "MODULE")
|
||||
top_module = True
|
||||
for mod in modules:
|
||||
# origNames are before parameterization, name if after
|
||||
mod_name = module.get('name')
|
||||
mod_number = self.name_to_vertex_number(mod_name)
|
||||
fh.write(" n%d [label=\"%s\"" % (mod_number, mod_name))
|
||||
if module.get('topModule'):
|
||||
mod_number = self.addr_to_vertex_number(mod['addr'])
|
||||
fh.write(" n%d [label=\"%s\"" % (mod_number, mod['name']))
|
||||
if top_module:
|
||||
fh.write(" color=\"red\" rank=1")
|
||||
top_module = False
|
||||
fh.write("];\n")
|
||||
|
||||
for instance in module.findall('instance'):
|
||||
inst_name = instance.get('name')
|
||||
def_name = instance.get('defName')
|
||||
def_number = self.name_to_vertex_number(def_name)
|
||||
cells = self.flatten(mod, lambda n: n['type'] == "CELL")
|
||||
for cell in cells:
|
||||
def_number = self.addr_to_vertex_number(cell['modp'])
|
||||
fh.write(" n%d->n%d [label=\"%s\"];\n" %
|
||||
(mod_number, def_number, inst_name))
|
||||
(mod_number, def_number, cell['name']))
|
||||
|
||||
fh.write("}\n")
|
||||
|
||||
def name_to_vertex_number(self, name):
|
||||
if name not in self.name_to_number:
|
||||
def flatten(self, node, accept_cb=lambda n: True):
|
||||
"""Flatten tree to list using DFS.
|
||||
accept_cb(node) should return True for nodes you want to save"""
|
||||
arr = []
|
||||
self.dfs(node, lambda n: accept_cb(n) and arr.append(n))
|
||||
return arr
|
||||
|
||||
def dfs(self, node, node_cb):
|
||||
"""Traverse given tree using DFS and apply node_cb(node) on each one"""
|
||||
node_cb(node)
|
||||
for _, v in node.items():
|
||||
if isinstance(v, list): # childlist
|
||||
for child in v:
|
||||
self.dfs(child, node_cb)
|
||||
|
||||
def addr_to_vertex_number(self, name):
|
||||
if name not in self.addr_to_number:
|
||||
self.next_vertex_number += 1
|
||||
self.name_to_number[name] = self.next_vertex_number
|
||||
return self.name_to_number[name]
|
||||
self.addr_to_number[name] = self.next_vertex_number
|
||||
return self.addr_to_number[name]
|
||||
|
||||
def run_verilator(self, vargs):
|
||||
"""Run Verilator command, check errors"""
|
||||
@@ -94,7 +112,7 @@ if __name__ == '__main__':
|
||||
allow_abbrev=False,
|
||||
formatter_class=argparse.RawTextHelpFormatter,
|
||||
description=
|
||||
"""Example of using Verilator XML output to create a .dot file showing the
|
||||
"""Example of using Verilator JSON output to create a .dot file showing the
|
||||
design module hierarchy.
|
||||
|
||||
Example usage:
|
||||
@@ -19,14 +19,14 @@ int main(int argc, char** argv) {
|
||||
// e.g. examples/c_tracing.
|
||||
|
||||
// Construct a VerilatedContext to hold simulation time, etc.
|
||||
VerilatedContext* contextp = new VerilatedContext;
|
||||
VerilatedContext* const contextp = new VerilatedContext;
|
||||
|
||||
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
|
||||
// This needs to be called before you create any model
|
||||
contextp->commandArgs(argc, argv);
|
||||
|
||||
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
|
||||
Vtop* top = new Vtop{contextp};
|
||||
Vtop* const top = new Vtop{contextp};
|
||||
|
||||
// Simulate until $finish
|
||||
while (!contextp->gotFinish()) {
|
||||
|
||||
@@ -25,7 +25,7 @@ int sc_main(int argc, char* argv[]) {
|
||||
// e.g. examples/c_tracing.
|
||||
|
||||
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
|
||||
Vtop* top = new Vtop{"top"};
|
||||
Vtop* const top = new Vtop{"top"};
|
||||
|
||||
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
|
||||
// This needs to be called before you create any model
|
||||
|
||||
@@ -17,16 +17,17 @@
|
||||
#endif
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (false && argc && argv) {}
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
// Construct context to hold simulation time, etc
|
||||
VerilatedContext* contextp = new VerilatedContext;
|
||||
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
|
||||
contextp->debug(0);
|
||||
contextp->randReset(2);
|
||||
contextp->commandArgs(argc, argv);
|
||||
|
||||
// Construct the Verilated model, including the secret module
|
||||
Vtop* top = new Vtop{contextp};
|
||||
const std::unique_ptr<Vtop> top{new Vtop{contextp.get(), "TOP"}};
|
||||
|
||||
#if VM_TRACE
|
||||
// When tracing, the contents of the secret module will not be seen
|
||||
@@ -46,12 +47,12 @@ int main(int argc, char** argv) {
|
||||
|
||||
// Simulate until $finish
|
||||
while (!contextp->gotFinish()) {
|
||||
contextp->timeInc(1);
|
||||
top->clk = ~top->clk & 0x1;
|
||||
top->eval();
|
||||
#if VM_TRACE
|
||||
if (tfp) tfp->dump(contextp->time());
|
||||
#endif
|
||||
contextp->timeInc(1);
|
||||
}
|
||||
|
||||
// Final model cleanup
|
||||
@@ -65,12 +66,6 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Destroy model
|
||||
delete top;
|
||||
top = nullptr;
|
||||
delete contextp;
|
||||
contextp = nullptr;
|
||||
|
||||
// Return good completion status
|
||||
// Don't use exit() or destructor won't get called
|
||||
return 0;
|
||||
|
||||
@@ -20,9 +20,6 @@ double sc_time_stamp() { return 0; }
|
||||
int main(int argc, char** argv) {
|
||||
// This is a more complicated example, please also see the simpler examples/make_hello_c.
|
||||
|
||||
// Prevent unused variable warnings
|
||||
if (false && argc && argv) {}
|
||||
|
||||
// Create logs/ directory in case we have traces to put under it
|
||||
Verilated::mkdir("logs");
|
||||
|
||||
@@ -120,6 +117,9 @@ int main(int argc, char** argv) {
|
||||
contextp->coveragep()->write("logs/coverage.dat");
|
||||
#endif
|
||||
|
||||
// Final simulation summary
|
||||
contextp->statsPrintSummary();
|
||||
|
||||
// Return good completion status
|
||||
// Don't use exit() or destructor won't get called
|
||||
return 0;
|
||||
|
||||
@@ -29,9 +29,6 @@ using namespace sc_dt;
|
||||
int sc_main(int argc, char* argv[]) {
|
||||
// This is a more complicated example, please also see the simpler examples/make_hello_c.
|
||||
|
||||
// Prevent unused variable warnings
|
||||
if (false && argc && argv) {}
|
||||
|
||||
// Create logs/ directory in case we have traces to put under it
|
||||
Verilated::mkdir("logs");
|
||||
|
||||
|
||||
+199
-38
@@ -34,7 +34,6 @@
|
||||
* FST_DEBUG : not for production use, only enable for development
|
||||
* FST_REMOVE_DUPLICATE_VC : glitch removal (has writer performance impact)
|
||||
* HAVE_LIBPTHREAD -> FST_WRITER_PARALLEL : enables inclusion of parallel writer code
|
||||
* FST_DO_MISALIGNED_OPS (defined automatically for x86 and some others) : CPU architecture can handle misaligned loads/stores
|
||||
* _WAVE_HAVE_JUDY : use Judy arrays instead of Jenkins (undefine if LGPL is not acceptable)
|
||||
*
|
||||
*/
|
||||
@@ -131,10 +130,7 @@ void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint3
|
||||
#define FST_HDR_TIMEZERO_SIZE (8)
|
||||
#define FST_GZIO_LEN (32768)
|
||||
#define FST_HDR_FOURPACK_DUO_SIZE (4*1024*1024)
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__) || defined(_AIX) || defined(__aarch64__)
|
||||
#define FST_DO_MISALIGNED_OPS
|
||||
#endif
|
||||
#define FST_ZWRAPPER_HDR_SIZE (1+8+8)
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
#define FST_MACOSX
|
||||
@@ -192,6 +188,16 @@ void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint3
|
||||
/* 01234567 */
|
||||
|
||||
|
||||
/*
|
||||
* report abort messages
|
||||
*/
|
||||
static void chk_report_abort(const char *s)
|
||||
{
|
||||
fprintf(stderr,"Triggered %s security check, exiting.\n", s);
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* prevent old file overwrite when currently being read
|
||||
*/
|
||||
@@ -342,8 +348,9 @@ return(NULL);
|
||||
|
||||
static void *fstMmap2(size_t __len, int __fd, fst_off_t __off)
|
||||
{
|
||||
DWORD64 len64 = __len; /* Must be 64-bit for shift below */
|
||||
HANDLE handle = CreateFileMapping((HANDLE)_get_osfhandle(__fd), NULL,
|
||||
PAGE_READWRITE, (DWORD)(__len >> 32),
|
||||
PAGE_READWRITE, (DWORD)(len64 >> 32),
|
||||
(DWORD)__len, NULL);
|
||||
if (!handle) { return NULL; }
|
||||
|
||||
@@ -367,22 +374,15 @@ return ptr;
|
||||
/*
|
||||
* regular and variable-length integer access functions
|
||||
*/
|
||||
#ifdef FST_DO_MISALIGNED_OPS
|
||||
#define fstGetUint32(x) (*(uint32_t *)(x))
|
||||
#else
|
||||
static uint32_t fstGetUint32(unsigned char *mem)
|
||||
{
|
||||
uint32_t u32;
|
||||
unsigned char *buf = (unsigned char *)(&u32);
|
||||
|
||||
buf[0] = mem[0];
|
||||
buf[1] = mem[1];
|
||||
buf[2] = mem[2];
|
||||
buf[3] = mem[3];
|
||||
memcpy(buf, mem, sizeof(uint32_t));
|
||||
|
||||
return(*(uint32_t *)buf);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static int fstWriterUint64(FILE *handle, uint64_t v)
|
||||
@@ -550,7 +550,8 @@ return(rc);
|
||||
|
||||
static uint32_t fstReaderVarint32(FILE *f)
|
||||
{
|
||||
unsigned char buf[5];
|
||||
int chk_len = 5; /* TALOS-2023-1783 */
|
||||
unsigned char buf[chk_len];
|
||||
unsigned char *mem = buf;
|
||||
uint32_t rc = 0;
|
||||
int ch;
|
||||
@@ -559,7 +560,9 @@ do
|
||||
{
|
||||
ch = fgetc(f);
|
||||
*(mem++) = ch;
|
||||
} while(ch & 0x80);
|
||||
} while((ch & 0x80) && (--chk_len));
|
||||
|
||||
if(ch & 0x80) chk_report_abort("TALOS-2023-1783");
|
||||
mem--;
|
||||
|
||||
for(;;)
|
||||
@@ -579,7 +582,8 @@ return(rc);
|
||||
|
||||
static uint32_t fstReaderVarint32WithSkip(FILE *f, uint32_t *skiplen)
|
||||
{
|
||||
unsigned char buf[5];
|
||||
int chk_len = 5; /* TALOS-2023-1783 */
|
||||
unsigned char buf[chk_len];
|
||||
unsigned char *mem = buf;
|
||||
uint32_t rc = 0;
|
||||
int ch;
|
||||
@@ -588,7 +592,9 @@ do
|
||||
{
|
||||
ch = fgetc(f);
|
||||
*(mem++) = ch;
|
||||
} while(ch & 0x80);
|
||||
} while((ch & 0x80) && (--chk_len));
|
||||
|
||||
if(ch & 0x80) chk_report_abort("TALOS-2023-1783");
|
||||
*skiplen = mem - buf;
|
||||
mem--;
|
||||
|
||||
@@ -609,7 +615,8 @@ return(rc);
|
||||
|
||||
static uint64_t fstReaderVarint64(FILE *f)
|
||||
{
|
||||
unsigned char buf[16];
|
||||
int chk_len = 16; /* TALOS-2023-1783 */
|
||||
unsigned char buf[chk_len];
|
||||
unsigned char *mem = buf;
|
||||
uint64_t rc = 0;
|
||||
int ch;
|
||||
@@ -618,9 +625,12 @@ do
|
||||
{
|
||||
ch = fgetc(f);
|
||||
*(mem++) = ch;
|
||||
} while(ch & 0x80);
|
||||
} while((ch & 0x80) && (--chk_len));
|
||||
|
||||
if(ch & 0x80) chk_report_abort("TALOS-2023-1783");
|
||||
mem--;
|
||||
|
||||
|
||||
for(;;)
|
||||
{
|
||||
rc <<= 7;
|
||||
@@ -851,11 +861,7 @@ unsigned char *pnt = buf;
|
||||
uint32_t nxt;
|
||||
uint32_t len;
|
||||
|
||||
#ifdef FST_DO_MISALIGNED_OPS
|
||||
(*(uint32_t *)(pnt)) = (*(uint32_t *)(u));
|
||||
#else
|
||||
memcpy(pnt, u, sizeof(uint32_t));
|
||||
#endif
|
||||
pnt += 4;
|
||||
|
||||
while((nxt = v>>7))
|
||||
@@ -878,11 +884,7 @@ unsigned char *pnt = buf;
|
||||
uint32_t nxt;
|
||||
uint32_t len;
|
||||
|
||||
#ifdef FST_DO_MISALIGNED_OPS
|
||||
(*(uint32_t *)(pnt)) = (*(uint32_t *)(u));
|
||||
#else
|
||||
memcpy(pnt, u, sizeof(uint32_t));
|
||||
#endif
|
||||
pnt += 4;
|
||||
|
||||
while((nxt = v>>7))
|
||||
@@ -1542,7 +1544,7 @@ for(i=0;i<xc->maxhandle;i++)
|
||||
dmem = packmem = (unsigned char *)malloc(packmemlen = (wrlen * 2) + 2);
|
||||
}
|
||||
|
||||
rc = (xc->fourpack) ? LZ4_compress((char *)scratchpnt, (char *)dmem, wrlen) : fastlz_compress(scratchpnt, wrlen, dmem);
|
||||
rc = (xc->fourpack) ? LZ4_compress_default((char *)scratchpnt, (char *)dmem, wrlen, packmemlen) : fastlz_compress(scratchpnt, wrlen, dmem);
|
||||
if(rc < destlen)
|
||||
{
|
||||
#ifndef FST_DYNAMIC_ALIAS_DISABLE
|
||||
@@ -1646,7 +1648,11 @@ if(1)
|
||||
{
|
||||
if(vm4ip[2] != prev_alias)
|
||||
{
|
||||
fpos += fstWriterSVarint(f, (((int64_t)((int32_t)(prev_alias = vm4ip[2]))) << 1) | 1);
|
||||
int32_t t_i32 = ((int32_t)(prev_alias = vm4ip[2])); /* vm4ip is generic unsigned data */
|
||||
int64_t t_i64 = (int64_t)t_i32; /* convert to signed */
|
||||
uint64_t t_u64 = (uint64_t)t_i64; /* sign extend through 64b */
|
||||
|
||||
fpos += fstWriterSVarint(f, (int64_t)((t_u64 << 1) | 1)); /* all in this block was: fpos += fstWriterSVarint(f, (((int64_t)((int32_t)(prev_alias = vm4ip[2]))) << 1) | 1); */
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1838,6 +1844,14 @@ if(xc->parallel_enabled)
|
||||
xc->xc_parent = xc;
|
||||
memcpy(xc2, xc, sizeof(struct fstWriterContext));
|
||||
|
||||
if(sizeof(size_t) < sizeof(uint64_t))
|
||||
{
|
||||
/* TALOS-2023-1777 for 32b overflow */
|
||||
uint64_t chk_64 = xc->maxhandle * 4 * sizeof(uint32_t);
|
||||
size_t chk_32 = xc->maxhandle * 4 * sizeof(uint32_t);
|
||||
if(chk_64 != chk_32) chk_report_abort("TALOS-2023-1777");
|
||||
}
|
||||
|
||||
xc2->valpos_mem = (uint32_t *)malloc(xc->maxhandle * 4 * sizeof(uint32_t));
|
||||
memcpy(xc2->valpos_mem, xc->valpos_mem, xc->maxhandle * 4 * sizeof(uint32_t));
|
||||
|
||||
@@ -2101,7 +2115,7 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
|
||||
{
|
||||
fstWriterMmapSanity(hmem = (unsigned char *)fstMmap(NULL, xc->hier_file_len, PROT_READ|PROT_WRITE, MAP_SHARED, fileno(xc->hier_handle), 0), __FILE__, __LINE__, "hmem");
|
||||
}
|
||||
packed_len = LZ4_compress((char *)hmem, (char *)mem, xc->hier_file_len);
|
||||
packed_len = LZ4_compress_default((char *)hmem, (char *)mem, xc->hier_file_len, lz4_maxlen);
|
||||
fstMunmap(hmem, xc->hier_file_len);
|
||||
|
||||
fourpack_duo = (!xc->repack_on_close) && (xc->hier_file_len > FST_HDR_FOURPACK_DUO_SIZE); /* double pack when hierarchy is large */
|
||||
@@ -2114,7 +2128,7 @@ if(xc && !xc->already_in_close && !xc->already_in_flush)
|
||||
|
||||
lz4_maxlen_duo = LZ4_compressBound(packed_len);
|
||||
mem_duo = (unsigned char *)malloc(lz4_maxlen_duo);
|
||||
packed_len_duo = LZ4_compress((char *)mem, (char *)mem_duo, packed_len);
|
||||
packed_len_duo = LZ4_compress_default((char *)mem, (char *)mem_duo, packed_len, lz4_maxlen_duo);
|
||||
|
||||
fstWriterVarint(xc->handle, packed_len); /* 1st round compressed length */
|
||||
fstFwrite(mem_duo, packed_len_duo, 1, xc->handle);
|
||||
@@ -3434,7 +3448,7 @@ return(rc);
|
||||
|
||||
|
||||
#ifndef FST_WRITEX_DISABLE
|
||||
static void fstWritex(struct fstReaderContext *xc, void *v, int len)
|
||||
static void fstWritex(struct fstReaderContext *xc, void *v, uint32_t len) /* TALOS-2023-1793: change len to unsigned */
|
||||
{
|
||||
unsigned char *s = (unsigned char *)v;
|
||||
|
||||
@@ -4620,9 +4634,14 @@ if(sectype == FST_BL_ZWRAPPER)
|
||||
}
|
||||
#endif
|
||||
|
||||
fstReaderFseeko(xc, xc->f, 1+8+8, SEEK_SET);
|
||||
fstReaderFseeko(xc, xc->f, FST_ZWRAPPER_HDR_SIZE, SEEK_SET);
|
||||
#ifndef __MINGW32__
|
||||
fflush(xc->f);
|
||||
#else
|
||||
/* Windows UCRT runtime library reads one byte ahead in the file
|
||||
even with buffering disabled and does not synchronise the
|
||||
file position after fseek. */
|
||||
_lseek(fileno(xc->f), FST_ZWRAPPER_HDR_SIZE, SEEK_SET);
|
||||
#endif
|
||||
|
||||
zfd = dup(fileno(xc->f));
|
||||
@@ -5060,6 +5079,7 @@ if(fv)
|
||||
for(;;)
|
||||
{
|
||||
uint32_t *tc_head = NULL;
|
||||
uint32_t tc_head_items = 0;
|
||||
traversal_mem_offs = 0;
|
||||
|
||||
fstReaderFseeko(xc, xc->f, blkpos, SEEK_SET);
|
||||
@@ -5103,12 +5123,12 @@ for(;;)
|
||||
}
|
||||
|
||||
|
||||
mem_required_for_traversal = fstReaderUint64(xc->f);
|
||||
mem_for_traversal = (unsigned char *)malloc(mem_required_for_traversal + 66); /* add in potential fastlz overhead */
|
||||
mem_required_for_traversal = fstReaderUint64(xc->f) + 66; /* add in potential fastlz overhead */
|
||||
mem_for_traversal = (unsigned char *)malloc(mem_required_for_traversal);
|
||||
#ifdef FST_DEBUG
|
||||
fprintf(stderr, FST_APIMESS "sec: %u seclen: %d begtim: %d endtim: %d\n",
|
||||
secnum, (int)seclen, (int)beg_tim, (int)end_tim);
|
||||
fprintf(stderr, FST_APIMESS "mem_required_for_traversal: %d\n", (int)mem_required_for_traversal);
|
||||
fprintf(stderr, FST_APIMESS "mem_required_for_traversal: %d\n", (int)mem_required_for_traversal-66);
|
||||
#endif
|
||||
/* process time block */
|
||||
{
|
||||
@@ -5158,6 +5178,22 @@ for(;;)
|
||||
}
|
||||
|
||||
free(time_table);
|
||||
|
||||
if(sizeof(size_t) < sizeof(uint64_t))
|
||||
{
|
||||
/* TALOS-2023-1792 for 32b overflow */
|
||||
uint64_t chk_64 = tsec_nitems * sizeof(uint64_t);
|
||||
size_t chk_32 = ((size_t)tsec_nitems) * sizeof(uint64_t);
|
||||
if(chk_64 != chk_32) chk_report_abort("TALOS-2023-1792");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t chk_64 = tsec_nitems * sizeof(uint64_t);
|
||||
if((chk_64/sizeof(uint64_t)) != tsec_nitems)
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1792");
|
||||
}
|
||||
}
|
||||
time_table = (uint64_t *)calloc(tsec_nitems, sizeof(uint64_t));
|
||||
tpnt = ucdata;
|
||||
tpval = 0;
|
||||
@@ -5169,7 +5205,23 @@ for(;;)
|
||||
tpnt += skiplen;
|
||||
}
|
||||
|
||||
tc_head = (uint32_t *)calloc(tsec_nitems /* scan-build */ ? tsec_nitems : 1, sizeof(uint32_t));
|
||||
tc_head_items = tsec_nitems /* scan-build */ ? tsec_nitems : 1;
|
||||
if(sizeof(size_t) < sizeof(uint64_t))
|
||||
{
|
||||
/* TALOS-2023-1792 for 32b overflow */
|
||||
uint64_t chk_64 = tc_head_items * sizeof(uint32_t);
|
||||
size_t chk_32 = ((size_t)tc_head_items) * sizeof(uint32_t);
|
||||
if(chk_64 != chk_32) chk_report_abort("TALOS-2023-1792");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t chk_64 = tc_head_items * sizeof(uint32_t);
|
||||
if((chk_64/sizeof(uint32_t)) != tc_head_items)
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1792");
|
||||
}
|
||||
}
|
||||
tc_head = (uint32_t *)calloc(tc_head_items, sizeof(uint32_t));
|
||||
free(ucdata);
|
||||
}
|
||||
|
||||
@@ -5273,6 +5325,10 @@ for(;;)
|
||||
{
|
||||
if(value_change_callback)
|
||||
{
|
||||
if(xc->signal_lens[idx] > xc->longest_signal_value_len)
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1797");
|
||||
}
|
||||
memcpy(xc->temp_signal_value_buf, mu+sig_offs, xc->signal_lens[idx]);
|
||||
xc->temp_signal_value_buf[xc->signal_lens[idx]] = 0;
|
||||
value_change_callback(user_callback_data_pointer, beg_tim, idx+1, xc->temp_signal_value_buf);
|
||||
@@ -5286,6 +5342,10 @@ for(;;)
|
||||
|
||||
vcd_id[0] = (xc->signal_typs[idx] != FST_VT_VCD_PORT) ? 'b' : 'p';
|
||||
fstWritex(xc, vcd_id, 1);
|
||||
if((sig_offs + xc->signal_lens[idx]) > frame_uclen)
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1793");
|
||||
}
|
||||
fstWritex(xc,mu+sig_offs, xc->signal_lens[idx]);
|
||||
|
||||
vcd_id[0] = ' '; /* collapse 3 writes into one I/O call */
|
||||
@@ -5410,7 +5470,44 @@ for(;;)
|
||||
free(chain_table_lengths);
|
||||
|
||||
vc_maxhandle_largest = vc_maxhandle;
|
||||
|
||||
if(!(vc_maxhandle+1))
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1798");
|
||||
}
|
||||
|
||||
if(sizeof(size_t) < sizeof(uint64_t))
|
||||
{
|
||||
/* TALOS-2023-1798 for 32b overflow */
|
||||
uint64_t chk_64 = (vc_maxhandle+1) * sizeof(fst_off_t);
|
||||
size_t chk_32 = ((size_t)(vc_maxhandle+1)) * sizeof(fst_off_t);
|
||||
if(chk_64 != chk_32) chk_report_abort("TALOS-2023-1798");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t chk_64 = (vc_maxhandle+1) * sizeof(fst_off_t);
|
||||
if((chk_64/sizeof(fst_off_t)) != (vc_maxhandle+1))
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1798");
|
||||
}
|
||||
}
|
||||
chain_table = (fst_off_t *)calloc((vc_maxhandle+1), sizeof(fst_off_t));
|
||||
|
||||
if(sizeof(size_t) < sizeof(uint64_t))
|
||||
{
|
||||
/* TALOS-2023-1798 for 32b overflow */
|
||||
uint64_t chk_64 = (vc_maxhandle+1) * sizeof(uint32_t);
|
||||
size_t chk_32 = ((size_t)(vc_maxhandle+1)) * sizeof(uint32_t);
|
||||
if(chk_64 != chk_32) chk_report_abort("TALOS-2023-1798");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint64_t chk_64 = (vc_maxhandle+1) * sizeof(uint32_t);
|
||||
if((chk_64/sizeof(uint32_t)) != (vc_maxhandle+1))
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1798");
|
||||
}
|
||||
}
|
||||
chain_table_lengths = (uint32_t *)calloc((vc_maxhandle+1), sizeof(uint32_t));
|
||||
}
|
||||
|
||||
@@ -5454,6 +5551,11 @@ for(;;)
|
||||
uint64_t val = fstGetVarint32(pnt, &skiplen);
|
||||
|
||||
fstHandle loopcnt = val >> 1;
|
||||
if((idx+loopcnt-1) > vc_maxhandle) /* TALOS-2023-1789 */
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1789");
|
||||
}
|
||||
|
||||
for(i=0;i<loopcnt;i++)
|
||||
{
|
||||
chain_table[idx++] = 0;
|
||||
@@ -5487,6 +5589,12 @@ for(;;)
|
||||
else
|
||||
{
|
||||
fstHandle loopcnt = val >> 1;
|
||||
|
||||
if((idx+loopcnt-1) > vc_maxhandle) /* TALOS-2023-1789 */
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1789");
|
||||
}
|
||||
|
||||
for(i=0;i<loopcnt;i++)
|
||||
{
|
||||
chain_table[idx++] = 0;
|
||||
@@ -5547,6 +5655,11 @@ for(;;)
|
||||
unsigned long destlen = val;
|
||||
unsigned long sourcelen = chain_table_lengths[i];
|
||||
|
||||
if(traversal_mem_offs >= mem_required_for_traversal)
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1785");
|
||||
}
|
||||
|
||||
if(mc_mem_len < chain_table_lengths[i])
|
||||
{
|
||||
free(mc_mem);
|
||||
@@ -5575,6 +5688,12 @@ for(;;)
|
||||
{
|
||||
int destlen = chain_table_lengths[i] - skiplen;
|
||||
unsigned char *mu = mem_for_traversal + traversal_mem_offs;
|
||||
|
||||
if(traversal_mem_offs >= mem_required_for_traversal)
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1785");
|
||||
}
|
||||
|
||||
fstFread(mu, destlen, 1, xc->f);
|
||||
/* data to process is for(j=0;j<destlen;j++) in mu[j] */
|
||||
headptr[i] = traversal_mem_offs;
|
||||
@@ -5600,6 +5719,11 @@ for(;;)
|
||||
tdelta = vli >> 1;
|
||||
}
|
||||
|
||||
if(tdelta >= tc_head_items)
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1791");
|
||||
}
|
||||
|
||||
scatterptr[i] = tc_head[tdelta];
|
||||
tc_head[tdelta] = i+1;
|
||||
}
|
||||
@@ -5698,6 +5822,11 @@ for(;;)
|
||||
shamt = 2 << (vli & 1);
|
||||
tdelta = vli >> shamt;
|
||||
|
||||
if((tdelta+i) >= tc_head_items)
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1791");
|
||||
}
|
||||
|
||||
scatterptr[idx] = tc_head[i+tdelta];
|
||||
tc_head[i+tdelta] = idx+1;
|
||||
}
|
||||
@@ -5731,6 +5860,14 @@ for(;;)
|
||||
|
||||
vcdid_len = fstVcdIDForFwrite(vcd_id+1, idx+1);
|
||||
{
|
||||
if(sizeof(size_t) < sizeof(uint64_t))
|
||||
{
|
||||
/* TALOS-2023-1790 for 32b overflow */
|
||||
uint64_t chk_64 = len*4 + 1;
|
||||
size_t chk_32 = len*4 + 1;
|
||||
if(chk_64 != chk_32) chk_report_abort("TALOS-2023-1790");
|
||||
}
|
||||
|
||||
unsigned char *vesc = (unsigned char *)malloc(len*4 + 1);
|
||||
int vlen = fstUtilityBinToEsc(vesc, vdata, len);
|
||||
fstWritex(xc, vesc, vlen);
|
||||
@@ -5756,6 +5893,11 @@ for(;;)
|
||||
vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[idx]);
|
||||
tdelta = vli >> 1;
|
||||
|
||||
if((tdelta+i) >= tc_head_items)
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1791");
|
||||
}
|
||||
|
||||
scatterptr[idx] = tc_head[i+tdelta];
|
||||
tc_head[i+tdelta] = idx+1;
|
||||
}
|
||||
@@ -5772,6 +5914,11 @@ for(;;)
|
||||
|
||||
if(xc->signal_typs[idx] != FST_VT_VCD_REAL)
|
||||
{
|
||||
if(len > xc->longest_signal_value_len)
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1797");
|
||||
}
|
||||
|
||||
if(!(vli & 1))
|
||||
{
|
||||
int byte = 0;
|
||||
@@ -5817,8 +5964,13 @@ for(;;)
|
||||
if(fv)
|
||||
{
|
||||
unsigned char ch_bp = (xc->signal_typs[idx] != FST_VT_VCD_PORT) ? 'b' : 'p';
|
||||
uint64_t mem_required_for_traversal_chk = vdata - mem_for_traversal + len;
|
||||
|
||||
fstWritex(xc, &ch_bp, 1);
|
||||
if(mem_required_for_traversal_chk > mem_required_for_traversal)
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1793");
|
||||
}
|
||||
fstWritex(xc, vdata, len);
|
||||
}
|
||||
}
|
||||
@@ -5941,6 +6093,11 @@ for(;;)
|
||||
vli = fstGetVarint32NoSkip(mem_for_traversal + headptr[idx]);
|
||||
tdelta = vli >> 1;
|
||||
|
||||
if((tdelta+i) >= tc_head_items)
|
||||
{
|
||||
chk_report_abort("TALOS-2023-1791");
|
||||
}
|
||||
|
||||
scatterptr[idx] = tc_head[i+tdelta];
|
||||
tc_head[i+tdelta] = idx+1;
|
||||
}
|
||||
@@ -6034,7 +6191,9 @@ struct fstReaderContext *xc = (struct fstReaderContext *)ctx;
|
||||
fst_off_t blkpos = 0, prev_blkpos;
|
||||
uint64_t beg_tim, end_tim, beg_tim2, end_tim2;
|
||||
int sectype;
|
||||
#ifdef FST_DEBUG
|
||||
unsigned int secnum = 0;
|
||||
#endif
|
||||
uint64_t seclen;
|
||||
uint64_t tsec_uclen = 0, tsec_clen = 0;
|
||||
uint64_t tsec_nitems;
|
||||
@@ -6126,7 +6285,9 @@ for(;;)
|
||||
}
|
||||
|
||||
blkpos += seclen;
|
||||
#ifdef FST_DEBUG
|
||||
secnum++;
|
||||
#endif
|
||||
}
|
||||
|
||||
xc->rvat_beg_tim = beg_tim;
|
||||
|
||||
+2240
-972
File diff suppressed because it is too large
Load Diff
+771
-265
File diff suppressed because it is too large
Load Diff
+373
-145
@@ -71,12 +71,23 @@
|
||||
# include <execinfo.h>
|
||||
# define _VL_HAVE_STACKTRACE
|
||||
#endif
|
||||
#if defined(__linux) || (defined(__APPLE__) && defined(__MACH__))
|
||||
# include <sys/time.h>
|
||||
# include <sys/resource.h>
|
||||
# define _VL_HAVE_GETRLIMIT
|
||||
#endif
|
||||
|
||||
#include "verilated_threads.h"
|
||||
// clang-format on
|
||||
|
||||
#include "verilated_trace.h"
|
||||
|
||||
#ifdef VM_SOLVER_DEFAULT
|
||||
#define VL_SOLVER_DEFAULT VM_SOLVER_DEFAULT
|
||||
#else
|
||||
#define VL_SOLVER_DEFAULT "z3 --in"
|
||||
#endif
|
||||
|
||||
// Max characters in static char string for VL_VALUE_STRING
|
||||
constexpr unsigned VL_VALUE_STRING_MAX_WIDTH = 8192;
|
||||
|
||||
@@ -107,7 +118,8 @@ thread_local Verilated::ThreadLocal Verilated::t_s;
|
||||
|
||||
#ifndef VL_USER_FINISH ///< Define this to override the vl_finish function
|
||||
void vl_finish(const char* filename, int linenum, const char* hier) VL_MT_UNSAFE {
|
||||
if (false && hier) {} // Unused argument
|
||||
// hier is unused in the default implementation.
|
||||
(void)hier;
|
||||
VL_PRINTF( // Not VL_PRINTF_MT, already on main thread
|
||||
"- %s:%d: Verilog $finish\n", filename, linenum);
|
||||
Verilated::threadContextp()->gotFinish(true);
|
||||
@@ -135,7 +147,8 @@ void vl_stop(const char* filename, int linenum, const char* hier) VL_MT_UNSAFE {
|
||||
|
||||
#ifndef VL_USER_FATAL ///< Define this to override the vl_fatal function
|
||||
void vl_fatal(const char* filename, int linenum, const char* hier, const char* msg) VL_MT_UNSAFE {
|
||||
if (false && hier) {}
|
||||
// hier is unused in the default implementation.
|
||||
(void)hier;
|
||||
Verilated::threadContextp()->gotError(true);
|
||||
Verilated::threadContextp()->gotFinish(true);
|
||||
if (filename && filename[0]) {
|
||||
@@ -162,9 +175,12 @@ void vl_stop_maybe(const char* filename, int linenum, const char* hier, bool may
|
||||
Verilated::threadContextp()->errorCountInc();
|
||||
if (maybe
|
||||
&& Verilated::threadContextp()->errorCount() < Verilated::threadContextp()->errorLimit()) {
|
||||
VL_PRINTF( // Not VL_PRINTF_MT, already on main thread
|
||||
"-Info: %s:%d: %s\n", filename, linenum,
|
||||
"Verilog $stop, ignored due to +verilator+error+limit");
|
||||
// Do just once when cross error limit
|
||||
if (Verilated::threadContextp()->errorCount() == 1) {
|
||||
VL_PRINTF( // Not VL_PRINTF_MT, already on main thread
|
||||
"-Info: %s:%d: %s\n", filename, linenum,
|
||||
"Verilog $stop, ignored due to +verilator+error+limit");
|
||||
}
|
||||
} else {
|
||||
vl_stop(filename, linenum, hier);
|
||||
}
|
||||
@@ -173,7 +189,8 @@ void vl_stop_maybe(const char* filename, int linenum, const char* hier, bool may
|
||||
|
||||
#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) {}
|
||||
// hier is unused in the default implementation.
|
||||
(void)hier;
|
||||
if (filename && filename[0]) {
|
||||
// Not VL_PRINTF_MT, already on main thread
|
||||
VL_PRINTF("%%Warning: %s:%d: %s\n", filename, linenum, msg);
|
||||
@@ -395,6 +412,8 @@ IData VL_RAND_RESET_I(int obits) VL_MT_SAFE {
|
||||
data &= VL_MASK_I(obits);
|
||||
return data;
|
||||
}
|
||||
IData VL_RAND_RESET_ASSIGN_I(int obits) VL_MT_SAFE { return VL_RANDOM_I() & VL_MASK_I(obits); }
|
||||
|
||||
QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE {
|
||||
if (Verilated::threadContextp()->randReset() == 0) return 0;
|
||||
QData data = ~0ULL;
|
||||
@@ -404,11 +423,19 @@ QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE {
|
||||
data &= VL_MASK_Q(obits);
|
||||
return data;
|
||||
}
|
||||
|
||||
QData VL_RAND_RESET_ASSIGN_Q(int obits) VL_MT_SAFE { return VL_RANDOM_Q() & VL_MASK_Q(obits); }
|
||||
|
||||
WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE {
|
||||
for (int i = 0; i < VL_WORDS_I(obits) - 1; ++i) outwp[i] = VL_RAND_RESET_I(32);
|
||||
outwp[VL_WORDS_I(obits) - 1] = VL_RAND_RESET_I(32) & VL_MASK_E(obits);
|
||||
return outwp;
|
||||
}
|
||||
WDataOutP VL_RAND_RESET_ASSIGN_W(int obits, WDataOutP outwp) VL_MT_SAFE {
|
||||
for (int i = 0; i < VL_WORDS_I(obits) - 1; ++i) outwp[i] = VL_RAND_RESET_ASSIGN_I(32);
|
||||
outwp[VL_WORDS_I(obits) - 1] = VL_RAND_RESET_ASSIGN_I(32) & VL_MASK_E(obits);
|
||||
return outwp;
|
||||
}
|
||||
WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE {
|
||||
// Not inlined to speed up compilation of slowpath code
|
||||
return VL_ZERO_W(obits, outwp);
|
||||
@@ -594,7 +621,7 @@ WDataOutP VL_POWSS_WWW(int obits, int, int rbits, WDataOutP owp, const WDataInP
|
||||
const int words = VL_WORDS_I(obits);
|
||||
VL_ZERO_W(obits, owp);
|
||||
EData lor = 0; // 0=all zeros, ~0=all ones, else mix
|
||||
for (int i = 1; i < (words - 1); ++i) { lor |= lwp[i]; }
|
||||
for (int i = 1; i < (words - 1); ++i) lor |= lwp[i];
|
||||
lor |= ((lwp[words - 1] == VL_MASK_E(rbits)) ? ~VL_EUL(0) : 0);
|
||||
if (lor == 0 && lwp[0] == 0) { // "X" so return 0
|
||||
return owp;
|
||||
@@ -783,7 +810,7 @@ std::string _vl_vsformat_time(char* tmp, T ld, int timeunit, bool left, size_t w
|
||||
}
|
||||
}
|
||||
|
||||
const int needmore = width - digits;
|
||||
const int needmore = static_cast<int>(width) - digits;
|
||||
std::string padding;
|
||||
if (needmore > 0) padding.append(needmore, ' '); // Pad with spaces
|
||||
return left ? (tmp + padding) : (padding + tmp);
|
||||
@@ -792,7 +819,7 @@ std::string _vl_vsformat_time(char* tmp, T ld, int timeunit, bool left, size_t w
|
||||
// Do a va_arg returning a quad, assuming input argument is anything less than wide
|
||||
#define VL_VA_ARG_Q_(ap, bits) (((bits) <= VL_IDATASIZE) ? va_arg(ap, IData) : va_arg(ap, QData))
|
||||
|
||||
void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SAFE {
|
||||
void _vl_vsformat(std::string& output, const std::string& format, va_list ap) VL_MT_SAFE {
|
||||
// Format a Verilog $write style format into the output list
|
||||
// The format must be pre-processed (and lower cased) by Verilator
|
||||
// Arguments are in "width, arg-value (or WDataIn* if wide)" form
|
||||
@@ -801,24 +828,24 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
||||
// Note also assumes variables < 64 are not wide, this assumption is
|
||||
// sometimes not true in low-level routines written here in verilated.cpp
|
||||
static thread_local char t_tmp[VL_VALUE_STRING_MAX_WIDTH];
|
||||
const char* pctp = nullptr; // Most recent %##.##g format
|
||||
std::string::const_iterator pctit = format.end(); // Most recent %##.##g format
|
||||
bool inPct = false;
|
||||
bool widthSet = false;
|
||||
bool left = false;
|
||||
size_t width = 0;
|
||||
for (const char* pos = formatp; *pos; ++pos) {
|
||||
for (std::string::const_iterator pos = format.cbegin(); pos != format.cend(); ++pos) {
|
||||
if (!inPct && pos[0] == '%') {
|
||||
pctp = pos;
|
||||
pctit = pos;
|
||||
inPct = true;
|
||||
widthSet = false;
|
||||
width = 0;
|
||||
} else if (!inPct) { // Normal text
|
||||
// Fast-forward to next escape and add to output
|
||||
const char* ep = pos;
|
||||
while (ep[0] && ep[0] != '%') ++ep;
|
||||
std::string::const_iterator ep = pos;
|
||||
while (ep != format.end() && ep[0] != '%') ++ep;
|
||||
if (ep != pos) {
|
||||
output.append(pos, ep - pos);
|
||||
pos += ep - pos - 1;
|
||||
output.append(pos, ep);
|
||||
pos = ep - 1;
|
||||
}
|
||||
} else { // Format character
|
||||
inPct = false;
|
||||
@@ -875,14 +902,13 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
||||
case '^': { // Realtime
|
||||
const int lbits = va_arg(ap, int);
|
||||
const double d = va_arg(ap, double);
|
||||
if (lbits) {} // UNUSED - always 64
|
||||
(void)lbits; // UNUSED - always 64
|
||||
if (fmt == '^') { // Realtime
|
||||
if (!widthSet) width = Verilated::threadContextp()->impp()->timeFormatWidth();
|
||||
const int timeunit = va_arg(ap, int);
|
||||
output += _vl_vsformat_time(t_tmp, d, timeunit, left, width);
|
||||
} else {
|
||||
const size_t len = pos - pctp + 1;
|
||||
const std::string fmts{pctp, len};
|
||||
const std::string fmts{pctit, pos + 1};
|
||||
VL_SNPRINTF(t_tmp, VL_VALUE_STRING_MAX_WIDTH, fmts.c_str(), d);
|
||||
output += t_tmp;
|
||||
}
|
||||
@@ -936,20 +962,20 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
||||
if (VL_SIGN_E(lbits, lwp[VL_WORDS_I(lbits) - 1])) {
|
||||
VlWide<VL_VALUE_STRING_MAX_WIDTH / 4 + 2> neg;
|
||||
VL_NEGATE_W(VL_WORDS_I(lbits), neg, lwp);
|
||||
append = std::string{"-"} + VL_DECIMAL_NW(lbits, neg);
|
||||
append = "-"s + VL_DECIMAL_NW(lbits, neg);
|
||||
} else {
|
||||
append = VL_DECIMAL_NW(lbits, lwp);
|
||||
}
|
||||
digits = append.length();
|
||||
digits = static_cast<int>(append.length());
|
||||
}
|
||||
const int needmore = width - digits;
|
||||
const int needmore = static_cast<int>(width) - digits;
|
||||
if (needmore > 0) {
|
||||
std::string padding;
|
||||
if (left) {
|
||||
padding.append(needmore, ' '); // Pre-pad spaces
|
||||
output += append + padding;
|
||||
} else {
|
||||
if (pctp && pctp[0] && pctp[1] == '0') { // %0
|
||||
if (pctit != format.end() && pctit[0] && pctit[1] == '0') { // %0
|
||||
padding.append(needmore, '0'); // Pre-pad zero
|
||||
} else {
|
||||
padding.append(needmore, ' '); // Pre-pad spaces
|
||||
@@ -969,16 +995,16 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
||||
append = t_tmp;
|
||||
} else {
|
||||
append = VL_DECIMAL_NW(lbits, lwp);
|
||||
digits = append.length();
|
||||
digits = static_cast<int>(append.length());
|
||||
}
|
||||
const int needmore = width - digits;
|
||||
const int needmore = static_cast<int>(width) - digits;
|
||||
if (needmore > 0) {
|
||||
std::string padding;
|
||||
if (left) {
|
||||
padding.append(needmore, ' '); // Pre-pad spaces
|
||||
output += append + padding;
|
||||
} else {
|
||||
if (pctp && pctp[0] && pctp[1] == '0') { // %0
|
||||
if (pctit != format.end() && pctit[0] && pctit[1] == '0') { // %0
|
||||
padding.append(needmore, '0'); // Pre-pad zero
|
||||
} else {
|
||||
padding.append(needmore, ' '); // Pre-pad spaces
|
||||
@@ -1037,7 +1063,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
||||
}
|
||||
} // switch
|
||||
|
||||
const int needmore = width - digits;
|
||||
const int needmore = static_cast<int>(width) - digits;
|
||||
if (needmore > 0) {
|
||||
std::string padding;
|
||||
if (left) {
|
||||
@@ -1078,7 +1104,7 @@ void _vl_vsformat(std::string& output, const char* formatp, va_list ap) VL_MT_SA
|
||||
}
|
||||
break;
|
||||
default: { // LCOV_EXCL_START
|
||||
const std::string msg = std::string{"Unknown _vl_vsformat code: "} + pos[0];
|
||||
const std::string msg = "Unknown _vl_vsformat code: "s + pos[0];
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str());
|
||||
break;
|
||||
} // LCOV_EXCL_STOP
|
||||
@@ -1161,8 +1187,8 @@ static char* _vl_vsss_read_bin(FILE* fp, int& floc, const WDataInP fromp, const
|
||||
static void _vl_vsss_setbit(WDataOutP iowp, int obits, int lsb, int nbits, IData ld) VL_MT_SAFE {
|
||||
for (; nbits && lsb < obits; nbits--, lsb++, ld >>= 1) VL_ASSIGNBIT_WI(lsb, iowp, ld & 1);
|
||||
}
|
||||
static void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp,
|
||||
size_t posstart, size_t posend) VL_MT_SAFE {
|
||||
void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp, 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.
|
||||
VL_ZERO_W(obits, owp);
|
||||
int lsb = 0;
|
||||
@@ -1196,7 +1222,7 @@ static void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* s
|
||||
IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||
int fbits, const WDataInP fromp, // Else if a sscanf
|
||||
const std::string& fstr, // if a sscanf to string
|
||||
const char* formatp, va_list ap) VL_MT_SAFE {
|
||||
const std::string& format, va_list ap) VL_MT_SAFE {
|
||||
// Read a Verilog $sscanf/$fscanf style format into the output list
|
||||
// The format must be pre-processed (and lower cased) by Verilator
|
||||
// Arguments are in "width, arg-value (or WDataIn* if wide)" form
|
||||
@@ -1205,15 +1231,15 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||
IData got = 0;
|
||||
bool inPct = false;
|
||||
bool inIgnore = false;
|
||||
const char* pos = formatp;
|
||||
for (; *pos && !_vl_vsss_eof(fp, floc); ++pos) {
|
||||
std::string::const_iterator pos = format.cbegin();
|
||||
for (; pos != format.cend() && !_vl_vsss_eof(fp, floc); ++pos) {
|
||||
// VL_DBG_MSGF("_vlscan fmt='"<<pos[0]<<"' floc="<<floc<<" file='"<<_vl_vsss_peek(fp, floc,
|
||||
// fromp, fstr)<<"'\n");
|
||||
if (!inPct && pos[0] == '%') {
|
||||
inPct = true;
|
||||
inIgnore = false;
|
||||
} else if (!inPct && std::isspace(pos[0])) { // Format spaces
|
||||
while (std::isspace(pos[1])) pos++;
|
||||
while (std::isspace(pos[1])) ++pos;
|
||||
_vl_vsss_skipspace(fp, floc, fromp, fstr);
|
||||
} else if (!inPct) { // Expected Format
|
||||
_vl_vsss_skipspace(fp, floc, fromp, fstr);
|
||||
@@ -1360,7 +1386,7 @@ IData _vl_vsscanf(FILE* fp, // If a fscanf
|
||||
break;
|
||||
}
|
||||
default: { // LCOV_EXCL_START
|
||||
const std::string msg = std::string{"Unknown _vl_vsscanf code: "} + pos[0];
|
||||
const std::string msg = "Unknown _vl_vsscanf code: "s + pos[0];
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str());
|
||||
break;
|
||||
} // LCOV_EXCL_STOP
|
||||
@@ -1429,8 +1455,8 @@ void _vl_string_to_vint(int obits, void* destp, size_t srclen, const char* srcp)
|
||||
char* op = reinterpret_cast<char*>(destp);
|
||||
if (srclen > bytes) srclen = bytes; // Don't overflow destination
|
||||
size_t i = 0;
|
||||
for (i = 0; i < srclen; ++i) { *op++ = srcp[srclen - 1 - i]; }
|
||||
for (; i < bytes; ++i) { *op++ = 0; }
|
||||
for (i = 0; i < srclen; ++i) *op++ = srcp[srclen - 1 - i];
|
||||
for (; i < bytes; ++i) *op++ = 0;
|
||||
}
|
||||
|
||||
static IData getLine(std::string& str, IData fpi, size_t maxLen) VL_MT_SAFE {
|
||||
@@ -1500,149 +1526,153 @@ void VL_FCLOSE_I(IData fdi) VL_MT_SAFE {
|
||||
Verilated::threadContextp()->impp()->fdClose(fdi);
|
||||
}
|
||||
|
||||
void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...) VL_MT_SAFE {
|
||||
void VL_SFORMAT_NX(int obits, CData& destr, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
va_list ap;
|
||||
va_start(ap, formatp);
|
||||
_vl_vsformat(t_output, formatp, ap);
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
_vl_string_to_vint(obits, &destr, t_output.length(), t_output.c_str());
|
||||
}
|
||||
|
||||
void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...) VL_MT_SAFE {
|
||||
void VL_SFORMAT_NX(int obits, SData& destr, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
va_list ap;
|
||||
va_start(ap, formatp);
|
||||
_vl_vsformat(t_output, formatp, ap);
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
_vl_string_to_vint(obits, &destr, t_output.length(), t_output.c_str());
|
||||
}
|
||||
|
||||
void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...) VL_MT_SAFE {
|
||||
void VL_SFORMAT_NX(int obits, IData& destr, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
va_list ap;
|
||||
va_start(ap, formatp);
|
||||
_vl_vsformat(t_output, formatp, ap);
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
_vl_string_to_vint(obits, &destr, t_output.length(), t_output.c_str());
|
||||
}
|
||||
|
||||
void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...) VL_MT_SAFE {
|
||||
void VL_SFORMAT_NX(int obits, QData& destr, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
va_list ap;
|
||||
va_start(ap, formatp);
|
||||
_vl_vsformat(t_output, formatp, ap);
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
_vl_string_to_vint(obits, &destr, t_output.length(), t_output.c_str());
|
||||
}
|
||||
|
||||
void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) VL_MT_SAFE {
|
||||
void VL_SFORMAT_NX(int obits, void* destp, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
va_list ap;
|
||||
va_start(ap, formatp);
|
||||
_vl_vsformat(t_output, formatp, ap);
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
_vl_string_to_vint(obits, destp, t_output.length(), t_output.c_str());
|
||||
}
|
||||
|
||||
void VL_SFORMAT_X(int obits_ignored, std::string& output, const char* formatp, ...) VL_MT_SAFE {
|
||||
if (obits_ignored) {}
|
||||
void VL_SFORMAT_NX(int obits_ignored, std::string& output, const std::string& format, int argc,
|
||||
...) VL_MT_SAFE {
|
||||
(void)obits_ignored; // So VL_SFORMAT_NNX function signatures all match
|
||||
std::string temp_output;
|
||||
va_list ap;
|
||||
va_start(ap, formatp);
|
||||
_vl_vsformat(temp_output, formatp, ap);
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(temp_output, format, ap);
|
||||
va_end(ap);
|
||||
output = temp_output;
|
||||
}
|
||||
|
||||
std::string VL_SFORMATF_NX(const char* formatp, ...) VL_MT_SAFE {
|
||||
std::string VL_SFORMATF_N_NX(const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
va_list ap;
|
||||
va_start(ap, formatp);
|
||||
_vl_vsformat(t_output, formatp, ap);
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return t_output;
|
||||
}
|
||||
|
||||
void VL_WRITEF(const char* formatp, ...) VL_MT_SAFE {
|
||||
void VL_WRITEF_NX(const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
va_list ap;
|
||||
va_start(ap, formatp);
|
||||
_vl_vsformat(t_output, formatp, ap);
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
VL_PRINTF_MT("%s", t_output.c_str());
|
||||
}
|
||||
|
||||
void VL_FWRITEF(IData fpi, const char* formatp, ...) VL_MT_SAFE {
|
||||
void VL_FWRITEF_NX(IData fpi, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
// While threadsafe, each thread can only access different file handles
|
||||
static thread_local std::string t_output; // static only for speed
|
||||
t_output = "";
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, formatp);
|
||||
_vl_vsformat(t_output, formatp, ap);
|
||||
va_start(ap, argc);
|
||||
_vl_vsformat(t_output, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
Verilated::threadContextp()->impp()->fdWrite(fpi, t_output);
|
||||
}
|
||||
|
||||
IData VL_FSCANF_IX(IData fpi, const char* formatp, ...) VL_MT_SAFE {
|
||||
IData VL_FSCANF_INX(IData fpi, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
// While threadsafe, each thread can only access different file handles
|
||||
FILE* const fp = VL_CVT_I_FP(fpi);
|
||||
if (VL_UNLIKELY(!fp)) return ~0U; // -1
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, formatp);
|
||||
const IData got = _vl_vsscanf(fp, 0, nullptr, "", formatp, ap);
|
||||
va_start(ap, argc);
|
||||
const IData got = _vl_vsscanf(fp, 0, nullptr, "", format, ap);
|
||||
va_end(ap);
|
||||
return got;
|
||||
}
|
||||
|
||||
IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) VL_MT_SAFE {
|
||||
IData VL_SSCANF_IINX(int lbits, IData ld, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
VlWide<VL_WQ_WORDS_E> fnw;
|
||||
VL_SET_WI(fnw, ld);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, formatp);
|
||||
const IData got = _vl_vsscanf(nullptr, lbits, fnw, "", formatp, ap);
|
||||
va_start(ap, argc);
|
||||
const IData got = _vl_vsscanf(nullptr, lbits, fnw, "", format, ap);
|
||||
va_end(ap);
|
||||
return got;
|
||||
}
|
||||
IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...) VL_MT_SAFE {
|
||||
IData VL_SSCANF_IQNX(int lbits, QData ld, const std::string& format, int argc, ...) VL_MT_SAFE {
|
||||
VlWide<VL_WQ_WORDS_E> fnw;
|
||||
VL_SET_WQ(fnw, ld);
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, formatp);
|
||||
const IData got = _vl_vsscanf(nullptr, lbits, fnw, "", formatp, ap);
|
||||
va_start(ap, argc);
|
||||
const IData got = _vl_vsscanf(nullptr, lbits, fnw, "", format, ap);
|
||||
va_end(ap);
|
||||
return got;
|
||||
}
|
||||
IData VL_SSCANF_IWX(int lbits, const WDataInP lwp, const char* formatp, ...) VL_MT_SAFE {
|
||||
IData VL_SSCANF_IWNX(int lbits, const WDataInP lwp, const std::string& format, int argc,
|
||||
...) VL_MT_SAFE {
|
||||
va_list ap;
|
||||
va_start(ap, formatp);
|
||||
const IData got = _vl_vsscanf(nullptr, lbits, lwp, "", formatp, ap);
|
||||
va_start(ap, argc);
|
||||
const IData got = _vl_vsscanf(nullptr, lbits, lwp, "", format, ap);
|
||||
va_end(ap);
|
||||
return got;
|
||||
}
|
||||
IData VL_SSCANF_INX(int, const std::string& ld, const char* formatp, ...) VL_MT_SAFE {
|
||||
IData VL_SSCANF_INNX(int, const std::string& ld, const std::string& format, int argc,
|
||||
...) VL_MT_SAFE {
|
||||
va_list ap;
|
||||
va_start(ap, formatp);
|
||||
const IData got = _vl_vsscanf(nullptr, ld.length() * 8, nullptr, ld, formatp, ap);
|
||||
va_start(ap, argc);
|
||||
const IData got
|
||||
= _vl_vsscanf(nullptr, static_cast<int>(ld.length() * 8), nullptr, ld, format, ap);
|
||||
va_end(ap);
|
||||
return got;
|
||||
}
|
||||
@@ -1717,7 +1747,7 @@ std::string VL_STACKTRACE_N() VL_MT_SAFE {
|
||||
if (!strings) return "Unable to backtrace\n";
|
||||
|
||||
std::string result = "Backtrace:\n";
|
||||
for (int j = 0; j < nptrs; j++) result += std::string{strings[j]} + std::string{"\n"};
|
||||
for (int j = 0; j < nptrs; j++) result += std::string{strings[j]} + "\n"s;
|
||||
free(strings);
|
||||
return result;
|
||||
}
|
||||
@@ -1735,7 +1765,10 @@ IData VL_SYSTEM_IQ(QData lhs) VL_MT_SAFE {
|
||||
IData VL_SYSTEM_IW(int lhswords, const WDataInP lhsp) VL_MT_SAFE {
|
||||
char filenamez[VL_VALUE_STRING_MAX_CHARS + 1];
|
||||
_vl_vint_to_string(lhswords * VL_EDATASIZE, filenamez, lhsp);
|
||||
const int code = std::system(filenamez); // Yes, std::system() is threadsafe
|
||||
return VL_SYSTEM_IN(filenamez);
|
||||
}
|
||||
IData VL_SYSTEM_IN(const std::string& lhs) VL_MT_SAFE {
|
||||
const int code = std::system(lhs.c_str()); // Yes, std::system() is threadsafe
|
||||
return code >> 8; // Want exit status
|
||||
}
|
||||
|
||||
@@ -1860,13 +1893,13 @@ const char* vl_mc_scan_plusargs(const char* prefixp) VL_MT_SAFE {
|
||||
//===========================================================================
|
||||
// Heavy string functions
|
||||
|
||||
std::string VL_TO_STRING(CData lhs) { return VL_SFORMATF_NX("'h%0x", 8, lhs); }
|
||||
std::string VL_TO_STRING(SData lhs) { return VL_SFORMATF_NX("'h%0x", 16, lhs); }
|
||||
std::string VL_TO_STRING(IData lhs) { return VL_SFORMATF_NX("'h%0x", 32, lhs); }
|
||||
std::string VL_TO_STRING(QData lhs) { return VL_SFORMATF_NX("'h%0x", 64, lhs); }
|
||||
std::string VL_TO_STRING(double lhs) { return VL_SFORMATF_NX("%d", 64, lhs); }
|
||||
std::string VL_TO_STRING(CData lhs) { return VL_SFORMATF_N_NX("'h%0x", 0, 8, lhs); }
|
||||
std::string VL_TO_STRING(SData lhs) { return VL_SFORMATF_N_NX("'h%0x", 0, 16, lhs); }
|
||||
std::string VL_TO_STRING(IData lhs) { return VL_SFORMATF_N_NX("'h%0x", 0, 32, lhs); }
|
||||
std::string VL_TO_STRING(QData lhs) { return VL_SFORMATF_N_NX("'h%0x", 0, 64, lhs); }
|
||||
std::string VL_TO_STRING(double lhs) { return VL_SFORMATF_N_NX("%d", 0, 64, lhs); }
|
||||
std::string VL_TO_STRING_W(int words, const WDataInP obj) {
|
||||
return VL_SFORMATF_NX("'h%0x", words * VL_EDATASIZE, obj);
|
||||
return VL_SFORMATF_N_NX("'h%0x", 0, words * VL_EDATASIZE, obj);
|
||||
}
|
||||
|
||||
std::string VL_TOLOWER_NN(const std::string& ld) VL_PURE {
|
||||
@@ -1931,7 +1964,7 @@ std::string VL_SUBSTR_N(const std::string& lhs, IData rhs, IData ths) VL_PURE {
|
||||
|
||||
IData VL_ATOI_N(const std::string& str, int base) VL_PURE {
|
||||
std::string str_mod = str;
|
||||
// IEEE 1800-2017 6.16.9 says '_' may exist.
|
||||
// IEEE 1800-2023 6.16.9 says '_' may exist.
|
||||
str_mod.erase(std::remove(str_mod.begin(), str_mod.end(), '_'), str_mod.end());
|
||||
|
||||
errno = 0;
|
||||
@@ -2023,22 +2056,26 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) {
|
||||
if (VL_UNLIKELY(!m_fp)) return false;
|
||||
valuer = "";
|
||||
// Prep for reading
|
||||
bool indata = false;
|
||||
bool ignore_to_eol = false;
|
||||
bool ignore_to_cmt = false;
|
||||
bool reading_addr = false;
|
||||
int lastc = ' ';
|
||||
bool inData = false;
|
||||
bool ignoreToEol = false;
|
||||
bool ignoreToComment = false;
|
||||
bool readingAddress = false;
|
||||
int lastCh = ' ';
|
||||
// Read the data
|
||||
// We process a character at a time, as then we don't need to deal
|
||||
// with changing buffer sizes dynamically, etc.
|
||||
while (true) {
|
||||
int c = std::fgetc(m_fp);
|
||||
if (VL_UNLIKELY(c == EOF)) break;
|
||||
const bool chIs4StateBin
|
||||
= c == '0' || c == '1' || c == 'x' || c == 'X' || c == 'z' || c == 'Z';
|
||||
const bool chIs2StateHex = std::isxdigit(c);
|
||||
const bool chIs4StateHex = std::isxdigit(c) || chIs4StateBin;
|
||||
// printf("%d: Got '%c' Addr%lx IN%d IgE%d IgC%d\n",
|
||||
// m_linenum, c, m_addr, indata, ignore_to_eol, ignore_to_cmt);
|
||||
// m_linenum, c, m_addr, inData, ignoreToEol, ignoreToComment);
|
||||
// See if previous data value has completed, and if so return
|
||||
if (c == '_') continue; // Ignore _ e.g. inside a number
|
||||
if (indata && !std::isxdigit(c) && c != 'x' && c != 'X') {
|
||||
if (inData && !chIs4StateHex) {
|
||||
// printf("Got data @%lx = %s\n", m_addr, valuer.c_str());
|
||||
ungetc(c, m_fp);
|
||||
addrr = m_addr;
|
||||
@@ -2048,58 +2085,55 @@ bool VlReadMem::get(QData& addrr, std::string& valuer) {
|
||||
// Parse line
|
||||
if (c == '\n') {
|
||||
++m_linenum;
|
||||
ignore_to_eol = false;
|
||||
reading_addr = false;
|
||||
ignoreToEol = false;
|
||||
readingAddress = false;
|
||||
} else if (c == '\t' || c == ' ' || c == '\r' || c == '\f') {
|
||||
reading_addr = false;
|
||||
readingAddress = false;
|
||||
}
|
||||
// Skip // comments and detect /* comments
|
||||
else if (ignore_to_cmt && lastc == '*' && c == '/') {
|
||||
ignore_to_cmt = false;
|
||||
reading_addr = false;
|
||||
} else if (!ignore_to_eol && !ignore_to_cmt) {
|
||||
if (lastc == '/' && c == '*') {
|
||||
ignore_to_cmt = true;
|
||||
} else if (lastc == '/' && c == '/') {
|
||||
ignore_to_eol = true;
|
||||
else if (ignoreToComment && lastCh == '*' && c == '/') {
|
||||
ignoreToComment = false;
|
||||
readingAddress = false;
|
||||
} else if (!ignoreToEol && !ignoreToComment) {
|
||||
if (lastCh == '/' && c == '*') {
|
||||
ignoreToComment = true;
|
||||
} else if (lastCh == '/' && c == '/') {
|
||||
ignoreToEol = true;
|
||||
} else if (c == '/') { // Part of /* or //
|
||||
} else if (c == '#') {
|
||||
ignore_to_eol = true;
|
||||
ignoreToEol = true;
|
||||
} else if (c == '@') {
|
||||
reading_addr = true;
|
||||
readingAddress = true;
|
||||
m_anyAddr = true;
|
||||
m_addr = 0;
|
||||
}
|
||||
// Check for hex or binary digits as file format requests
|
||||
else if (std::isxdigit(c) || (!reading_addr && (c == 'x' || c == 'X'))) {
|
||||
} else if (readingAddress && chIs2StateHex) {
|
||||
c = std::tolower(c);
|
||||
const int value
|
||||
= (c >= 'a' ? (c == 'x' ? VL_RAND_RESET_I(4) : (c - 'a' + 10)) : (c - '0'));
|
||||
if (reading_addr) {
|
||||
// Decode @ addresses
|
||||
m_addr = (m_addr << 4) + value;
|
||||
} else {
|
||||
indata = true;
|
||||
valuer += static_cast<char>(c);
|
||||
// printf(" Value width=%d @%x = %c\n", width, m_addr, c);
|
||||
if (VL_UNLIKELY(value > 1 && !m_hex)) {
|
||||
VL_FATAL_MT(m_filename.c_str(), m_linenum, "",
|
||||
"$readmemb (binary) file contains hex characters");
|
||||
}
|
||||
const int addressValue = (c >= 'a') ? (c - 'a' + 10) : (c - '0');
|
||||
m_addr = (m_addr << 4) + addressValue;
|
||||
} else if (readingAddress && chIs4StateHex) {
|
||||
VL_FATAL_MT(m_filename.c_str(), m_linenum, "",
|
||||
"$readmem address contains 4-state characters");
|
||||
} else if (chIs4StateHex) {
|
||||
inData = true;
|
||||
valuer += static_cast<char>(c);
|
||||
if (VL_UNLIKELY(!m_hex && !chIs4StateBin)) {
|
||||
VL_FATAL_MT(m_filename.c_str(), m_linenum, "",
|
||||
"$readmemb (binary) file contains hex characters");
|
||||
}
|
||||
} else {
|
||||
VL_FATAL_MT(m_filename.c_str(), m_linenum, "", "$readmem file syntax error");
|
||||
}
|
||||
}
|
||||
lastc = c;
|
||||
lastCh = c;
|
||||
}
|
||||
|
||||
if (VL_UNLIKELY(m_end != ~0ULL && m_addr <= m_end && !m_anyAddr)) {
|
||||
VL_WARN_MT(m_filename.c_str(), m_linenum, "",
|
||||
"$readmem file ended before specified final address (IEEE 1800-2017 21.4)");
|
||||
"$readmem file ended before specified final address (IEEE 1800-2023 21.4)");
|
||||
}
|
||||
|
||||
return false; // EOF
|
||||
addrr = m_addr;
|
||||
return inData; // EOF
|
||||
}
|
||||
void VlReadMem::setData(void* valuep, const std::string& rhs) {
|
||||
const QData shift = m_hex ? 4ULL : 1ULL;
|
||||
@@ -2107,8 +2141,9 @@ void VlReadMem::setData(void* valuep, const std::string& rhs) {
|
||||
// Shift value in
|
||||
for (const auto& i : rhs) {
|
||||
const char c = std::tolower(i);
|
||||
const int value
|
||||
= (c >= 'a' ? (c == 'x' ? VL_RAND_RESET_I(4) : (c - 'a' + 10)) : (c - '0'));
|
||||
const int value = (c == 'x' || c == 'z') ? VL_RAND_RESET_I(m_hex ? 4 : 1)
|
||||
: (c >= 'a') ? (c - 'a' + 10)
|
||||
: (c - '0');
|
||||
if (m_bits <= 8) {
|
||||
CData* const datap = reinterpret_cast<CData*>(valuep);
|
||||
if (!innum) *datap = 0;
|
||||
@@ -2248,6 +2283,7 @@ void VL_READMEM_N(bool hex, // Hex format, else binary
|
||||
QData addr = 0;
|
||||
std::string value;
|
||||
if (rmem.get(addr /*ref*/, value /*ref*/)) {
|
||||
// printf("readmem.get [%" PRIu64 "]=%s\n", addr, value.c_str());
|
||||
if (VL_UNLIKELY(addr < static_cast<QData>(array_lsb)
|
||||
|| addr >= static_cast<QData>(array_lsb + depth))) {
|
||||
VL_FATAL_MT(filename.c_str(), rmem.linenum(), "",
|
||||
@@ -2402,6 +2438,22 @@ uint64_t vl_time_pow10(int n) {
|
||||
return pow10[n];
|
||||
}
|
||||
|
||||
std::string vl_timescaled_double(double value, const char* format) VL_PURE {
|
||||
const char* suffixp = "s";
|
||||
// clang-format off
|
||||
if (value >= 1e0) { suffixp = "s"; value *= 1e0; }
|
||||
else if (value >= 1e-3) { suffixp = "ms"; value *= 1e3; }
|
||||
else if (value >= 1e-6) { suffixp = "us"; value *= 1e6; }
|
||||
else if (value >= 1e-9) { suffixp = "ns"; value *= 1e9; }
|
||||
else if (value >= 1e-12) { suffixp = "ps"; value *= 1e12; }
|
||||
else if (value >= 1e-15) { suffixp = "fs"; value *= 1e15; }
|
||||
else if (value >= 1e-18) { suffixp = "as"; value *= 1e18; }
|
||||
// clang-format on
|
||||
char valuestr[100];
|
||||
VL_SNPRINTF(valuestr, 100, format, value, suffixp);
|
||||
return std::string{valuestr}; // Gets converted to string, so no ref to stack
|
||||
}
|
||||
|
||||
void VL_PRINTTIMESCALE(const char* namep, const char* timeunitp,
|
||||
const VerilatedContext* contextp) VL_MT_SAFE {
|
||||
VL_PRINTF_MT("Time scale of %s is %s / %s\n", namep, timeunitp,
|
||||
@@ -2422,12 +2474,15 @@ VerilatedContext::VerilatedContext()
|
||||
: m_impdatap{new VerilatedContextImpData} {
|
||||
Verilated::lastContextp(this);
|
||||
Verilated::threadContextp(this);
|
||||
m_ns.m_coverageFilename = "coverage.dat";
|
||||
m_ns.m_profExecFilename = "profile_exec.dat";
|
||||
m_ns.m_profVltFilename = "profile.vlt";
|
||||
m_ns.m_solverProgram = VlOs::getenvStr("VERILATOR_SOLVER", VL_SOLVER_DEFAULT);
|
||||
m_fdps.resize(31);
|
||||
std::fill(m_fdps.begin(), m_fdps.end(), static_cast<FILE*>(nullptr));
|
||||
m_fdFreeMct.resize(30);
|
||||
for (std::size_t i = 0, id = 1; i < m_fdFreeMct.size(); ++i, ++id) m_fdFreeMct[i] = id;
|
||||
IData id = 1;
|
||||
for (std::size_t i = 0; i < m_fdFreeMct.size(); ++i, ++id) m_fdFreeMct[i] = id;
|
||||
}
|
||||
|
||||
// Must declare here not in interface, as otherwise forward declarations not known
|
||||
@@ -2449,14 +2504,60 @@ VerilatedContext::Serialized::Serialized() {
|
||||
m_timeprecision = picosecond; // Initial value until overridden by _Vconfigure
|
||||
}
|
||||
|
||||
bool VerilatedContext::assertOn() const VL_MT_SAFE { return m_s.m_assertOn; }
|
||||
void VerilatedContext::assertOn(bool flag) VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
m_s.m_assertOn = flag;
|
||||
// Set all assert and directive types when true, clear otherwise.
|
||||
m_s.m_assertOn = VL_MASK_I(ASSERT_ON_WIDTH) * flag;
|
||||
}
|
||||
bool VerilatedContext::assertOnGet(VerilatedAssertType_t type,
|
||||
VerilatedAssertDirectiveType_t directive) const VL_MT_SAFE {
|
||||
// Check if selected directive type bit in the assertOn is enabled for assertion type.
|
||||
// Note: it is assumed that this is checked only for one type at the time.
|
||||
|
||||
// Flag unspecified assertion types as disabled.
|
||||
if (type == 0) return false;
|
||||
|
||||
// Get index of 3-bit group guarding assertion type status.
|
||||
// Since the assertOnGet is generated __always__ for a single assert type, we assume that only
|
||||
// a single bit will be set. Thus, ceil log2 will work fine.
|
||||
VL_DEBUG_IFDEF(assert((type & (type - 1)) == 0););
|
||||
const IData typeMaskPosition = VL_CLOG2_I(type);
|
||||
|
||||
// Check if directive type bit is enabled in corresponding assertion type bits.
|
||||
return m_s.m_assertOn & (directive << (typeMaskPosition * ASSERT_DIRECTIVE_TYPE_MASK_WIDTH));
|
||||
}
|
||||
void VerilatedContext::assertOnSet(VerilatedAssertType_t types,
|
||||
VerilatedAssertDirectiveType_t directives) VL_MT_SAFE {
|
||||
// For each assertion type, set directive bits.
|
||||
|
||||
// Iterate through all positions of assertion type bits. If bit for this assertion type is set,
|
||||
// set directive type bits mask at this group index.
|
||||
for (int i = 0; i < std::numeric_limits<VerilatedAssertType_t>::digits; ++i) {
|
||||
if (VL_BITISSET_I(types, i))
|
||||
m_s.m_assertOn |= directives << (i * ASSERT_DIRECTIVE_TYPE_MASK_WIDTH);
|
||||
}
|
||||
}
|
||||
void VerilatedContext::assertOnClear(VerilatedAssertType_t types,
|
||||
VerilatedAssertDirectiveType_t directives) VL_MT_SAFE {
|
||||
// Iterate through all positions of assertion type bits. If bit for this assertion type is set,
|
||||
// clear directive type bits mask at this group index.
|
||||
for (int i = 0; i < std::numeric_limits<VerilatedAssertType_t>::digits; ++i) {
|
||||
if (VL_BITISSET_I(types, i))
|
||||
m_s.m_assertOn &= ~(directives << (i * ASSERT_DIRECTIVE_TYPE_MASK_WIDTH));
|
||||
}
|
||||
}
|
||||
void VerilatedContext::calcUnusedSigs(bool flag) VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
m_s.m_calcUnusedSigs = flag;
|
||||
}
|
||||
void VerilatedContext::coverageFilename(const std::string& flag) VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
m_ns.m_coverageFilename = flag;
|
||||
}
|
||||
std::string VerilatedContext::coverageFilename() const VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
return m_ns.m_coverageFilename;
|
||||
}
|
||||
void VerilatedContext::dumpfile(const std::string& flag) VL_MT_SAFE_EXCLUDES(m_timeDumpMutex) {
|
||||
const VerilatedLockGuard lock{m_timeDumpMutex};
|
||||
m_dumpfile = flag;
|
||||
@@ -2525,6 +2626,18 @@ std::string VerilatedContext::profVltFilename() const VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
return m_ns.m_profVltFilename;
|
||||
}
|
||||
void VerilatedContext::solverProgram(const std::string& flag) VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
m_ns.m_solverProgram = flag;
|
||||
}
|
||||
std::string VerilatedContext::solverProgram() const VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
return m_ns.m_solverProgram;
|
||||
}
|
||||
void VerilatedContext::quiet(bool flag) VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
m_s.m_quiet = flag;
|
||||
}
|
||||
void VerilatedContext::randReset(int val) VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
m_s.m_randReset = val;
|
||||
@@ -2592,8 +2705,24 @@ void VerilatedContext::internalsDump() const VL_MT_SAFE {
|
||||
}
|
||||
|
||||
void VerilatedContext::addModel(VerilatedModel* modelp) {
|
||||
threadPoolp(); // Ensure thread pool is created, so m_threads cannot change any more
|
||||
if (!quiet()) {
|
||||
// CPU time isn't read as starting point until model creation, so that quiet() is set
|
||||
// Thus if quiet(), avoids slow OS read affecting some usages that make many models
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
m_ns.m_cpuTimeStart.start();
|
||||
m_ns.m_wallTimeStart.start();
|
||||
}
|
||||
|
||||
// We look for time passing, as opposed to post-eval(), as embedded
|
||||
// models might get added inside initial blocks.
|
||||
if (VL_UNLIKELY(time()))
|
||||
VL_FATAL_MT(
|
||||
"", 0, "",
|
||||
"Adding model when time is non-zero. ... Suggest check time(), or for restarting"
|
||||
" model use a new VerilatedContext");
|
||||
|
||||
threadPoolp(); // Ensure thread pool is created, so m_threads cannot change any more
|
||||
m_threadsInModels += modelp->threads();
|
||||
if (VL_UNLIKELY(modelp->threads() > m_threads)) {
|
||||
std::ostringstream msg;
|
||||
msg << "VerilatedContext has " << m_threads << " threads but model '"
|
||||
@@ -2626,6 +2755,7 @@ VerilatedContext::enableExecutionProfiler(VerilatedVirtualBase* (*construct)(Ver
|
||||
|
||||
//======================================================================
|
||||
// VerilatedContextImp:: Methods - command line
|
||||
|
||||
void VerilatedContextImp::commandArgsGuts(int argc, const char** argv)
|
||||
VL_MT_SAFE_EXCLUDES(m_argMutex) {
|
||||
const VerilatedLockGuard lock{m_argMutex};
|
||||
@@ -2685,7 +2815,7 @@ std::pair<int, char**> VerilatedContextImp::argc_argv() VL_MT_SAFE_EXCLUDES(m_ar
|
||||
int in = 0;
|
||||
for (const auto& i : m_args.m_argVec) {
|
||||
s_argvp[in] = new char[i.length() + 1];
|
||||
std::strcpy(s_argvp[in], i.c_str());
|
||||
std::memcpy(s_argvp[in], i.c_str(), i.length() + 1);
|
||||
++in;
|
||||
}
|
||||
s_argvp[s_argc] = nullptr;
|
||||
@@ -2697,7 +2827,9 @@ void VerilatedContextImp::commandArgVl(const std::string& arg) {
|
||||
if (0 == std::strncmp(arg.c_str(), "+verilator+", std::strlen("+verilator+"))) {
|
||||
std::string str;
|
||||
uint64_t u64;
|
||||
if (arg == "+verilator+debug") {
|
||||
if (commandArgVlString(arg, "+verilator+coverage+file+", str)) {
|
||||
coverageFilename(str);
|
||||
} else if (arg == "+verilator+debug") {
|
||||
Verilated::debug(4);
|
||||
} else if (commandArgVlUint64(arg, "+verilator+debugi+", u64, 0,
|
||||
std::numeric_limits<int>::max())) {
|
||||
@@ -2720,6 +2852,8 @@ void VerilatedContextImp::commandArgVl(const std::string& arg) {
|
||||
profExecFilename(str);
|
||||
} else if (commandArgVlString(arg, "+verilator+prof+vlt+file+", str)) {
|
||||
profVltFilename(str);
|
||||
} else if (arg == "+verilator+quiet") {
|
||||
quiet(true);
|
||||
} else if (commandArgVlUint64(arg, "+verilator+rand+reset+", u64, 0, 2)) {
|
||||
randReset(static_cast<int>(u64));
|
||||
} else if (commandArgVlUint64(arg, "+verilator+seed+", u64, 1,
|
||||
@@ -2765,7 +2899,7 @@ bool VerilatedContextImp::commandArgVlUint64(const std::string& arg, const std::
|
||||
VL_FATAL_MT("COMMAND_LINE", 0, "", msg.c_str());
|
||||
};
|
||||
|
||||
if (std::any_of(str.begin(), str.end(), [](int c) { return !std::isdigit(c); })) fail();
|
||||
if (std::any_of(str.cbegin(), str.cend(), [](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");
|
||||
@@ -2797,6 +2931,36 @@ uint64_t VerilatedContextImp::randSeedDefault64() const VL_MT_SAFE {
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// VerilatedContext:: Statistics
|
||||
|
||||
double VerilatedContext::statCpuTimeSinceStart() const VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
return m_ns.m_cpuTimeStart.deltaTime();
|
||||
}
|
||||
double VerilatedContext::statWallTimeSinceStart() const VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
return m_ns.m_wallTimeStart.deltaTime();
|
||||
}
|
||||
void VerilatedContext::statsPrintSummary() VL_MT_UNSAFE {
|
||||
if (quiet()) return;
|
||||
VL_PRINTF("- S i m u l a t i o n R e p o r t: %s %s\n", Verilated::productName(),
|
||||
Verilated::productVersion());
|
||||
const std::string endwhy = gotError() ? "$stop" : gotFinish() ? "$finish" : "end";
|
||||
const double simtimeInUnits = VL_TIME_Q() * vl_time_multiplier(timeunit())
|
||||
* vl_time_multiplier(timeprecision() - timeunit());
|
||||
const std::string simtime = vl_timescaled_double(simtimeInUnits);
|
||||
const double walltime = statWallTimeSinceStart();
|
||||
const double cputime = statCpuTimeSinceStart();
|
||||
const std::string simtimePerf
|
||||
= vl_timescaled_double((cputime != 0.0) ? (simtimeInUnits / cputime) : 0, "%0.3f %s");
|
||||
VL_PRINTF("- Verilator: %s at %s; walltime %0.3f s; speed %s/s\n", endwhy.c_str(),
|
||||
simtime.c_str(), walltime, simtimePerf.c_str());
|
||||
const double modelMB = VlOs::memUsageBytes() / 1024.0 / 1024.0;
|
||||
VL_PRINTF("- Verilator: cpu %0.3f s on %u threads; alloced %0.0f MB\n", cputime,
|
||||
threadsInModels(), modelMB);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// VerilatedContext:: Methods - scopes
|
||||
|
||||
@@ -2835,6 +2999,36 @@ const VerilatedScopeNameMap* VerilatedContext::scopeNameMap() VL_MT_SAFE {
|
||||
return &(impp()->m_impdatap->m_nameMap);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// VerilatedContext:: Methods - trace
|
||||
|
||||
void VerilatedContext::trace(VerilatedTraceBaseC* tfp, int levels, int options) VL_MT_SAFE {
|
||||
VL_DEBUG_IF(VL_DBG_MSGF("+ VerilatedContext::trace\n"););
|
||||
if (tfp->isOpen()) {
|
||||
VL_FATAL_MT("", 0, "",
|
||||
"Testbench C call to 'VerilatedContext::trace()' must not be called"
|
||||
" after 'VerilatedTrace*::open()'\n");
|
||||
}
|
||||
{
|
||||
// Legacy usage may call {modela}->trace(...) then {modelb}->trace(...)
|
||||
// So check for and suppress second and later calls
|
||||
if (tfp->modelConnected()) return;
|
||||
tfp->modelConnected(true);
|
||||
}
|
||||
// We rely on m_ns.m_traceBaseModelCbs being stable when trace() is called
|
||||
// nope: const VerilatedLockGuard lock{m_mutex};
|
||||
if (m_ns.m_traceBaseModelCbs.empty())
|
||||
VL_FATAL_MT("", 0, "",
|
||||
"Testbench C call to 'VerilatedContext::trace()' requires model(s) Verilated"
|
||||
" with --trace or --trace-vcd option");
|
||||
for (auto& cbr : m_ns.m_traceBaseModelCbs) cbr(tfp, levels, options);
|
||||
}
|
||||
void VerilatedContext::traceBaseModelCbAdd(traceBaseModelCb_t cb) VL_MT_SAFE {
|
||||
// Model creation registering a callback for when Verilated::trace() called
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
m_ns.m_traceBaseModelCbs.push_back(cb);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// VerilatedSyms:: Methods
|
||||
|
||||
@@ -2969,7 +3163,7 @@ void Verilated::nullPointerError(const char* filename, int linenum) VL_MT_SAFE {
|
||||
|
||||
void Verilated::overWidthError(const char* signame) VL_MT_SAFE {
|
||||
// Slowpath - Called only when signal sets too high of a bit
|
||||
const std::string msg = (std::string{"Testbench C set input '"} + signame
|
||||
const std::string msg = ("Testbench C set input '"s + signame
|
||||
+ "' to value that overflows what the signal's width can fit");
|
||||
VL_FATAL_MT("unknown", 0, "", msg.c_str());
|
||||
VL_UNREACHABLE;
|
||||
@@ -2995,6 +3189,38 @@ void Verilated::scTraceBeforeElaborationError() VL_MT_SAFE {
|
||||
VL_UNREACHABLE;
|
||||
}
|
||||
|
||||
void Verilated::stackCheck(QData needSize) VL_MT_UNSAFE {
|
||||
// Slowpath - Called only when constructing
|
||||
#ifdef _VL_HAVE_GETRLIMIT
|
||||
QData haveSize = 0;
|
||||
rlimit rlim;
|
||||
if (0 == getrlimit(RLIMIT_STACK, &rlim)) {
|
||||
haveSize = rlim.rlim_cur;
|
||||
if (haveSize == RLIM_INFINITY) haveSize = rlim.rlim_max;
|
||||
if (haveSize == RLIM_INFINITY) haveSize = 0;
|
||||
}
|
||||
// VL_PRINTF_MT("-Info: stackCheck(%" PRIu64 ") have %" PRIu64 "\n", needSize, haveSize);
|
||||
// Check and request for 1.5x need. This is automated so the user doesn't need to do anything.
|
||||
QData requestSize = needSize + needSize / 2;
|
||||
if (VL_UNLIKELY(haveSize && needSize && haveSize < requestSize)) {
|
||||
// Try to increase the stack limit to the requested size
|
||||
rlim.rlim_cur = requestSize;
|
||||
if (
|
||||
#ifdef _VL_TEST_RLIMIT_FAIL
|
||||
true ||
|
||||
#endif
|
||||
setrlimit(RLIMIT_STACK, &rlim)) {
|
||||
VL_PRINTF_MT("%%Warning: System has stack size %" PRIu64 " kb"
|
||||
" which may be too small; failed to request more"
|
||||
" using 'ulimit -s %" PRIu64 "'\n",
|
||||
haveSize / 1024, requestSize);
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)needSize; // Unused argument
|
||||
#endif
|
||||
}
|
||||
|
||||
void Verilated::mkdir(const char* dirname) VL_MT_UNSAFE {
|
||||
#if defined(_WIN32) || defined(__MINGW32__)
|
||||
::mkdir(dirname);
|
||||
@@ -3168,8 +3394,7 @@ void VerilatedScope::varInsert(int finalize, const char* namep, void* datap, boo
|
||||
} else {
|
||||
// We could have a linked list of ranges, but really this whole thing needs
|
||||
// to be generalized to support structs and unions, etc.
|
||||
const std::string msg
|
||||
= std::string{"Unsupported multi-dimensional public varInsert: "} + namep;
|
||||
const std::string msg = "Unsupported multi-dimensional public varInsert: "s + namep;
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "", msg.c_str());
|
||||
}
|
||||
}
|
||||
@@ -3189,10 +3414,9 @@ VerilatedVar* VerilatedScope::varFind(const char* namep) const VL_MT_SAFE_POSTIN
|
||||
|
||||
void* VerilatedScope::exportFindNullError(int funcnum) VL_MT_SAFE {
|
||||
// Slowpath - Called only when find has failed
|
||||
const std::string msg
|
||||
= (std::string{"Testbench C called '"} + VerilatedImp::exportName(funcnum)
|
||||
+ "' but scope wasn't set, perhaps due to dpi import call without "
|
||||
+ "'context', or missing svSetScope. See IEEE 1800-2017 35.5.3.");
|
||||
const std::string msg = ("Testbench C called '"s + VerilatedImp::exportName(funcnum)
|
||||
+ "' but scope wasn't set, perhaps due to dpi import call without "
|
||||
+ "'context', or missing svSetScope. See IEEE 1800-2023 35.5.3.");
|
||||
VL_FATAL_MT("unknown", 0, "", msg.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
@@ -3200,7 +3424,7 @@ void* VerilatedScope::exportFindNullError(int funcnum) VL_MT_SAFE {
|
||||
void* VerilatedScope::exportFindError(int funcnum) const VL_MT_SAFE {
|
||||
// Slowpath - Called only when find has failed
|
||||
const std::string msg
|
||||
= (std::string{"Testbench C called '"} + VerilatedImp::exportName(funcnum)
|
||||
= ("Testbench C called '"s + VerilatedImp::exportName(funcnum)
|
||||
+ "' but this DPI export function exists only in other scopes, not scope '" + name()
|
||||
+ "'");
|
||||
VL_FATAL_MT("unknown", 0, "", msg.c_str());
|
||||
@@ -3258,3 +3482,7 @@ void VlDeleter::deleteAll() VL_EXCLUDES(m_mutex) VL_EXCLUDES(m_deleteMutex) VL_M
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
// OS functions (last, so we have minimal OS dependencies above)
|
||||
|
||||
#define VL_ALLOW_VERILATEDOS_C
|
||||
#include "verilatedos_c.h"
|
||||
|
||||
+132
-42
@@ -55,6 +55,7 @@
|
||||
#include <cstring>
|
||||
#include <deque>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
@@ -73,6 +74,8 @@
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
using namespace std::literals; // "<std::string literal>"s; see SF.7 core guideline
|
||||
|
||||
//=============================================================================
|
||||
// Switches
|
||||
|
||||
@@ -99,6 +102,7 @@ class VerilatedScope;
|
||||
class VerilatedScopeNameMap;
|
||||
template <class, class>
|
||||
class VerilatedTrace;
|
||||
class VerilatedTraceBaseC;
|
||||
class VerilatedTraceConfig;
|
||||
class VerilatedVar;
|
||||
class VerilatedVarNameMap;
|
||||
@@ -150,6 +154,27 @@ enum VerilatedVarFlags {
|
||||
VLVF_DPI_CLAY = (1 << 10) // DPI compatible C standard layout
|
||||
};
|
||||
|
||||
// IEEE 1800-2023 Table 20-6
|
||||
enum class VerilatedAssertType : uint8_t {
|
||||
ASSERT_TYPE_CONCURRENT = (1 << 0),
|
||||
ASSERT_TYPE_SIMPLE_IMMEDIATE = (1 << 1),
|
||||
ASSERT_TYPE_OBSERVED_DEFERRED_IMMEDIATE = (1 << 2),
|
||||
ASSERT_TYPE_FINAL_DEFERRED_IMMEDIATE = (1 << 3),
|
||||
ASSERT_TYPE_EXPECT = (1 << 4),
|
||||
ASSERT_TYPE_UNIQUE = (1 << 5),
|
||||
ASSERT_TYPE_UNIQUE0 = (1 << 6),
|
||||
ASSERT_TYPE_PRIORITY = (1 << 7),
|
||||
};
|
||||
|
||||
// IEEE 1800-2023 Table 20-7
|
||||
enum class VerilatedAssertDirectiveType : uint8_t {
|
||||
DIRECTIVE_TYPE_ASSERT = (1 << 0),
|
||||
DIRECTIVE_TYPE_COVER = (1 << 1),
|
||||
DIRECTIVE_TYPE_ASSUME = (1 << 2),
|
||||
};
|
||||
using VerilatedAssertType_t = std::underlying_type<VerilatedAssertType>::type;
|
||||
using VerilatedAssertDirectiveType_t = std::underlying_type<VerilatedAssertDirectiveType>::type;
|
||||
|
||||
//=============================================================================
|
||||
// Utility functions
|
||||
|
||||
@@ -344,21 +369,43 @@ public:
|
||||
class VerilatedContext VL_NOT_FINAL {
|
||||
friend class VerilatedContextImp;
|
||||
|
||||
private:
|
||||
// MEMBERS
|
||||
// Numer of assertion directive type members. Then each of them will represented as 1-bit in a
|
||||
// mask.
|
||||
static constexpr size_t ASSERT_DIRECTIVE_TYPE_MASK_WIDTH = 3;
|
||||
// Specifies how many groups of directive type bit groups there are based on a number of
|
||||
// assertion types.
|
||||
// Note: we add one bit to store information whether Verilator's internal
|
||||
// directive types are enabled, for example `violation if`s.
|
||||
static constexpr size_t ASSERT_ON_WIDTH
|
||||
= ASSERT_DIRECTIVE_TYPE_MASK_WIDTH * std::numeric_limits<VerilatedAssertType_t>::digits
|
||||
+ 1;
|
||||
|
||||
protected:
|
||||
// TYPES
|
||||
using traceBaseModelCb_t
|
||||
= std::function<void(VerilatedTraceBaseC*, int, int)>; // Type of traceBaseModel callbacks
|
||||
|
||||
// MEMBERS
|
||||
// Slow path variables
|
||||
mutable VerilatedMutex m_mutex; // Mutex for most s_s/s_ns members
|
||||
|
||||
struct Serialized { // All these members serialized/deserialized
|
||||
struct Serialized final { // All these members serialized/deserialized
|
||||
// No std::strings or pointers or will serialize badly!
|
||||
// Fast path
|
||||
bool m_assertOn = true; // Assertions are enabled
|
||||
uint64_t m_time = 0; // Current $time (unscaled), 0=at zero, or legacy
|
||||
std::atomic<uint32_t> m_assertOn{
|
||||
std::numeric_limits<uint32_t>::max()}; // Enabled assertions,
|
||||
// for each VerilatedAssertType we store
|
||||
// 3-bits, one for each directive type. Last
|
||||
// bit guards internal directive types.
|
||||
bool m_calcUnusedSigs = false; // Waves file on, need all signals calculated
|
||||
bool m_fatalOnError = true; // Fatal on $stop/non-fatal error
|
||||
bool m_fatalOnVpiError = true; // Fatal on vpi error/unsupported
|
||||
bool m_gotError = false; // A $finish statement executed
|
||||
bool m_gotFinish = false; // A $finish or $stop statement executed
|
||||
uint64_t m_time = 0; // Current $time (unscaled), 0=at zero, or legacy
|
||||
bool m_quiet = false; // Quiet, no summary report
|
||||
// Slow path
|
||||
int8_t m_timeunit; // Time unit as 0..15
|
||||
int8_t m_timeprecision; // Time precision as 0..15
|
||||
@@ -379,20 +426,25 @@ protected:
|
||||
std::string m_timeFormatSuffix VL_GUARDED_BY(m_timeDumpMutex); // $timeformat printf format
|
||||
std::string m_dumpfile VL_GUARDED_BY(m_timeDumpMutex); // $dumpfile setting
|
||||
|
||||
struct NonSerialized { // Non-serialized information
|
||||
struct NonSerialized final { // Non-serialized information
|
||||
// These are reloaded from on command-line settings, so do not need to persist
|
||||
// Fast path
|
||||
uint64_t m_profExecStart = 1; // +prof+exec+start time
|
||||
uint32_t m_profExecWindow = 2; // +prof+exec+window size
|
||||
// Slow path
|
||||
std::string m_coverageFilename; // +coverage+file filename
|
||||
std::string m_profExecFilename; // +prof+exec+file filename
|
||||
std::string m_profVltFilename; // +prof+vlt filename
|
||||
std::string m_solverProgram; // SMT solver program
|
||||
VlOs::DeltaCpuTime m_cpuTimeStart{false}; // CPU time, starts when create first model
|
||||
VlOs::DeltaWallTime m_wallTimeStart{false}; // Wall time, starts when create first model
|
||||
std::vector<traceBaseModelCb_t> m_traceBaseModelCbs; // Callbacks to traceRegisterModel
|
||||
} m_ns;
|
||||
|
||||
mutable VerilatedMutex m_argMutex; // Protect m_argVec, m_argVecLoaded
|
||||
// no need to be save-restored (serialized) the
|
||||
// assumption is that the restore is allowed to pass different arguments
|
||||
struct NonSerializedCommandArgs {
|
||||
struct NonSerializedCommandArgs final {
|
||||
// Medium speed
|
||||
std::vector<std::string> m_argVec; // Argument list
|
||||
bool m_argVecLoaded = false; // Ever loaded argument list
|
||||
@@ -402,6 +454,8 @@ protected:
|
||||
const std::unique_ptr<VerilatedContextImpData> m_impdatap;
|
||||
// Number of threads to use for simulation (size of m_threadPool + 1 for main thread)
|
||||
unsigned m_threads = std::thread::hardware_concurrency();
|
||||
// Number of threads in added models
|
||||
unsigned m_threadsInModels = 0;
|
||||
// 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
|
||||
@@ -433,14 +487,23 @@ public:
|
||||
|
||||
// METHODS - User called
|
||||
|
||||
/// Enable assertions
|
||||
void assertOn(bool flag) VL_MT_SAFE;
|
||||
/// Return if assertions enabled
|
||||
bool assertOn() const VL_MT_SAFE { return m_s.m_assertOn; }
|
||||
/// Enable calculation of unused signals (for traces)
|
||||
void calcUnusedSigs(bool flag) VL_MT_SAFE;
|
||||
bool assertOn() const VL_MT_SAFE;
|
||||
/// Enable all assertion types
|
||||
void assertOn(bool flag) VL_MT_SAFE;
|
||||
/// Get enabled status for given assertion types
|
||||
bool assertOnGet(VerilatedAssertType_t type,
|
||||
VerilatedAssertDirectiveType_t directive) const VL_MT_SAFE;
|
||||
/// Set enabled status for given assertion types
|
||||
void assertOnSet(VerilatedAssertType_t types,
|
||||
VerilatedAssertDirectiveType_t directives) VL_MT_SAFE;
|
||||
/// Clear enabled status for given assertion types
|
||||
void assertOnClear(VerilatedAssertType_t types,
|
||||
VerilatedAssertDirectiveType_t directives) VL_MT_SAFE;
|
||||
/// Return if calculating of unused signals (for traces)
|
||||
bool calcUnusedSigs() const VL_MT_SAFE { return m_s.m_calcUnusedSigs; }
|
||||
/// Enable calculation of unused signals (for traces)
|
||||
void calcUnusedSigs(bool flag) VL_MT_SAFE;
|
||||
/// Record command-line arguments, for retrieval by $test$plusargs/$value$plusargs,
|
||||
/// and for parsing +verilator+ run-time arguments.
|
||||
/// This should be called before the first model is created.
|
||||
@@ -455,48 +518,58 @@ public:
|
||||
/// Return VerilatedCovContext, allocate if needed
|
||||
/// Note if get unresolved reference then likely forgot to link verilated_cov.cpp
|
||||
VerilatedCovContext* coveragep() VL_MT_SAFE;
|
||||
/// Set debug level
|
||||
/// Return debug level
|
||||
static inline int debug() VL_MT_SAFE; /// Set debug level
|
||||
/// Debug is currently global, but for forward compatibility have a per-context method
|
||||
static inline void debug(int val) VL_MT_SAFE;
|
||||
/// Return debug level
|
||||
static inline int debug() VL_MT_SAFE;
|
||||
/// Return current number of errors/assertions
|
||||
int errorCount() const VL_MT_SAFE { return m_s.m_errorCount; }
|
||||
/// Set current number of errors/assertions
|
||||
void errorCount(int val) VL_MT_SAFE;
|
||||
/// Increment current number of errors/assertions
|
||||
void errorCountInc() VL_MT_SAFE;
|
||||
/// Return current number of errors/assertions
|
||||
int errorCount() const VL_MT_SAFE { return m_s.m_errorCount; }
|
||||
/// Set number of errors/assertions before stop
|
||||
void errorLimit(int val) VL_MT_SAFE;
|
||||
/// Return number of errors/assertions before stop
|
||||
int errorLimit() const VL_MT_SAFE { return m_s.m_errorLimit; }
|
||||
/// Set to throw fatal error on $stop/non-fatal error
|
||||
void fatalOnError(bool flag) VL_MT_SAFE;
|
||||
/// Set number of errors/assertions before stop
|
||||
void errorLimit(int val) VL_MT_SAFE;
|
||||
/// Return if to throw fatal error on $stop/non-fatal
|
||||
bool fatalOnError() const VL_MT_SAFE { return m_s.m_fatalOnError; }
|
||||
/// Set to throw fatal error on VPI errors
|
||||
void fatalOnVpiError(bool flag) VL_MT_SAFE;
|
||||
/// Set to throw fatal error on $stop/non-fatal error
|
||||
void fatalOnError(bool flag) VL_MT_SAFE;
|
||||
/// Return if to throw fatal error on VPI errors
|
||||
bool fatalOnVpiError() const VL_MT_SAFE { return m_s.m_fatalOnVpiError; }
|
||||
/// Set if got a $stop or non-fatal error
|
||||
void gotError(bool flag) VL_MT_SAFE;
|
||||
/// Set to throw fatal error on VPI errors
|
||||
void fatalOnVpiError(bool flag) VL_MT_SAFE;
|
||||
/// Return if got a $stop or non-fatal error
|
||||
bool gotError() const VL_MT_SAFE { return m_s.m_gotError; }
|
||||
/// Set if got a $finish or $stop/error
|
||||
void gotFinish(bool flag) VL_MT_SAFE;
|
||||
/// Set if got a $stop or non-fatal error
|
||||
void gotError(bool flag) VL_MT_SAFE;
|
||||
/// Return if got a $finish or $stop/error
|
||||
bool gotFinish() const VL_MT_SAFE { return m_s.m_gotFinish; }
|
||||
/// Set if got a $finish or $stop/error
|
||||
void gotFinish(bool flag) VL_MT_SAFE;
|
||||
/// Return if quiet enabled
|
||||
bool quiet() const VL_MT_SAFE { return m_s.m_quiet; }
|
||||
/// Enable quiet (also prevents need for OS calls to get CPU time)
|
||||
void quiet(bool flag) VL_MT_SAFE;
|
||||
/// Return randReset value
|
||||
int randReset() VL_MT_SAFE { return m_s.m_randReset; }
|
||||
/// Select initial value of otherwise uninitialized signals.
|
||||
/// 0 = Set to zeros
|
||||
/// 1 = Set all bits to one
|
||||
/// 2 = Randomize all bits
|
||||
void randReset(int val) VL_MT_SAFE;
|
||||
/// Return randReset value
|
||||
int randReset() VL_MT_SAFE { return m_s.m_randReset; }
|
||||
/// Return default random seed
|
||||
void randSeed(int val) VL_MT_SAFE;
|
||||
/// Set default random seed, 0 = seed it automatically
|
||||
int randSeed() const VL_MT_SAFE { return m_s.m_randSeed; }
|
||||
/// Return default random seed
|
||||
void randSeed(int val) VL_MT_SAFE;
|
||||
|
||||
/// Return statistic: CPU time delta from model created until now
|
||||
double statCpuTimeSinceStart() const VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||
/// Return statistic: Wall time delta from model created until now
|
||||
double statWallTimeSinceStart() const VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||
/// Print statistics summary (if not quiet)
|
||||
void statsPrintSummary() VL_MT_UNSAFE;
|
||||
|
||||
// Time handling
|
||||
/// Returns current simulation time in units of timeprecision().
|
||||
@@ -541,10 +614,14 @@ public:
|
||||
|
||||
/// Get number of threads used for simulation (including the main thread)
|
||||
unsigned threads() const { return m_threads; }
|
||||
/// Get number of threads in added models (for statistical use only)
|
||||
unsigned threadsInModels() const { return m_threadsInModels; }
|
||||
/// 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);
|
||||
|
||||
/// Trace signals in models within the context; called by application code
|
||||
void trace(VerilatedTraceBaseC* tfp, int levels, int options = 0);
|
||||
/// Allow traces to at some point be enabled (disables some optimizations)
|
||||
void traceEverOn(bool flag) VL_MT_SAFE {
|
||||
if (flag) calcUnusedSigs(true);
|
||||
@@ -568,28 +645,36 @@ public:
|
||||
return reinterpret_cast<const VerilatedContextImp*>(this);
|
||||
}
|
||||
|
||||
// Internal: Model and thread setup
|
||||
void addModel(VerilatedModel*);
|
||||
|
||||
VerilatedVirtualBase* threadPoolp();
|
||||
void prepareClone();
|
||||
VerilatedVirtualBase* threadPoolpOnClone();
|
||||
VerilatedVirtualBase*
|
||||
enableExecutionProfiler(VerilatedVirtualBase* (*construct)(VerilatedContext&));
|
||||
|
||||
// Internal: coverage
|
||||
std::string coverageFilename() const VL_MT_SAFE;
|
||||
void coverageFilename(const std::string& flag) VL_MT_SAFE;
|
||||
|
||||
// Internal: $dumpfile
|
||||
void dumpfile(const std::string& flag) VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
|
||||
std::string dumpfile() const VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
|
||||
void dumpfile(const std::string& flag) VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
|
||||
std::string dumpfileCheck() const VL_MT_SAFE_EXCLUDES(m_timeDumpMutex);
|
||||
|
||||
// Internal: --prof-exec related settings
|
||||
void profExecStart(uint64_t flag) VL_MT_SAFE;
|
||||
uint64_t profExecStart() const VL_MT_SAFE { return m_ns.m_profExecStart; }
|
||||
void profExecWindow(uint64_t flag) VL_MT_SAFE;
|
||||
void profExecStart(uint64_t flag) VL_MT_SAFE;
|
||||
uint32_t profExecWindow() const VL_MT_SAFE { return m_ns.m_profExecWindow; }
|
||||
void profExecFilename(const std::string& flag) VL_MT_SAFE;
|
||||
void profExecWindow(uint64_t flag) VL_MT_SAFE;
|
||||
std::string profExecFilename() const VL_MT_SAFE;
|
||||
void profVltFilename(const std::string& flag) VL_MT_SAFE;
|
||||
void profExecFilename(const std::string& flag) VL_MT_SAFE;
|
||||
std::string profVltFilename() const VL_MT_SAFE;
|
||||
void profVltFilename(const std::string& flag) VL_MT_SAFE;
|
||||
|
||||
// Internal: SMT solver program
|
||||
std::string solverProgram() const VL_MT_SAFE;
|
||||
void solverProgram(const std::string& flag) VL_MT_SAFE;
|
||||
|
||||
// Internal: Find scope
|
||||
const VerilatedScope* scopeFind(const char* namep) const VL_MT_SAFE;
|
||||
@@ -599,6 +684,9 @@ public:
|
||||
static constexpr size_t serialized1Size() VL_PURE { return sizeof(m_s); }
|
||||
void* serialized1Ptr() VL_MT_UNSAFE { return &m_s; }
|
||||
|
||||
// Internal: trace registration
|
||||
void traceBaseModelCbAdd(traceBaseModelCb_t cb) VL_MT_SAFE;
|
||||
|
||||
// Internal: Check magic number
|
||||
static void checkMagic(const VerilatedContext* contextp);
|
||||
void selfTestClearMagic() { m_magic = 0x2; }
|
||||
@@ -763,18 +851,18 @@ public:
|
||||
}
|
||||
|
||||
#ifndef VL_NO_LEGACY
|
||||
/// Call VerilatedContext::assertOn using current thread's VerilatedContext
|
||||
static void assertOn(bool flag) VL_MT_SAFE { Verilated::threadContextp()->assertOn(flag); }
|
||||
/// Return VerilatedContext::assertOn() using current thread's VerilatedContext
|
||||
static bool assertOn() VL_MT_SAFE { return Verilated::threadContextp()->assertOn(); }
|
||||
/// Call VerilatedContext::calcUnusedSigs using current thread's VerilatedContext
|
||||
static void calcUnusedSigs(bool flag) VL_MT_SAFE {
|
||||
Verilated::threadContextp()->calcUnusedSigs(flag);
|
||||
}
|
||||
/// Call VerilatedContext::assertOn using current thread's VerilatedContext
|
||||
static void assertOn(bool flag) VL_MT_SAFE { Verilated::threadContextp()->assertOn(flag); }
|
||||
/// Return VerilatedContext::calcUnusedSigs using current thread's VerilatedContext
|
||||
static bool calcUnusedSigs() VL_MT_SAFE {
|
||||
return Verilated::threadContextp()->calcUnusedSigs();
|
||||
}
|
||||
/// Call VerilatedContext::calcUnusedSigs using current thread's VerilatedContext
|
||||
static void calcUnusedSigs(bool flag) VL_MT_SAFE {
|
||||
Verilated::threadContextp()->calcUnusedSigs(flag);
|
||||
}
|
||||
/// Call VerilatedContext::commandArgs using current thread's VerilatedContext
|
||||
static void commandArgs(int argc, const char** argv) VL_MT_SAFE {
|
||||
Verilated::threadContextp()->commandArgs(argc, argv);
|
||||
@@ -898,6 +986,7 @@ public:
|
||||
static void overWidthError(const char* signame) VL_ATTR_NORETURN VL_MT_SAFE;
|
||||
static void scTimePrecisionError(int sc_prec, int vl_prec) VL_ATTR_NORETURN VL_MT_SAFE;
|
||||
static void scTraceBeforeElaborationError() VL_ATTR_NORETURN VL_MT_SAFE;
|
||||
static void stackCheck(QData needSize) VL_MT_UNSAFE;
|
||||
|
||||
// Internal: Get and set DPI context
|
||||
static const VerilatedScope* dpiScope() VL_MT_SAFE { return t_s.t_dpiScopep; }
|
||||
@@ -916,8 +1005,8 @@ public:
|
||||
|
||||
// Internal: Set the mtaskId, called when an mtask starts
|
||||
// Per thread, so no need to be in VerilatedContext
|
||||
static void mtaskId(uint32_t id) VL_MT_SAFE { t_s.t_mtaskId = id; }
|
||||
static uint32_t mtaskId() VL_MT_SAFE { return t_s.t_mtaskId; }
|
||||
static void mtaskId(uint32_t id) VL_MT_SAFE { t_s.t_mtaskId = id; }
|
||||
static void endOfEvalReqdInc() VL_MT_SAFE { ++t_s.t_endOfEvalReqd; }
|
||||
static void endOfEvalReqdDec() VL_MT_SAFE { --t_s.t_endOfEvalReqd; }
|
||||
|
||||
@@ -971,6 +1060,7 @@ void VerilatedContext::timeprecision(int value) VL_MT_SAFE {
|
||||
} else if (sc_res == sc_core::sc_time(1, sc_core::SC_FS)) {
|
||||
sc_prec = 15;
|
||||
}
|
||||
// SC_AS, SC_ZS, SC_YS not supported as no Verilog equivalent; will error below
|
||||
#endif
|
||||
}
|
||||
#if VM_SC
|
||||
|
||||
@@ -80,6 +80,7 @@ VK_CPPFLAGS_ALWAYS += \
|
||||
-I$(VERILATOR_ROOT)/include/vltstd \
|
||||
-DVM_COVERAGE=$(VM_COVERAGE) \
|
||||
-DVM_SC=$(VM_SC) \
|
||||
-DVM_TIMING=$(VM_TIMING) \
|
||||
-DVM_TRACE=$(VM_TRACE) \
|
||||
-DVM_TRACE_FST=$(VM_TRACE_FST) \
|
||||
-DVM_TRACE_VCD=$(VM_TRACE_VCD) \
|
||||
@@ -101,9 +102,6 @@ LDFLAGS += $(CFG_LDFLAGS_VERILATED)
|
||||
#OPT = -ggdb -DPRINTINITSTR
|
||||
CPPFLAGS += $(OPT)
|
||||
|
||||
CPPFLAGS += $(M32)
|
||||
LDFLAGS += $(M32)
|
||||
|
||||
# On macOS, specify all weak symbols as dynamic_lookup.
|
||||
# Otherwise, you get undefined symbol errors.
|
||||
ifeq ($(UNAME_S),Darwin)
|
||||
@@ -228,7 +226,6 @@ endif
|
||||
# 1. Extract object files from .a
|
||||
# 2. Create a new archive from extracted .o and given .o
|
||||
%.a: | %.verilator_deplist.tmp
|
||||
$(info Archive $(AR) -rcs $@ $^)
|
||||
$(foreach L, $(filter-out %.a,$^), $(shell echo $L >>[email protected]_deplist.tmp))
|
||||
@if test $(words $(filter %.a,$^)) -eq 0; then \
|
||||
$(RM) -f $@; \
|
||||
|
||||
+17
-11
@@ -106,6 +106,7 @@ private:
|
||||
using ItemList = std::deque<VerilatedCovImpItem*>;
|
||||
|
||||
// MEMBERS
|
||||
VerilatedContext* const m_contextp; // Context VerilatedCovImp is pointed-to by
|
||||
mutable VerilatedMutex m_mutex; // Protects all members
|
||||
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
|
||||
@@ -120,7 +121,8 @@ private:
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
VerilatedCovImp() = default;
|
||||
explicit VerilatedCovImp(VerilatedContext* contextp)
|
||||
: m_contextp{contextp} {}
|
||||
VL_UNCOPYABLE(VerilatedCovImp);
|
||||
|
||||
protected:
|
||||
@@ -166,11 +168,11 @@ private:
|
||||
const std::string& value) VL_PURE {
|
||||
std::string name;
|
||||
if (key.length() == 1 && std::isalpha(key[0])) {
|
||||
name += std::string{"\001"} + key;
|
||||
name += "\001"s + key;
|
||||
} else {
|
||||
name += std::string{"\001"} + dequote(key);
|
||||
name += "\001"s + dequote(key);
|
||||
}
|
||||
name += std::string{"\002"} + dequote(value);
|
||||
name += "\002"s + dequote(value);
|
||||
return name;
|
||||
}
|
||||
static std::string combineHier(const std::string& old, const std::string& add) VL_PURE {
|
||||
@@ -253,6 +255,7 @@ private:
|
||||
|
||||
public:
|
||||
// PUBLIC METHODS
|
||||
std::string defaultFilename() VL_MT_SAFE { return m_contextp->coverageFilename(); }
|
||||
void forcePerInstance(const bool flag) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
Verilated::quiesce();
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
@@ -302,7 +305,7 @@ public:
|
||||
// First two key/vals are filename
|
||||
ckeyps[0] = "filename";
|
||||
valps[0] = m_insertFilenamep;
|
||||
const std::string linestr = vlCovCvtToStr(m_insertLineno);
|
||||
const std::string linestr = std::to_string(m_insertLineno);
|
||||
ckeyps[1] = "lineno";
|
||||
valps[1] = linestr.c_str();
|
||||
// Default page if not specified
|
||||
@@ -354,14 +357,14 @@ public:
|
||||
m_insertp = nullptr;
|
||||
}
|
||||
|
||||
void write(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
void write(const std::string& filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
Verilated::quiesce();
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
selftest();
|
||||
|
||||
std::ofstream os{filename};
|
||||
if (os.fail()) {
|
||||
const std::string msg = std::string{"%Error: Can't write '"} + filename + "'";
|
||||
const std::string msg = "%Error: Can't write '"s + filename + "'";
|
||||
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||
return;
|
||||
}
|
||||
@@ -426,6 +429,7 @@ public:
|
||||
//=============================================================================
|
||||
// VerilatedCovContext
|
||||
|
||||
std::string VerilatedCovContext::defaultFilename() VL_MT_SAFE { return impp()->defaultFilename(); }
|
||||
void VerilatedCovContext::forcePerInstance(bool flag) VL_MT_SAFE {
|
||||
impp()->forcePerInstance(flag);
|
||||
}
|
||||
@@ -434,7 +438,9 @@ void VerilatedCovContext::clearNonMatch(const char* matchp) VL_MT_SAFE {
|
||||
impp()->clearNonMatch(matchp);
|
||||
}
|
||||
void VerilatedCovContext::zero() VL_MT_SAFE { impp()->zero(); }
|
||||
void VerilatedCovContext::write(const char* filenamep) VL_MT_SAFE { impp()->write(filenamep); }
|
||||
void VerilatedCovContext::write(const std::string& filename) VL_MT_SAFE {
|
||||
impp()->write(filename);
|
||||
}
|
||||
void VerilatedCovContext::_inserti(uint32_t* itemp) VL_MT_SAFE {
|
||||
impp()->inserti(new VerilatedCoverItemSpec<uint32_t>{itemp});
|
||||
}
|
||||
@@ -484,8 +490,8 @@ void VerilatedCovContext::_insertp(A(0), A(1), A(2), A(3), A(4), A(5), A(6), A(7
|
||||
// Backward compatibility for Verilator
|
||||
void VerilatedCovContext::_insertp(A(0), A(1), K(2), int val2, K(3), int val3, K(4),
|
||||
const std::string& val4, A(5), A(6), A(7)) VL_MT_SAFE {
|
||||
std::string val2str = vlCovCvtToStr(val2);
|
||||
std::string val3str = vlCovCvtToStr(val3);
|
||||
const std::string val2str = std::to_string(val2);
|
||||
const std::string val3str = std::to_string(val3);
|
||||
_insertp(C(0), C(1), key2, val2str.c_str(), key3, val3str.c_str(), key4, val4.c_str(), C(5),
|
||||
C(6), C(7), N(8), N(9), N(10), N(11), N(12), N(13), N(14), N(15), N(16), N(17), N(18),
|
||||
N(19), N(20), N(21), N(22), N(23), N(24), N(25), N(26), N(27), N(28), N(29));
|
||||
@@ -516,7 +522,7 @@ VerilatedCovContext* VerilatedContext::coveragep() VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock{s_mutex};
|
||||
// cppcheck-suppress identicalInnerCondition
|
||||
if (VL_LIKELY(!m_coveragep)) { // LCOV_EXCL_LINE // Not redundant, prevents race
|
||||
m_coveragep.reset(new VerilatedCovImp);
|
||||
m_coveragep.reset(new VerilatedCovImp{this});
|
||||
}
|
||||
}
|
||||
return reinterpret_cast<VerilatedCovContext*>(m_coveragep.get());
|
||||
|
||||
+14
-22
@@ -63,26 +63,18 @@ class VerilatedCovImp;
|
||||
/// for (int i = 0; i < 10; ++i) m_cases[i] = 0;
|
||||
/// // Insert
|
||||
/// for (int i = 0; i < 10; ++i)
|
||||
/// VL_COVER_INSERT(&m_cases[i], "comment", "Coverage Case", "i", cvtToNumStr(i));
|
||||
/// VL_COVER_INSERT(covp, name(), &m_cases[i], "comment", "Coverage Case",
|
||||
/// "i", cvtToNumStr(i));
|
||||
/// }
|
||||
|
||||
#define VL_COVER_INSERT(covcontextp, countp, ...) \
|
||||
#define VL_COVER_INSERT(covcontextp, name, countp, ...) \
|
||||
do { \
|
||||
covcontextp->_inserti(countp); \
|
||||
covcontextp->_insertf(__FILE__, __LINE__); \
|
||||
covcontextp->_insertp("hier", name(), __VA_ARGS__); \
|
||||
auto const ccontextp = covcontextp; \
|
||||
ccontextp->_inserti(countp); \
|
||||
ccontextp->_insertf(__FILE__, __LINE__); \
|
||||
ccontextp->_insertp("hier", name, __VA_ARGS__); \
|
||||
} while (false)
|
||||
|
||||
//=============================================================================
|
||||
// Convert VL_COVER_INSERT value arguments to strings, is \internal
|
||||
|
||||
template <class T>
|
||||
std::string vlCovCvtToStr(const T& t) VL_PURE {
|
||||
std::ostringstream os;
|
||||
os << t;
|
||||
return os.str();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedCov
|
||||
/// Per-VerilatedContext coverage data class.
|
||||
@@ -96,12 +88,13 @@ class VerilatedCovContext VL_NOT_FINAL : public VerilatedVirtualBase {
|
||||
|
||||
public:
|
||||
// METHODS
|
||||
/// Return default filename
|
||||
static const char* defaultFilename() VL_PURE { return "coverage.dat"; }
|
||||
/// Return default filename, may override with +verilator+coverage+file
|
||||
std::string defaultFilename() VL_MT_SAFE;
|
||||
/// Make all data per_instance, overriding point's per_instance
|
||||
void forcePerInstance(bool flag) VL_MT_SAFE;
|
||||
void write() VL_MT_SAFE { write(defaultFilename()); }
|
||||
/// Write all coverage data to a file
|
||||
void write(const char* filenamep = defaultFilename()) VL_MT_SAFE;
|
||||
void write(const std::string& filename) VL_MT_SAFE;
|
||||
/// Clear coverage points (and call delete on all items)
|
||||
void clear() VL_MT_SAFE;
|
||||
/// Clear items not matching the provided string
|
||||
@@ -170,11 +163,10 @@ class VerilatedCov final {
|
||||
public:
|
||||
// METHODS
|
||||
/// Return default filename for the current thread
|
||||
static const char* defaultFilename() VL_PURE { return VerilatedCovContext::defaultFilename(); }
|
||||
static std::string defaultFilename() VL_MT_SAFE { return threadCovp()->defaultFilename(); }
|
||||
/// Write all coverage data to a file for the current thread
|
||||
static void write(const char* filenamep = defaultFilename()) VL_MT_SAFE {
|
||||
threadCovp()->write(filenamep);
|
||||
}
|
||||
static void write(const std::string& filename) VL_MT_SAFE { threadCovp()->write(filename); }
|
||||
static void write() VL_MT_SAFE { write(defaultFilename()); }
|
||||
/// Clear coverage points (and call delete on all items) for the current thread
|
||||
static void clear() VL_MT_SAFE { threadCovp()->clear(); }
|
||||
/// Clear items not matching the provided string for the current thread
|
||||
|
||||
@@ -770,6 +770,36 @@ int svGetCallerInfo(const char** fileNamepp, int* lineNumberp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Time
|
||||
|
||||
int svGetTime(const svScope scope, svTimeVal* time) {
|
||||
if (VL_UNLIKELY(!time)) return -1;
|
||||
const QData qtime = VL_TIME_Q();
|
||||
VlWide<2> itime;
|
||||
VL_SET_WQ(itime, qtime);
|
||||
time->low = itime[0];
|
||||
time->high = itime[1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
int svGetTimeUnit(const svScope scope, int32_t* time_unit) {
|
||||
if (VL_UNLIKELY(!time_unit)) return -1;
|
||||
const VerilatedScope* const vscopep = reinterpret_cast<const VerilatedScope*>(scope);
|
||||
if (!vscopep) { // Null asks for global, not unlikely
|
||||
*time_unit = Verilated::threadContextp()->timeunit();
|
||||
} else {
|
||||
*time_unit = vscopep->timeunit();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int svGetTimePrecision(const svScope scope, int32_t* time_precision) {
|
||||
if (VL_UNLIKELY(!time_precision)) return -1;
|
||||
*time_precision = Verilated::threadContextp()->timeprecision();
|
||||
return 0;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Disables
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
// GTKWave configuration
|
||||
#define HAVE_LIBPTHREAD
|
||||
#define FST_WRITER_PARALLEL
|
||||
#define LZ4_DISABLE_DEPRECATE_WARNINGS
|
||||
|
||||
// Include the GTKWave implementation directly
|
||||
#define FST_CONFIG_INCLUDE "fst_config.h"
|
||||
@@ -174,7 +175,7 @@ void VerilatedFst::declare(uint32_t code, const char* name, int dtypenum,
|
||||
|
||||
if (dtypenum > 0) fstWriterEmitEnumTableRef(m_fst, m_local2fstdtype[dtypenum]);
|
||||
|
||||
fstVarDir varDir;
|
||||
fstVarDir varDir = FST_VD_IMPLICIT;
|
||||
switch (direction) {
|
||||
case VerilatedTraceSigDirection::INOUT: varDir = FST_VD_INOUT; break;
|
||||
case VerilatedTraceSigDirection::OUTPUT: varDir = FST_VD_OUTPUT; break;
|
||||
|
||||
@@ -192,7 +192,7 @@ class VerilatedFstBuffer VL_NOT_FINAL {
|
||||
/// Create a FST dump file in C standalone (no SystemC) simulations.
|
||||
/// Also derived for use in SystemC simulations.
|
||||
|
||||
class VerilatedFstC VL_NOT_FINAL {
|
||||
class VerilatedFstC VL_NOT_FINAL : public VerilatedTraceBaseC {
|
||||
VerilatedFst m_sptrace; // Trace file being created
|
||||
|
||||
// CONSTRUCTORS
|
||||
@@ -208,11 +208,14 @@ public:
|
||||
// METHODS - User called
|
||||
|
||||
/// Return if file is open
|
||||
bool isOpen() const VL_MT_SAFE { return m_sptrace.isOpen(); }
|
||||
bool isOpen() const override VL_MT_SAFE { return m_sptrace.isOpen(); }
|
||||
/// Open a new FST file
|
||||
virtual void open(const char* filename) VL_MT_SAFE { m_sptrace.open(filename); }
|
||||
/// Close dump
|
||||
void close() VL_MT_SAFE { m_sptrace.close(); }
|
||||
void close() VL_MT_SAFE {
|
||||
m_sptrace.close();
|
||||
modelConnected(false);
|
||||
}
|
||||
/// Flush dump
|
||||
void flush() VL_MT_SAFE { m_sptrace.flush(); }
|
||||
/// Write one cycle of dump data
|
||||
|
||||
+507
-42
@@ -106,6 +106,14 @@ extern IData VL_RAND_RESET_I(int obits) VL_MT_SAFE;
|
||||
extern QData VL_RAND_RESET_Q(int obits) VL_MT_SAFE;
|
||||
/// Random reset a signal of given width (init time only)
|
||||
extern WDataOutP VL_RAND_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE;
|
||||
|
||||
/// Random reset a signal of given width (assign time only)
|
||||
extern IData VL_RAND_RESET_ASSIGN_I(int obits) VL_MT_SAFE;
|
||||
/// Random reset a signal of given width (assign time only)
|
||||
extern QData VL_RAND_RESET_ASSIGN_Q(int obits) VL_MT_SAFE;
|
||||
/// Random reset a signal of given width (assign time only)
|
||||
extern WDataOutP VL_RAND_RESET_ASSIGN_W(int obits, WDataOutP outwp) VL_MT_SAFE;
|
||||
|
||||
/// Zero reset a signal (slow - else use VL_ZERO_W)
|
||||
extern WDataOutP VL_ZERO_RESET_W(int obits, WDataOutP outwp) VL_MT_SAFE;
|
||||
|
||||
@@ -115,6 +123,9 @@ extern void VL_PRINTTIMESCALE(const char* namep, const char* timeunitp,
|
||||
extern WDataOutP _vl_moddiv_w(int lbits, WDataOutP owp, WDataInP const lwp, WDataInP const rwp,
|
||||
bool is_modulus) VL_MT_SAFE;
|
||||
|
||||
extern void _vl_vsss_based(WDataOutP owp, int obits, int baseLog2, const char* strp,
|
||||
size_t posstart, size_t posend) VL_MT_SAFE;
|
||||
|
||||
extern IData VL_FGETS_IXI(int obits, void* destp, IData fpi) VL_MT_SAFE;
|
||||
|
||||
extern void VL_FFLUSH_I(IData fdi) VL_MT_SAFE;
|
||||
@@ -125,25 +136,34 @@ extern void VL_FCLOSE_I(IData fdi) VL_MT_SAFE;
|
||||
extern IData VL_FREAD_I(int width, int array_lsb, int array_size, void* memp, IData fpi,
|
||||
IData start, IData count) VL_MT_SAFE;
|
||||
|
||||
extern void VL_WRITEF(const char* formatp, ...) VL_MT_SAFE;
|
||||
extern void VL_FWRITEF(IData fpi, const char* formatp, ...) VL_MT_SAFE;
|
||||
extern void VL_WRITEF_NX(const std::string& format, int argc, ...) VL_MT_SAFE;
|
||||
extern void VL_FWRITEF_NX(IData fpi, const std::string& format, int argc, ...) VL_MT_SAFE;
|
||||
|
||||
extern IData VL_FSCANF_IX(IData fpi, const char* formatp, ...) VL_MT_SAFE;
|
||||
extern IData VL_SSCANF_IIX(int lbits, IData ld, const char* formatp, ...) VL_MT_SAFE;
|
||||
extern IData VL_SSCANF_IQX(int lbits, QData ld, const char* formatp, ...) VL_MT_SAFE;
|
||||
extern IData VL_SSCANF_IWX(int lbits, WDataInP const lwp, const char* formatp, ...) VL_MT_SAFE;
|
||||
extern IData VL_FSCANF_INX(IData fpi, const std::string& format, int argc, ...) VL_MT_SAFE;
|
||||
extern IData VL_SSCANF_IINX(int lbits, IData ld, const std::string& format, int argc,
|
||||
...) VL_MT_SAFE;
|
||||
extern IData VL_SSCANF_IQNX(int lbits, QData ld, const std::string& format, int argc,
|
||||
...) VL_MT_SAFE;
|
||||
extern IData VL_SSCANF_IWNX(int lbits, WDataInP const lwp, const std::string& format, int argc,
|
||||
...) VL_MT_SAFE;
|
||||
|
||||
extern void VL_SFORMAT_X(int obits, CData& destr, const char* formatp, ...) VL_MT_SAFE;
|
||||
extern void VL_SFORMAT_X(int obits, SData& destr, const char* formatp, ...) VL_MT_SAFE;
|
||||
extern void VL_SFORMAT_X(int obits, IData& destr, const char* formatp, ...) VL_MT_SAFE;
|
||||
extern void VL_SFORMAT_X(int obits, QData& destr, const char* formatp, ...) VL_MT_SAFE;
|
||||
extern void VL_SFORMAT_X(int obits, void* destp, const char* formatp, ...) VL_MT_SAFE;
|
||||
extern void VL_SFORMAT_NX(int obits, CData& destr, const std::string& format, int argc,
|
||||
...) VL_MT_SAFE;
|
||||
extern void VL_SFORMAT_NX(int obits, SData& destr, const std::string& format, int argc,
|
||||
...) VL_MT_SAFE;
|
||||
extern void VL_SFORMAT_NX(int obits, IData& destr, const std::string& format, int argc,
|
||||
...) VL_MT_SAFE;
|
||||
extern void VL_SFORMAT_NX(int obits, QData& destr, const std::string& format, int argc,
|
||||
...) VL_MT_SAFE;
|
||||
extern void VL_SFORMAT_NX(int obits, void* destp, const std::string& format, int argc,
|
||||
...) VL_MT_SAFE;
|
||||
|
||||
extern void VL_STACKTRACE() VL_MT_SAFE;
|
||||
extern std::string VL_STACKTRACE_N() VL_MT_SAFE;
|
||||
extern IData VL_SYSTEM_IW(int lhswords, WDataInP const lhsp) VL_MT_SAFE;
|
||||
extern IData VL_SYSTEM_IQ(QData lhs) VL_MT_SAFE;
|
||||
inline IData VL_SYSTEM_II(IData lhs) VL_MT_SAFE { return VL_SYSTEM_IQ(lhs); }
|
||||
extern IData VL_SYSTEM_IN(const std::string& lhs) VL_MT_SAFE;
|
||||
|
||||
extern IData VL_TESTPLUSARGS_I(const std::string& format) VL_MT_SAFE;
|
||||
extern const char* vl_mc_scan_plusargs(const char* prefixp) VL_MT_SAFE; // PLIish
|
||||
@@ -207,6 +227,10 @@ static inline QData VL_CVT_Q_D(double lhs) VL_PURE {
|
||||
return u.q;
|
||||
}
|
||||
// clang-format on
|
||||
// Return string from DPI char*
|
||||
static inline std::string VL_CVT_N_CSTR(const char* lhsp) VL_PURE {
|
||||
return lhsp ? std::string{lhsp} : ""s;
|
||||
}
|
||||
|
||||
// Return double from lhs (numeric) unsigned
|
||||
double VL_ITOR_D_W(int lbits, WDataInP const lwp) VL_PURE;
|
||||
@@ -230,7 +254,7 @@ static inline double VL_ISTOR_D_Q(int lbits, QData lhs) VL_MT_SAFE {
|
||||
VL_SET_WQ(lwp, lhs);
|
||||
return VL_ISTOR_D_W(lbits, lwp);
|
||||
}
|
||||
// Return QData from double (numeric)
|
||||
// Return IData truncated from double (numeric)
|
||||
static inline IData VL_RTOI_I_D(double lhs) VL_PURE { return static_cast<int32_t>(VL_TRUNC(lhs)); }
|
||||
|
||||
// Sign extend such that if MSB set, we get ffff_ffff, else 0s
|
||||
@@ -255,7 +279,7 @@ static inline QData VL_EXTENDSIGN_Q(int lbits, QData lhs) VL_PURE {
|
||||
extern void _vl_debug_print_w(int lbits, WDataInP const iwp) VL_MT_SAFE;
|
||||
|
||||
//=========================================================================
|
||||
// Pli macros
|
||||
// Time handling
|
||||
|
||||
// clang-format off
|
||||
|
||||
@@ -305,13 +329,16 @@ uint64_t VerilatedContext::time() const VL_MT_SAFE {
|
||||
// Time scaled from 1-per-precision into a module's time units ("Unit"-ed, not "United")
|
||||
// Optimized assuming scale is always constant.
|
||||
// Can't use multiply in Q flavor, as might lose precision
|
||||
#define VL_TIME_UNITED_Q(scale) (VL_TIME_Q() / static_cast<QData>(scale))
|
||||
#define VL_TIME_ROUND(t, p) (((t) + ((p) / 2)) / (p))
|
||||
#define VL_TIME_UNITED_Q(scale) VL_TIME_ROUND(VL_TIME_Q(), static_cast<QData>(scale))
|
||||
#define VL_TIME_UNITED_D(scale) (VL_TIME_D() / static_cast<double>(scale))
|
||||
|
||||
// Return time precision as multiplier of time units
|
||||
double vl_time_multiplier(int scale) VL_PURE;
|
||||
// Return power of 10. e.g. returns 100 if n==2
|
||||
uint64_t vl_time_pow10(int n) VL_PURE;
|
||||
// Return time as string with timescale suffix
|
||||
std::string vl_timescaled_double(double value, const char* format = "%0.0f%s") VL_PURE;
|
||||
|
||||
//=========================================================================
|
||||
// Functional macros/routines
|
||||
@@ -493,24 +520,24 @@ static inline void VL_ASSIGNBIT_WO(int bit, WDataOutP owp) VL_MT_SAFE {
|
||||
{ (svar).write(rd); }
|
||||
#define VL_ASSIGN_SBQ(obits, svar, 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) \
|
||||
{ \
|
||||
sc_dt::sc_biguint<(obits)> _butemp; \
|
||||
int32_t lsb = 0; \
|
||||
uint32_t* chunkp = _butemp.get_raw(); \
|
||||
while (lsb + VL_SC_BITS_PER_DIGIT < (obits)) { \
|
||||
while (lsb + BITS_PER_DIGIT < (obits)) { \
|
||||
static_assert(std::is_same<IData, EData>::value, "IData and EData mismatch"); \
|
||||
const uint32_t data = VL_SEL_IWII(lsb + VL_SC_BITS_PER_DIGIT + 1, (rwp).data(), lsb, \
|
||||
VL_SC_BITS_PER_DIGIT); \
|
||||
*chunkp = data & VL_MASK_E(VL_SC_BITS_PER_DIGIT); \
|
||||
const uint32_t data \
|
||||
= VL_SEL_IWII(lsb + BITS_PER_DIGIT + 1, (rwp).data(), lsb, BITS_PER_DIGIT); \
|
||||
*chunkp = data & VL_MASK_E(BITS_PER_DIGIT); \
|
||||
++chunkp; \
|
||||
lsb += VL_SC_BITS_PER_DIGIT; \
|
||||
lsb += BITS_PER_DIGIT; \
|
||||
} \
|
||||
if (lsb < (obits)) { \
|
||||
const uint32_t msb_data = VL_SEL_IWII((obits) + 1, (rwp).data(), lsb, (obits)-lsb); \
|
||||
*chunkp = msb_data & VL_MASK_E((obits)-lsb); \
|
||||
} \
|
||||
_butemp.set(0, *(rwp).data() & 1); /* force update the sign */ \
|
||||
(svar).write(_butemp); \
|
||||
}
|
||||
|
||||
@@ -1265,6 +1292,7 @@ static inline void _vl_insert_QQ(QData& lhsr, QData ld, int hbit, int lbit, int
|
||||
}
|
||||
static inline void _vl_insert_WI(WDataOutP iowp, IData ld, int hbit, int lbit,
|
||||
int rbits = 0) VL_MT_SAFE {
|
||||
// Insert value ld into iowp at bit slice [hbit:lbit]. iowp is rbits wide.
|
||||
const int hoffset = VL_BITBIT_E(hbit);
|
||||
const int loffset = VL_BITBIT_E(lbit);
|
||||
const int roffset = VL_BITBIT_E(rbits);
|
||||
@@ -1275,7 +1303,7 @@ static inline void _vl_insert_WI(WDataOutP iowp, IData ld, int hbit, int lbit,
|
||||
|
||||
if (hoffset == VL_SIZEBITS_E && loffset == 0) {
|
||||
// Fast and common case, word based insertion
|
||||
iowp[VL_BITWORD_E(lbit)] = ld & cleanmask;
|
||||
iowp[lword] = ld & cleanmask;
|
||||
} else {
|
||||
const EData lde = static_cast<EData>(ld);
|
||||
if (hword == lword) { // know < EData bits because above checks it
|
||||
@@ -1288,12 +1316,36 @@ static inline void _vl_insert_WI(WDataOutP iowp, IData ld, int hbit, int lbit,
|
||||
const EData linsmask = (VL_MASK_E((VL_EDATASIZE - 1) - loffset + 1)) << loffset;
|
||||
const int nbitsonright = VL_EDATASIZE - loffset; // bits that end up in lword
|
||||
iowp[lword] = (iowp[lword] & ~linsmask) | ((lde << loffset) & linsmask);
|
||||
iowp[hword]
|
||||
= (iowp[hword] & ~hinsmask) | ((lde >> nbitsonright) & (hinsmask & cleanmask));
|
||||
// Prevent unsafe write where lword was final writable location and hword is
|
||||
// out-of-bounds.
|
||||
if (VL_LIKELY(!(hword == rword && roffset == 0))) {
|
||||
iowp[hword]
|
||||
= (iowp[hword] & ~hinsmask) | ((lde >> nbitsonright) & (hinsmask & cleanmask));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Copy bits from lwp[hbit:lbit] to low bits of lhsr. rbits is real width of lshr
|
||||
static inline void _vl_insert_IW(IData& lhsr, WDataInP const lwp, int hbit, int lbit,
|
||||
int rbits = 0) VL_MT_SAFE {
|
||||
const int hoffset = VL_BITBIT_E(hbit);
|
||||
const int loffset = VL_BITBIT_E(lbit);
|
||||
const int hword = VL_BITWORD_E(hbit);
|
||||
const int lword = VL_BITWORD_E(lbit);
|
||||
const IData cleanmask = VL_MASK_I(rbits);
|
||||
if (hword == lword) {
|
||||
const IData insmask = (VL_MASK_I(hoffset - loffset + 1));
|
||||
lhsr = (lhsr & ~insmask) | ((lwp[lword] >> loffset) & (insmask & cleanmask));
|
||||
} else {
|
||||
const int nbitsonright = VL_IDATASIZE - loffset; // bits that filled by lword
|
||||
const IData hinsmask = (VL_MASK_E(hoffset - 0 + 1)) << nbitsonright;
|
||||
const IData linsmask = VL_MASK_E(VL_EDATASIZE - loffset);
|
||||
lhsr = (lhsr & ~linsmask) | ((lwp[lword] >> loffset) & (linsmask & cleanmask));
|
||||
lhsr = (lhsr & ~hinsmask) | ((lwp[hword] << nbitsonright) & (hinsmask & cleanmask));
|
||||
}
|
||||
}
|
||||
|
||||
// INTERNAL: Stuff large LHS bit 0++ into OUTPUT at specified offset
|
||||
// lwp may be "dirty"
|
||||
static inline void _vl_insert_WW(WDataOutP iowp, WDataInP const lwp, int hbit, int lbit,
|
||||
@@ -1533,28 +1585,184 @@ static inline WDataOutP VL_STREAML_WWI(int lbits, WDataOutP owp, WDataInP const
|
||||
return owp;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline void VL_ASSIGN_DYN_Q(VlQueue<T>& q, int elem_size, int lbits, QData from) {
|
||||
const int size = (lbits + elem_size - 1) / elem_size;
|
||||
q.renew(size);
|
||||
const QData mask = VL_MASK_Q(elem_size);
|
||||
for (int i = 0; i < size; ++i) q.at(i) = (T)((from >> (i * elem_size)) & mask);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline IData VL_DYN_TO_I(const VlQueue<T>& q, int elem_size) {
|
||||
static inline IData VL_PACK_II(int obits, int lbits, const VlQueue<CData>& q) {
|
||||
IData ret = 0;
|
||||
for (int i = 0; i < q.size(); ++i) ret |= q.at(i) << (i * elem_size);
|
||||
for (size_t i = 0; i < q.size(); ++i) ret |= static_cast<IData>(q.at(i)) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static inline QData VL_DYN_TO_Q(const VlQueue<T>& q, int elem_size) {
|
||||
QData ret = 0;
|
||||
for (int i = 0; i < q.size(); ++i) ret |= q.at(i) << (i * elem_size);
|
||||
static inline IData VL_PACK_II(int obits, int lbits, const VlQueue<SData>& q) {
|
||||
IData ret = 0;
|
||||
for (size_t i = 0; i < q.size(); ++i) ret |= static_cast<IData>(q.at(i)) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline IData VL_PACK_II(int obits, int lbits, const VlQueue<IData>& q) {
|
||||
IData ret = 0;
|
||||
for (size_t i = 0; i < q.size(); ++i) ret |= q.at(i) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked<CData, T_Depth>& q) {
|
||||
IData ret = 0;
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
ret |= static_cast<IData>(q[T_Depth - 1 - i]) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked<SData, T_Depth>& q) {
|
||||
IData ret = 0;
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
ret |= static_cast<IData>(q[T_Depth - 1 - i]) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline IData VL_PACK_II(int obits, int lbits, const VlUnpacked<IData, T_Depth>& q) {
|
||||
IData ret = 0;
|
||||
for (size_t i = 0; i < T_Depth; ++i) ret |= q[T_Depth - 1 - i] << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline QData VL_PACK_QI(int obits, int lbits, const VlQueue<CData>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < q.size(); ++i) ret |= static_cast<QData>(q.at(i)) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline QData VL_PACK_QI(int obits, int lbits, const VlQueue<SData>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < q.size(); ++i) ret |= static_cast<QData>(q.at(i)) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline QData VL_PACK_QI(int obits, int lbits, const VlQueue<IData>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < q.size(); ++i) ret |= static_cast<QData>(q.at(i)) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline QData VL_PACK_QI(int obits, int lbits, const VlUnpacked<CData, T_Depth>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
ret |= static_cast<QData>(q[T_Depth - 1 - i]) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline QData VL_PACK_QI(int obits, int lbits, const VlUnpacked<SData, T_Depth>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
ret |= static_cast<QData>(q[T_Depth - 1 - i]) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline QData VL_PACK_QI(int obits, int lbits, const VlUnpacked<IData, T_Depth>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
ret |= static_cast<QData>(q[T_Depth - 1 - i]) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline QData VL_PACK_QQ(int obits, int lbits, const VlQueue<QData>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < q.size(); ++i) ret |= q.at(i) << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline QData VL_PACK_QQ(int obits, int lbits, const VlUnpacked<QData, T_Depth>& q) {
|
||||
QData ret = 0;
|
||||
for (size_t i = 0; i < T_Depth; ++i) ret |= q[T_Depth - 1 - i] << (i * lbits);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, const VlQueue<CData>& q) {
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
for (size_t i = 0; i < q.size(); ++i)
|
||||
_vl_insert_WI(owp, q.at(i), i * lbits + lbits - 1, i * lbits);
|
||||
return owp;
|
||||
}
|
||||
|
||||
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, const VlQueue<SData>& q) {
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
for (size_t i = 0; i < q.size(); ++i)
|
||||
_vl_insert_WI(owp, q.at(i), i * lbits + lbits - 1, i * lbits);
|
||||
return owp;
|
||||
}
|
||||
|
||||
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp, const VlQueue<IData>& q) {
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
for (size_t i = 0; i < q.size(); ++i)
|
||||
_vl_insert_WI(owp, q.at(i), i * lbits + lbits - 1, i * lbits);
|
||||
return owp;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp,
|
||||
const VlUnpacked<CData, T_Depth>& q) {
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
_vl_insert_WI(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits);
|
||||
return owp;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp,
|
||||
const VlUnpacked<SData, T_Depth>& q) {
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
_vl_insert_WI(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits);
|
||||
return owp;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline WDataOutP VL_PACK_WI(int obits, int lbits, WDataOutP owp,
|
||||
const VlUnpacked<IData, T_Depth>& q) {
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
_vl_insert_WI(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits);
|
||||
return owp;
|
||||
}
|
||||
|
||||
static inline WDataOutP VL_PACK_WQ(int obits, int lbits, WDataOutP owp, const VlQueue<QData>& q) {
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
for (size_t i = 0; i < q.size(); ++i)
|
||||
_vl_insert_WQ(owp, q.at(i), i * lbits + lbits - 1, i * lbits);
|
||||
return owp;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline WDataOutP VL_PACK_WQ(int obits, int lbits, WDataOutP owp,
|
||||
const VlUnpacked<QData, T_Depth>& q) {
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
_vl_insert_WQ(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits);
|
||||
return owp;
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
static inline WDataOutP VL_PACK_WW(int obits, int lbits, WDataOutP owp,
|
||||
const VlQueue<VlWide<N>>& q) {
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
for (size_t i = 0; i < q.size(); ++i)
|
||||
_vl_insert_WW(owp, q.at(i), i * lbits + lbits - 1, i * lbits);
|
||||
return owp;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth, std::size_t N>
|
||||
static inline WDataOutP VL_PACK_WW(int obits, int lbits, WDataOutP owp,
|
||||
const VlUnpacked<VlWide<N>, T_Depth>& q) {
|
||||
VL_MEMSET_ZERO_W(owp + 1, VL_WORDS_I(obits) - 1);
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
_vl_insert_WW(owp, q[T_Depth - 1 - i], i * lbits + lbits - 1, i * lbits);
|
||||
return owp;
|
||||
}
|
||||
|
||||
// Because concats are common and wide, it's valuable to always have a clean output.
|
||||
// Thus we specify inputs must be clean, so we don't need to clean the output.
|
||||
// Note the bit shifts are always constants, so the adds in these constify out.
|
||||
@@ -1994,6 +2202,171 @@ static inline WDataOutP VL_SEL_WWII(int obits, int lbits, WDataOutP owp, WDataIn
|
||||
//======================================================================
|
||||
// Expressions needing insert/select
|
||||
|
||||
static inline void VL_UNPACK_II(int lbits, int rbits, VlQueue<CData>& q, IData from) {
|
||||
const size_t size = (rbits + lbits - 1) / lbits;
|
||||
q.renew(size);
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < size; ++i) q.at(i) = (from >> (i * lbits)) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_II(int lbits, int rbits, VlQueue<SData>& q, IData from) {
|
||||
const size_t size = (rbits + lbits - 1) / lbits;
|
||||
q.renew(size);
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < size; ++i) q.at(i) = (from >> (i * lbits)) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_II(int lbits, int rbits, VlQueue<IData>& q, IData from) {
|
||||
const size_t size = (rbits + lbits - 1) / lbits;
|
||||
q.renew(size);
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < size; ++i) q.at(i) = (from >> (i * lbits)) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlQueue<CData>& q, QData from) {
|
||||
const size_t size = (rbits + lbits - 1) / lbits;
|
||||
q.renew(size);
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < size; ++i) q.at(i) = (from >> (i * lbits)) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlQueue<SData>& q, QData from) {
|
||||
const size_t size = (rbits + lbits - 1) / lbits;
|
||||
q.renew(size);
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < size; ++i) q.at(i) = (from >> (i * lbits)) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlQueue<IData>& q, QData from) {
|
||||
const size_t size = (rbits + lbits - 1) / lbits;
|
||||
q.renew(size);
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < size; ++i) q.at(i) = (from >> (i * lbits)) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_QQ(int lbits, int rbits, VlQueue<QData>& q, QData from) {
|
||||
const size_t size = (rbits + lbits - 1) / lbits;
|
||||
q.renew(size);
|
||||
const QData mask = VL_MASK_Q(lbits);
|
||||
for (size_t i = 0; i < size; ++i) q.at(i) = (from >> (i * lbits)) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_IW(int lbits, int rbits, VlQueue<CData>& q, WDataInP rwp) {
|
||||
const int size = (rbits + lbits - 1) / lbits;
|
||||
q.renew(size);
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < size; ++i) q.at(i) = VL_SEL_IWII(rbits, rwp, i * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_IW(int lbits, int rbits, VlQueue<SData>& q, WDataInP rwp) {
|
||||
const int size = (rbits + lbits - 1) / lbits;
|
||||
q.renew(size);
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < size; ++i) q.at(i) = VL_SEL_IWII(rbits, rwp, i * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_IW(int lbits, int rbits, VlQueue<IData>& q, WDataInP rwp) {
|
||||
const int size = (rbits + lbits - 1) / lbits;
|
||||
q.renew(size);
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < size; ++i) q.at(i) = VL_SEL_IWII(rbits, rwp, i * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
static inline void VL_UNPACK_QW(int lbits, int rbits, VlQueue<QData>& q, WDataInP rwp) {
|
||||
const int size = (rbits + lbits - 1) / lbits;
|
||||
q.renew(size);
|
||||
const QData mask = VL_MASK_Q(lbits);
|
||||
for (size_t i = 0; i < size; ++i) q.at(i) = VL_SEL_QWII(rbits, rwp, i * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t N>
|
||||
static inline void VL_UNPACK_WW(int lbits, int rbits, VlQueue<VlWide<N>>& q, WDataInP rwp) {
|
||||
const int size = (rbits + lbits - 1) / lbits;
|
||||
q.renew(size);
|
||||
for (size_t i = 0; i < size; ++i) VL_SEL_WWII(lbits, rbits, q.at(i), rwp, i * lbits, lbits);
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked<CData, T_Depth>& q, IData from) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked<SData, T_Depth>& q, IData from) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_II(int lbits, int rbits, VlUnpacked<IData, T_Depth>& q, IData from) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlUnpacked<CData, T_Depth>& q, QData from) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlUnpacked<SData, T_Depth>& q, QData from) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_IQ(int lbits, int rbits, VlUnpacked<IData, T_Depth>& q, QData from) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_QQ(int lbits, int rbits, VlUnpacked<QData, T_Depth>& q, QData from) {
|
||||
const QData mask = VL_MASK_Q(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i) q[i] = (from >> ((T_Depth - 1 - i) * lbits)) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked<CData, T_Depth>& q,
|
||||
WDataInP rwp) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
q[i] = VL_SEL_IWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked<SData, T_Depth>& q,
|
||||
WDataInP rwp) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
q[i] = VL_SEL_IWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_IW(int lbits, int rbits, VlUnpacked<IData, T_Depth>& q,
|
||||
WDataInP rwp) {
|
||||
const IData mask = VL_MASK_I(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
q[i] = VL_SEL_IWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth>
|
||||
static inline void VL_UNPACK_QW(int lbits, int rbits, VlUnpacked<QData, T_Depth>& q,
|
||||
WDataInP rwp) {
|
||||
const QData mask = VL_MASK_Q(lbits);
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
q[i] = VL_SEL_QWII(rbits, rwp, (T_Depth - 1 - i) * lbits, lbits) & mask;
|
||||
}
|
||||
|
||||
template <std::size_t T_Depth, std::size_t N>
|
||||
static inline void VL_UNPACK_WW(int lbits, int rbits, VlUnpacked<VlWide<N>, T_Depth>& q,
|
||||
WDataInP rwp) {
|
||||
for (size_t i = 0; i < T_Depth; ++i)
|
||||
VL_SEL_WWII(lbits, rbits, q[i], rwp, (T_Depth - 1 - i) * lbits, lbits);
|
||||
}
|
||||
|
||||
// Return QData from double (numeric)
|
||||
// EMIT_RULE: VL_RTOIROUND_Q_D: oclean=dirty; lclean==clean/real
|
||||
static inline QData VL_RTOIROUND_Q_D(double lhs) VL_PURE {
|
||||
@@ -2068,6 +2441,97 @@ static inline void VL_ASSIGNSEL_WW(int rbits, int obits, int lsb, WDataOutP iowp
|
||||
_vl_insert_WW(iowp, rwp, lsb + obits - 1, lsb, rbits);
|
||||
}
|
||||
|
||||
//====================================================
|
||||
// Range assignments
|
||||
|
||||
// These additional functions copy bits range [obis+roffset-1:roffset] from rhs to lower bits
|
||||
// of lhs(select before assigning). Rhs should always be wider than lhs.
|
||||
static inline void VL_SELASSIGN_II(int rbits, int obits, CData& lhsr, IData rhs,
|
||||
int roffset) VL_PURE {
|
||||
_vl_insert_II(lhsr, rhs >> roffset, obits - 1, 0, rbits);
|
||||
}
|
||||
static inline void VL_SELASSIGN_II(int rbits, int obits, SData& lhsr, IData rhs,
|
||||
int roffset) VL_PURE {
|
||||
_vl_insert_II(lhsr, rhs >> roffset, obits - 1, 0, rbits);
|
||||
}
|
||||
static inline void VL_SELASSIGN_II(int rbits, int obits, IData& lhsr, IData rhs,
|
||||
int roffset) VL_PURE {
|
||||
_vl_insert_II(lhsr, rhs >> roffset, obits - 1, 0, rbits);
|
||||
}
|
||||
static inline void VL_SELASSIGN_IQ(int rbits, int obits, CData& lhsr, QData rhs,
|
||||
int roffset) VL_PURE {
|
||||
// it will be truncated to right CData mask
|
||||
const CData cleanmask = VL_MASK_I(rbits);
|
||||
const CData insmask = VL_MASK_I(obits);
|
||||
lhsr = (lhsr & ~insmask) | (static_cast<CData>(rhs >> roffset) & (insmask & cleanmask));
|
||||
}
|
||||
static inline void VL_SELASSIGN_IQ(int rbits, int obits, SData& lhsr, QData rhs,
|
||||
int roffset) VL_PURE {
|
||||
// it will be truncated to right CData mask
|
||||
const SData cleanmask = VL_MASK_I(rbits);
|
||||
const SData insmask = VL_MASK_I(obits);
|
||||
lhsr = (lhsr & ~insmask) | (static_cast<SData>(rhs >> roffset) & (insmask & cleanmask));
|
||||
}
|
||||
static inline void VL_SELASSIGN_IQ(int rbits, int obits, IData& lhsr, QData rhs,
|
||||
int roffset) VL_PURE {
|
||||
const IData cleanmask = VL_MASK_I(rbits);
|
||||
const IData insmask = VL_MASK_I(obits);
|
||||
lhsr = (lhsr & ~insmask) | (static_cast<IData>(rhs >> roffset) & (insmask & cleanmask));
|
||||
}
|
||||
|
||||
static inline void VL_SELASSIGN_QQ(int rbits, int obits, QData& lhsr, QData rhs,
|
||||
int roffset) VL_PURE {
|
||||
_vl_insert_QQ(lhsr, rhs >> roffset, obits - 1, 0, rbits);
|
||||
}
|
||||
|
||||
static inline void VL_SELASSIGN_IW(int rbits, int obits, CData& lhsr, WDataInP const rhs,
|
||||
int roffset) VL_MT_SAFE {
|
||||
IData l = static_cast<IData>(lhsr);
|
||||
_vl_insert_IW(l, rhs, roffset + obits - 1, roffset, rbits);
|
||||
lhsr = static_cast<CData>(l);
|
||||
}
|
||||
static inline void VL_SELASSIGN_IW(int rbits, int obits, SData& lhsr, WDataInP const rhs,
|
||||
int roffset) VL_MT_SAFE {
|
||||
IData l = static_cast<IData>(lhsr);
|
||||
_vl_insert_IW(l, rhs, roffset + obits - 1, roffset, rbits);
|
||||
lhsr = static_cast<SData>(l);
|
||||
}
|
||||
static inline void VL_SELASSIGN_IW(int rbits, int obits, IData& lhsr, WDataInP const rhs,
|
||||
int roffset) VL_MT_SAFE {
|
||||
_vl_insert_IW(lhsr, rhs, roffset + obits - 1, roffset, rbits);
|
||||
}
|
||||
static inline void VL_SELASSIGN_QW(int rbits, int obits, QData& lhsr, WDataInP const rhs,
|
||||
int roffset) VL_MT_SAFE {
|
||||
// assert VL_QDATASIZE >= rbits > VL_IDATASIZE;
|
||||
IData low = static_cast<IData>(lhsr);
|
||||
IData high = static_cast<IData>(lhsr >> VL_IDATASIZE);
|
||||
if (obits <= VL_IDATASIZE) {
|
||||
_vl_insert_IW(low, rhs, obits + roffset - 1, roffset, VL_IDATASIZE);
|
||||
} else {
|
||||
_vl_insert_IW(low, rhs, roffset + VL_IDATASIZE - 1, roffset, VL_IDATASIZE);
|
||||
_vl_insert_IW(high, rhs, roffset + obits - 1, roffset + VL_IDATASIZE,
|
||||
rbits - VL_IDATASIZE);
|
||||
}
|
||||
lhsr = (static_cast<QData>(high) << VL_IDATASIZE) | low;
|
||||
}
|
||||
|
||||
static inline void VL_SELASSIGN_WW(int rbits, int obits, WDataOutP iowp, WDataInP const rwp,
|
||||
int roffset) VL_MT_SAFE {
|
||||
// assert rbits > VL_QDATASIZE
|
||||
const int wordoff = roffset / VL_EDATASIZE;
|
||||
const int lsb = roffset & VL_SIZEBITS_E;
|
||||
const int upperbits = lsb == 0 ? 0 : VL_EDATASIZE - lsb;
|
||||
// If roffset is not aligned, we copy some bits to align it.
|
||||
if (lsb != 0) {
|
||||
const int w = obits < upperbits ? obits : upperbits;
|
||||
const int insmask = VL_MASK_E(w);
|
||||
iowp[0] = (iowp[0] & ~insmask) | ((rwp[wordoff] >> lsb) & insmask);
|
||||
if (w == obits) return;
|
||||
obits -= w;
|
||||
}
|
||||
_vl_insert_WW(iowp, rwp + wordoff + (lsb != 0), upperbits + obits - 1, upperbits, rbits);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Triops
|
||||
|
||||
@@ -2284,10 +2748,11 @@ extern void VL_READMEM_N(bool hex, int bits, QData depth, int array_lsb,
|
||||
extern void VL_WRITEMEM_N(bool hex, int bits, QData depth, int array_lsb,
|
||||
const std::string& filename, const void* memp, QData start,
|
||||
QData end) VL_MT_SAFE;
|
||||
extern IData VL_SSCANF_INX(int lbits, const std::string& ld, const char* formatp, ...) VL_MT_SAFE;
|
||||
extern void VL_SFORMAT_X(int obits_ignored, std::string& output, const char* formatp,
|
||||
...) VL_MT_SAFE;
|
||||
extern std::string VL_SFORMATF_NX(const char* formatp, ...) VL_MT_SAFE;
|
||||
extern IData VL_SSCANF_INNX(int lbits, const std::string& ld, const std::string& format, int argc,
|
||||
...) VL_MT_SAFE;
|
||||
extern void VL_SFORMAT_NX(int obits_ignored, std::string& output, const std::string& format,
|
||||
int argc, ...) VL_MT_SAFE;
|
||||
extern std::string VL_SFORMATF_N_NX(const std::string& format, int argc, ...) VL_MT_SAFE;
|
||||
extern void VL_TIMEFORMAT_IINI(int units, int precision, const std::string& suffix, int width,
|
||||
VerilatedContext* contextp) VL_MT_SAFE;
|
||||
extern IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) VL_MT_SAFE;
|
||||
|
||||
@@ -54,7 +54,7 @@ class VerilatedScope;
|
||||
class VerilatedMsg final {
|
||||
public:
|
||||
// TYPES
|
||||
struct Cmp {
|
||||
struct Cmp final {
|
||||
bool operator()(const VerilatedMsg& a, const VerilatedMsg& b) const {
|
||||
return a.mtaskId() < b.mtaskId();
|
||||
}
|
||||
@@ -221,7 +221,7 @@ class VerilatedContextImp final : VerilatedContext {
|
||||
// Internal note: Globals may multi-construct, see verilated.cpp top.
|
||||
|
||||
// Medium speed, so uses singleton accessing
|
||||
struct Statics {
|
||||
struct Statics final {
|
||||
VerilatedMutex s_randMutex; // Mutex protecting s_randSeedEpoch
|
||||
// Number incrementing on each reseed, 0=illegal
|
||||
int s_randSeedEpoch = 1; // Reads ok, wish had a VL_WRITE_GUARDED_BY(s_randMutex)
|
||||
@@ -294,7 +294,7 @@ public: // But only for verilated*.cpp
|
||||
std::fill(m_fdps.begin() + start, m_fdps.end(), static_cast<FILE*>(nullptr));
|
||||
m_fdFree.resize(excess);
|
||||
for (std::size_t i = 0, id = start; i < m_fdFree.size(); ++i, ++id) {
|
||||
m_fdFree[i] = id;
|
||||
m_fdFree[i] = static_cast<IData>(id);
|
||||
}
|
||||
}
|
||||
const IData idx = m_fdFree.back();
|
||||
@@ -552,7 +552,7 @@ public:
|
||||
const VerilatedLockGuard lock{s().m_exportMutex};
|
||||
const auto& it = s().m_exportMap.find(namep);
|
||||
if (VL_LIKELY(it != s().m_exportMap.end())) return it->second;
|
||||
const std::string msg = (std::string{"%Error: Testbench C called "} + namep
|
||||
const std::string msg = ("%Error: Testbench C called "s + namep
|
||||
+ " but no such DPI export function name exists in ANY model");
|
||||
VL_FATAL_MT("unknown", 0, "", msg.c_str());
|
||||
return -1;
|
||||
|
||||
@@ -116,7 +116,7 @@ IData VL_DIST_ERLANG(IData& seedr, IData uk, IData umean) VL_MT_SAFE {
|
||||
return 0;
|
||||
}
|
||||
double x = 1.0;
|
||||
for (int32_t i = 1; i <= k; i++) { x = x * _vl_dbase_uniform(seedr, 0, 1); }
|
||||
for (int32_t i = 1; i <= k; i++) x = x * _vl_dbase_uniform(seedr, 0, 1);
|
||||
const double a = static_cast<double>(mean);
|
||||
const double b = static_cast<double>(k);
|
||||
double r = -a * log(x) / b;
|
||||
|
||||
@@ -106,7 +106,7 @@ VerilatedVirtualBase* VlExecutionProfiler::construct(VerilatedContext& context)
|
||||
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 {
|
||||
struct Data final {
|
||||
VlExecutionProfiler* const selfp;
|
||||
const uint32_t threadId;
|
||||
} data{selfp, static_cast<uint32_t>(i + 1)};
|
||||
|
||||
@@ -0,0 +1,430 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2024 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 randomization implementation code
|
||||
///
|
||||
/// This file must be compiled and linked against all Verilated objects
|
||||
/// that use randomization features.
|
||||
///
|
||||
/// See the internals documentation docs/internals.rst for details.
|
||||
///
|
||||
//=========================================================================
|
||||
|
||||
#include "verilated_random.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <streambuf>
|
||||
|
||||
#define _VL_SOLVER_HASH_LEN 1
|
||||
#define _VL_SOLVER_HASH_LEN_TOTAL 4
|
||||
|
||||
// clang-format off
|
||||
#if defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
|
||||
# define _VL_SOLVER_PIPE // Allow pipe SMT solving. Needs fork()
|
||||
#endif
|
||||
|
||||
#ifdef _VL_SOLVER_PIPE
|
||||
# include <sys/wait.h>
|
||||
# include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) || defined(__MINGW32__)
|
||||
# include <io.h> // open, read, write, close
|
||||
#endif
|
||||
// clang-format on
|
||||
|
||||
class Process final : private std::streambuf, public std::iostream {
|
||||
static constexpr int BUFFER_SIZE = 4096;
|
||||
const char* const* m_cmd = nullptr; // fork() process argv
|
||||
#ifdef _VL_SOLVER_PIPE
|
||||
pid_t m_pid = 0; // fork() process id
|
||||
#else
|
||||
int m_pid = 0; // fork() process id - always zero as disabled
|
||||
#endif
|
||||
bool m_pidExited = true; // If subprocess has exited and can be opened
|
||||
int m_pidStatus = 0; // fork() process exit status, valid if m_pidExited
|
||||
int m_writeFd = -1; // File descriptor TO subprocess
|
||||
int m_readFd = -1; // File descriptor FROM subprocess
|
||||
char m_readBuf[BUFFER_SIZE];
|
||||
char m_writeBuf[BUFFER_SIZE];
|
||||
|
||||
public:
|
||||
typedef std::streambuf::traits_type traits_type;
|
||||
|
||||
protected:
|
||||
int overflow(int c = traits_type::eof()) override {
|
||||
char c2 = static_cast<char>(c);
|
||||
if (pbase() == pptr()) return 0;
|
||||
size_t size = pptr() - pbase();
|
||||
ssize_t n = ::write(m_writeFd, pbase(), size);
|
||||
if (n == -1) perror("write");
|
||||
if (n <= 0) {
|
||||
wait_report();
|
||||
return traits_type::eof();
|
||||
}
|
||||
if (n == size)
|
||||
setp(m_writeBuf, m_writeBuf + sizeof(m_writeBuf));
|
||||
else
|
||||
setp(m_writeBuf + n, m_writeBuf + sizeof(m_writeBuf));
|
||||
if (c != traits_type::eof()) sputc(c2);
|
||||
return 0;
|
||||
}
|
||||
int underflow() override {
|
||||
sync();
|
||||
ssize_t n = ::read(m_readFd, m_readBuf, sizeof(m_readBuf));
|
||||
if (n == -1) perror("read");
|
||||
if (n <= 0) {
|
||||
wait_report();
|
||||
return traits_type::eof();
|
||||
}
|
||||
setg(m_readBuf, m_readBuf, m_readBuf + n);
|
||||
return traits_type::to_int_type(m_readBuf[0]);
|
||||
}
|
||||
int sync() override {
|
||||
overflow();
|
||||
return 0;
|
||||
}
|
||||
|
||||
public:
|
||||
explicit Process(const char* const* const cmd = nullptr)
|
||||
: std::streambuf{}
|
||||
, std::iostream{this}
|
||||
, m_cmd{cmd} {
|
||||
open(cmd);
|
||||
}
|
||||
|
||||
void wait_report() {
|
||||
if (m_pidExited) return;
|
||||
#ifdef _VL_SOLVER_PIPE
|
||||
if (waitpid(m_pid, &m_pidStatus, 0) != m_pid) return;
|
||||
if (m_pidStatus) {
|
||||
std::stringstream msg;
|
||||
msg << "Subprocess command `" << m_cmd[0];
|
||||
for (const char* const* arg = m_cmd + 1; *arg; arg++) msg << ' ' << *arg;
|
||||
msg << "' failed: ";
|
||||
if (WIFSIGNALED(m_pidStatus))
|
||||
msg << strsignal(WTERMSIG(m_pidStatus))
|
||||
<< (WCOREDUMP(m_pidStatus) ? " (core dumped)" : "");
|
||||
else if (WIFEXITED(m_pidStatus))
|
||||
msg << "exit status " << WEXITSTATUS(m_pidStatus);
|
||||
const std::string str = msg.str();
|
||||
VL_WARN_MT("", 0, "Process", str.c_str());
|
||||
}
|
||||
#endif
|
||||
m_pidExited = true;
|
||||
m_pid = 0;
|
||||
closeFds();
|
||||
}
|
||||
|
||||
void closeFds() {
|
||||
if (m_writeFd != -1) {
|
||||
close(m_writeFd);
|
||||
m_writeFd = -1;
|
||||
}
|
||||
if (m_readFd != -1) {
|
||||
close(m_readFd);
|
||||
m_readFd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool open(const char* const* const cmd) {
|
||||
setp(std::begin(m_writeBuf), std::end(m_writeBuf));
|
||||
setg(m_readBuf, m_readBuf, m_readBuf);
|
||||
#ifdef _VL_SOLVER_PIPE
|
||||
if (!cmd || !cmd[0]) return false;
|
||||
m_cmd = cmd;
|
||||
int fd_stdin[2]; // Can't use std::array
|
||||
int fd_stdout[2]; // Can't use std::array
|
||||
constexpr int P_RD = 0;
|
||||
constexpr int P_WR = 1;
|
||||
|
||||
if (pipe(fd_stdin) != 0) {
|
||||
perror("Process::open: pipe");
|
||||
return false;
|
||||
}
|
||||
if (pipe(fd_stdout) != 0) {
|
||||
perror("Process::open: pipe");
|
||||
close(fd_stdin[P_RD]);
|
||||
close(fd_stdin[P_WR]);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fd_stdin[P_RD] <= 2 || fd_stdin[P_WR] <= 2 || fd_stdout[P_RD] <= 2
|
||||
|| fd_stdout[P_WR] <= 2) {
|
||||
// We'd have to rearrange all of the FD usages in this case.
|
||||
// Too unlikely; verilator isn't a daemon.
|
||||
fprintf(stderr, "stdin/stdout closed before pipe opened\n");
|
||||
close(fd_stdin[P_RD]);
|
||||
close(fd_stdin[P_WR]);
|
||||
close(fd_stdout[P_RD]);
|
||||
close(fd_stdout[P_WR]);
|
||||
return false;
|
||||
}
|
||||
|
||||
const pid_t pid = fork();
|
||||
if (pid < 0) {
|
||||
perror("Process::open: fork");
|
||||
close(fd_stdin[P_RD]);
|
||||
close(fd_stdin[P_WR]);
|
||||
close(fd_stdout[P_RD]);
|
||||
close(fd_stdout[P_WR]);
|
||||
return false;
|
||||
}
|
||||
if (pid == 0) {
|
||||
// Child
|
||||
close(fd_stdin[P_WR]);
|
||||
dup2(fd_stdin[P_RD], STDIN_FILENO);
|
||||
close(fd_stdout[P_RD]);
|
||||
dup2(fd_stdout[P_WR], STDOUT_FILENO);
|
||||
execvp(cmd[0], const_cast<char* const*>(cmd));
|
||||
std::stringstream msg;
|
||||
msg << "Process::open: execvp(" << cmd[0] << ")";
|
||||
const std::string str = msg.str();
|
||||
perror(str.c_str());
|
||||
_exit(127);
|
||||
}
|
||||
// Parent
|
||||
m_pid = pid;
|
||||
m_pidExited = false;
|
||||
m_pidStatus = 0;
|
||||
m_readFd = fd_stdout[P_RD];
|
||||
m_writeFd = fd_stdin[P_WR];
|
||||
|
||||
close(fd_stdin[P_RD]);
|
||||
close(fd_stdout[P_WR]);
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
static Process& getSolver() {
|
||||
static Process s_solver;
|
||||
static bool s_done = false;
|
||||
if (s_done) return s_solver;
|
||||
s_done = true;
|
||||
|
||||
static std::vector<const char*> s_argv;
|
||||
static std::string s_program = Verilated::threadContextp()->solverProgram();
|
||||
s_argv.emplace_back(&s_program[0]);
|
||||
for (char* arg = &s_program[0]; *arg; arg++) {
|
||||
if (*arg == ' ') {
|
||||
*arg = '\0';
|
||||
s_argv.emplace_back(arg + 1);
|
||||
}
|
||||
}
|
||||
s_argv.emplace_back(nullptr);
|
||||
|
||||
const char* const* const cmd = &s_argv[0];
|
||||
s_solver.open(cmd);
|
||||
s_solver << "(set-logic QF_BV)\n";
|
||||
s_solver << "(check-sat)\n";
|
||||
s_solver << "(reset)\n";
|
||||
std::string s;
|
||||
getline(s_solver, s);
|
||||
if (s == "sat") return s_solver;
|
||||
|
||||
std::stringstream msg;
|
||||
msg << "Unable to communicate with SAT solver, please check its installation or specify a "
|
||||
"different one in VERILATOR_SOLVER environment variable.\n";
|
||||
msg << " ... Tried: $";
|
||||
for (const char* const* arg = cmd; *arg; arg++) msg << ' ' << *arg;
|
||||
msg << '\n';
|
||||
const std::string str = msg.str();
|
||||
VL_WARN_MT("", 0, "randomize", str.c_str());
|
||||
|
||||
while (getline(s_solver, s)) {}
|
||||
return s_solver;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// VlRandomizer:: Methods
|
||||
|
||||
void VlRandomVar::emit(std::ostream& s) const { s << m_name; }
|
||||
void VlRandomConst::emit(std::ostream& s) const {
|
||||
s << "#b";
|
||||
for (int i = 0; i < m_width; i++) s << (VL_BITISSET_Q(m_val, m_width - i - 1) ? '1' : '0');
|
||||
}
|
||||
void VlRandomBinOp::emit(std::ostream& s) const {
|
||||
s << '(' << m_op << ' ';
|
||||
m_lhs->emit(s);
|
||||
s << ' ';
|
||||
m_rhs->emit(s);
|
||||
s << ')';
|
||||
}
|
||||
void VlRandomExtract::emit(std::ostream& s) const {
|
||||
s << "((_ extract " << m_idx << ' ' << m_idx << ") ";
|
||||
m_expr->emit(s);
|
||||
s << ')';
|
||||
}
|
||||
bool VlRandomVar::set(std::string&& val) const {
|
||||
VlWide<VL_WQ_WORDS_E> qowp;
|
||||
VL_SET_WQ(qowp, 0ULL);
|
||||
WDataOutP owp = qowp;
|
||||
int obits = width();
|
||||
if (obits > VL_QUADSIZE) owp = reinterpret_cast<WDataOutP>(datap());
|
||||
int i;
|
||||
for (i = 0; val[i] && val[i] != '#'; i++) {}
|
||||
if (val[i++] != '#') return false;
|
||||
switch (val[i++]) {
|
||||
case 'b': _vl_vsss_based(owp, obits, 1, &val[i], 0, val.size() - i); break;
|
||||
case 'o': _vl_vsss_based(owp, obits, 3, &val[i], 0, val.size() - i); break;
|
||||
case 'h': // FALLTHRU
|
||||
case 'x': _vl_vsss_based(owp, obits, 4, &val[i], 0, val.size() - i); break;
|
||||
default:
|
||||
VL_WARN_MT(__FILE__, __LINE__, "randomize",
|
||||
"Internal: Unable to parse solver's randomized number");
|
||||
return false;
|
||||
}
|
||||
if (obits <= VL_BYTESIZE) {
|
||||
CData* const p = static_cast<CData*>(datap());
|
||||
*p = VL_CLEAN_II(obits, obits, owp[0]);
|
||||
} else if (obits <= VL_SHORTSIZE) {
|
||||
SData* const p = static_cast<SData*>(datap());
|
||||
*p = VL_CLEAN_II(obits, obits, owp[0]);
|
||||
} else if (obits <= VL_IDATASIZE) {
|
||||
IData* const p = static_cast<IData*>(datap());
|
||||
*p = VL_CLEAN_II(obits, obits, owp[0]);
|
||||
} else if (obits <= VL_QUADSIZE) {
|
||||
QData* const p = static_cast<QData*>(datap());
|
||||
*p = VL_CLEAN_QQ(obits, obits, VL_SET_QW(owp));
|
||||
} else {
|
||||
_vl_clean_inplace_w(obits, owp);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<const VlRandomExpr> VlRandomizer::randomConstraint(VlRNG& rngr, int bits) {
|
||||
unsigned long long hash = VL_RANDOM_RNG_I(rngr) & ((1 << bits) - 1);
|
||||
std::shared_ptr<const VlRandomExpr> concat = nullptr;
|
||||
std::vector<std::shared_ptr<const VlRandomExpr>> varbits;
|
||||
for (const auto& var : m_vars) {
|
||||
for (int i = 0; i < var.second->width(); i++)
|
||||
varbits.emplace_back(std::make_shared<const VlRandomExtract>(var.second, i));
|
||||
}
|
||||
for (int i = 0; i < bits; i++) {
|
||||
std::shared_ptr<const VlRandomExpr> bit = nullptr;
|
||||
for (unsigned j = 0; j * 2 < varbits.size(); j++) {
|
||||
unsigned idx = j + VL_RANDOM_RNG_I(rngr) % (varbits.size() - j);
|
||||
auto sel = varbits[idx];
|
||||
std::swap(varbits[idx], varbits[j]);
|
||||
bit = bit == nullptr ? sel : std::make_shared<const VlRandomBinOp>("bvxor", bit, sel);
|
||||
}
|
||||
concat = concat == nullptr ? bit
|
||||
: std::make_shared<const VlRandomBinOp>("concat", concat, bit);
|
||||
}
|
||||
return std::make_shared<const VlRandomBinOp>(
|
||||
"=", concat, std::make_shared<const VlRandomConst>(hash, bits));
|
||||
}
|
||||
|
||||
bool VlRandomizer::next(VlRNG& rngr) {
|
||||
if (m_vars.empty()) return true;
|
||||
std::iostream& f = getSolver();
|
||||
if (!f) return false;
|
||||
|
||||
f << "(set-option :produce-models true)\n";
|
||||
f << "(set-logic QF_BV)\n";
|
||||
for (const auto& var : m_vars) {
|
||||
f << "(declare-fun " << var.second->name() << " () (_ BitVec " << var.second->width()
|
||||
<< "))\n";
|
||||
}
|
||||
for (const std::string& constraint : m_constraints) { f << "(assert " << constraint << ")\n"; }
|
||||
f << "(check-sat)\n";
|
||||
|
||||
bool sat = parseSolution(f);
|
||||
if (!sat) {
|
||||
f << "(reset)\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < _VL_SOLVER_HASH_LEN_TOTAL && sat; i++) {
|
||||
f << "(assert ";
|
||||
randomConstraint(rngr, _VL_SOLVER_HASH_LEN)->emit(f);
|
||||
f << ")\n";
|
||||
f << "\n(check-sat)\n";
|
||||
sat = parseSolution(f);
|
||||
}
|
||||
|
||||
f << "(reset)\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VlRandomizer::parseSolution(std::iostream& f) {
|
||||
std::string sat;
|
||||
do { std::getline(f, sat); } while (sat == "");
|
||||
|
||||
if (sat == "unsat") return false;
|
||||
if (sat != "sat") {
|
||||
std::stringstream msg;
|
||||
msg << "Internal: Solver error: " << sat;
|
||||
const std::string str = msg.str();
|
||||
VL_WARN_MT(__FILE__, __LINE__, "randomize", str.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
f << "(get-value (";
|
||||
for (const auto& var : m_vars) f << var.second->name() << ' ';
|
||||
f << "))\n";
|
||||
|
||||
// Quasi-parse S-expression of the form ((x #xVALUE) (y #bVALUE) (z #xVALUE))
|
||||
char c;
|
||||
f >> c;
|
||||
if (c != '(') {
|
||||
VL_WARN_MT(__FILE__, __LINE__, "randomize",
|
||||
"Internal: Unable to parse solver's response: invalid S-expression");
|
||||
return false;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
f >> c;
|
||||
if (c == ')') break;
|
||||
if (c != '(') {
|
||||
VL_WARN_MT(__FILE__, __LINE__, "randomize",
|
||||
"Internal: Unable to parse solver's response: invalid S-expression");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string name, value;
|
||||
f >> name;
|
||||
std::getline(f, value, ')');
|
||||
|
||||
auto it = m_vars.find(name);
|
||||
if (it == m_vars.end()) continue;
|
||||
const VlRandomVar& varr = *it->second;
|
||||
if (m_randmode && !varr.randModeIdxNone()) {
|
||||
if (!(m_randmode->at(varr.randModeIdx()))) continue;
|
||||
}
|
||||
|
||||
varr.set(std::move(value));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void VlRandomizer::hard(std::string&& constraint) {
|
||||
m_constraints.emplace_back(std::move(constraint));
|
||||
}
|
||||
|
||||
void VlRandomizer::clear() { m_constraints.clear(); }
|
||||
|
||||
#ifdef VL_DEBUG
|
||||
void VlRandomizer::dump() const {
|
||||
for (const auto& var : m_vars) {
|
||||
VL_PRINTF("Variable (%d): %s\n", var.second->width(), var.second->name());
|
||||
}
|
||||
for (const std::string& c : m_constraints) VL_PRINTF("Constraint: %s\n", c.c_str());
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,128 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2024 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 randomization header
|
||||
///
|
||||
/// This file is included automatically by Verilator in some of the C++ files
|
||||
/// it generates if randomization features are used.
|
||||
///
|
||||
/// This file is not part of the Verilated public-facing API.
|
||||
/// It is only for internal use.
|
||||
///
|
||||
/// See the internals documentation docs/internals.rst for details.
|
||||
///
|
||||
//*************************************************************************
|
||||
#ifndef VERILATOR_VERILATED_RANDOM_H_
|
||||
#define VERILATOR_VERILATED_RANDOM_H_
|
||||
|
||||
#include "verilated.h"
|
||||
|
||||
//=============================================================================
|
||||
// VlRandomExpr and subclasses represent expressions for the constraint solver.
|
||||
|
||||
class VlRandomExpr VL_NOT_FINAL {
|
||||
public:
|
||||
virtual void emit(std::ostream& s) const = 0;
|
||||
};
|
||||
class VlRandomVar final : public VlRandomExpr {
|
||||
const char* const m_name; // Variable name
|
||||
void* const m_datap; // Reference to variable data
|
||||
const int m_width; // Variable width in bits
|
||||
const std::uint32_t m_randModeIdx; // rand_mode index
|
||||
|
||||
public:
|
||||
VlRandomVar(const char* name, int width, void* datap, std::uint32_t randModeIdx)
|
||||
: m_name{name}
|
||||
, m_datap{datap}
|
||||
, m_width{width}
|
||||
, m_randModeIdx{randModeIdx} {}
|
||||
const char* name() const { return m_name; }
|
||||
int width() const { return m_width; }
|
||||
void* datap() const { return m_datap; }
|
||||
std::uint32_t randModeIdx() const { return m_randModeIdx; }
|
||||
bool randModeIdxNone() const { return randModeIdx() == std::numeric_limits<unsigned>::max(); }
|
||||
bool set(std::string&&) const;
|
||||
void emit(std::ostream& s) const override;
|
||||
};
|
||||
|
||||
class VlRandomConst final : public VlRandomExpr {
|
||||
const QData m_val; // Constant value
|
||||
const int m_width; // Constant width in bits
|
||||
|
||||
public:
|
||||
VlRandomConst(QData val, int width)
|
||||
: m_val{val}
|
||||
, m_width{width} {
|
||||
assert(width <= sizeof(m_val) * 8);
|
||||
}
|
||||
void emit(std::ostream& s) const override;
|
||||
};
|
||||
|
||||
class VlRandomExtract final : public VlRandomExpr {
|
||||
const std::shared_ptr<const VlRandomExpr> m_expr; // Sub-expression
|
||||
const unsigned m_idx; // Extracted index
|
||||
|
||||
public:
|
||||
VlRandomExtract(std::shared_ptr<const VlRandomExpr> expr, unsigned idx)
|
||||
: m_expr{expr}
|
||||
, m_idx{idx} {}
|
||||
void emit(std::ostream& s) const override;
|
||||
};
|
||||
|
||||
class VlRandomBinOp final : public VlRandomExpr {
|
||||
const char* const m_op; // Binary operation identifier
|
||||
const std::shared_ptr<const VlRandomExpr> m_lhs, m_rhs; // Sub-expressions
|
||||
|
||||
public:
|
||||
VlRandomBinOp(const char* op, std::shared_ptr<const VlRandomExpr> lhs,
|
||||
std::shared_ptr<const VlRandomExpr> rhs)
|
||||
: m_op{op}
|
||||
, m_lhs{lhs}
|
||||
, m_rhs{rhs} {}
|
||||
void emit(std::ostream& s) const override;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VlRandomizer is the object holding constraints and variable references.
|
||||
|
||||
class VlRandomizer final {
|
||||
// MEMBERS
|
||||
std::vector<std::string> m_constraints; // Solver-dependent constraints
|
||||
std::map<std::string, std::shared_ptr<const VlRandomVar>> m_vars; // Solver-dependent
|
||||
// variables
|
||||
const VlQueue<CData>* m_randmode; // rand_mode state;
|
||||
|
||||
// PRIVATE METHODS
|
||||
std::shared_ptr<const VlRandomExpr> randomConstraint(VlRNG& rngr, int bits);
|
||||
bool parseSolution(std::iostream& file);
|
||||
|
||||
public:
|
||||
// METHODS
|
||||
// Finds the next solution satisfying the constraints
|
||||
bool next(VlRNG& rngr);
|
||||
template <typename T>
|
||||
void write_var(T& var, int width, const char* name,
|
||||
std::uint32_t randmodeIdx = std::numeric_limits<std::uint32_t>::max()) {
|
||||
auto it = m_vars.find(name);
|
||||
if (it != m_vars.end()) return;
|
||||
m_vars[name] = std::make_shared<const VlRandomVar>(name, width, &var, randmodeIdx);
|
||||
}
|
||||
void hard(std::string&& constraint);
|
||||
void clear();
|
||||
void set_randmode(const VlQueue<CData>& randmode) { m_randmode = &randmode; }
|
||||
#ifdef VL_DEBUG
|
||||
void dump() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
@@ -95,8 +95,7 @@ void VerilatedDeserialize::header() VL_MT_UNSAFE_ONE {
|
||||
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_HEADER_STR, std::strlen(VLTSAVE_HEADER_STR)))) {
|
||||
const std::string fn = filename();
|
||||
const std::string msg
|
||||
= std::
|
||||
string{"Can't deserialize; file has wrong header signature, or file not found: "}
|
||||
= "Can't deserialize; file has wrong header signature, or file not found: "s
|
||||
+ filename();
|
||||
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
||||
// Die before we close() as close would infinite loop
|
||||
@@ -114,8 +113,7 @@ void VerilatedDeserialize::trailer() VL_MT_UNSAFE_ONE {
|
||||
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_TRAILER_STR, std::strlen(VLTSAVE_TRAILER_STR)))) {
|
||||
const std::string fn = filename();
|
||||
const std::string msg
|
||||
= std::string{"Can't deserialize; file has wrong end-of-file signature: "}
|
||||
+ filename();
|
||||
= "Can't deserialize; file has wrong end-of-file signature: "s + filename();
|
||||
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
||||
// Die before we close() as close would infinite loop
|
||||
}
|
||||
|
||||
@@ -24,8 +24,13 @@
|
||||
#include "verilated.h"
|
||||
#include "verilated_sc.h"
|
||||
|
||||
#if SYSTEMC_VERSION < 20140417 // SystemC's simulation phase callback introduced in 2.3.1
|
||||
#define _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
|
||||
#if SYSTEMC_VERSION >= 20140417 && SYSTEMC_VERSION < 20231124
|
||||
// SystemC's simulation phase callback introduced in 2.3.1, and removed since 3.0.0 (PubRev)
|
||||
#define _VL_HAVE_SYSTEMC_PHASE_CALLBACK
|
||||
#endif
|
||||
#if SYSTEMC_VERSION >= 20231124
|
||||
// SystemC's stage callback introduced in 3.0.0 (PubRev)
|
||||
#define _VL_HAVE_SYSTEMC_STAGE_CALLBACK
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
@@ -49,6 +54,9 @@
|
||||
/// instead.
|
||||
|
||||
class VerilatedScTraceBase VL_NOT_FINAL : private sc_core::sc_object,
|
||||
#ifdef _VL_HAVE_SYSTEMC_STAGE_CALLBACK
|
||||
private sc_core::sc_stage_callback_if,
|
||||
#endif
|
||||
private sc_core::sc_trace_file {
|
||||
bool m_enableDeltaCycles = false;
|
||||
bool m_traceFileAdded = false;
|
||||
@@ -56,8 +64,8 @@ class VerilatedScTraceBase VL_NOT_FINAL : private sc_core::sc_object,
|
||||
|
||||
public:
|
||||
void enableDeltaCycles(bool flag = true) {
|
||||
#ifndef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
|
||||
using namespace sc_core;
|
||||
#ifdef _VL_HAVE_SYSTEMC_PHASE_CALLBACK
|
||||
// Save old report handler before overriding it
|
||||
const auto oldHandler = sc_report_handler::get_handler();
|
||||
// Override the old handler to hide 'phase callbacks not enabled' message
|
||||
@@ -70,6 +78,13 @@ public:
|
||||
}
|
||||
// Restore the old handler
|
||||
sc_report_handler::set_handler(oldHandler);
|
||||
#endif
|
||||
#ifdef _VL_HAVE_SYSTEMC_STAGE_CALLBACK
|
||||
if (flag) {
|
||||
sc_register_stage_callback(*this, SC_POST_UPDATE);
|
||||
} else {
|
||||
sc_unregister_stage_callback(*this, SC_POST_UPDATE);
|
||||
}
|
||||
#endif
|
||||
m_enableDeltaCycles = flag;
|
||||
}
|
||||
@@ -81,15 +96,22 @@ protected:
|
||||
registerTraceCallback();
|
||||
};
|
||||
~VerilatedScTraceBase() override {
|
||||
#if SYSTEMC_VERSION >= 20140417 // remove_trace_file added in 2.3.1
|
||||
using namespace sc_core;
|
||||
#ifdef _VL_HAVE_SYSTEMC_PHASE_CALLBACK
|
||||
// remove_trace_file added in 2.3.1 and removed in 3.0.0
|
||||
// Phase callback is automatically unregistered in ~sc_object(). Only the trace file is
|
||||
// needed to be removed here
|
||||
if (m_traceFileAdded) simcontext()->remove_trace_file(this);
|
||||
#else
|
||||
(void)m_traceFileAdded;
|
||||
#endif
|
||||
#ifdef _VL_HAVE_SYSTEMC_STAGE_CALLBACK
|
||||
sc_unregister_stage_callback(*this, SC_PRE_TIMESTEP | SC_POST_UPDATE);
|
||||
#endif
|
||||
};
|
||||
void registerTraceCallback() {
|
||||
#ifndef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
|
||||
using namespace sc_core;
|
||||
#ifdef _VL_HAVE_SYSTEMC_PHASE_CALLBACK
|
||||
// Save old report handler before overriding it
|
||||
const auto oldHandler = sc_report_handler::get_handler();
|
||||
// Override the old handler to hide 'phase callbacks not enabled' message
|
||||
@@ -98,13 +120,18 @@ protected:
|
||||
phase_cb_mask cb_mask = sc_object::register_simulation_phase_callback(SC_BEFORE_TIMESTEP);
|
||||
if (cb_mask == SC_UNITIALIZED) {
|
||||
#endif
|
||||
#if SYSTEMC_VERSION < 20231124 // add_trace_file removed in 3.0.0
|
||||
// Phase callback not enabled, use trace file instead
|
||||
simcontext()->add_trace_file(this);
|
||||
m_traceFileAdded = true;
|
||||
#ifndef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
|
||||
#endif
|
||||
#ifdef _VL_HAVE_SYSTEMC_PHASE_CALLBACK
|
||||
}
|
||||
// Restore the old handler
|
||||
sc_report_handler::set_handler(oldHandler);
|
||||
#endif
|
||||
#ifdef _VL_HAVE_SYSTEMC_STAGE_CALLBACK
|
||||
sc_register_stage_callback(*this, SC_PRE_TIMESTEP);
|
||||
#endif
|
||||
}
|
||||
static std::string getScTimeUnit() {
|
||||
@@ -129,9 +156,13 @@ protected:
|
||||
}
|
||||
|
||||
// METHODS - for SC kernel
|
||||
#ifndef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
|
||||
#ifdef _VL_HAVE_SYSTEMC_PHASE_CALLBACK
|
||||
// Override sc_object. Called if using phase callback
|
||||
void simulation_phase_callback() final { cycle(); }
|
||||
#endif
|
||||
#ifdef _VL_HAVE_SYSTEMC_STAGE_CALLBACK
|
||||
// Override sc_stage_callback_if. Called if using stage callback
|
||||
void stage_callback(const sc_core::sc_stage&) final { cycle(); }
|
||||
#endif
|
||||
// Override sc_trace_file. Called if using trace file
|
||||
void cycle(bool delta_cycle) final {
|
||||
@@ -155,6 +186,7 @@ private:
|
||||
// SystemC 2.1.v1
|
||||
|
||||
void write_comment(const std::string&) override {}
|
||||
void trace(sc_core::sc_trace_file*) const override {}
|
||||
void trace(const unsigned int&, const std::string&, const char**) override {}
|
||||
|
||||
#define DECL_TRACE_METHOD_A(tp) \
|
||||
@@ -205,8 +237,11 @@ private:
|
||||
#undef DECL_TRACE_METHOD_B
|
||||
};
|
||||
|
||||
#ifdef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
|
||||
#undef _VERILATOR_SYSTEMC_NO_PHASE_CALLBACK
|
||||
#ifdef _VL_HAVE_SYSTEMC_PHASE_CALLBACK
|
||||
#undef _VL_HAVE_SYSTEMC_PHASE_CALLBACK
|
||||
#endif
|
||||
#ifdef _VL_HAVE_SYSTEMC_STAGE_CALLBACK
|
||||
#undef _VL_HAVE_SYSTEMC_STAGE_CALLBACK
|
||||
#endif
|
||||
|
||||
#endif // Guard
|
||||
|
||||
@@ -40,7 +40,7 @@ package std;
|
||||
|
||||
task put(T message);
|
||||
`ifdef VERILATOR_TIMING
|
||||
if (m_bound != 0)
|
||||
while (m_bound != 0 && m_queue.size() >= m_bound)
|
||||
wait (m_queue.size() < m_bound);
|
||||
m_queue.push_back(message);
|
||||
`endif
|
||||
@@ -56,7 +56,9 @@ package std;
|
||||
|
||||
task get(ref T message);
|
||||
`ifdef VERILATOR_TIMING
|
||||
wait (m_queue.size() > 0);
|
||||
while (m_queue.size() == 0) begin
|
||||
wait (m_queue.size() > 0);
|
||||
end
|
||||
message = m_queue.pop_front();
|
||||
`endif
|
||||
endtask
|
||||
@@ -71,7 +73,9 @@ package std;
|
||||
|
||||
task peek(ref T message);
|
||||
`ifdef VERILATOR_TIMING
|
||||
wait (m_queue.size() > 0);
|
||||
while (m_queue.size() == 0) begin
|
||||
wait (m_queue.size() > 0);
|
||||
end
|
||||
message = m_queue[0];
|
||||
`endif
|
||||
endtask
|
||||
@@ -98,7 +102,9 @@ package std;
|
||||
|
||||
task get(int keyCount = 1);
|
||||
`ifdef VERILATOR_TIMING
|
||||
wait (m_keyCount >= keyCount);
|
||||
while (m_keyCount < keyCount) begin
|
||||
wait (m_keyCount >= keyCount);
|
||||
end
|
||||
m_keyCount -= keyCount;
|
||||
`endif
|
||||
endtask
|
||||
@@ -189,4 +195,7 @@ package std;
|
||||
$urandom(s.atoi()); // Set the seed using a string
|
||||
endfunction
|
||||
endclass
|
||||
function int randomize();
|
||||
randomize = 0;
|
||||
endfunction
|
||||
endpackage
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
// Types
|
||||
|
||||
// Class to sort maps keyed by const char*'s
|
||||
struct VerilatedCStrCmp {
|
||||
struct VerilatedCStrCmp final {
|
||||
bool operator()(const char* a, const char* b) const { return std::strcmp(a, b) < 0; }
|
||||
};
|
||||
|
||||
|
||||
@@ -127,7 +127,7 @@ public:
|
||||
class VlWorkerThread final {
|
||||
private:
|
||||
// TYPES
|
||||
struct ExecRec {
|
||||
struct ExecRec final {
|
||||
VlExecFnp m_fnp = nullptr; // Function to execute
|
||||
VlSelfP m_selfp = nullptr; // Symbol table to execute
|
||||
bool m_evenCycle = false; // Even/odd for flag alternation
|
||||
@@ -214,10 +214,10 @@ public:
|
||||
~VlThreadPool() override;
|
||||
|
||||
// METHODS
|
||||
int numThreads() const { return m_workers.size(); }
|
||||
int numThreads() const { return static_cast<int>(m_workers.size()); }
|
||||
VlWorkerThread* workerp(int index) {
|
||||
assert(index >= 0);
|
||||
assert(static_cast<size_t>(index) < m_workers.size());
|
||||
assert(index < static_cast<int>(m_workers.size()));
|
||||
return m_workers[index];
|
||||
}
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ void VlDelayScheduler::resume() {
|
||||
#endif
|
||||
bool resumed = false;
|
||||
|
||||
while (!m_queue.empty() && (m_queue.begin()->first == m_context.time())) {
|
||||
while (!m_queue.empty() && (m_queue.cbegin()->first == m_context.time())) {
|
||||
VlCoroutineHandle handle = std::move(m_queue.begin()->second);
|
||||
m_queue.erase(m_queue.begin());
|
||||
handle.resume();
|
||||
@@ -67,9 +67,16 @@ void VlDelayScheduler::resume() {
|
||||
}
|
||||
|
||||
if (!m_zeroDelayed.empty()) {
|
||||
for (auto&& handle : m_zeroDelayed) handle.resume();
|
||||
m_zeroDelayed.clear();
|
||||
// First, we need to move the coroutines out of the queue, as a resumed coroutine can
|
||||
// suspend on #0 again, adding itself to the queue, which can result in reallocating the
|
||||
// queue mid-iteration.
|
||||
// We swap with the m_zeroDlyResumed field to keep the allocated buffer.
|
||||
m_zeroDlyResumed.swap(m_zeroDelayed);
|
||||
for (auto&& handle : m_zeroDlyResumed) handle.resume();
|
||||
m_zeroDlyResumed.clear();
|
||||
resumed = true;
|
||||
// We are now in the Active region, so any coroutines added to m_zeroDelayed in the
|
||||
// meantime will have to wait until the next Inactive region.
|
||||
}
|
||||
|
||||
if (!resumed) {
|
||||
@@ -80,7 +87,7 @@ void VlDelayScheduler::resume() {
|
||||
}
|
||||
|
||||
uint64_t VlDelayScheduler::nextTimeSlot() const {
|
||||
if (!m_queue.empty()) return m_queue.begin()->first;
|
||||
if (!m_queue.empty()) return m_queue.cbegin()->first;
|
||||
if (m_zeroDelayed.empty())
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: There is no next time slot scheduled");
|
||||
return m_context.time();
|
||||
|
||||
+26
-19
@@ -32,14 +32,18 @@
|
||||
// clang-format off
|
||||
// Some preprocessor magic to support both Clang and GCC coroutines with both libc++ and libstdc++
|
||||
#if defined _LIBCPP_VERSION // libc++
|
||||
# if __clang_major__ > 13 // Clang > 13 warns that coroutine types in std::experimental are deprecated
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wdeprecated-experimental-coroutine"
|
||||
# if defined(__has_include) && !__has_include(<coroutine>) && __has_include(<experimental/coroutine>)
|
||||
# if __clang_major__ > 13 // Clang > 13 warns that coroutine types in std::experimental are deprecated
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wdeprecated-experimental-coroutine"
|
||||
# endif
|
||||
# include <experimental/coroutine>
|
||||
namespace std {
|
||||
using namespace experimental; // Bring std::experimental into the std namespace
|
||||
}
|
||||
# else
|
||||
# include <coroutine>
|
||||
# endif
|
||||
# include <experimental/coroutine>
|
||||
namespace std {
|
||||
using namespace experimental; // Bring std::experimental into the std namespace
|
||||
}
|
||||
#else
|
||||
# if defined __clang__ && defined __GLIBCXX__ && !defined __cpp_impl_coroutine
|
||||
# define __cpp_impl_coroutine 1 // Clang doesn't define this, but it's needed for libstdc++
|
||||
@@ -165,6 +169,9 @@ class VlDelayScheduler final {
|
||||
VerilatedContext& m_context;
|
||||
VlDelayedCoroutineQueue m_queue; // Coroutines to be restored at a certain simulation time
|
||||
std::vector<VlCoroutineHandle> m_zeroDelayed; // Coroutines waiting for #0
|
||||
std::vector<VlCoroutineHandle> m_zeroDlyResumed; // Coroutines that waited for #0 and are
|
||||
// to be resumed. Kept as a field to avoid
|
||||
// reallocation.
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
@@ -180,7 +187,7 @@ public:
|
||||
bool empty() const { return m_queue.empty() && m_zeroDelayed.empty(); }
|
||||
// Are there coroutines to resume at the current simulation time?
|
||||
bool awaitingCurrentTime() const {
|
||||
return (!m_queue.empty() && (m_queue.begin()->first <= m_context.time()))
|
||||
return (!m_queue.empty() && (m_queue.cbegin()->first <= m_context.time()))
|
||||
|| !m_zeroDelayed.empty();
|
||||
}
|
||||
#ifdef VL_DEBUG
|
||||
@@ -189,13 +196,13 @@ public:
|
||||
// Used by coroutines for co_awaiting a certain simulation time
|
||||
auto delay(uint64_t delay, VlProcessRef process, const char* filename = VL_UNKNOWN,
|
||||
int lineno = 0) {
|
||||
struct Awaitable {
|
||||
struct Awaitable final {
|
||||
VlProcessRef process; // Data of the suspended process, null if not needed
|
||||
VlDelayedCoroutineQueue& queue;
|
||||
std::vector<VlCoroutineHandle>& queueZeroDelay;
|
||||
uint64_t delay;
|
||||
VlDelayPhase phase;
|
||||
VlFileLineDebug fileline;
|
||||
const uint64_t delay;
|
||||
const VlDelayPhase phase;
|
||||
const VlFileLineDebug fileline;
|
||||
|
||||
bool await_ready() const { return false; } // Always suspend
|
||||
void await_suspend(std::coroutine_handle<> coro) {
|
||||
@@ -208,7 +215,7 @@ public:
|
||||
void await_resume() const {}
|
||||
};
|
||||
|
||||
VlDelayPhase phase = (delay == 0) ? VlDelayPhase::INACTIVE : VlDelayPhase::ACTIVE;
|
||||
const VlDelayPhase phase = (delay == 0) ? VlDelayPhase::INACTIVE : VlDelayPhase::ACTIVE;
|
||||
#ifdef VL_DEBUG
|
||||
if (phase == VlDelayPhase::INACTIVE) {
|
||||
VL_WARN_MT(filename, lineno, VL_UNKNOWN,
|
||||
@@ -260,7 +267,7 @@ public:
|
||||
const char* filename = VL_UNKNOWN, int lineno = 0) {
|
||||
VL_DEBUG_IF(VL_DBG_MSGF(" Suspending process waiting for %s at %s:%d\n",
|
||||
eventDescription, filename, lineno););
|
||||
struct Awaitable {
|
||||
struct Awaitable final {
|
||||
VlCoroutineVec& suspended; // Coros waiting on trigger
|
||||
VlProcessRef process; // Data of the suspended process, null if not needed
|
||||
VlFileLineDebug fileline;
|
||||
@@ -308,7 +315,7 @@ class VlDynamicTriggerScheduler final {
|
||||
|
||||
// METHODS
|
||||
auto awaitable(VlProcessRef process, VlCoroutineVec& queue, const char* filename, int lineno) {
|
||||
struct Awaitable {
|
||||
struct Awaitable final {
|
||||
VlProcessRef process; // Data of the suspended process, null if not needed
|
||||
VlCoroutineVec& suspended; // Coros waiting on trigger
|
||||
VlFileLineDebug fileline;
|
||||
@@ -362,7 +369,7 @@ public:
|
||||
// VlForever is a helper awaitable type for suspending coroutines forever. Used for constant
|
||||
// wait statements.
|
||||
|
||||
struct VlForever {
|
||||
struct VlForever final {
|
||||
bool await_ready() const { return false; } // Always suspend
|
||||
void await_suspend(std::coroutine_handle<> coro) const { coro.destroy(); }
|
||||
void await_resume() const {}
|
||||
@@ -374,7 +381,7 @@ struct VlForever {
|
||||
class VlForkSync final {
|
||||
// VlJoin stores the handle of a suspended coroutine that did a fork..join or fork..join_any.
|
||||
// If the counter reaches 0, the suspended coroutine shall be resumed.
|
||||
struct VlJoin {
|
||||
struct VlJoin final {
|
||||
size_t m_counter = 0; // When reaches 0, resume suspended coroutine
|
||||
VlCoroutineHandle m_susp; // Coroutine to resume
|
||||
};
|
||||
@@ -393,7 +400,7 @@ public:
|
||||
assert(m_join);
|
||||
VL_DEBUG_IF(
|
||||
VL_DBG_MSGF(" Awaiting join of fork at: %s:%d\n", filename, lineno););
|
||||
struct Awaitable {
|
||||
struct Awaitable final {
|
||||
VlProcessRef process; // Data of the suspended process, null if not needed
|
||||
const std::shared_ptr<VlJoin> join; // Join to await on
|
||||
VlFileLineDebug fileline;
|
||||
@@ -415,7 +422,7 @@ public:
|
||||
class VlCoroutine final {
|
||||
private:
|
||||
// TYPES
|
||||
struct VlPromise {
|
||||
struct VlPromise final {
|
||||
std::coroutine_handle<> m_continuation; // Coroutine to resume after this one finishes
|
||||
VlCoroutine* m_corop = nullptr; // Pointer to the coroutine return object
|
||||
|
||||
|
||||
+27
-15
@@ -30,8 +30,9 @@
|
||||
#include <condition_variable>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <type_traits>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include <deque>
|
||||
@@ -179,6 +180,21 @@ public:
|
||||
, m_useFstWriterThread{useFstWriterThread} {}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedTraceBaseC - base class of all Verilated*C trace classes
|
||||
// Internal use only
|
||||
|
||||
class VerilatedTraceBaseC VL_NOT_FINAL {
|
||||
bool m_modelConnected = false; // Model connected by calling Verilated::trace()
|
||||
public:
|
||||
/// True if file currently open
|
||||
virtual bool isOpen() const VL_MT_SAFE = 0;
|
||||
|
||||
// internal use only
|
||||
bool modelConnected() const VL_MT_SAFE { return m_modelConnected; }
|
||||
void modelConnected(bool flag) VL_MT_SAFE { m_modelConnected = flag; }
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedTrace
|
||||
|
||||
@@ -204,16 +220,12 @@ private:
|
||||
friend Buffer;
|
||||
friend OffloadBuffer;
|
||||
|
||||
struct CallbackRecord {
|
||||
// Note: would make these fields const, but some old STL implementations
|
||||
// (the one in Ubuntu 14.04 with GCC 4.8.4 in particular) use the
|
||||
// assignment operator on inserting into collections, so they don't work
|
||||
// with const fields...
|
||||
const union { // The callback
|
||||
initCb_t m_initCb;
|
||||
dumpCb_t m_dumpCb;
|
||||
dumpOffloadCb_t m_dumpOffloadCb;
|
||||
cleanupCb_t m_cleanupCb;
|
||||
struct CallbackRecord final {
|
||||
union { // The callback
|
||||
const initCb_t m_initCb;
|
||||
const dumpCb_t m_dumpCb;
|
||||
const dumpOffloadCb_t m_dumpOffloadCb;
|
||||
const cleanupCb_t m_cleanupCb;
|
||||
};
|
||||
const uint32_t m_fidx; // The index of the tracing function
|
||||
void* const m_userp; // The user pointer to pass to the callback (the symbol table)
|
||||
@@ -238,7 +250,7 @@ private:
|
||||
bool m_offload = false; // Use the offload thread
|
||||
bool m_parallel = false; // Use parallel tracing
|
||||
|
||||
struct ParallelWorkerData {
|
||||
struct ParallelWorkerData final {
|
||||
const dumpCb_t m_cb; // The callback
|
||||
void* const m_userp; // The use pointer to pass to the callback
|
||||
Buffer* const m_bufp; // The buffer pointer to pass to the callback
|
||||
@@ -283,7 +295,7 @@ private:
|
||||
uint64_t m_timeLastDump = 0; // Last time we did a dump
|
||||
bool m_didSomeDump = false; // Did at least one dump (i.e.: m_timeLastDump is valid)
|
||||
VerilatedContext* m_contextp = nullptr; // The context used by the traced models
|
||||
std::unordered_set<const VerilatedModel*> m_models; // The collection of models being traced
|
||||
std::set<const VerilatedModel*> m_models; // The collection of models being traced
|
||||
|
||||
void addCallbackRecord(std::vector<CallbackRecord>& cbVec, CallbackRecord&& cbRec)
|
||||
VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||
@@ -582,7 +594,7 @@ public:
|
||||
m_offloadBufferWritep[0] = (bits << 4) | VerilatedTraceOffloadCommand::CHG_WDATA;
|
||||
m_offloadBufferWritep[1] = code;
|
||||
m_offloadBufferWritep += 2;
|
||||
for (int i = 0; i < (bits + 31) / 32; ++i) { *m_offloadBufferWritep++ = newvalp[i]; }
|
||||
for (int i = 0; i < (bits + 31) / 32; ++i) *m_offloadBufferWritep++ = newvalp[i];
|
||||
VL_DEBUG_IF(assert(m_offloadBufferWritep <= m_offloadBufferEndp););
|
||||
}
|
||||
void chgDouble(uint32_t code, double newval) {
|
||||
|
||||
@@ -60,22 +60,6 @@ static double timescaleToDouble(const char* unitp) VL_PURE {
|
||||
return value;
|
||||
}
|
||||
|
||||
static std::string doubleToTimescale(double value) VL_PURE {
|
||||
const char* suffixp = "s";
|
||||
// clang-format off
|
||||
if (value >= 1e0) { suffixp = "s"; value *= 1e0; }
|
||||
else if (value >= 1e-3) { suffixp = "ms"; value *= 1e3; }
|
||||
else if (value >= 1e-6) { suffixp = "us"; value *= 1e6; }
|
||||
else if (value >= 1e-9) { suffixp = "ns"; value *= 1e9; }
|
||||
else if (value >= 1e-12) { suffixp = "ps"; value *= 1e12; }
|
||||
else if (value >= 1e-15) { suffixp = "fs"; value *= 1e15; }
|
||||
else if (value >= 1e-18) { suffixp = "as"; value *= 1e18; }
|
||||
// clang-format on
|
||||
char valuestr[100];
|
||||
VL_SNPRINTF(valuestr, 100, "%0.0f%s", value, suffixp);
|
||||
return valuestr; // Gets converted to string, so no ref to stack
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
// Buffer management
|
||||
|
||||
@@ -190,13 +174,16 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::offloadWorkerThreadMain() {
|
||||
|
||||
//===
|
||||
// Rare commands
|
||||
case VerilatedTraceOffloadCommand::TIME_CHANGE:
|
||||
case VerilatedTraceOffloadCommand::TIME_CHANGE: {
|
||||
VL_TRACE_OFFLOAD_DEBUG("Command TIME_CHANGE " << top);
|
||||
readp -= 1; // No code in this command, undo increment
|
||||
emitTimeChange(*reinterpret_cast<const uint64_t*>(readp));
|
||||
const uint64_t timeui
|
||||
= static_cast<uint64_t>(*reinterpret_cast<const uint32_t*>(readp)) << 32ULL
|
||||
| static_cast<uint64_t>(*reinterpret_cast<const uint32_t*>(readp + 1));
|
||||
emitTimeChange(timeui);
|
||||
readp += 2;
|
||||
continue;
|
||||
|
||||
}
|
||||
case VerilatedTraceOffloadCommand::TRACE_BUFFER:
|
||||
VL_TRACE_OFFLOAD_DEBUG("Command TRACE_BUFFER " << top);
|
||||
readp -= 1; // No code in this command, undo increment
|
||||
@@ -418,7 +405,7 @@ bool VerilatedTrace<VL_SUB_T, VL_BUF_T>::declCode(uint32_t code, const std::stri
|
||||
|
||||
template <>
|
||||
std::string VerilatedTrace<VL_SUB_T, VL_BUF_T>::timeResStr() const {
|
||||
return doubleToTimescale(m_timeRes);
|
||||
return vl_timescaled_double(m_timeRes);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
@@ -574,7 +561,10 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::dump(uint64_t timeui) VL_MT_SAFE_EXCLUD
|
||||
|
||||
// Tell worker to update time point
|
||||
m_offloadBufferWritep[0] = VerilatedTraceOffloadCommand::TIME_CHANGE;
|
||||
*reinterpret_cast<uint64_t*>(m_offloadBufferWritep + 1) = timeui;
|
||||
*reinterpret_cast<uint32_t*>(m_offloadBufferWritep + 1)
|
||||
= static_cast<uint32_t>(timeui >> 32ULL);
|
||||
*reinterpret_cast<uint32_t*>(m_offloadBufferWritep + 2)
|
||||
= static_cast<uint32_t>(timeui);
|
||||
m_offloadBufferWritep += 3;
|
||||
} else {
|
||||
// Update time point
|
||||
@@ -643,12 +633,13 @@ void VerilatedTrace<VL_SUB_T, VL_BUF_T>::addModel(VerilatedModel* modelp)
|
||||
|
||||
// Validate
|
||||
if (!newModel) { // LCOV_EXCL_START
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||
"The same model has already been added to this trace file");
|
||||
VL_FATAL_MT(
|
||||
__FILE__, __LINE__, "",
|
||||
"The same model has already been added to this trace file or VerilatedContext");
|
||||
}
|
||||
if (VL_UNCOVERABLE(m_contextp && contextp != m_contextp)) {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||
"A trace file instance can only handle models from the same context");
|
||||
"A trace file instance can only handle models from the same VerilatedContext");
|
||||
}
|
||||
if (VL_UNCOVERABLE(m_didSomeDump)) {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user