mirror of
https://github.com/verilator/verilator.git
synced 2026-10-02 16:13:34 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5b2fbf4f37 | ||
|
|
592dab2bdb | ||
|
|
51daa64e9a | ||
|
|
2136afde6b | ||
|
|
ea55db7286 | ||
|
|
6a5f77b278 | ||
|
|
8658a0d7dc | ||
|
|
c335aad25f | ||
|
|
9d9d647c1f | ||
|
|
d47a37fb76 | ||
|
|
0a3a15a66e | ||
|
|
2358ced061 | ||
|
|
5869fdf7f6 | ||
|
|
1a1d2ecfd9 | ||
|
|
9ac64d0b92 | ||
|
|
c6607724cb | ||
|
|
90dc04cf93 | ||
|
|
4d81eb021d | ||
|
|
83475008d9 | ||
|
|
03ac7ad730 | ||
|
|
cd50949a7e | ||
|
|
f0040c7b9a | ||
|
|
f8a0389e73 | ||
|
|
b436794773 | ||
|
|
90d22cbec6 | ||
|
|
33e2acfe61 | ||
|
|
db5fdfb0ee | ||
|
|
951cd73fe0 | ||
|
|
0eeb40b975 | ||
|
|
93272c13fd | ||
|
|
43abaeb055 | ||
|
|
18b9e661c9 | ||
|
|
f435d96241 | ||
|
|
d32e3f042f | ||
|
|
df5f95a5bd | ||
|
|
b0c475205b | ||
|
|
1e2219347e | ||
|
|
cbe1b8e266 | ||
|
|
2b12fe5773 | ||
|
|
d20f22beb1 | ||
|
|
f4fe10844b | ||
|
|
122e89ffde | ||
|
|
96a4b3e5a5 | ||
|
|
fac8e76923 | ||
|
|
b864f5f5ba | ||
|
|
f9f66d787e | ||
|
|
bd211c87aa | ||
|
|
6c33e6e889 | ||
|
|
cfb6fd8b34 | ||
|
|
cb60663d49 | ||
|
|
0d2bf23d82 | ||
|
|
682a60e325 | ||
|
|
2ab6272cc7 | ||
|
|
152a6cd886 | ||
|
|
f91793e931 | ||
|
|
a2d26b45bb | ||
|
|
dce8f3d25d | ||
|
|
38e5b6c1ad | ||
|
|
b9d7819faa | ||
|
|
1f9323d086 | ||
|
|
574dbfded1 | ||
|
|
2a87387eb3 | ||
|
|
a5ddd10e31 | ||
|
|
e871cd8a44 | ||
|
|
7b431b37c7 | ||
|
|
eeef5ab4de | ||
|
|
ac4ec87942 | ||
|
|
290c2e0388 | ||
|
|
89924bda51 | ||
|
|
60eab3eb8c | ||
|
|
e0b61ceabd | ||
|
|
30e3edb81d | ||
|
|
542e324869 | ||
|
|
1c5e5704f5 | ||
|
|
1d400dd98c | ||
|
|
a4ed3c2086 | ||
|
|
efb5caad22 | ||
|
|
3a002b6cf2 | ||
|
|
f8b7981be4 | ||
|
|
b55ee79d86 | ||
|
|
af70db88db | ||
|
|
7ef033f876 | ||
|
|
db59c07f27 | ||
|
|
9085e34d70 | ||
|
|
0dfa7d3af5 | ||
|
|
b0e796ca83 | ||
|
|
3bd830eacf | ||
|
|
f4efcbde5c | ||
|
|
658819bb71 | ||
|
|
3fc8249429 | ||
|
|
e0a38ce2c2 | ||
|
|
178e1789b5 | ||
|
|
108c900387 | ||
|
|
63507e8e29 | ||
|
|
87f1e06c41 | ||
|
|
7e8bafd217 | ||
|
|
457ad07ade | ||
|
|
79c901c220 | ||
|
|
b61d819fcb | ||
|
|
f4038e3674 | ||
|
|
8377514127 | ||
|
|
d8ea989eda | ||
|
|
5f3316d3dc | ||
|
|
a4fddb3fbe | ||
|
|
3d71716a8a | ||
|
|
9f37cef1bb | ||
|
|
0de1bbc85b | ||
|
|
3aa8624658 | ||
|
|
42b711b862 | ||
|
|
2873dbe154 | ||
|
|
31a83cb0d8 | ||
|
|
383e384739 | ||
|
|
1bb6433649 | ||
|
|
ced39d0982 | ||
|
|
fc4d6a62af | ||
|
|
fa99cbbc73 | ||
|
|
49455721a3 | ||
|
|
11032b1936 | ||
|
|
f2fba51fe2 | ||
|
|
7c79f0d431 | ||
|
|
41b9b30b9b | ||
|
|
1fa82ffb7b | ||
|
|
4f93ac6477 | ||
|
|
f7533010c6 | ||
|
|
47b650d821 | ||
|
|
0c2c097377 | ||
|
|
d721f70690 | ||
|
|
ea8aaa21e8 | ||
|
|
660d1059b0 | ||
|
|
e7dc2de14b | ||
|
|
32100a3c91 | ||
|
|
67f7432dd7 | ||
|
|
59dc2853e3 | ||
|
|
ada58465b2 | ||
|
|
173f57c636 | ||
|
|
1f3e8640f7 | ||
|
|
6039e9dcc3 | ||
|
|
d64f979f99 | ||
|
|
0c53d19113 | ||
|
|
c64a07fd09 | ||
|
|
694919b9d1 | ||
|
|
606b35853b | ||
|
|
26b7452178 | ||
|
|
b51f887567 | ||
|
|
c4b8675d77 | ||
|
|
a7cd7a1ed9 | ||
|
|
a48c779367 | ||
|
|
cf1eccc24f | ||
|
|
d45caca011 | ||
|
|
0722f47539 | ||
|
|
a372e010bd | ||
|
|
530817191e | ||
|
|
1282548a1c | ||
|
|
c7610ed044 | ||
|
|
ffc1c51526 | ||
|
|
b130a8cfeb | ||
|
|
551bd284dd | ||
|
|
9edccfdffa | ||
|
|
1a056f6db9 | ||
|
|
e018eb7bac | ||
|
|
0a91ddf38a | ||
|
|
67bb2c640e | ||
|
|
561eaa311d | ||
|
|
3f7a248ed4 | ||
|
|
ecaa07a72a | ||
|
|
99bdc27be3 | ||
|
|
c3c46967dc | ||
|
|
7f1a9239ab | ||
|
|
c8102c8ffe | ||
|
|
5aa12e9b51 | ||
|
|
829437b20b | ||
|
|
3c4131d45d | ||
|
|
ae8d8ee1ac | ||
|
|
89ec3d16dc | ||
|
|
7602c983c5 | ||
|
|
560efb2c9e | ||
|
|
c2328ef46a | ||
|
|
f6035447ae | ||
|
|
38438b3373 | ||
|
|
71dedccbbe | ||
|
|
cddbe4642f | ||
|
|
bdfdc737a0 | ||
|
|
3d045c3aee | ||
|
|
9583f152ee | ||
|
|
5b2755d28d | ||
|
|
9378259779 | ||
|
|
3d762282b9 | ||
|
|
30783e6a79 | ||
|
|
aa86c777f4 | ||
|
|
a2792785fe | ||
|
|
267315e7d4 | ||
|
|
99d39cb6ff | ||
|
|
915ceb2d04 | ||
|
|
49c90ecbce | ||
|
|
8395004d25 | ||
|
|
5de1c619c8 | ||
|
|
a6d678d41d | ||
|
|
2b91d764b5 | ||
|
|
62337bb6ac | ||
|
|
9abab2c366 | ||
|
|
b22e368b25 | ||
|
|
a9cd2998e5 | ||
|
|
f1ea30f257 | ||
|
|
0b74e9b354 | ||
|
|
8189416d0c | ||
|
|
5f0e1fae7f | ||
|
|
880a9be3b1 | ||
|
|
7bfc1a00a7 | ||
|
|
baff64a43d | ||
|
|
b7f2bb0e80 | ||
|
|
08e0a397d3 | ||
|
|
5f333be947 | ||
|
|
f5f4e15ce2 | ||
|
|
fbd568dc47 | ||
|
|
c79ea88576 | ||
|
|
9be4e7b576 | ||
|
|
33105f017c | ||
|
|
e02f97854c | ||
|
|
960d0de361 | ||
|
|
31ce1fdfd3 | ||
|
|
9821381059 | ||
|
|
3f7bf3d2dc | ||
|
|
f9e69984ff | ||
|
|
b1b5b5dfe2 | ||
|
|
c7440b250f | ||
|
|
bab8462789 | ||
|
|
4eaa6fdd06 | ||
|
|
38b2845e2a | ||
|
|
14d24213a8 | ||
|
|
c61258c0d0 | ||
|
|
47226236f4 | ||
|
|
e744c21f56 | ||
|
|
89a0632ecc | ||
|
|
dcc05db7f1 | ||
|
|
90fb2e5487 | ||
|
|
b5ce7d5982 | ||
|
|
f211616a4c | ||
|
|
a9cb9bac21 | ||
|
|
ae005434e4 | ||
|
|
ef87d057fc | ||
|
|
181b9a5795 | ||
|
|
9baf9c55c2 | ||
|
|
e29132377e | ||
|
|
999751c422 | ||
|
|
22656d6fdd | ||
|
|
ef0c5fd772 | ||
|
|
90c61c79d6 | ||
|
|
4ba3bff87f | ||
|
|
c3dd6f5344 | ||
|
|
321880f5a6 | ||
|
|
3737d209f6 | ||
|
|
29c4b0a141 | ||
|
|
956f64c6ba | ||
|
|
c2d18d8ae4 | ||
|
|
5b9806ae6d | ||
|
|
665fa140a8 | ||
|
|
32f843a214 | ||
|
|
72a3c756ad | ||
|
|
47069dfe52 | ||
|
|
43a84d7ad8 | ||
|
|
b6ca2a42f2 | ||
|
|
e52a4ac74f | ||
|
|
decfa6bd7a | ||
|
|
8931bd37e2 | ||
|
|
4b79d23d00 | ||
|
|
77fe7c426e | ||
|
|
331c2244fc | ||
|
|
5a3eab634a | ||
|
|
77e68acf54 | ||
|
|
7a355d448a | ||
|
|
3b7ad1820d | ||
|
|
d3b63b2653 | ||
|
|
046896e60a | ||
|
|
fb9119ff49 | ||
|
|
818aaa8b89 | ||
|
|
26bdfc3474 | ||
|
|
0e91d8a10e | ||
|
|
434c3c3ef3 | ||
|
|
21e05c43dd | ||
|
|
0e154b35ef | ||
|
|
e6554e061c | ||
|
|
0f004c8e7b | ||
|
|
f5b1a5cd58 | ||
|
|
48a098b041 | ||
|
|
f8c0169e82 | ||
|
|
539c9d4c63 | ||
|
|
b4d8220cbb | ||
|
|
5eded789aa | ||
|
|
e931c6230a | ||
|
|
64a6e1ac8b | ||
|
|
50094ca296 | ||
|
|
15b32dc140 | ||
|
|
441ecfedc9 | ||
|
|
78147ee8d7 | ||
|
|
8c58612a3b | ||
|
|
56f9d244de | ||
|
|
2ba9eb4228 | ||
|
|
9a8c878f2d | ||
|
|
41a563bdc8 | ||
|
|
4e5f30858b | ||
|
|
b989ac6db5 | ||
|
|
4d1f4bbf49 | ||
|
|
e9ad665d32 | ||
|
|
78052f87bd | ||
|
|
ebf5c11e03 | ||
|
|
7e355e211c | ||
|
|
f36461e696 | ||
|
|
88d7ca01b0 | ||
|
|
2e2b82c052 | ||
|
|
f1bb0544be | ||
|
|
3b1371124e | ||
|
|
e6857df5c6 | ||
|
|
73374a0303 | ||
|
|
e334740dd6 | ||
|
|
84ee833ea7 | ||
|
|
b7ad1e6d61 | ||
|
|
340efe3a3a | ||
|
|
2342549caf | ||
|
|
028737cde8 | ||
|
|
bf972963f4 | ||
|
|
9bda91b3bf | ||
|
|
e4c5eb5e69 | ||
|
|
2e8cc22c54 | ||
|
|
655910d486 | ||
|
|
2a0ec88379 | ||
|
|
80859a609a | ||
|
|
d679d50eca | ||
|
|
65de118e51 | ||
|
|
4cd56b1fb9 | ||
|
|
f3945e7c02 | ||
|
|
5ef982b4b5 | ||
|
|
f96d336b97 | ||
|
|
a68a4fc888 | ||
|
|
0c3ffa1841 | ||
|
|
24a0d2a0c9 | ||
|
|
ca42be982c | ||
|
|
ffc31e2efa | ||
|
|
8952aa59ff | ||
|
|
2966f03042 | ||
|
|
d15e9e2b7a | ||
|
|
fd45be3def | ||
|
|
0658a7654f | ||
|
|
7526151670 | ||
|
|
560b59f97f | ||
|
|
b2ca89c185 | ||
|
|
1de2de4bde | ||
|
|
4135867e53 | ||
|
|
ff425369ac | ||
|
|
30ccccdb67 | ||
|
|
5e3016f34a | ||
|
|
f775feb7f0 | ||
|
|
0a94ea5386 | ||
|
|
aa8423ba46 | ||
|
|
d753f36ebc | ||
|
|
55976dbc25 | ||
|
|
77c005835d | ||
|
|
6b0601fd54 | ||
|
|
c1652979d5 | ||
|
|
740fee660e | ||
|
|
984ee624ed | ||
|
|
00ef0519f5 | ||
|
|
59d170c6f8 | ||
|
|
9a722ccf62 | ||
|
|
748fa4cb80 | ||
|
|
694cf371f9 | ||
|
|
8696e38e6f | ||
|
|
706162ecc6 | ||
|
|
c3f17ce2c4 | ||
|
|
41f29d2ce3 | ||
|
|
7b119a594f | ||
|
|
b7d20b102b | ||
|
|
ac05a779ae | ||
|
|
935032366f | ||
|
|
1160dddc6d | ||
|
|
293a5f402b | ||
|
|
ca09f73446 | ||
|
|
e814855357 | ||
|
|
692306ef44 | ||
|
|
ffdc0afe5f | ||
|
|
98037cad56 | ||
|
|
61e3536163 | ||
|
|
a1a186a86c | ||
|
|
04e0c7e4f1 | ||
|
|
833686446c | ||
|
|
c6dae40cf6 | ||
|
|
cd737065f2 | ||
|
|
010084201a | ||
|
|
60f7eff701 | ||
|
|
d1862e25eb | ||
|
|
b0018fd680 | ||
|
|
2742a8c813 | ||
|
|
05e12ab60e | ||
|
|
9bda2cb4ad | ||
|
|
393b9e435d | ||
|
|
e87a726989 | ||
|
|
62387a0e32 | ||
|
|
31079ca8b5 | ||
|
|
4184ad1921 | ||
|
|
e7ebe0e280 | ||
|
|
c14bbb9421 | ||
|
|
b1b92b7dd4 | ||
|
|
a14394dbb5 | ||
|
|
96b7831243 | ||
|
|
1e440765c0 | ||
|
|
2ccf49031b | ||
|
|
0abc856be9 | ||
|
|
d2a8fa7440 | ||
|
|
106d635d0f | ||
|
|
cff9f8143e | ||
|
|
cfa401e01d | ||
|
|
d6195e354f | ||
|
|
c0892dd11c | ||
|
|
899de9a282 | ||
|
|
4b593f8eb3 | ||
|
|
28b6e79cf7 | ||
|
|
fe5822ba54 | ||
|
|
c496649c49 | ||
|
|
37e3c6da70 | ||
|
|
4cb5c1e1db | ||
|
|
b7a7504ba5 | ||
|
|
3a5cbd5b67 | ||
|
|
27883b52d6 | ||
|
|
b95ee84343 | ||
|
|
185e5d8f42 | ||
|
|
987ce927eb | ||
|
|
b08c694cd6 | ||
|
|
e69a8e838d | ||
|
|
61612582e6 | ||
|
|
8b00939f0c | ||
|
|
da5644211f | ||
|
|
c1d7bfa617 | ||
|
|
c26ce25cea | ||
|
|
758264dc77 | ||
|
|
304697d133 | ||
|
|
fdbf465eda | ||
|
|
90102d9867 | ||
|
|
a1bb471aca | ||
|
|
4ef37d9411 | ||
|
|
f3b10df454 | ||
|
|
f5a226a183 | ||
|
|
5515eed0b6 | ||
|
|
381c87a1eb | ||
|
|
20e896ec21 | ||
|
|
70603bb752 | ||
|
|
7cb6dc664e | ||
|
|
dae9fa5053 | ||
|
|
aa1a0b0f13 | ||
|
|
371bf01957 | ||
|
|
ef7759a522 | ||
|
|
0ef9087f89 | ||
|
|
00059987a1 | ||
|
|
8f090176a6 | ||
|
|
43e8263d1f | ||
|
|
ac622f9db8 | ||
|
|
749a66b7a2 | ||
|
|
fc80ace6e4 | ||
|
|
b8f6b262e4 | ||
|
|
b64e89f7ed | ||
|
|
c3bec344a4 | ||
|
|
9731ec76e3 | ||
|
|
a9646cf45c | ||
|
|
5f597dd9fc | ||
|
|
7d57c3ca78 | ||
|
|
4739956cfe | ||
|
|
e202a6324a | ||
|
|
66d70c8b37 | ||
|
|
02aa639425 | ||
|
|
55da66164b | ||
|
|
2560fc867f | ||
|
|
f5c9deecb8 | ||
|
|
20af8a36a7 | ||
|
|
1c1c805b07 | ||
|
|
9029da5ab8 | ||
|
|
def7c8fe4d | ||
|
|
9184c4f501 | ||
|
|
44809f1843 | ||
|
|
87ced0cc3e | ||
|
|
741bb5328e | ||
|
|
33650336f5 | ||
|
|
bbce1dc256 | ||
|
|
8ab51dbf22 | ||
|
|
fd4595d6b4 | ||
|
|
204804ae52 | ||
|
|
c2819923c5 | ||
|
|
68f1432a68 | ||
|
|
0defb61a18 | ||
|
|
0fc805202c | ||
|
|
a7374e84a2 | ||
|
|
76681fd931 | ||
|
|
2418df7bb2 | ||
|
|
97d8d32049 | ||
|
|
08c8b0d7d6 | ||
|
|
81fd3e4732 | ||
|
|
d384a69877 | ||
|
|
a8b480559d | ||
|
|
f1b8b1d99b | ||
|
|
f67637144f | ||
|
|
4b274a8d4d | ||
|
|
c678e7ec3e | ||
|
|
2a79e46c46 | ||
|
|
d09b6a7d2c | ||
|
|
35eac0c457 | ||
|
|
cac0b0f316 | ||
|
|
8519dc1383 | ||
|
|
72f198d79e | ||
|
|
1cb8091125 | ||
|
|
18c543f2f2 | ||
|
|
496b9f9c63 | ||
|
|
1ee46ac5e1 | ||
|
|
f37c875be8 | ||
|
|
56dc66d842 | ||
|
|
7ae54ef973 | ||
|
|
4ed00c563c | ||
|
|
a49bfe871c | ||
|
|
6d97fea2f5 | ||
|
|
da833d55fe | ||
|
|
960813cb0f | ||
|
|
cd56dfee1c | ||
|
|
3e03cd5a4d | ||
|
|
cd9e9da4b5 | ||
|
|
f64d9d87f6 | ||
|
|
43aa3229fb | ||
|
|
27d53691bd | ||
|
|
959793cde3 | ||
|
|
c3d64d9743 | ||
|
|
f9806595f2 | ||
|
|
34a0bb448e | ||
|
|
8681861be9 | ||
|
|
fffc63970d | ||
|
|
8f527a0c6e | ||
|
|
c69ddc46f8 | ||
|
|
4ec8bc3589 | ||
|
|
536bdf506e | ||
|
|
d1836b7b6f | ||
|
|
00fe36f44c | ||
|
|
5adc856950 | ||
|
|
bc3e24c8cd | ||
|
|
2c8456ea75 | ||
|
|
519cc7d61c | ||
|
|
0f4daa12e4 | ||
|
|
6bad0e14ce | ||
|
|
3ec3c2c268 | ||
|
|
b8e804f05b | ||
|
|
cdeb6e792f | ||
|
|
deebfa3239 | ||
|
|
f937e3282f | ||
|
|
b46664c70a | ||
|
|
33af14eba8 | ||
|
|
18b0f6387d | ||
|
|
43ecaec9a0 | ||
|
|
275885a797 | ||
|
|
68aa731ce9 | ||
|
|
b90fce55f4 | ||
|
|
44173b40a1 | ||
|
|
ab13a2ebdc | ||
|
|
19875d2e85 | ||
|
|
1de33b9fb7 | ||
|
|
90c917ee83 | ||
|
|
4ab4c0c8ba | ||
|
|
9907d211ff | ||
|
|
13933743ad | ||
|
|
fc25721e55 | ||
|
|
fa64f8fb32 | ||
|
|
ab4063f098 | ||
|
|
8bb77f86ec | ||
|
|
42d918c163 | ||
|
|
e3dd70c373 | ||
|
|
9273fafbbf | ||
|
|
d9c893af11 | ||
|
|
a9c4a96c0f | ||
|
|
32e99ba0d9 | ||
|
|
da8930a57a | ||
|
|
1166728a8d | ||
|
|
30fa5e41be | ||
|
|
cf39331d1f | ||
|
|
bac84726e1 | ||
|
|
ddef61d62e | ||
|
|
4081a1a539 | ||
|
|
1691bbfe25 | ||
|
|
17cc452f79 | ||
|
|
8ecdc85cf7 | ||
|
|
5ad3c4e499 | ||
|
|
8073e8bb46 | ||
|
|
8a9d6d225b | ||
|
|
c7499133b2 | ||
|
|
687dd440a9 | ||
|
|
f1bb0bb725 | ||
|
|
a8168d5d62 | ||
|
|
896b18e024 | ||
|
|
766ad14ae0 | ||
|
|
add3811f46 | ||
|
|
f55177a49f | ||
|
|
bdceb08963 | ||
|
|
825d6b87a8 | ||
|
|
61e2e55ba5 | ||
|
|
e6b75f752b | ||
|
|
a4f5d95648 | ||
|
|
686baaf2cf | ||
|
|
76b3776fa3 | ||
|
|
3ed2af638b |
+21
-11
@@ -17,7 +17,7 @@ AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: false
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
BraceWrapping:
|
||||
@@ -59,15 +59,27 @@ ForEachMacros:
|
||||
- foreach
|
||||
- Q_FOREACH
|
||||
- BOOST_FOREACH
|
||||
IncludeBlocks: Preserve
|
||||
|
||||
# Include grouping/sorting
|
||||
SortIncludes: true
|
||||
IncludeBlocks: Regroup
|
||||
IncludeCategories:
|
||||
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||
Priority: 2
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
IncludeIsMainRegex: '(Test)?$'
|
||||
- Regex: '"(config_build|verilated_config|verilatedos)\.h"'
|
||||
Priority: -1 # Sepecials before main header
|
||||
- Regex: '(<|")verilated.*'
|
||||
Priority: 1 # Runtime headers
|
||||
- Regex: '"V3.*__gen.*\.h"'
|
||||
Priority: 3 # Generated internal headers separately
|
||||
- Regex: '"V3.*"'
|
||||
Priority: 2 # Internal header
|
||||
- Regex: '".*"'
|
||||
Priority: 4 # Other non-system headers
|
||||
- Regex: '<[[:alnum:]_.]+>'
|
||||
Priority: 5 # Simple system headers next
|
||||
- Regex: '<.*>'
|
||||
Priority: 6 # Other system headers next
|
||||
IncludeIsMainRegex: '$'
|
||||
|
||||
IndentCaseLabels: false
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 4
|
||||
@@ -91,7 +103,6 @@ PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 60
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: false
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
@@ -108,4 +119,3 @@ Standard: Cpp11
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
...
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Something isn't working as expected, and it isn't "Unsupported." (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.rst)
|
||||
about: Use this to report that something isn't working as expected, and it isn't "Unsupported." (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.rst)
|
||||
title: ''
|
||||
labels: new
|
||||
assignees: ''
|
||||
@@ -13,4 +13,6 @@ Can you attach an example that shows the issue? (Must be openly licensed, ideal
|
||||
|
||||
What 'verilator --version' are you using? Did you try it with the git master version?
|
||||
|
||||
Would you be willing to try to fix Verilator yourself with assistance?
|
||||
What OS and distribution are you using?
|
||||
|
||||
May we assist you in trying to fix this in Verilator yourself?
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Feature Request
|
||||
about: Request something should be supported, or a new feature added. (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.rst)
|
||||
about: Use this to request something should be supported, or a new feature added. (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.rst)
|
||||
title: ''
|
||||
labels: new
|
||||
assignees: ''
|
||||
@@ -13,4 +13,4 @@ What would you like added/supported?
|
||||
|
||||
Can you attach an example that runs on other simulators? (Must be openly licensed, ideally in test_regress format.)
|
||||
|
||||
May we assist you in trying to fix this yourself?
|
||||
May we assist you in trying to fix this in Verilator yourself?
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Q and A, or Other
|
||||
about: Ask a question, not related to a specific bug or feature request. (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.rst)
|
||||
about: Use this to ask a question, not related to a specific bug nor feature request. (Note our contributor agreement at https://github.com/verilator/verilator/blob/master/docs/CONTRIBUTING.rst)
|
||||
title: ''
|
||||
labels: new
|
||||
assignees: ''
|
||||
|
||||
@@ -29,7 +29,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04, ubuntu-18.04, ubuntu-16.04]
|
||||
os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04]
|
||||
compiler:
|
||||
- { cc: clang, cxx: clang++ }
|
||||
- { cc: gcc, cxx: g++ }
|
||||
@@ -37,11 +37,16 @@ jobs:
|
||||
exclude:
|
||||
# Build pull requests only with ubuntu-20.04 and without m32
|
||||
- os: ${{ github.event_name == 'pull_request' && 'ubuntu-18.04' || 'do-not-exclude' }}
|
||||
- os: ${{ github.event_name == 'pull_request' && 'ubuntu-16.04' || 'do-not-exclude' }}
|
||||
- os: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'do-not-exclude' }}
|
||||
- m32: ${{ github.event_name == 'pull_request' && 1 || 'do-not-exclude' }}
|
||||
# Build -m32 only on ubuntu-20.04
|
||||
- {os: ubuntu-18.04, m32: 1}
|
||||
- {os: ubuntu-16.04, m32: 1}
|
||||
- {os: ubuntu-22.04, m32: 1}
|
||||
include:
|
||||
# Build GCC 10 on ubuntu-20.04
|
||||
- os: ubuntu-20.04
|
||||
compiler: { cc: gcc-10, cxx: g++-10 }
|
||||
m32: 0
|
||||
runs-on: ${{ matrix.os }}
|
||||
name: Build | ${{ matrix.os }} | ${{ matrix.compiler.cc }} ${{ matrix.m32 && '| -m32' || '' }}
|
||||
env:
|
||||
@@ -92,7 +97,7 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-20.04, ubuntu-18.04, ubuntu-16.04]
|
||||
os: [ubuntu-22.04, ubuntu-20.04, ubuntu-18.04]
|
||||
compiler:
|
||||
- { cc: clang, cxx: clang++ }
|
||||
- { cc: gcc, cxx: g++ }
|
||||
@@ -101,11 +106,18 @@ jobs:
|
||||
exclude:
|
||||
# Build pull requests only with ubuntu-20.04 and without m32
|
||||
- os: ${{ github.event_name == 'pull_request' && 'ubuntu-18.04' || 'do-not-exclude' }}
|
||||
- os: ${{ github.event_name == 'pull_request' && 'ubuntu-16.04' || 'do-not-exclude' }}
|
||||
- os: ${{ github.event_name == 'pull_request' && 'ubuntu-22.04' || 'do-not-exclude' }}
|
||||
- m32: ${{ github.event_name == 'pull_request' && 1 || 'do-not-exclude' }}
|
||||
# Build -m32 only on ubuntu-20.04
|
||||
- {os: ubuntu-18.04, m32: 1}
|
||||
- {os: ubuntu-16.04, m32: 1}
|
||||
- {os: ubuntu-22.04, m32: 1}
|
||||
include:
|
||||
# Test with GCC 10 on ubuntu-20.04 without m32
|
||||
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, m32: 0, suite: dist-vlt-0}
|
||||
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, m32: 0, suite: dist-vlt-1}
|
||||
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, m32: 0, suite: dist-vlt-2}
|
||||
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, m32: 0, suite: vltmt-0}
|
||||
- {os: ubuntu-20.04, compiler: { cc: gcc-10, cxx: g++-10 }, m32: 0, suite: vltmt-1}
|
||||
runs-on: ${{ matrix.os }}
|
||||
name: Test | ${{ matrix.os }} | ${{ matrix.compiler.cc }} | ${{ matrix.suite }} ${{ matrix.m32 && '| -m32' || '' }}
|
||||
env:
|
||||
@@ -114,7 +126,7 @@ jobs:
|
||||
CI_M32: ${{ matrix.m32 }}
|
||||
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 }}-m32=${{ matrix.m32 }}-${{ matrix.suite }}
|
||||
CCACHE_MAXSIZE: 64M # Per build matrix entry (2160M in total)
|
||||
VERILATOR_ARCHIVE: verilator-${{ github.sha }}-${{ matrix.os }}-${{ matrix.compiler.cc }}${{ matrix.m32 && '-m32' || '' }}.tar.gz
|
||||
steps:
|
||||
|
||||
@@ -39,3 +39,4 @@ verilator-config-version.cmake
|
||||
**/__pycache__/*
|
||||
**/_build/*
|
||||
**/obj_dir/*
|
||||
/.vscode/
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
set noparent
|
||||
linelength=100
|
||||
filter=-build/c++11
|
||||
filter=-build/header_guard
|
||||
filter=-build/include_order
|
||||
filter=-build/include_subdir
|
||||
filter=-readability/inheritance
|
||||
filter=-readability/nolint
|
||||
filter=-readability/todo
|
||||
filter=-runtime/references
|
||||
filter=-whitespace/blank_line
|
||||
filter=-whitespace/empty_if_body
|
||||
filter=-whitespace/indent
|
||||
filter=-whitespace/newline
|
||||
filter=-whitespace/braces
|
||||
filter=-whitespace/parens
|
||||
filter=-whitespace/todo
|
||||
@@ -8,6 +8,242 @@ The changes in each Verilator version are described below. The
|
||||
contributors that suggested a given feature are shown in []. Thanks!
|
||||
|
||||
|
||||
Verilator 4.226 2022-08-31
|
||||
==========================
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Add --future0 and --future1 options.
|
||||
* Support class parameters (#2231) (#3541). [Arkadiusz Kozdra/Antmicro]
|
||||
* Support wildcard index associative arrays (#3501). [Arkadiusz Kozdra/Antmicro]
|
||||
* Support negated properties (#3572). [Aleksander Kiryk]
|
||||
* Support $test$plusargs(expr) (#3489).
|
||||
* Rename trace rolloverSize() (#3570).
|
||||
* Improve Verilation speed with --threads on large designs. [Geza Lore]
|
||||
* Fix struct pattern assignment (#2328) (#3517). [Mostafa Gamal]
|
||||
* Fix public combo propagation issues (#2905). [Todd Strader]
|
||||
* Fix incorrect tristate logic (#3399) [shareefj, Vighnesh Iyer]
|
||||
* Fix incorrect bit op tree optimization (#3470). [algrobman]
|
||||
* Fix bisonpre for MSYS2 (#3471).
|
||||
* Fix max memory usage (#3483). [Kamil Rakoczy]
|
||||
* Fix empty string arguments to display (#3484). [Grulfen]
|
||||
* Fix table misoptimizing away display (#3488). [Stefan Post]
|
||||
* Fix unique_ptr memory header for MinGW64 (#3493).
|
||||
* Fix $dump systemtask with --output-split-cfuncs (#3495) (#3497). [Varun Koyyalagunta]
|
||||
* Fix wrong bit op tree optimization (#3509). [Nathan Graybeal]
|
||||
* Fix nested default assignment for struct pattern (#3511) (#3524). [Mostafa Gamal]
|
||||
* Fix sformat string incorrectly cleared (#3515) (#3519). [Gustav Svensk]
|
||||
* Fix segfault exporting non-existant package (#3535).
|
||||
* Fix void-cast queue pop_front or pop_back (#3542) (#3364). [Drew Ranck]
|
||||
* Fix case statement comparing string literal (#3544). [Gustav Svensk]
|
||||
* Fix === with some tristate constants (#3551). [Ryszard Rozak]
|
||||
* Fix converting subclasses to string (#3552). [Arkadiusz Kozdra/Antmicro]
|
||||
* Fix --hierarchical with order-based pin connections (#3583) (#3585). [Kelin9298]
|
||||
|
||||
|
||||
Verilator 4.224 2022-06-19
|
||||
==========================
|
||||
|
||||
**Major:**
|
||||
|
||||
* VCD tracing is now parallelized with --threads (#3449). [Geza Lore, Shunyao CAD]
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Add -f<optimization> options to replace -O<letter> options (#3436).
|
||||
* Changed --no-merge-const-pool to -fno-merge-const-pool (#3436).
|
||||
* Changed --no-decoration to remove output whitespace (#3460). [Kamil Rakoczy]
|
||||
* Support compile time trace signal selection with tracing_on/off (#3323). [Shunyao CAD]
|
||||
* Support non-ANSI interface port declarations (#3439). [Geza Lore, Shunyao CAD]
|
||||
* Support concat assignment to packed array (#3446).
|
||||
* Improve conditional merging optimization (#3125). [Geza Lore, Shunyao CAD]
|
||||
* Define VM_TRACE_VCD when tracing in VCD format. [Geza Lore, Shunyao CAD]
|
||||
* Add assert when VerilatedContext is mis-deleted (#3121). [Rupert Swarbrick]
|
||||
* Internal prep work towards timing control. [Krzysztof Bieganski/Antmicro]
|
||||
* Fix hang with large case statement optimization (#3405). [Mike Urbach]
|
||||
* Fix UNOPTFLAT warning from initial static var (#3406). [Kamil Rakoczy]
|
||||
* Fix compile error when enable VL_LEAK_CHECKS (#3411). [HungMingWu]
|
||||
* Fix cmake rules to support higher-level targets (#3377) (#3386). [Martin Stadler]
|
||||
* Fix BLKANDNBLK on $readmem/$writemem (#3379). [Alex Solomatnikov]
|
||||
* Fix 'with' operator with type casting (#3387). [xiak95]
|
||||
* Fix incorrect conditional merging (#3409). [Raynard Qiao]
|
||||
* Fix passing VL_TRACE_FST_WRITER_THREAD in CMake build. [Geza Lore, Shunyao CAD]
|
||||
* Fix compile error under strict C++11 mode (#3463). [Kevin Kiningham]
|
||||
* Fix public unpacked input ports (#3465). [Todd Strader]
|
||||
|
||||
|
||||
Verilator 4.222 2022-05-02
|
||||
==========================
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Split --prof-threads into --prof-exec and --prof-pgo (#3365). [Geza Lore, Shunyao CAD]
|
||||
* Deprecate 'vluint64_t' and similar types (#3255).
|
||||
* Raise error on assignment to const in initial blocks. [Geza Lore, Shunyao CAD]
|
||||
* Issue INITIALDLY/COMBDLY/BLKSEQ warnings consistent with Verilator execution. [Geza Lore, Shunyao CAD]
|
||||
* Support LoongArch ISA multithreading (#3353) (#3354). [Xi Zhang]
|
||||
* Fix MSVC localtime_s (#3124).
|
||||
* Fix Bison 3.8.2 error (#3366). [elike-ypq]
|
||||
* Fix rare bug in -Oz (V3Localize) (#3286). [Geza Lore, Shunyao CAD]
|
||||
* Fix tracing interfaces inside interfaces (#3309). [Kevin Millis]
|
||||
* Fix filenames with dots overwriting debug .vpp files (#3373).
|
||||
* Fix including VK_USER_OBJS in make library (#3370) (#3382). [Julien Margetts]
|
||||
* Fix hang in generate symbol references (#3391) (#3398). [Yoda Lee]
|
||||
* Fix missing #include <memory> (#3392). [Aliaksei Chapyzhenka]
|
||||
* Fix crash in recursive module inlining (#3393). [david-sawatzke]
|
||||
* Fix --protect-ids mangling names of library methods. [Geza Lore, Shunyao CAD]
|
||||
* Fix foreach segmentation fault (#3400). [Kamil Rakoczy]
|
||||
|
||||
|
||||
Verilator 4.220 2022-03-12
|
||||
==========================
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Removed the deprecated lint_off flag -msg; use -rule instead.
|
||||
* Removed the deprecated "fl" attribute in XML output; use "loc" attribute instead.
|
||||
* Suppress WIDTH warning on negate using carry bit (#3295). [Peter Monsson]
|
||||
* Add trace dumpvars() call for selective runtime tracing (#3322). [Shunyao CAD]
|
||||
* Add VERILATOR_VERSION_INTEGER for determining API (#3343). [Larry Doolittle]
|
||||
* Improve various V3Combine algorithm details (#3328). [Yutetsu TAKATSUKASA]
|
||||
* Improve various V3Order algorithm details. [Geza Lore]
|
||||
* Fix MacOS arm64 build (#3285) (#3291). [Guokai Chen]
|
||||
* Fix signed number operation (#3294) (#3308). [Raynard Qiao]
|
||||
* Fix FST traces to include vector range (#3296) (#3297). [Jamie Iles]
|
||||
* Fix skipping public enum values with four-state values (#3303).
|
||||
* Fix $readmem file not found to be warning not error (#3310). [Alexander Grobman]
|
||||
* Fix class stringification on wide arrays (#3312). [Iru Cai]
|
||||
* Fix $fscanf etc to return -1 on EOF (#3313). [Jose Tejada]
|
||||
* Fix public function arguments that are arrayed (#3316). [pawel256]
|
||||
* Fix unnamedblk error on foreach (#3321). [Aliaksei Chapyzhenka]
|
||||
* Fix crash in recursive module inlining (#3324). [Larry Doolittle]
|
||||
* Fix VL_RESTORER behavior on passing a lvalue reference (#3326). [HungMingWu]
|
||||
* Fix compile error with --trace-fst --sc (#3332). [leavinel]
|
||||
* Fix cast to array types (#3333). [Todd Strader]
|
||||
* Fix Vdeeptemp error with --threads and --compiler clang (#3338). [Per Karlsson]
|
||||
|
||||
|
||||
Verilator 4.218 2022-01-17
|
||||
==========================
|
||||
|
||||
**Major:**
|
||||
|
||||
* Primary inputs and outputs (VL_INW/VL_OUTW) now use VlWide type.
|
||||
In general this should be backward compatible, but may lead to some
|
||||
wrapper code needing changes.
|
||||
* Option --cdc is deprecated and is planned for removal,
|
||||
file a bug if this is still being used.
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Support class static members (#2233).
|
||||
* Support force/release (#2431) (#2593). [Shunyao CAD]
|
||||
* Add 'forceable' attribute to allow forcing from C++. (#3272). [Geza Lore, Shunyao CAD]
|
||||
* Support lower dimension looping in foreach loops (#3172). [Ehab Ibrahim]
|
||||
* Support up to 64 bit enums for .next/.prev/.name (#3244). [Alexander Grobman]
|
||||
* Reduce .rodata footprint of trace initialization (#3250). [Geza Lore, Shunyao CAD]
|
||||
* Support FST tracing in hierarchical Verilation (#3251). [Yutetsu TAKATSUKASA]
|
||||
* Use C++11 standard types for MacOS portability (#3254) (#3257). [Adrien Le Masle]
|
||||
* Fix make support for BSD ar (#2999) (#3256). [Julie Schwartz]
|
||||
* Fix bad ending address on $readmem (#3205). [Julie Schwartz]
|
||||
* Fix MSWIN compile error (#2681). [Unai Martinez-Corral]
|
||||
* Fix break under foreach loop (#3230).
|
||||
* Fix VL_STREAML_FAST_QQI with 64 bit left-hand-side (#3232) (#3235). [Adrien Le Masle]
|
||||
* Fix $sformat of inputs/outputs (#3236). [Adrien Le Masle]
|
||||
* Fix associative array first method as statement (#3228). [Adrien Le Masle]
|
||||
* Fix associative array foreach loop (#3229).
|
||||
* Fix $fclose not accepting expressions (#3237). [Julie Schwartz]
|
||||
* Fix $random not updating seed (#3238). [Julie Schwartz]
|
||||
* Fix top level param overwrite when package has same param (#3241) (#3247). [Adrien Le Masle]
|
||||
* Fix spurious UNUSED by ignoring inout pin connections (#3242). [Julie Schwartz]
|
||||
* Fix splitting of _eval and other top level functions. [Geza Lore, Shunyao CAD]
|
||||
* Fix internal error by inout port (#3258). [Yutetsu TAKATSUKASA]
|
||||
* Fix GCC 11 compile error (#3273). [HungMingWu]
|
||||
|
||||
|
||||
Verilator 4.216 2021-12-05
|
||||
==========================
|
||||
|
||||
**Major:**
|
||||
|
||||
* Add --lib-create, similar to --protect-lib but without protections.
|
||||
* Support tracing through --hierarchical/--lib-create libraries (#3200).
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Internal code cleanups and improvements. [Geza Lore]
|
||||
* Improve --thread Verilation-time performance.
|
||||
* Support task name in $display %m (#3211). [Julie Schwartz]
|
||||
* Make 'bit', 'logic' and 'time' types unsigned by default. [Geza Lore]
|
||||
* Optimize $random concatenates/selects (#3114).
|
||||
* Fix array method names with parenthesis (#3181) (#3183). [Teng Huang]
|
||||
* Fix split_var assign merging (#3177) (#3179). [Yutetsu TAKATSUKASA]
|
||||
* Fix wrong bit op tree optimization (#3185). [Yutetsu TAKATSUKASA]
|
||||
* Fix some SliceSels not being constants (#3186) (#3218). [Michaël Lefebvre]
|
||||
* Fix nested generate if genblk naming (#3189). [yanx21]
|
||||
* Fix hang on recursive definition error (#3199). [Jonathan Kimmitt]
|
||||
* Fix display of signed without format (#3204). [Julie Schwartz]
|
||||
* Fix display of empty string constant (#3207) (#3215). [Julie Schwartz]
|
||||
* Fix incorrect width after and-or optimization (#3208). [Julie Schwartz]
|
||||
* Fix $fopen etc on integer arrays (#3214). [adrienlemasle]
|
||||
* Fix $size on dynamic strings (#3216).
|
||||
* Fix %0 format on $value$plusargs (#3217).
|
||||
* Fix timescale portability on Arm64 (#3222).
|
||||
|
||||
|
||||
Verilator 4.214 2021-10-17
|
||||
==========================
|
||||
|
||||
**Major:**
|
||||
|
||||
* Add profile-guided optimization of mtasks (#3150).
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Verilator_gantt has removed the ASCII graphics, use the VCD output instead.
|
||||
* Verilator_gantt now shows the predicted mtask times, eval times, and additional statistics.
|
||||
* Verilator_gantt data files now include processor information, to allow later processing.
|
||||
* Support displaying x and z in $display task (#3107) (#3109). [Iru Cai]
|
||||
* Fix verilator_profcfunc profile accounting (#3115).
|
||||
* Fix display has no time units on class function (#3116). [Damien Pretet]
|
||||
* Fix removing if statement with side effect in condition (#3131). [Alexander Grobman]
|
||||
* Fix --waiver-output for multiline warnings (#2429) (#3141). [Keith Colbert]
|
||||
* Fix internal error on bad widths (#3140) (#3145). [Zhanglei Wang]
|
||||
* Fix crash on clang 12/13 (#3148). [Kouping Hsu]
|
||||
* Fix cygwin compile error due to missing -std=gnu++14 (#3149). [Sun Kim]
|
||||
* Fix $urandom_range when the range is 0 ... UINT_MAX (#3161). [Iru Cai]
|
||||
* Fix constructor-parameter argument comma-separation in C++ (#3162). [Matthew Ballance]
|
||||
* Fix missing install of vl_file_copy/vl_hier_graph (#3165). [Popolon]
|
||||
* Fix calling new with arguments in same class (#3166). [Matthew Ballance]
|
||||
* Fix false EOFNEWLINE warning when DOS carriage returns present (#3171).
|
||||
|
||||
|
||||
Verilator 4.212 2021-09-01
|
||||
==========================
|
||||
|
||||
**Minor:**
|
||||
|
||||
* Fix re-evaluation of logic dependent on state set in DPI exports (#3091). [Geza Lore]
|
||||
* Support unpacked array localparams in tasks/functions (#3078). [Geza Lore]
|
||||
* Support timeunit/timeprecision in $unit.
|
||||
* Support assignment patterns as children of pins (#3041). [Krzysztof Bieganski/Antmicro]
|
||||
* Add --instr-count-dpi to tune assumed DPI import cost for multithreaded
|
||||
model scheduling. Default value changed to 200 (#3068). [Yinan Xu]
|
||||
* Output files are split based on the set of headers required
|
||||
in order to aid incremental compilation via ccache (#3071). [Geza Lore]
|
||||
* Parameter values are now emitted as 'static constexpr' instead of enum.
|
||||
C++ direct references to parameters might require updating (#3077). [Geza Lore]
|
||||
* Refactored Verilated include files; include verilated.h not verilated_heavy.h.
|
||||
* Add header guards on Dpi.h generated files (#2979). [Tood Strader]
|
||||
* Add XML ccall, constpool, initarray, and if/while begins (#3080). [Steven Hugg]
|
||||
* Add error when constant function under a generate (#3103). [Don Owen]
|
||||
* Fix -G to treat simple integer literals as signed (#3060). [Anikin1610]
|
||||
* Fix emitted string array initializers (#2895). [Iztok Jeras]
|
||||
* Fix bitop tree optimization dropping necessary & operator (#3096). [Flavien Solt]
|
||||
* Fix internal error on wide -x-initial unique (#3106). [Alexandre Joannou]
|
||||
* Fix traces to show array instances with brackets (#3092) (#3095). [Pieter Kapsenberg]
|
||||
|
||||
|
||||
Verilator 4.210 2021-07-07
|
||||
==========================
|
||||
|
||||
@@ -26,7 +262,7 @@ Verilator 4.210 2021-07-07
|
||||
|
||||
* Add --prof-c to pass profiling to compiler (#3059). [Alexander Grobman]
|
||||
* Optimize a lot more model variables into function locals (#3027). [Geza Lore]
|
||||
* Support middle-of-design nested topmodules (#3026). [Dan Petrisko]
|
||||
* Support middle-of-design nested top modules (#3026). [Dan Petrisko]
|
||||
* Remove deprecated --no-relative-cfuncs option (#3024). [Geza Lore]
|
||||
* Remove deprecated --inhibit-sim option (#3035). [Geza Lore]
|
||||
* Merge const static data globally into a new constant pool (#3013). [Geza Lore]
|
||||
@@ -55,7 +291,7 @@ Verilator 4.204 2021-06-12
|
||||
* Prep work towards better ccache hashing/performance. [Geza Lore]
|
||||
* Fix assertion failure in bitOpTree optimization (#2891) (#2899). [Raynard Qiao]
|
||||
* Fix DPI functions not seen as vpiModule (#2893). [Todd Strader]
|
||||
* Fix bounds check in VL_SEL_IWII (#2910). [Krzysztof Bieganski]
|
||||
* Fix bounds check in VL_SEL_IWII (#2910). [Krzysztof Bieganski/Antmicro]
|
||||
* Fix slowdown in elaboration (#2911). [Nathan Graybeal]
|
||||
* Fix initialization of assoc in assoc array (#2914). [myftptoyman]
|
||||
* Fix make support for gmake 3.x (#2920) (#2921). [Philipp Wagner]
|
||||
@@ -65,10 +301,10 @@ Verilator 4.204 2021-06-12
|
||||
* Fix to emit 'else if' without nesting (#2944). [Geza Lore]
|
||||
* Fix part select issues in LATCH warning (#2948) (#2938). [Julien Margetts]
|
||||
* Fix to not emit empty files with low split limits (#2961). [Geza Lore]
|
||||
* Fix merging of assignments in C++ code (#2970). [Ruper Swarbrick]
|
||||
* Fix merging of assignments in C++ code (#2970). [Rupert Swarbrick]
|
||||
* Fix unused variable warnings (#2991). [Pieter Kapsenberg]
|
||||
* Fix --protect-ids when using SV classes (#2994). [Geza Lore]
|
||||
* Fix constant function calls with uninit value (#2995). [yanx21]
|
||||
* Fix constant function calls with uninitialized value (#2995). [yanx21]
|
||||
* Fix Makefiles to support Windows EXEEXT usage (#3008). [Miodrag Milanovic]
|
||||
|
||||
|
||||
@@ -106,7 +342,7 @@ Verilator 4.202 2021-04-24
|
||||
* Fix Cygwin example compile issues (#2856). [Mark Shaw]
|
||||
* Fix select of with index variable (#2880). [Alexander Grobman]
|
||||
* Fix cmake version number to be numeric (#2881). [Yuri Victorovich]
|
||||
* Fix MinGW not supportting 'localtime_r' (#2882). [HyungKi Jeong]
|
||||
* Fix MinGW not supporting 'localtime_r' (#2882). [HyungKi Jeong]
|
||||
* Fix cast from packed, typedef'ed interface signal (#2884). [Todd Strader]
|
||||
* Fix VPI package reported as vpiModule (#2885). [Todd Strader]
|
||||
* Fix dumping waveforms to multiple FST files (#2889). [David Metz]
|
||||
@@ -170,7 +406,7 @@ Verilator 4.108 2021-01-10
|
||||
**Major:**
|
||||
|
||||
* Many VPI changes for IEEE compatibility, which may alter behavior from previous releases.
|
||||
* Support randomize() class method and rand (#2607). [Krzysztof Bieganski]
|
||||
* Support randomize() class method and rand (#2607). [Krzysztof Bieganski/Antmicro]
|
||||
|
||||
**Minor:**
|
||||
|
||||
@@ -230,7 +466,7 @@ Verilator 4.104 2020-11-14
|
||||
* Support queue and associative array 'with' statements (#2616).
|
||||
* Support queue slicing (#2326).
|
||||
* Support associative array pattern assignments and defaults.
|
||||
* Support static methods and typedefs in classes (#2615). [Krzysztof Bieganski]
|
||||
* Support static methods and typedefs in classes (#2615). [Krzysztof Bieganski/Antmicro]
|
||||
* Add error on typedef referencing self (#2539). [Cody Piersall]
|
||||
* With --debug, turn off address space layout randomization.
|
||||
* Fix iteration over mutating list bug in VPI (#2588). [Kaleb Barrett]
|
||||
@@ -253,7 +489,7 @@ Verilator 4.102 2020-10-15
|
||||
* Support # as a comment in -f files (#2497). [phantom-killua]
|
||||
* Support 'this' (#2585). [Rafal Kapuscik]
|
||||
* Support defines for FST tracing (#2592). [Markus Krause]
|
||||
* Support non-overapping implication inside properties (#1292). [Peter Monsson]
|
||||
* Support non-overlapping implication inside properties (#1292). [Peter Monsson]
|
||||
* Fix timescale with --hierarchical (#2554). [Yutetsu TAKATSUKASA]
|
||||
* Fix cmake build with --hierarchical (#2560). [Yutetsu TAKATSUKASA]
|
||||
* Fix -G dropping public indication (#2561). [Andrew Goessling]
|
||||
@@ -279,7 +515,7 @@ Verilator 4.100 2020-09-07
|
||||
* Support (with limitations) class extern, class extends, virtual class.
|
||||
* Support $urandom, $urandom_range without stability.
|
||||
* Support assume property. [Peter Monsson]
|
||||
* Support non-overapping implication inside properties (#1292). [Peter Monsson]
|
||||
* Support non-overlapping implication inside properties (#1292). [Peter Monsson]
|
||||
* Fix false DECLFILENAME on black-boxed modules (#2430). [Philipp Wagner]
|
||||
* Fix naming of "id : begin" blocks.
|
||||
* Fix class constructor error on assignments to const.
|
||||
@@ -3679,7 +3915,7 @@ Verilator 0.0 1994-07-08
|
||||
Copyright
|
||||
=========
|
||||
|
||||
Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
||||
Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
\.ccache/
|
||||
\.clang-format
|
||||
\.clang-tidy
|
||||
\.git/
|
||||
\.git$
|
||||
\.github/
|
||||
\.svn/
|
||||
\.(bak|old)/
|
||||
\.(bak|old)$
|
||||
\.tar\.
|
||||
.*\.tgz
|
||||
.*\.log
|
||||
\..*\.swp
|
||||
.*\.tmp
|
||||
.*\.tidy
|
||||
.*\.tex
|
||||
.*\.key
|
||||
.*\.vcd
|
||||
.*\.1
|
||||
\.codacy\.yml
|
||||
\.travis\.yml
|
||||
/_build/
|
||||
/build/
|
||||
/obj_dbg/
|
||||
/obj_dir/
|
||||
/obj_dist/
|
||||
/obj_iv/
|
||||
/obj_ms/
|
||||
/obj_nc/
|
||||
/obj_opt/
|
||||
/obj_vcs/
|
||||
/obj_vlt/
|
||||
/obj_vltmt/
|
||||
INCA_libs/
|
||||
/cov_work/
|
||||
/logs/
|
||||
^Makefile$
|
||||
README.html
|
||||
bin/verilator_bin.*
|
||||
bin/verilator_coverage_bin.*
|
||||
docs/.*\.html$
|
||||
docs/_build/
|
||||
docs/clang-format.txt$
|
||||
docs/doxygen-doc/.*
|
||||
docs/spelling.txt
|
||||
examples/xml_py/copied/
|
||||
examples/xml_py/graph.*
|
||||
sonar-project.properties
|
||||
src/Makefile$
|
||||
src/Makefile_obj$
|
||||
include/verilated.mk$
|
||||
test_regress/.gdbinit$
|
||||
test_regress/transcript
|
||||
codecov.yml
|
||||
config.cache$
|
||||
config.status$
|
||||
verilator\.log
|
||||
verilator\.tex
|
||||
verilator-config.cmake$
|
||||
verilator-config-version.cmake$
|
||||
verilator.pc$
|
||||
verilator_bin.*
|
||||
verilator_coverage_bin.*
|
||||
.vcsmx_rebuild$
|
||||
ncverilog.history
|
||||
autom4te\.cache/
|
||||
nodist/
|
||||
ci/
|
||||
/simv$
|
||||
/simv.daidir/
|
||||
/vc_hdrs.h$
|
||||
/csrc/
|
||||
obj_dir.*
|
||||
TAGS
|
||||
gmon.out
|
||||
.*~
|
||||
+17
-170
@@ -7,7 +7,7 @@
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
# Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
@@ -118,98 +118,6 @@ INFOS = verilator.html verilator.pdf
|
||||
|
||||
INFOS_OLD = README README.html README.pdf
|
||||
|
||||
# Files that can be generated, but should be up to date for a distribution.
|
||||
DISTDEP = info Makefile
|
||||
|
||||
DISTFILES1 = $(INFOS) .gitignore \
|
||||
*.in *.ac \
|
||||
Artistic \
|
||||
Changes \
|
||||
LICENSE \
|
||||
MANIFEST.SKIP \
|
||||
README.rst \
|
||||
verilator-config.cmake.in \
|
||||
verilator-config-version.cmake.in \
|
||||
bin/verilator \
|
||||
bin/verilator_ccache_report \
|
||||
bin/verilator_coverage \
|
||||
bin/verilator_difftree \
|
||||
bin/verilator_gantt \
|
||||
bin/verilator_includer \
|
||||
bin/verilator_profcfunc \
|
||||
docs/.gitignore \
|
||||
docs/CONTRIBUTING.rst \
|
||||
docs/CONTRIBUTORS \
|
||||
docs/Makefile \
|
||||
docs/_static/*.png \
|
||||
docs/_static/css/* \
|
||||
docs/bin/* \
|
||||
docs/gen/* \
|
||||
docs/guide/*.py \
|
||||
docs/guide/*.rst \
|
||||
docs/guide/figures/* \
|
||||
docs/install.rst \
|
||||
docs/internals.rst \
|
||||
docs/internals.rst \
|
||||
docs/verilated.dox \
|
||||
docs/xml.rst \
|
||||
install-sh configure *.pod \
|
||||
include/*.[chv]* \
|
||||
include/*.in \
|
||||
include/.*ignore \
|
||||
include/gtkwave/*.[chv]* \
|
||||
include/vltstd/*.[chv]* \
|
||||
.*attributes */.*attributes */*/.*attributes \
|
||||
src/.*ignore src/*.in src/*.cpp src/*.[chly] \
|
||||
src/astgen src/bisonpre src/*fix src/cppcheck_filtered \
|
||||
src/config_rev \
|
||||
src/vlcovgen src/mkinstalldirs \
|
||||
src/.gdbinit \
|
||||
src/*.pl src/*.pod \
|
||||
examples/*/.*ignore examples/*/Makefile* \
|
||||
examples/*/*.[chv]* examples/*/vl_* \
|
||||
examples/*/CMakeLists.txt \
|
||||
|
||||
DISTFILES2 = \
|
||||
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
|
||||
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \
|
||||
test_regress/*.pl \
|
||||
test_regress/Makefile \
|
||||
test_regress/Makefile_obj \
|
||||
test_regress/input.vc \
|
||||
test_regress/CMakeLists.txt \
|
||||
test_regress/t/t*/*.sv* \
|
||||
test_regress/t/t*/*.v* \
|
||||
test_regress/t/t*/*/*.sv* \
|
||||
test_regress/t/t*/*/*.v* \
|
||||
test_regress/t/t*/*.cpp \
|
||||
test_regress/t/t*/CMakeLists.txt \
|
||||
test_regress/t/*.cpp \
|
||||
test_regress/t/*.h \
|
||||
test_regress/t/*.dat \
|
||||
test_regress/t/*.mem \
|
||||
test_regress/t/*.out \
|
||||
test_regress/t/*.pl \
|
||||
test_regress/t/*.pf \
|
||||
test_regress/t/*.v* \
|
||||
|
||||
INST_PROJ_FILES = \
|
||||
bin/verilator \
|
||||
bin/verilator_ccache_report \
|
||||
bin/verilator_coverage \
|
||||
bin/verilator_gantt \
|
||||
bin/verilator_includer \
|
||||
bin/verilator_profcfunc \
|
||||
include/verilated.mk \
|
||||
include/*.[chv]* \
|
||||
include/gtkwave/*.[chv]* \
|
||||
include/vltstd/*.[chv]* \
|
||||
|
||||
INST_PROJ_BIN_FILES = \
|
||||
bin/verilator_bin$(EXEEXT) \
|
||||
bin/verilator_bin_dbg$(EXEEXT) \
|
||||
bin/verilator_coverage_bin_dbg$(EXEEXT) \
|
||||
|
||||
EXAMPLES_FIRST = \
|
||||
examples/make_hello_c \
|
||||
examples/make_hello_sc \
|
||||
@@ -217,7 +125,7 @@ EXAMPLES_FIRST = \
|
||||
EXAMPLES = $(EXAMPLES_FIRST) $(filter-out $(EXAMPLES_FIRST), $(sort $(wildcard examples/*)))
|
||||
|
||||
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
|
||||
VL_INST_MAN_FILES = verilator.1 verilator_coverage.1 verilator_gantt.1 verilator_profcfunc.1
|
||||
VL_INST_MAN_FILES = verilator.1 verilator_coverage.1
|
||||
|
||||
default: all
|
||||
all: all_nomsg msg_test
|
||||
@@ -299,8 +207,10 @@ VL_INST_INC_SRCDIR_FILES = \
|
||||
include/vltstd/*.[chv]* \
|
||||
|
||||
VL_INST_DATA_SRCDIR_FILES = \
|
||||
examples/*/*.[chv]* examples/*/Makefile* \
|
||||
examples/*/CMakeLists.txt
|
||||
examples/*/*.[chv]* \
|
||||
examples/*/CMakeLists.txt \
|
||||
examples/*/Makefile* \
|
||||
examples/*/vl_* \
|
||||
|
||||
installbin:
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(bindir)
|
||||
@@ -386,44 +296,7 @@ uninstall:
|
||||
install: all_nomsg install-all
|
||||
install-all: installbin installman installdata install-msg
|
||||
|
||||
install-here: installman ftp
|
||||
|
||||
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
|
||||
DISTNAMEREV = $(shell sed -e '/DTVERSION/!d' -e 's/.*verilator_\([^"]*\).*/\1/' -e q ${srcdir}/src/config_rev.h)
|
||||
|
||||
VERILATOR_CAD_DIR = $(CAD_DIR)/verilator/$(DISTNAMEREV)/$(DIRPROJECT_ARCH)
|
||||
INST_PROJ_CVS = cp_if_cvs_diff
|
||||
|
||||
install-cadtools: dist
|
||||
@echo "Install-project to $(CAD_DIR)"
|
||||
strip bin/verilator_bin*
|
||||
strip bin/verilator_coverage_bin*
|
||||
$(MAKE) install-cadtools-quick
|
||||
$(MKINSTALLDIRS) $(VERILATOR_CAD_DIR)/man/man1
|
||||
for p in $(VL_INST_MAN_FILES) ; do \
|
||||
$(INSTALL_DATA) $$p $(VERILATOR_CAD_DIR)/man/man1/$$p; \
|
||||
done
|
||||
$(INST_PROJ_CVS) $(DISTNAME).tgz $(VERILATOR_CAD_DIR)/verilator.tgz
|
||||
rm $(DISTNAME).tgz
|
||||
|
||||
install-cadtools-quick:
|
||||
ifeq ($(CFG_WITH_DEFENV),yes)
|
||||
@echo "%Error: Reconfigure with './configure --disable-defenv' to avoid hardcoded paths."
|
||||
false
|
||||
endif
|
||||
@echo "Install-cadtools-quick (no strip) to $(VERILATOR_CAD_DIR)"
|
||||
$(MKINSTALLDIRS) $(VERILATOR_CAD_DIR)/include/gtkwave
|
||||
$(MKINSTALLDIRS) $(VERILATOR_CAD_DIR)/include/vltstd
|
||||
$(MKINSTALLDIRS) $(VERILATOR_CAD_DIR)/bin
|
||||
for p in $(INST_PROJ_FILES) ; do \
|
||||
$(INST_PROJ_CVS) $$p $(VERILATOR_CAD_DIR)/$$p; \
|
||||
done
|
||||
for p in $(INST_PROJ_BIN_FILES) ; do \
|
||||
$(INST_PROJ_CVS) $$p $(VERILATOR_CAD_DIR)/$$p; \
|
||||
done
|
||||
|
||||
# VERILATOR_AUTHOR_SITE
|
||||
endif
|
||||
install-here: installman info
|
||||
|
||||
# Use --xml flag to see the cppcheck code to use for suppression
|
||||
CPPCHECK_CPP = $(wildcard \
|
||||
@@ -449,7 +322,10 @@ cppcheck: $(CPPCHECK_DEP)
|
||||
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 -DVL_THREADED=1 $(CPPCHECK_INC) $<
|
||||
|
||||
CLANGTIDY = clang-tidy
|
||||
CLANGTIDY_FLAGS = -config='' -checks='-fuchsia-*,-cppcoreguidelines-avoid-c-arrays,-cppcoreguidelines-init-variables'
|
||||
CLANGTIDY_FLAGS = -config='' \
|
||||
-header-filter='.*' \
|
||||
-checks='-fuchsia-*,-cppcoreguidelines-avoid-c-arrays,-cppcoreguidelines-init-variables,-cppcoreguidelines-avoid-goto,-modernize-avoid-c-arrays,-readability-magic-numbers,-readability-simplify-boolean-expr,-cppcoreguidelines-macro-usage' \
|
||||
|
||||
CLANGTIDY_DEP = $(subst .h,.h.tidy,$(CPPCHECK_H)) \
|
||||
$(subst .cpp,.cpp.tidy,$(CPPCHECK_CPP))
|
||||
CLANGTIDY_DEFS = -DVL_DEBUG=1 -DVL_THREADED=1 -DVL_CPPCHECK=1
|
||||
@@ -458,7 +334,7 @@ clang-tidy: $(CLANGTIDY_DEP)
|
||||
%.cpp.tidy: %.cpp
|
||||
$(CLANGTIDY) $(CLANGTIDY_FLAGS) $< -- $(CLANGTIDY_DEFS) $(CPPCHECK_INC) | 2>&1 tee $@
|
||||
%.h.tidy: %.h
|
||||
$(CLANGTIDY) $(CLANGTIDY_FLAGS) $< -- $(CLANGTIDY_DEFS) $(CPPCHECK_INC) | 2>&1 tee $@
|
||||
$(CLANGTIDY) $(CLANGTIDY_FLAGS) $< -- $(CLANGTIDY_DEFS) $(CPPCHECK_INC) -x c++-header | 2>&1 tee $@
|
||||
|
||||
analyzer-src:
|
||||
-rm -rf src/obj_dbg
|
||||
@@ -481,6 +357,9 @@ clang-format:
|
||||
|
||||
PY_PROGRAMS = \
|
||||
bin/verilator_ccache_report \
|
||||
bin/verilator_difftree \
|
||||
bin/verilator_gantt \
|
||||
bin/verilator_profcfunc \
|
||||
examples/xml_py/vl_file_copy \
|
||||
examples/xml_py/vl_hier_graph \
|
||||
docs/guide/conf.py \
|
||||
@@ -524,9 +403,6 @@ lint-py:
|
||||
format-pl-exec:
|
||||
-chmod a+x test_regress/t/*.pl
|
||||
|
||||
|
||||
ftp: info
|
||||
|
||||
install-msg:
|
||||
@echo
|
||||
@echo "Installed binaries to $(DESTDIR)$(bindir)/verilator"
|
||||
@@ -597,15 +473,6 @@ TAGS: $(TAGFILES)
|
||||
doxygen:
|
||||
$(MAKE) -C docs doxygen
|
||||
|
||||
######################################################################
|
||||
# Test targets
|
||||
|
||||
dist-file-list:
|
||||
@echo "begin-dist-file-list:"; # Scripts look for this
|
||||
@echo $(wildcard $(DISTFILES1))
|
||||
@echo $(wildcard $(DISTFILES2))
|
||||
@echo "end-dist-file-list:"; # Scripts look for this
|
||||
|
||||
######################################################################
|
||||
# Distributions
|
||||
|
||||
@@ -613,36 +480,16 @@ DISTTITLE := Verilator $(word 1,$(PACKAGE_VERSION))
|
||||
DISTNAME := verilator-$(word 1,$(PACKAGE_VERSION))
|
||||
DISTDATEPRE := $(word 2,$(PACKAGE_VERSION))
|
||||
DISTDATE := $(subst /,-,$(DISTDATEPRE))
|
||||
|
||||
DISTTAGNAME := $(subst .,_,$(subst -,_,$(DISTNAME)))
|
||||
|
||||
tag:
|
||||
svnorcvs tag $(DISTTAGNAME)
|
||||
|
||||
# Don't depend on DISTFILES because there's no rule for "standards.info*".
|
||||
dist: $(DISTDEP) maintainer-copy
|
||||
-rm -fr $(DISTNAME)
|
||||
for file in $(DISTFILES1); do \
|
||||
mkdir -p `dirname $(DISTNAME)/$$file` >/dev/null ; \
|
||||
ln $$file $(DISTNAME)/$$file \
|
||||
|| { echo copying $$file instead; cp -p $$file $(DISTNAME)/$$file;}; \
|
||||
done; true;
|
||||
for file in $(DISTFILES2); do \
|
||||
mkdir -p `dirname $(DISTNAME)/$$file` >/dev/null ; \
|
||||
ln $$file $(DISTNAME)/$$file \
|
||||
|| { echo copying $$file instead; cp -p $$file $(DISTNAME)/$$file;}; \
|
||||
done; true;
|
||||
chmod -R a+r $(DISTNAME)
|
||||
tar chf $(DISTNAME).tar $(DISTNAME)
|
||||
gzip --force --best $(DISTNAME).tar
|
||||
mv $(DISTNAME).tar.gz $(DISTNAME).tgz
|
||||
rm -fr $(DISTNAME)
|
||||
|
||||
maintainer-diff:
|
||||
svnorcvs diff $(DISTTAGNAME)
|
||||
|
||||
preexist:
|
||||
svnorcvs nexists $(DISTTAGNAME)
|
||||
|
||||
maintainer-dist: preexist dist tag
|
||||
svnorcvs release $(DISTNAME).tgz
|
||||
maintainer-dist: preexist tag
|
||||
svnorcvs release $(DISTTAGNAME)
|
||||
|
||||
+16
-12
@@ -5,6 +5,8 @@
|
||||
:target: https://www.gnu.org/licenses/lgpl-3.0]
|
||||
.. 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
|
||||
:target: https://repology.org/project/verilator/versions
|
||||
.. 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
|
||||
@@ -12,13 +14,14 @@
|
||||
.. image:: https://github.com/verilator/verilator/workflows/build/badge.svg
|
||||
:target: https://github.com/verilator/verilator/actions?query=workflow%3Abuild
|
||||
|
||||
|
||||
Welcome to Verilator
|
||||
====================
|
||||
|
||||
.. list-table::
|
||||
|
||||
* - **Welcome to Verilator, the fastest Verilog/SystemVerilog simulator.**
|
||||
* Accepts synthesizable Verilog or SystemVerilog
|
||||
* Accepts Verilog or SystemVerilog
|
||||
* Performs lint code-quality checks
|
||||
* Compiles into multithreaded C++, or SystemC
|
||||
* Creates XML to front-end your own tools
|
||||
@@ -54,23 +57,24 @@ files, the "Verilated" code.
|
||||
|
||||
The user writes a little C++/SystemC wrapper file, which instantiates the
|
||||
"Verilated" model of the user's top level module. These C++/SystemC files
|
||||
are then compiled by a C++ compiler (gcc/clang/MSVC++). The resulting
|
||||
executable performs the design simulation. Verilator also supports linking
|
||||
its generated libraries, optionally encrypted, into other simulators.
|
||||
are then compiled by a C++ compiler (gcc/clang/MSVC++). Executing the
|
||||
resulting 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 NC-Verilog, VCS or another commercial Verilog simulator, or
|
||||
if you are looking for a behavioral Verilog simulator e.g. for a quick
|
||||
class project (we recommend `Icarus Verilog`_ for this.) However, if you
|
||||
are looking for a path to migrate SystemVerilog to C++ or SystemC, or your
|
||||
team is comfortable writing just a touch of C++ code, Verilator is the tool
|
||||
for you.
|
||||
replacement for Incisive, ModelSim/Questa, VCS or another commercial
|
||||
Verilog simulator, or if you are looking for a behavioral Verilog simulator
|
||||
e.g. for a quick class project (we recommend `Icarus Verilog`_ for this.)
|
||||
However, if you are looking for a path to migrate SystemVerilog to C++ or
|
||||
SystemC, or your team is comfortable writing just a touch of C++ code,
|
||||
Verilator is the tool for you.
|
||||
|
||||
|
||||
Performance
|
||||
===========
|
||||
|
||||
Verilator does not simply convert Verilog HDL to C++ or SystemC. Rather,
|
||||
Verilator does not directly translate Verilog HDL to C++ or SystemC. Rather,
|
||||
Verilator compiles your code into a much faster optimized and optionally
|
||||
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
|
||||
@@ -134,7 +138,7 @@ Related Projects
|
||||
Open License
|
||||
============
|
||||
|
||||
Verilator is Copyright 2003-2021 by Wilson Snyder. (Report bugs to
|
||||
Verilator is Copyright 2003-2022 by Wilson Snyder. (Report bugs to
|
||||
`Verilator Issues <https://verilator.org/issues>`_.)
|
||||
|
||||
Verilator is free software; you can redistribute it and/or modify it under
|
||||
|
||||
+65
-59
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env perl
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
@@ -34,11 +34,11 @@ my $opt_quiet_exit;
|
||||
|
||||
# No arguments can't do anything useful. Give help
|
||||
if ($#ARGV < 0) {
|
||||
pod2usage(-exitstatus=>2, -verbose=>0);
|
||||
pod2usage(-exitstatus => 2, -verbose => 0);
|
||||
}
|
||||
|
||||
# Insert debugging options up front
|
||||
push @ARGV, (split ' ',$ENV{VERILATOR_TEST_FLAGS}||"");
|
||||
push @ARGV, (split ' ', $ENV{VERILATOR_TEST_FLAGS} || "");
|
||||
|
||||
# We sneak a look at the flags so we can do some pre-environment checks
|
||||
# All flags will hit verilator...
|
||||
@@ -46,7 +46,7 @@ foreach my $sw (@ARGV) {
|
||||
push @Opt_Verilator_Sw, $sw;
|
||||
}
|
||||
|
||||
Getopt::Long::config("no_auto_abbrev","pass_through");
|
||||
Getopt::Long::config("no_auto_abbrev", "pass_through");
|
||||
if (! GetOptions(
|
||||
# Major operating modes
|
||||
"help" => \&usage,
|
||||
@@ -60,7 +60,7 @@ if (! GetOptions(
|
||||
# Additional parameters
|
||||
"<>" => sub {}, # Ignored
|
||||
)) {
|
||||
pod2usage(-exitstatus=>2, -verbose=>0);
|
||||
pod2usage(-exitstatus => 2, -verbose => 0);
|
||||
}
|
||||
|
||||
if ($opt_gdbbt && !gdb_works()) {
|
||||
@@ -73,12 +73,12 @@ if ($opt_gdbbt && !gdb_works()) {
|
||||
# Starting with that, escape all special chars for the shell;
|
||||
# The shell will undo the escapes and the verilator binary should
|
||||
# then see exactly the contents of @Opt_Verilator_Sw.
|
||||
my @quoted_sw = map {sh_escape($_)} @Opt_Verilator_Sw;
|
||||
my @quoted_sw = map { sh_escape($_) } @Opt_Verilator_Sw;
|
||||
if ($opt_gdb) {
|
||||
# Generic GDB interactive
|
||||
run (aslr_off()
|
||||
.($ENV{VERILATOR_GDB}||"gdb")
|
||||
." ".verilator_bin()
|
||||
. ($ENV{VERILATOR_GDB} || "gdb")
|
||||
. " " . verilator_bin()
|
||||
# Note, uncomment to set breakpoints before running:
|
||||
# ." -ex 'break main'"
|
||||
|
||||
@@ -87,42 +87,41 @@ if ($opt_gdb) {
|
||||
# escapes as you would expect in a double-quoted string.
|
||||
# That's not true for a single-quoted string, where \'
|
||||
# actually terminates the string -- not what we want!
|
||||
." -ex \"run ".join(' ', @quoted_sw)."\""
|
||||
." -ex 'set width 0'"
|
||||
." -ex 'bt'");
|
||||
. " -ex \"run " . join(' ', @quoted_sw) . "\""
|
||||
. " -ex 'set width 0'"
|
||||
. " -ex 'bt'");
|
||||
} elsif ($opt_rr) {
|
||||
# Record with rr
|
||||
run (aslr_off()
|
||||
."rr record ".verilator_bin()
|
||||
." ".join(' ', @quoted_sw));
|
||||
. "rr record " . verilator_bin()
|
||||
. " " . join(' ', @quoted_sw));
|
||||
} elsif ($opt_gdbbt && $Debug) {
|
||||
# Run under GDB to get gdbbt
|
||||
run (aslr_off()
|
||||
."gdb"
|
||||
." ".verilator_bin()
|
||||
." --batch --quiet --return-child-result"
|
||||
." -ex \"run ".join(' ', @quoted_sw)."\""
|
||||
." -ex 'set width 0'"
|
||||
." -ex 'bt' -ex 'quit'");
|
||||
. "gdb"
|
||||
. " " . verilator_bin()
|
||||
. " --batch --quiet --return-child-result"
|
||||
. " -ex \"run " . join(' ', @quoted_sw)."\""
|
||||
. " -ex 'set width 0'"
|
||||
. " -ex 'bt' -ex 'quit'");
|
||||
} elsif ($Debug) {
|
||||
# Debug
|
||||
run(aslr_off()
|
||||
.verilator_bin()." ".join(' ',@quoted_sw));
|
||||
run(aslr_off() . verilator_bin() . " " . join(' ', @quoted_sw));
|
||||
} else {
|
||||
# Normal, non gdb
|
||||
run(verilator_bin()." ".join(' ',@quoted_sw));
|
||||
run(verilator_bin() . " " . join(' ', @quoted_sw));
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
pod2usage(-verbose=>2, -exitval=>0, -output=>\*STDOUT);
|
||||
pod2usage(-verbose => 2, -exitval => 0, -output => \*STDOUT);
|
||||
}
|
||||
|
||||
sub debug {
|
||||
shift;
|
||||
my $level = shift;
|
||||
$Debug = $level||3;
|
||||
$Debug = $level || 3;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
@@ -163,13 +162,13 @@ sub verilator_bin {
|
||||
sub gdb_works {
|
||||
$! = undef; # Cleanup -x
|
||||
system("gdb /bin/echo"
|
||||
." --batch-silent --quiet --return-child-result"
|
||||
." -ex 'run -n'" # `echo -n`
|
||||
." -ex 'set width 0'"
|
||||
." -ex 'bt'"
|
||||
." -ex 'quit'");
|
||||
. " --batch-silent --quiet --return-child-result"
|
||||
. " -ex 'run -n'" # `echo -n`
|
||||
. " -ex 'set width 0'"
|
||||
. " -ex 'bt'"
|
||||
. " -ex 'quit'");
|
||||
my $status = $?;
|
||||
return $status==0;
|
||||
return $status == 0;
|
||||
}
|
||||
|
||||
sub aslr_off {
|
||||
@@ -185,7 +184,7 @@ sub run {
|
||||
# Run command, check errors
|
||||
my $command = shift;
|
||||
$! = undef; # Cleanup -x
|
||||
print "\t$command\n" if $Debug>=3;
|
||||
print "\t$command\n" if $Debug >= 3;
|
||||
system($command);
|
||||
my $status = $?;
|
||||
if ($status) {
|
||||
@@ -193,7 +192,7 @@ sub run {
|
||||
warn "%Error: verilator: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
|
||||
}
|
||||
if ($Debug) { # For easy rerunning
|
||||
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
|
||||
warn "%Error: export VERILATOR_ROOT=" . ($ENV{VERILATOR_ROOT} || "") . "\n";
|
||||
warn "%Error: $command\n";
|
||||
}
|
||||
if ($status & 127) {
|
||||
@@ -201,13 +200,13 @@ sub run {
|
||||
|| ($status & 127) == 8 # SIGFPA
|
||||
|| ($status & 127) == 11) { # SIGSEGV
|
||||
warn "%Error: Verilator internal fault, sorry. "
|
||||
."Suggest trying --debug --gdbbt\n" if !$Debug;
|
||||
. "Suggest trying --debug --gdbbt\n" if !$Debug;
|
||||
} elsif (($status & 127) == 6) { # SIGABRT
|
||||
warn "%Error: Verilator aborted. "
|
||||
."Suggest trying --debug --gdbbt\n" if !$Debug;
|
||||
. "Suggest trying --debug --gdbbt\n" if !$Debug;
|
||||
} else {
|
||||
warn "%Error: Verilator threw signal $status. "
|
||||
."Suggest trying --debug --gdbbt\n" if !$Debug;
|
||||
. "Suggest trying --debug --gdbbt\n" if !$Debug;
|
||||
}
|
||||
}
|
||||
if (!$opt_quiet_exit && ($status != 256 || $Debug)) { # i.e. not normal exit(1)
|
||||
@@ -285,33 +284,34 @@ detailed descriptions of these arguments.
|
||||
--bbox-unsup Blackbox unsupported language features
|
||||
--bin <filename> Override Verilator binary
|
||||
--build Build model executable/library after Verilation
|
||||
-CFLAGS <flags> C++ compiler arguments for makefile
|
||||
--cc Create C++ output
|
||||
--cdc Clock domain crossing analysis
|
||||
-CFLAGS <flags> C++ compiler arguments for makefile
|
||||
--clk <signal-name> Mark specified signal as clock
|
||||
--make <build-tool> Generate scripts for specified build tool
|
||||
--no-clk <signal-name> Prevent marking specified signal as clock
|
||||
--compiler <compiler-name> Tune for specified C++ compiler
|
||||
--converge-limit <loops> Tune convergence settle time
|
||||
--coverage Enable all coverage
|
||||
--coverage-line Enable line coverage
|
||||
--coverage-max-width <width> Maximum array depth for coverage
|
||||
--coverage-toggle Enable toggle coverage
|
||||
--coverage-user Enable SVL user coverage
|
||||
--coverage-underscore Enable coverage of _signals
|
||||
--coverage-user Enable SVL user coverage
|
||||
-D<var>[=<value>] Set preprocessor define
|
||||
--debug Enable debugging
|
||||
--debug-check Enable debugging assertions
|
||||
--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
|
||||
--default-language <lang> Default language to parse
|
||||
+define+<var>=<value> Set preprocessor define
|
||||
--dpi-hdr-only Only produce the DPI header file
|
||||
--dump-defines Show preprocessor defines with -E
|
||||
--dump-tree Enable dumping .tree files
|
||||
--dump-tree-addrids Use short identifiers instead of addresses
|
||||
--dump-treei <level> Enable dumping .tree files at a level
|
||||
--dump-treei-<srcfile> <level> Enable dumping .tree file at a source file at a level
|
||||
--dump-tree-addrids Use short identifiers instead of addresses
|
||||
-E Preprocess, but do not compile
|
||||
--error-limit <value> Abort after this number of errors
|
||||
--exe Link to create executable
|
||||
@@ -320,7 +320,9 @@ 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
|
||||
-fno-<optimization> Disable internal optimization stage
|
||||
-G<name>=<value> Overwrite top-level parameter
|
||||
--gate-stmts <value> Tune gate optimizer depth
|
||||
--gdb Run Verilator under GDB interactively
|
||||
--gdbbt Run Verilator under GDB for backtrace
|
||||
--generate-key Create random key for --protect-key
|
||||
@@ -328,52 +330,50 @@ detailed descriptions of these arguments.
|
||||
--help Display this help
|
||||
--hierarchical Enable hierarchical Verilation
|
||||
-I<dir> Directory to search for includes
|
||||
-j <jobs> Parallelism for --build
|
||||
--gate-stmts <value> Tune gate optimizer depth
|
||||
--if-depth <value> Tune IFDEPTH warning
|
||||
+incdir+<dir> Directory to search for includes
|
||||
--inline-mult <value> Tune module inlining
|
||||
-LDFLAGS <flags> Linker pre-object arguments for makefile
|
||||
--instr-count-dpi <value> Assumed dynamic instruction count of DPI imports
|
||||
-j <jobs> Parallelism for --build
|
||||
--l2-name <value> Verilog scope name of the top module
|
||||
--language <lang> Default language standard to parse
|
||||
-LDFLAGS <flags> Linker pre-object arguments for makefile
|
||||
--lib-create <name> Create a DPI library
|
||||
+libext+<ext>+[ext]... Extensions for finding modules
|
||||
--lint-only Lint, but do not make output
|
||||
--make <build-tool> Generate scripts for specified build tool
|
||||
-MAKEFLAGS <flags> Arguments to pass to make during --build
|
||||
--max-num-width <value> Maximum number width (default: 64K)
|
||||
--MMD Create .d dependency files
|
||||
--MP Create phony dependency targets
|
||||
--Mdir <directory> Name of output object directory
|
||||
--no-merge-const-pool Disable merging of different types in const pool
|
||||
--MMD Create .d dependency files
|
||||
--mod-prefix <topname> Name to prepend to lower classes
|
||||
--no-clk <signal-name> Prevent marking specified signal as clock
|
||||
--no-decoration Disable comments and symbol decorations
|
||||
--no-pins64 Don't use vluint64_t's for 33-64 bit sigs
|
||||
--no-skip-identical Disable skipping identical output
|
||||
--MP Create phony dependency targets
|
||||
+notimingchecks Ignored
|
||||
-O0 Disable optimizations
|
||||
-O3 High performance optimizations
|
||||
-O<optimization-letter> Selectable optimizations
|
||||
-o <executable> Name of final executable
|
||||
--no-order-clock-delay Disable ordering clock enable assignments
|
||||
--no-verilate Skip verilation and just compile previously Verilated code.
|
||||
--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-sc-uint Specify types for top level ports
|
||||
--pins-sc-biguint Specify types for top level ports
|
||||
--pins-sc-uint Specify types for top level ports
|
||||
--pins-uint8 Specify types for top level ports
|
||||
--no-pins64 Don't use uint64_t's for 33-64 bit sigs
|
||||
--pipe-filter <command> Filter all input through a script
|
||||
--pp-comments Show preprocessor comments with -E
|
||||
--prefix <topname> Name of top level class
|
||||
--private Debugging; see docs
|
||||
--prof-c Compile C++ code with profiling
|
||||
--prof-cfuncs Name functions for profiling
|
||||
--prof-threads Enable generating gantt chart data for threads
|
||||
--protect-key <key> Key for symbol protection
|
||||
--prof-exec Enable generating execution profile for gantt chart
|
||||
--prof-pgo Enable generating profiling data for PGO
|
||||
--protect-ids Hash identifier names for obscurity
|
||||
--protect-key <key> Key for symbol protection
|
||||
--protect-lib <name> Create a DPI protected library
|
||||
--private Debugging; see docs
|
||||
--public Debugging; see docs
|
||||
--public-flat-rw Mark all variables, etc as public_flat_rw
|
||||
-pvalue+<name>=<value> Overwrite toplevel parameter
|
||||
@@ -384,6 +384,7 @@ detailed descriptions of these arguments.
|
||||
--rr Run Verilator and record with rr
|
||||
--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
|
||||
-sv Enable SystemVerilog parsing
|
||||
@@ -403,7 +404,7 @@ detailed descriptions of these arguments.
|
||||
--trace-max-width <width> Maximum array depth for tracing
|
||||
--trace-params Enable tracing of parameters
|
||||
--trace-structs Enable tracing structure names
|
||||
--trace-threads <threads> Enable waveform creation on separate threads
|
||||
--trace-threads <threads> Enable FST waveform creation on separate threads
|
||||
--trace-underscore Enable tracing of _signals
|
||||
-U<var> Undefine preprocessor define
|
||||
--unroll-count <loops> Tune maximum loop iterations
|
||||
@@ -411,6 +412,7 @@ detailed descriptions of these arguments.
|
||||
--unused-regexp <regexp> Tune UNUSED lint signals
|
||||
-V Verbose version and config
|
||||
-v <filename> Verilog library
|
||||
--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
|
||||
@@ -425,6 +427,9 @@ detailed descriptions of these arguments.
|
||||
-Wno-lint Disable all lint warnings
|
||||
-Wno-style Disable all style warnings
|
||||
-Wpedantic Warn on compliance-test issues
|
||||
-Wwarn-<message> Enable specified warning message
|
||||
-Wwarn-lint Enable lint warning message
|
||||
-Wwarn-style Enable style warning message
|
||||
--x-assign <mode> Assign non-initial Xs to this value
|
||||
--x-initial <mode> Assign initial Xs to this value
|
||||
--x-initial-edge Enable initial X->0 and X->1 edge triggers
|
||||
@@ -444,9 +449,10 @@ description of these arguments.
|
||||
+verilator+error+limit+<value> Set error limit
|
||||
+verilator+help Display help
|
||||
+verilator+noassert Disable assert checking
|
||||
+verilator+prof+threads+file+<filename> Set profile filename
|
||||
+verilator+prof+threads+start+<value> Set profile starting point
|
||||
+verilator+prof+threads+window+<value> Set profile duration
|
||||
+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
|
||||
@@ -457,7 +463,7 @@ description of these arguments.
|
||||
|
||||
The latest version is available from L<https://verilator.org>.
|
||||
|
||||
Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
|
||||
Copyright 2003-2022 by Wilson Snyder. This program is free software; you can
|
||||
redistribute it and/or modify the Verilator internals under the terms of
|
||||
either the GNU Lesser General Public License Version 3 or the Perl Artistic
|
||||
License Version 2.0.
|
||||
|
||||
@@ -14,7 +14,7 @@ parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""Report ccache behavior of a Verilated model build.""",
|
||||
epilog=
|
||||
"""Copyright 2002-2021 by Wilson Snyder. This program is free software; you
|
||||
"""Copyright 2002-2022 by Wilson Snyder. This program is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
+11
-11
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env perl
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
@@ -30,7 +30,7 @@ $Debug = 0;
|
||||
|
||||
# No arguments can't do anything useful. Give help
|
||||
if ($#ARGV < 0) {
|
||||
pod2usage(-exitstatus=>2, -verbose=>0);
|
||||
pod2usage(-exitstatus => 2, -verbose => 0);
|
||||
}
|
||||
|
||||
# We sneak a look at the flags so we can do some pre-environment checks
|
||||
@@ -40,7 +40,7 @@ foreach my $sw (@ARGV) {
|
||||
push @Opt_Verilator_Sw, $sw;
|
||||
}
|
||||
|
||||
Getopt::Long::config("no_auto_abbrev","pass_through");
|
||||
Getopt::Long::config("no_auto_abbrev", "pass_through");
|
||||
if (! GetOptions (
|
||||
# Major operating modes
|
||||
"help" => \&usage,
|
||||
@@ -49,23 +49,23 @@ if (! GetOptions (
|
||||
# Additional parameters
|
||||
"<>" => sub {}, # Ignored
|
||||
)) {
|
||||
pod2usage(-exitstatus=>2, -verbose=>0);
|
||||
pod2usage(-exitstatus => 2, -verbose => 0);
|
||||
}
|
||||
|
||||
# Normal, non gdb
|
||||
run(verilator_coverage_bin()
|
||||
." ".join(' ',@Opt_Verilator_Sw));
|
||||
. " " . join(' ', @Opt_Verilator_Sw));
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
pod2usage(-verbose=>2, -exitval=>0, -output=>\*STDOUT);
|
||||
pod2usage(-verbose => 2, -exitval => 0, -output => \*STDOUT);
|
||||
}
|
||||
|
||||
sub debug {
|
||||
shift;
|
||||
my $level = shift;
|
||||
$Debug = $level||3;
|
||||
$Debug = $level || 3;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
@@ -107,7 +107,7 @@ sub run {
|
||||
# Run command, check errors
|
||||
my $command = shift;
|
||||
$! = undef; # Cleanup -x
|
||||
print "\t$command\n" if $Debug>=3;
|
||||
print "\t$command\n" if $Debug >= 3;
|
||||
system($command);
|
||||
my $status = $?;
|
||||
if ($status) {
|
||||
@@ -115,11 +115,11 @@ sub run {
|
||||
warn "%Error: verilator_coverage: Misinstalled, or VERILATOR_ROOT might need to be in environment\n";
|
||||
}
|
||||
if ($Debug) { # For easy rerunning
|
||||
warn "%Error: export VERILATOR_ROOT=".($ENV{VERILATOR_ROOT}||"")."\n";
|
||||
warn "%Error: export VERILATOR_ROOT=" . ($ENV{VERILATOR_ROOT} || "") . "\n";
|
||||
warn "%Error: $command\n";
|
||||
}
|
||||
if ($status & 127) {
|
||||
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
|
||||
if (($status & 127) == 8 || ($status & 127) == 11) { # SIGFPA or SIGSEGV
|
||||
warn "%Error: Verilator_coverage internal fault, sorry.\n" if !$Debug;
|
||||
} elsif (($status & 127) == 6) { # SIGABRT
|
||||
warn "%Error: Verilator_coverage aborted.\n" if !$Debug;
|
||||
@@ -187,7 +187,7 @@ L<https://verilator.org/guide/latest/exe_verilator_coverage.html>.
|
||||
|
||||
The latest version is available from L<https://verilator.org>.
|
||||
|
||||
Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
||||
Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||
can redistribute it and/or modify the Verilator internals under the terms
|
||||
of either the GNU Lesser General Public License Version 3 or the Perl
|
||||
Artistic License Version 2.0.
|
||||
|
||||
+107
-201
@@ -1,233 +1,139 @@
|
||||
#!/usr/bin/env perl
|
||||
# See copyright, etc in below POD section.
|
||||
#!/usr/bin/env python3
|
||||
# pylint: disable=C0103,C0114,C0116
|
||||
######################################################################
|
||||
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
use IO::File;
|
||||
use Pod::Usage;
|
||||
use strict;
|
||||
use vars qw($Debug);
|
||||
import argparse
|
||||
import collections
|
||||
import glob
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
$Debug = 0;
|
||||
my $Opt_A;
|
||||
my $Opt_B;
|
||||
my $Opt_Lineno = 1;
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
Getopt::Long::config("no_auto_abbrev");
|
||||
if (! GetOptions(
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
"lineno!" => \$Opt_Lineno,
|
||||
)) {
|
||||
die "%Error: Bad usage, try 'verilator_difftree --help'\n";
|
||||
}
|
||||
def diff(a, b):
|
||||
|
||||
defined $Opt_A or die "%Error: No old diff filename\n";
|
||||
defined $Opt_B or die "%Error: No new diff filename\n";
|
||||
if not os.path.exists(a):
|
||||
sys.exit("%Error: No old diff filename found: " + a)
|
||||
if not os.path.exists(b):
|
||||
sys.exit("%Error: No new diff filename found: " + b)
|
||||
|
||||
-e $Opt_A or die "%Error: No old diff filename found: $Opt_A\n";
|
||||
-e $Opt_B or die "%Error: No new diff filename found: $Opt_B\n";
|
||||
if os.path.isdir(a) and os.path.isdir(b):
|
||||
diff_dir(a, b)
|
||||
elif os.path.isfile(a) and os.path.isfile(b):
|
||||
diff_file(a, b)
|
||||
else:
|
||||
sys.exit("%Error: Mix of files and dirs")
|
||||
|
||||
if (-d $Opt_A && -d $Opt_B) {
|
||||
diff_dir($Opt_A, $Opt_B);
|
||||
} elsif (-f $Opt_A && -f $Opt_B) {
|
||||
diff_file($Opt_A, $Opt_B);
|
||||
} else {
|
||||
die "%Error: Mix of files and dirs\n";
|
||||
}
|
||||
|
||||
sub diff_dir {
|
||||
my $a = shift;
|
||||
my $b = shift;
|
||||
def diff_dir(a, b):
|
||||
# Diff all files under two directories
|
||||
my %files;
|
||||
files = collections.defaultdict(lambda: {})
|
||||
|
||||
foreach my $fn (glob("$a/*.tree")) {
|
||||
(my $base = $fn) =~ s!.*/!!;
|
||||
$files{$base}{a} = $fn;
|
||||
}
|
||||
foreach my $fn (glob("$b/*.tree")) {
|
||||
(my $base = $fn) =~ s!.*/!!;
|
||||
$files{$base}{b} = $fn;
|
||||
}
|
||||
my $any;
|
||||
foreach my $base (sort (keys %files)) {
|
||||
my $a = $files{$base}{a};
|
||||
my $b = $files{$base}{b};
|
||||
next if !$a || !$b;
|
||||
print "="x70,"\n";
|
||||
print "= $a <-> $b\n";
|
||||
diff_file($a,$b);
|
||||
$any = 1;
|
||||
}
|
||||
$any or warn("%Warning: No .tree files found that have similar base names:\n "
|
||||
.join("\n ", sort keys %files),"\n");
|
||||
}
|
||||
for fn in glob.glob(a + "/*.tree"):
|
||||
base = re.sub(r'.*/', '', fn)
|
||||
files[base]['a'] = fn
|
||||
for fn in glob.glob(b + "/*.tree"):
|
||||
base = re.sub(r'.*/', '', fn)
|
||||
files[base]['b'] = fn
|
||||
|
||||
sub diff_file {
|
||||
my $a = shift;
|
||||
my $b = shift;
|
||||
anyfile = False
|
||||
for base in sorted(files.keys()):
|
||||
if (not 'a' in files[base]) or (not 'b' in files[base]):
|
||||
continue
|
||||
a = files[base]['a']
|
||||
b = files[base]['b']
|
||||
print("=" * 70)
|
||||
print("= %s <-> %s" % (a, b))
|
||||
diff_file(a, b)
|
||||
anyfile = True
|
||||
if not anyfile:
|
||||
sys.stderr.write(
|
||||
"%Warning: No .tree files found that have similar base names\n")
|
||||
|
||||
|
||||
def diff_file(a, b):
|
||||
# Compare the two tree files
|
||||
(my $short_a = $a) =~ s/[^a-zA-Z0-9.]+/_/g;
|
||||
(my $short_b = $b) =~ s/[^a-zA-Z0-9.]+/_/g;
|
||||
my $tmp_a = "/tmp/${$}_${short_a}.a";
|
||||
my $tmp_b = "/tmp/${$}_${short_b}.b";
|
||||
short_a = re.sub(r'[^a-zA-Z0-9.]+', '_', a)
|
||||
short_b = re.sub(r'[^a-zA-Z0-9.]+', '_', b)
|
||||
tmp_a = "/tmp/%s_%s.a" % (os.getpid(), short_a)
|
||||
tmp_b = "/tmp/%s_%s.b" % (os.getpid(), short_b)
|
||||
|
||||
my $vera = version_from($a);
|
||||
my $verb = version_from($b);
|
||||
my $verCvt = (($vera < 0x3900 && $verb >= 0x3900)
|
||||
|| ($vera >= 0x3900 && $verb < 0x3900));
|
||||
# Version conversion deprecated, but for future...
|
||||
# vera = version_from(a)
|
||||
# verb = version_from(b)
|
||||
# verCvt = ((vera < 0x3900 and verb >= 0x3900)
|
||||
# or (vera >= 0x3900 and verb < 0x3900))
|
||||
|
||||
filter($a, $tmp_a, $verCvt);
|
||||
filter($b, $tmp_b, $verCvt);
|
||||
system("diff -u $tmp_a $tmp_b");
|
||||
unlink $tmp_a;
|
||||
unlink $tmp_b;
|
||||
}
|
||||
filterf(a, tmp_a)
|
||||
filterf(b, tmp_b)
|
||||
os.system("diff -u " + tmp_a + " " + tmp_b)
|
||||
os.unlink(tmp_a)
|
||||
os.unlink(tmp_b)
|
||||
|
||||
sub version_from {
|
||||
my $fn = shift;
|
||||
|
||||
def version_from(filename):
|
||||
# Return dump format
|
||||
my $f1 = IO::File->new ($fn) or die "%Error: $! $fn,";
|
||||
while (defined (my $line=$f1->getline())) {
|
||||
last if $. > 10;
|
||||
return hex $1 if $line =~ /\(format (0x[0-9.]+)\)/;
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
with open(filename) as fh:
|
||||
lineno = 0
|
||||
for line in fh:
|
||||
if lineno > 10:
|
||||
break
|
||||
match = re.search(r'format (0x[0-9.]+)', line)
|
||||
if match:
|
||||
return hex(match.group(1))
|
||||
return 1.0
|
||||
|
||||
sub filter {
|
||||
my $fn1 = shift;
|
||||
my $fn2 = shift;
|
||||
my $verCvt = shift;
|
||||
|
||||
def filterf(fn1, fn2):
|
||||
# Remove hex numbers before diffing
|
||||
my $f1 = IO::File->new ($fn1) or die "%Error: $! $fn1,";
|
||||
my $f2 = IO::File->new ($fn2,"w") or die "%Error: $! $fn2,";
|
||||
while (defined (my $line=$f1->getline())) {
|
||||
same_line:
|
||||
next if $line =~ / This=/;
|
||||
$line =~ s/0x[a-f0-9]+/0x/g;
|
||||
$line =~ s/<e[0-9]+\#?>/<e>/g;
|
||||
$line =~ s/{[a-z]*\d+}/{}/g if !$Opt_Lineno;
|
||||
if ($verCvt) {
|
||||
next if $line =~ /^ NETLIST/;
|
||||
if ($line =~ /: ([A-Z]+) /) {
|
||||
my $type = $1;
|
||||
next if $type =~ 'DTYPE';
|
||||
if ($type eq 'TYPETABLE' || $type eq 'RANGE') {
|
||||
$line =~ /^(\s+\S+:) /; my $prefix = $1;
|
||||
while (defined ($line=$f1->getline())) {
|
||||
next if $line =~ /^\s+[a-z]/; # Table body
|
||||
next if $line =~ /^${prefix}[0-9]:/;
|
||||
goto same_line;
|
||||
}
|
||||
next;
|
||||
}
|
||||
}
|
||||
}
|
||||
print $f2 $line;
|
||||
}
|
||||
$f1->close;
|
||||
$f2->close;
|
||||
}
|
||||
with open(fn1) as fh1:
|
||||
with open(fn2, "w") as fh2:
|
||||
for line in fh1:
|
||||
if re.search(r' This=', line):
|
||||
continue
|
||||
line = re.sub(r'0x[a-f0-9]+', '0x', line)
|
||||
line = re.sub(r'<e[0-9]+\#?>', '<e>', line)
|
||||
if not Args.no_lineno:
|
||||
line = re.sub(r'{[a-z]*\d+}', '{}', line)
|
||||
fh2.write(line)
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
pod2usage(-verbose=>2, -exitval=>0, -output=>\*STDOUT);
|
||||
exit(1); # Unreachable
|
||||
}
|
||||
######################################################################
|
||||
######################################################################
|
||||
|
||||
sub debug {
|
||||
$Debug = 1;
|
||||
}
|
||||
|
||||
sub parameter {
|
||||
my $param = shift;
|
||||
if (!defined $Opt_A) {
|
||||
$Opt_A = $param;
|
||||
} elsif (!defined $Opt_B) {
|
||||
$Opt_B = $param;
|
||||
} else {
|
||||
die "%Error: Unknown parameter: $param\n";
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
|
||||
sub run {
|
||||
# Run a system command, check errors
|
||||
my $command = shift;
|
||||
print "\t$command\n";
|
||||
system "$command";
|
||||
my $status = $?;
|
||||
($status == 0) or die "%Error: Command Failed $command, $status, stopped";
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
verilator_difftree - Compare two Verilator debugging trees
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
verilator_difftree .../a/a.tree .../b/a.tree
|
||||
verilator_difftree .../a .../b
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Verilator_difftree is used for debugging Verilator tree output files. It
|
||||
performs a diff between two files, or all files common between two
|
||||
parser = argparse.ArgumentParser(
|
||||
allow_abbrev=False,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""Compare two Verilator debugging trees""",
|
||||
epilog=
|
||||
"""Verilator_difftree is used for debugging Verilator tree output files.
|
||||
It performs a diff between two files, or all files common between two
|
||||
directories, ignoring irrelevant pointer differences.
|
||||
|
||||
=head1 ARGUMENTS
|
||||
For documentation see
|
||||
https://verilator.org/guide/latest/exe_verilator_difftree.html
|
||||
|
||||
=over 4
|
||||
|
||||
=item --help
|
||||
|
||||
Displays this message and program version and exits.
|
||||
|
||||
=item --nolineno
|
||||
|
||||
Do not show differences in line numbering.
|
||||
|
||||
=back
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
The latest version is available from L<https://verilator.org>.
|
||||
|
||||
Copyright 2005-2021 by Wilson Snyder. This program is free software; you
|
||||
Copyright 2005-2022 by Wilson Snyder. This program is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
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
|
||||
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0""")
|
||||
|
||||
=head1 AUTHORS
|
||||
parser.add_argument('--debug',
|
||||
action='store_const',
|
||||
const=9,
|
||||
help='enable debug')
|
||||
parser.add_argument('--no-lineno',
|
||||
action='store_false',
|
||||
help='do not show differences in line numbering')
|
||||
parser.add_argument('filea', help='input file a to diff')
|
||||
parser.add_argument('fileb', help='input file b to diff')
|
||||
|
||||
Wilson Snyder <[email protected]>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
C<verilator>
|
||||
|
||||
and L<https://verilator.org/verilator_doc.html> for detailed documentation.
|
||||
|
||||
=cut
|
||||
Args = parser.parse_args()
|
||||
diff(Args.filea, Args.fileb)
|
||||
|
||||
######################################################################
|
||||
### Local Variables:
|
||||
### compile-command: "$V4/bin/verilator_difftree {$V4D,$V4}/test_regress/obj_dir/t_EXAMPLE/V*_03_*.tree"
|
||||
### End:
|
||||
# Local Variables:
|
||||
# compile-command: "./verilator_difftree ../test_regress/t/t_difftree.{a,b}.tree"
|
||||
# End:
|
||||
|
||||
+448
-511
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env perl
|
||||
# DESCRIPTION: Print include statements for each ARGV
|
||||
#
|
||||
# Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
@@ -10,11 +10,11 @@
|
||||
|
||||
require 5.005;
|
||||
use warnings;
|
||||
print "// DESCR"."IPTION: Generated by verilator_includer via makefile\n";
|
||||
print "// DESCR" . "IPTION: Generated by verilator_includer via makefile\n";
|
||||
foreach my $param (@ARGV) {
|
||||
if ($param =~ /^-D([^=]+)=(.*)/) {
|
||||
print "#define $1 $2\n"
|
||||
print "#define $1 $2\n";
|
||||
} else {
|
||||
print "#include \"$param\"\n"
|
||||
print "#include \"$param\"\n";
|
||||
}
|
||||
}
|
||||
|
||||
+173
-217
@@ -1,248 +1,204 @@
|
||||
#!/usr/bin/env perl
|
||||
# See copyright, etc in below POD section.
|
||||
#!/usr/bin/env python3
|
||||
# pylint: disable=C0103,C0114,C0116,R0914,R0912,R0915,eval-used
|
||||
######################################################################
|
||||
|
||||
require 5.006_001;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
use IO::File;
|
||||
use Pod::Usage;
|
||||
eval { use Data::Dumper; $Data::Dumper::Indent = 1; }; # Debug, ok if missing
|
||||
use strict;
|
||||
use vars qw($Debug);
|
||||
import argparse
|
||||
import collections
|
||||
import re
|
||||
# from pprint import pprint
|
||||
|
||||
#======================================================================
|
||||
######################################################################
|
||||
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
def profcfunc(filename):
|
||||
funcs = {}
|
||||
|
||||
$Debug = 0;
|
||||
my $Opt_File;
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
Getopt::Long::config("no_auto_abbrev");
|
||||
if (! GetOptions(
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
die "%Error: Bad usage, try 'verilator_profcfunc --help'\n";
|
||||
}
|
||||
with open(filename) as fh:
|
||||
|
||||
defined $Opt_File or die "%Error: No filename given\n";
|
||||
for line in fh:
|
||||
# %time cumesec selfsec calls {stuff} name
|
||||
match = re.match(
|
||||
r'^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$',
|
||||
line)
|
||||
if match:
|
||||
pct = float(match.group(1))
|
||||
sec = float(match.group(2))
|
||||
calls = float(match.group(3))
|
||||
func = match.group(4)
|
||||
if func not in funcs:
|
||||
funcs[func] = {'pct': 0, 'sec': 0, 'calls': 0}
|
||||
funcs[func]['pct'] += pct
|
||||
funcs[func]['sec'] += sec
|
||||
funcs[func]['calls'] += calls
|
||||
continue
|
||||
|
||||
profcfunc($Opt_File);
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
pod2usage(-verbose=>2, -exitval=>0, -output=>\*STDOUT);
|
||||
exit(1); # Unreachable
|
||||
}
|
||||
|
||||
sub debug {
|
||||
$Debug = 1;
|
||||
}
|
||||
|
||||
sub parameter {
|
||||
my $param = shift;
|
||||
if (!defined $Opt_File) {
|
||||
$Opt_File = $param;
|
||||
} else {
|
||||
die "%Error: Unknown parameter: $param\n";
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
|
||||
sub profcfunc {
|
||||
my $filename = shift;
|
||||
# Remove hex numbers before diffing
|
||||
my $fh = IO::File->new ($filename) or die "%Error: $! $filename,";
|
||||
|
||||
my %funcs;
|
||||
|
||||
while (defined (my $line=$fh->getline())) {
|
||||
# %time cumesec selfsec calls {stuff} name
|
||||
if ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$/) {
|
||||
my $pct=$1; my $sec=$2; my $calls=$3; my $func=$4;
|
||||
$funcs{$func}{pct} += $pct;
|
||||
$funcs{$func}{sec} += $sec;
|
||||
$funcs{$func}{calls} += $calls;
|
||||
}
|
||||
# Older gprofs have no call column for single-call functions
|
||||
# %time cumesec selfsec {stuff} name
|
||||
elsif ($line =~ /^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$/) {
|
||||
my $pct=$1; my $sec=$2; my $calls=1; my $func=$3;
|
||||
$funcs{$func}{pct} += $pct;
|
||||
$funcs{$func}{sec} += $sec;
|
||||
$funcs{$func}{calls} += $calls;
|
||||
}
|
||||
}
|
||||
$fh->close;
|
||||
# Older gprofs have no call column for single-call functions
|
||||
# %time cumesec selfsec {stuff} name
|
||||
match = re.match(
|
||||
r'^\s*([0-9.]+)\s+[0-9.]+\s+([0-9.]+)\s+[^a-zA-Z_]*([a-zA-Z_].*)$',
|
||||
line)
|
||||
if match:
|
||||
pct = float(match.group(1))
|
||||
sec = float(match.group(2))
|
||||
calls = 1
|
||||
func = match.group(3)
|
||||
if func not in funcs:
|
||||
funcs[func] = {'pct': 0, 'sec': 0, 'calls': 0}
|
||||
funcs[func]['pct'] += pct
|
||||
funcs[func]['sec'] += sec
|
||||
funcs[func]['calls'] += calls
|
||||
continue
|
||||
|
||||
# Find modules
|
||||
my %pointer_mods;
|
||||
my %verilated_mods;
|
||||
foreach my $func (keys %funcs) {
|
||||
if ($func =~ /(.*)::_eval\(([a-zA-Z_0-9]+__Syms).*\)$/) {
|
||||
$verilated_mods{$1} = qr/^$1/;
|
||||
$pointer_mods{$2} = $1;
|
||||
}
|
||||
}
|
||||
#print Dumper(\%pointer_mods, \%verilated_mods);
|
||||
verilated_mods = {}
|
||||
for func in funcs:
|
||||
match = re.search(r'(.*)::eval(_step)?\(', func)
|
||||
if match:
|
||||
prefix = match.group(1)
|
||||
if Args.debug:
|
||||
print("-got _eval %s prefix=%s" % (func, prefix))
|
||||
verilated_mods[prefix] = re.compile(r'^' + prefix)
|
||||
# pprint(verilated_mods)
|
||||
|
||||
# Resort by Verilog name
|
||||
my %vfuncs;
|
||||
my %groups;
|
||||
foreach my $func (keys %funcs) {
|
||||
my $pct = $funcs{$func}{pct};
|
||||
my $vfunc = $func;
|
||||
my $design;
|
||||
# Sort by Verilog name
|
||||
vfuncs = {}
|
||||
groups = {}
|
||||
groups['type'] = collections.defaultdict(lambda: 0)
|
||||
groups['design'] = collections.defaultdict(lambda: 0)
|
||||
groups['module'] = collections.defaultdict(lambda: 0)
|
||||
|
||||
if ($func =~ /\(([a-zA-Z_0-9]+__Syms)/) {
|
||||
$design = $pointer_mods{$1};
|
||||
}
|
||||
for func in funcs:
|
||||
pct = funcs[func]['pct']
|
||||
vfunc = func
|
||||
|
||||
foreach my $vde (keys %verilated_mods) {
|
||||
last if $design;
|
||||
if ($func =~ /$verilated_mods{$vde}/) {
|
||||
$design=$vde;
|
||||
last;
|
||||
}
|
||||
}
|
||||
funcarg = re.sub(r'^.*\(', '', func)
|
||||
|
||||
if ($vfunc =~ /__PROF__([a-zA-Z_0-9]+)__l?([0-9]+)\(/) {
|
||||
$vfunc = sprintf("VBlock %s:%d", $1, $2);
|
||||
$groups{type}{"Verilog Blocks under $design"} += $pct;
|
||||
$groups{design}{$design} += $pct;
|
||||
$groups{module}{$1} += $pct;
|
||||
} else {
|
||||
if ($design) {
|
||||
$vfunc = sprintf("VCommon %s", $func);
|
||||
$groups{type}{"Common code under $design"} += $pct;
|
||||
$groups{design}{$design} += $pct;
|
||||
$groups{module}{$design." common code"} += $pct;
|
||||
} elsif ($func =~ /^VL_[A-Z0-9_]+/
|
||||
|| $func =~ /^_?vl_[a-zA-Z0-9_]+/
|
||||
|| $func =~ /^verilated/i) {
|
||||
$vfunc = sprintf("VLib %s", $func);
|
||||
$groups{type}{'VLib'} += $pct;
|
||||
$groups{design}{'VLib'} += $pct;
|
||||
$groups{module}{'VLib'} += $pct;
|
||||
} elsif ($func =~ /^_mcount_private/) {
|
||||
$vfunc = sprintf("Prof %s", $func);
|
||||
$groups{type}{'Prof'} += $pct;
|
||||
$groups{design}{'Prof'} += $pct;
|
||||
$groups{module}{'Prof'} += $pct;
|
||||
} else {
|
||||
$vfunc = sprintf("C++ %s", $func);
|
||||
$groups{type}{'C++'} += $pct;
|
||||
$groups{design}{'C++'} += $pct;
|
||||
$groups{module}{'C++'} += $pct;
|
||||
}
|
||||
}
|
||||
$vfuncs{$vfunc} = $funcs{$func};
|
||||
}
|
||||
design = None
|
||||
for vde in verilated_mods:
|
||||
if verilated_mods[vde].match(func) or verilated_mods[vde].match(
|
||||
funcarg):
|
||||
design = vde
|
||||
break
|
||||
|
||||
vdesign = "-"
|
||||
|
||||
prof_match = re.search(r'__PROF__([a-zA-Z_0-9]+)__l?([0-9]+)\(', vfunc)
|
||||
if design and prof_match:
|
||||
linefunc = prof_match.group(1)
|
||||
lineno = int(prof_match.group(2))
|
||||
vfunc = "VBlock %s:%d" % (linefunc, lineno)
|
||||
vdesign = design
|
||||
groups['type']["Verilog Blocks under " + design] += pct
|
||||
groups['design'][design] += pct
|
||||
groups['module'][linefunc] += pct
|
||||
elif design:
|
||||
vfunc = "VCommon " + func
|
||||
vdesign = design
|
||||
groups['type']["Common code under " + design] += pct
|
||||
groups['design'][design] += pct
|
||||
groups['module'][design + " common code"] += pct
|
||||
elif re.match(r'(VL_[A-Z0-9_]+|_?vl_[a-zA-Z0-9_]+|Verilated)', vfunc):
|
||||
vfunc = "VLib " + func
|
||||
groups['type']['VLib'] += pct
|
||||
groups['design']['VLib'] += pct
|
||||
groups['module']['VLib'] += pct
|
||||
elif re.match(r'^_mcount_private', vfunc):
|
||||
vfunc = "Prof " + func
|
||||
groups['type']['Prof'] += pct
|
||||
groups['design']['Prof'] += pct
|
||||
groups['module']['Prof'] += pct
|
||||
else:
|
||||
vfunc = "C++ " + func
|
||||
groups['type']['C++'] += pct
|
||||
groups['design']['C++'] += pct
|
||||
groups['module']['C++'] += pct
|
||||
|
||||
if vfunc not in vfuncs:
|
||||
vfuncs[vfunc] = funcs[func]
|
||||
vfuncs[vfunc]['design'] = vdesign
|
||||
else:
|
||||
vfuncs[vfunc]['pct'] += funcs[func]['pct']
|
||||
vfuncs[vfunc]['calls'] += funcs[func]['calls']
|
||||
vfuncs[vfunc]['sec'] += funcs[func]['sec']
|
||||
|
||||
for ftype in ['type', 'design', 'module']:
|
||||
missing = 100
|
||||
for item in groups[ftype].keys():
|
||||
missing -= groups[ftype][item]
|
||||
groups[ftype]["\377Unaccounted for/rounding error"] = missing
|
||||
|
||||
print("Overall summary by %s:" % ftype)
|
||||
print(" %-6s %s" % ("% time", ftype))
|
||||
for what in sorted(groups[ftype].keys()):
|
||||
# \377 used to establish sort order
|
||||
pwhat = re.sub(r'^\377', '', what)
|
||||
print(" %6.2f %s" % (groups[ftype][what], pwhat))
|
||||
print()
|
||||
|
||||
design_width = 1
|
||||
for func in vfuncs:
|
||||
if design_width < len(vfuncs[func]['design']):
|
||||
design_width = len(vfuncs[func]['design'])
|
||||
|
||||
print("Verilog code profile:")
|
||||
print(" These are split into three categories:")
|
||||
print(" C++: Time in non-Verilated C++ code")
|
||||
print(" Prof: Time in profile overhead")
|
||||
print(" VBlock: Time attributable to a block in a" +
|
||||
" Verilog file and line")
|
||||
print(" VCommon: Time in a Verilated module," +
|
||||
" due to all parts of the design")
|
||||
print(" VLib: Time in Verilated common libraries," +
|
||||
" called by the Verilated code")
|
||||
print()
|
||||
|
||||
print(" % cumulative self ")
|
||||
print((" time seconds seconds calls %-" + str(design_width) +
|
||||
"s type filename and line number") % "design")
|
||||
|
||||
cume = 0
|
||||
for func in sorted(vfuncs.keys(),
|
||||
key=lambda f: vfuncs[f]['sec'],
|
||||
reverse=True):
|
||||
cume += vfuncs[func]['sec']
|
||||
print(("%6.2f %9.2f %8.2f %10d %-" + str(design_width) + "s %s") %
|
||||
(vfuncs[func]['pct'], cume, vfuncs[func]['sec'],
|
||||
vfuncs[func]['calls'], vfuncs[func]['design'], func))
|
||||
|
||||
|
||||
foreach my $type (qw(type design module)) {
|
||||
my $missing = 100;
|
||||
foreach (sort (keys %{$groups{$type}})) {
|
||||
$missing -= $groups{$type}{$_};
|
||||
}
|
||||
if ($missing) {
|
||||
$groups{$type}{"\377Unaccounted for/rounding error"} = $missing;
|
||||
}
|
||||
######################################################################
|
||||
######################################################################
|
||||
|
||||
print("Overall summary by $type:\n");
|
||||
printf(" %-6s %s\n","% time",$type);
|
||||
foreach my $what (sort (keys %{$groups{$type}})) {
|
||||
(my $pwhat = $what) =~ s/^\377//; # Just used to establish sort order
|
||||
printf(" %6.2f %s\n", $groups{$type}{$what}, $pwhat);
|
||||
}
|
||||
print("\n");
|
||||
}
|
||||
|
||||
print("Verilog code profile:\n");
|
||||
print(" These are split into three categories:\n");
|
||||
print(" C++: Time in non-Verilated C++ code\n");
|
||||
print(" Prof: Time in profile overhead\n");
|
||||
print(" VBlock: Time attributable to a block in a Verilog file and line\n");
|
||||
print(" VCommon: Time in a Verilated module, due to all parts of the design\n");
|
||||
print(" VLib: Time in Verilated common libraries, called by the Verilated code\n");
|
||||
print("\n");
|
||||
|
||||
print(" % cumulative self \n");
|
||||
print(" time seconds seconds calls type filename and line number\n");
|
||||
|
||||
my $cume = 0;
|
||||
foreach my $func (sort {$vfuncs{$b}{sec} <=> $vfuncs{$a}{sec}
|
||||
|| $a cmp $b}
|
||||
(keys %vfuncs)) {
|
||||
$cume += $vfuncs{$func}{sec};
|
||||
printf +("%6.2f %9.2f %8.2f %8d %s\n",
|
||||
$vfuncs{$func}{pct},
|
||||
$cume, $vfuncs{$func}{sec},
|
||||
$vfuncs{$func}{calls},
|
||||
$func);
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
verilator_profcfunc - Read gprof report created with --prof-cfuncs
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
verilator --prof-cfuncs ....
|
||||
gcc ....
|
||||
{run executable}
|
||||
gprof
|
||||
verilator_profcfuncs gprof.out
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Verilator_profcfunc reads a profile report created by gprof. The names of
|
||||
parser = argparse.ArgumentParser(
|
||||
allow_abbrev=False,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""Read gprof report created with --prof-cfuncs""",
|
||||
epilog=
|
||||
"""Verilator_profcfunc reads a profile report created by gprof. The names of
|
||||
the functions are then transformed, assuming the user used Verilator's
|
||||
--prof-cfuncs, and a report printed showing the percentage of time, etc,
|
||||
in each Verilog block.
|
||||
|
||||
For documentation see
|
||||
L<https://verilator.org/guide/latest/exe_verilator_profcfuncs.html>.
|
||||
https://verilator.org/guide/latest/exe_verilator_profcfunc.html
|
||||
|
||||
=head1 ARGUMENT SUMMARY
|
||||
|
||||
<filename> Input file (gprof.out)
|
||||
--help Display this help
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
The latest version is available from L<https://verilator.org>.
|
||||
|
||||
Copyright 2007-2021 by Wilson Snyder. This program is free software; you
|
||||
Copyright 2002-2022 by Wilson Snyder. This program is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
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
|
||||
SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0""")
|
||||
|
||||
=head1 SEE ALSO
|
||||
parser.add_argument('--debug',
|
||||
action='store_const',
|
||||
const=9,
|
||||
help='enable debug')
|
||||
parser.add_argument('filename', help='input gprof output to process')
|
||||
|
||||
C<verilator>
|
||||
|
||||
and L<https://verilator.org/guide/latest/exe_verilator_profcfuncs.html> for
|
||||
detailed documentation.
|
||||
|
||||
=cut
|
||||
Args = parser.parse_args()
|
||||
profcfunc(Args.filename)
|
||||
|
||||
######################################################################
|
||||
### Local Variables:
|
||||
### compile-command: "$V4/bin/verilator_profcfunc $V4/test_c/obj_dir/V*_03_*.tree $V4N/test_c/obj_dir/V*_03_*.tree"
|
||||
### End:
|
||||
# Local Variables:
|
||||
# compile-command: "./verilator_profcfunc ../test_regress/t/t_profcfunc.gprof"
|
||||
# End:
|
||||
|
||||
+7
-3
@@ -54,8 +54,12 @@ if [ "$CI_BUILD_STAGE_NAME" = "build" ]; then
|
||||
|
||||
if [ "$CI_OS_NAME" = "linux" ]; then
|
||||
sudo apt-get update
|
||||
sudo apt-get install libfl-dev libgoogle-perftools-dev ccache
|
||||
if [ "$CI_RUNS_ON" = "ubuntu-20.04" ]; then
|
||||
sudo apt-get install libfl-dev ccache
|
||||
if [ "$CI_RUNS_ON" != "ubuntu-22.04" ]; then
|
||||
# Some conflict of libunwind verison on 22.04, can live without it for now
|
||||
sudo apt-get install libgoogle-perftools-dev
|
||||
fi
|
||||
if [ "$CI_RUNS_ON" = "ubuntu-20.04" ] || [ "$CI_RUNS_ON" = "ubuntu-22.04" ]; then
|
||||
sudo apt-get install libsystemc libsystemc-dev
|
||||
fi
|
||||
if [ "$COVERAGE" = 1 ]; then
|
||||
@@ -85,7 +89,7 @@ elif [ "$CI_BUILD_STAGE_NAME" = "test" ]; then
|
||||
sudo apt-get update
|
||||
# libfl-dev needed for internal coverage's test runs
|
||||
sudo apt-get install gdb gtkwave lcov libfl-dev ccache
|
||||
if [ "$CI_RUNS_ON" = "ubuntu-20.04" ]; then
|
||||
if [ "$CI_RUNS_ON" = "ubuntu-20.04" ] || [ "$CI_RUNS_ON" = "ubuntu-22.04" ]; then
|
||||
sudo apt-get install libsystemc-dev
|
||||
fi
|
||||
if [ "$CI_M32" = 1 ]; then
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
# DESCRIPTION: codecov.io config
|
||||
#
|
||||
# Copyright 2020-2021 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2020-2022 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
+25
-33
@@ -1,20 +1,20 @@
|
||||
# DESCRIPTION: Process this file with autoconf to produce a configure script.
|
||||
#
|
||||
# Copyright 2003-2021 by Wilson Snyder. Verilator is free software; you
|
||||
# Copyright 2003-2022 by Wilson Snyder. Verilator is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[4.210 2021-07-07],
|
||||
[https://verilator.org],
|
||||
[verilator],[https://verilator.org])
|
||||
# When releasing, also update header of Changes file
|
||||
# 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],[4.226 2022-08-31],
|
||||
[https://verilator.org],
|
||||
[verilator],[https://verilator.org])
|
||||
|
||||
AC_CONFIG_HEADER(src/config_build.h)
|
||||
AC_CONFIG_HEADERS(src/config_build.h)
|
||||
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc verilator-config.cmake verilator-config-version.cmake)
|
||||
|
||||
# Version
|
||||
@@ -22,6 +22,8 @@ AC_MSG_RESULT([configuring for $PACKAGE_STRING])
|
||||
PACKAGE_VERSION_NUMBER=`AS_ECHO("$PACKAGE_VERSION") | sed 's/ .*//g'`
|
||||
AC_SUBST(PACKAGE_VERSION_NUMBER)
|
||||
AC_DEFINE_UNQUOTED([PACKAGE_VERSION_NUMBER_STRING],["$PACKAGE_VERSION_NUMBER"],[Package version as a number])
|
||||
VERILATOR_VERSION_INTEGER=`AS_ECHO("$PACKAGE_VERSION") | [sed 's/\([0-9]\)\.\([0-9][0-9][0-9]\) .*/\1\2000/g']`
|
||||
AC_SUBST(VERILATOR_VERSION_INTEGER)
|
||||
|
||||
# Ignore automake flags passed by Ubuntu builds
|
||||
AC_ARG_ENABLE([dependency-tracking],
|
||||
@@ -143,10 +145,10 @@ AC_SUBST(CFG_WITH_LONGTESTS)
|
||||
AC_MSG_RESULT($CFG_WITH_LONGTESTS)
|
||||
|
||||
# Compiler flags (ensure they are not empty to avoid configure defaults)
|
||||
CFLAGS+=" "
|
||||
CPPFLAGS+=" "
|
||||
CXXFLAGS+=" "
|
||||
LDFLAGS+=" "
|
||||
CFLAGS="$CFLAGS "
|
||||
CPPFLAGS="$CPPFLAGS "
|
||||
CXXFLAGS="$CXXFLAGS "
|
||||
LDFLAGS="$LDFLAGS "
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
@@ -346,33 +348,23 @@ AC_SUBST(CFG_CXXFLAGS_PROFILE)
|
||||
|
||||
# Flag to select newest language standard supported
|
||||
# Macros work such that first option that passes is the one we take
|
||||
# Currently enabled gnu++14/c++14 due to packaged SystemC dependency
|
||||
# gnu++17 is the newest that Verilator supports
|
||||
# std++03 is the oldest that Verilator supports
|
||||
# Currently enable c++17/c++14 due to packaged SystemC dependency
|
||||
# c++17 is the newest that Verilator is regularly tested to support
|
||||
# c++11 is the oldest that Verilator supports
|
||||
# gnu is requried for Cygwin to compile verilated.h successfully
|
||||
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++20)
|
||||
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++17)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++14)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++11)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++03)
|
||||
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++20)
|
||||
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++17)
|
||||
case "$(which lsb_release 2>&1 > /dev/null && lsb_release -d)" in
|
||||
*Arch*Linux* | *Ubuntu*22.04*)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++17)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++17)
|
||||
;;
|
||||
esac
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++14)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++14)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=gnu++11)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++11)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++03)
|
||||
AC_SUBST(CFG_CXXFLAGS_STD_NEWEST)
|
||||
# And likewise oldest standard (same list above, backwards)
|
||||
# This is used for internal testing
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=c++03)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=c++11)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=c++14)
|
||||
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=c++17)
|
||||
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=c++20)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++03)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++11)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++14)
|
||||
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++17)
|
||||
#_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_OLDEST,-std=gnu++20)
|
||||
AC_SUBST(CFG_CXXFLAGS_STD_OLDEST)
|
||||
|
||||
# Flags for compiling Verilator internals including parser, and Verilated files
|
||||
# These turn on extra warnings and are only used with 'configure --enable-ccwarn'
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
*.html
|
||||
*.pdf
|
||||
_build
|
||||
guide/spelling.txt
|
||||
|
||||
@@ -3,18 +3,25 @@ under the Developer Certificate of Origin (https://developercertificate.org/).
|
||||
|
||||
Please see the Verilator manual for 200+ additional contributors. Thanks to all.
|
||||
|
||||
Adrien Le Masle
|
||||
Ahmed El-Mahmoudy
|
||||
Aleksander Kiryk
|
||||
Alex Chadwick
|
||||
Àlex Torregrosa
|
||||
Aliaksei Chapyzhenka
|
||||
Ameya Vikram Singh
|
||||
Andreas Kuster
|
||||
Arkadiusz Kozdra
|
||||
Chris Randall
|
||||
Chuxuan Wang
|
||||
Conor McCullough
|
||||
Dan Petrisko
|
||||
Daniel Bates
|
||||
David Horton
|
||||
David Metz
|
||||
David Stanford
|
||||
David Turner
|
||||
Drew Ranck
|
||||
Drew Taussig
|
||||
Driss Hafdi
|
||||
Edgar E. Iglesias
|
||||
@@ -26,15 +33,22 @@ Geza Lore
|
||||
Gianfranco Costamagna
|
||||
Glen Gibb
|
||||
Graham Rushton
|
||||
Guokai Chen
|
||||
Gustav Svensk
|
||||
Harald Heckmann
|
||||
Howard Su
|
||||
Huang Rui
|
||||
Huanghuang Zhou
|
||||
HungMingWu
|
||||
HyungKi Jeong
|
||||
Iru Cai
|
||||
Ivan Vnučec
|
||||
Iztok Jeras
|
||||
James Hanlon
|
||||
James Hutchinson
|
||||
James Pallister
|
||||
Jamey Hicks
|
||||
Jamie Iles
|
||||
Jan Van Winkel
|
||||
Jean Berniolles
|
||||
Jeremy Bennett
|
||||
@@ -42,26 +56,34 @@ John Coiner
|
||||
John Demme
|
||||
Jonathan Drolet
|
||||
Josh Redford
|
||||
Julie Schwartz
|
||||
Julien Margetts
|
||||
Kaleb Barrett
|
||||
Kamil Rakoczy
|
||||
Kanad Kanhere
|
||||
Keith Colbert
|
||||
Kevin Kiningham
|
||||
Krzysztof Bieganski
|
||||
Kuba Ober
|
||||
Larry Doolittle
|
||||
Ludwig Rogiers
|
||||
Lukasz Dalek
|
||||
Maarten De Braekeleer
|
||||
Maciej Sobkowski
|
||||
Marco Widmer
|
||||
Mariusz Glebocki
|
||||
Markus Krause
|
||||
Marlon James
|
||||
Marshal Qiao
|
||||
Martin Schmidt
|
||||
Martin Stadler
|
||||
Matthew Ballance
|
||||
Michael Killough
|
||||
Michaël Lefebvre
|
||||
Mike Popoloski
|
||||
Miodrag Milanović
|
||||
Morten Borup Petersen
|
||||
Mostafa Gamal
|
||||
Nandu Raj
|
||||
Nathan Kohagen
|
||||
Nathan Myers
|
||||
@@ -75,14 +97,18 @@ Pieter Kapsenberg
|
||||
Piotr Binkowski
|
||||
Qingyao Sun
|
||||
Rafal Kapuscik
|
||||
Raynard Qiao
|
||||
Richard Myers
|
||||
Rupert Swarbrick
|
||||
Ryszard Rozak
|
||||
Samuel Riedel
|
||||
Sean Cross
|
||||
Sebastien Van Cauwenberghe
|
||||
Sergi Granell
|
||||
Stefan Wallentowitz
|
||||
Stephen Henry
|
||||
Steven Hugg
|
||||
Teng Huang
|
||||
Tim Snyder
|
||||
Tobias Rosenkranz
|
||||
Tobias Wölfel
|
||||
@@ -91,11 +117,16 @@ Tomasz Gorochowik
|
||||
Tymoteusz Blazejczyk
|
||||
Udi Finkelstein
|
||||
Unai Martinez-Corral
|
||||
Varun Koyyalagunta
|
||||
Vassilis Papaefstathiou
|
||||
Veripool API Bot
|
||||
Victor Besyakov
|
||||
William D. Jones
|
||||
Wilson Snyder
|
||||
Xi Zhang
|
||||
Yoda Lee
|
||||
Yossi Nivin
|
||||
Yuri Victorovich
|
||||
Yutetsu TAKATSUKASA
|
||||
Yves Mathieu
|
||||
Zhanglei Wang
|
||||
|
||||
+3
-1
@@ -5,7 +5,7 @@
|
||||
#
|
||||
# Code available from: https://verilator.org
|
||||
#
|
||||
# Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
@@ -35,6 +35,7 @@ default:
|
||||
# Intermediate rules
|
||||
|
||||
vl-extract: ../bin/verilator ../Changes
|
||||
ln -sf ../spelling.txt guide/spelling.txt
|
||||
mkdir -p _build/gen
|
||||
$(PYTHON3) bin/vl_sphinx_extract ../bin/verilator
|
||||
sed 's/`/\&96;/g' < ../Changes > _build/gen/Changes
|
||||
@@ -77,6 +78,7 @@ clean mostlyclean distclean maintainer-clean::
|
||||
rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs *.idx
|
||||
rm -f *.ev *.evs *.ov *.ovs *.cv *.cvs *.ma *.mas
|
||||
rm -f *.tex
|
||||
rm -f guide/spelling.txt
|
||||
|
||||
distclean maintainer-clean::
|
||||
rm -f *.info* *.1 *.html *.pdf $(INFOS)
|
||||
|
||||
@@ -40,7 +40,7 @@ parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""Read a file and extract documentation data.""",
|
||||
epilog=
|
||||
""" Copyright 2021-2021 by Wilson Snyder. This package is free software;
|
||||
""" Copyright 2021-2022 by Wilson Snyder. This package is free software;
|
||||
you can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
@@ -55,7 +55,7 @@ parser = argparse.ArgumentParser(
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
description="""Post-process Sphinx HTML.""",
|
||||
epilog=
|
||||
""" Copyright 2021-2021 by Wilson Snyder. This package is free software;
|
||||
""" Copyright 2021-2022 by Wilson Snyder. This package is free software;
|
||||
you can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
.. comment: generated by t_lint_didnotconverge_bad
|
||||
.. code-block:: sv
|
||||
:linenos:
|
||||
|
||||
always_comb b = ~a;
|
||||
always_comb a = b;
|
||||
@@ -0,0 +1,7 @@
|
||||
.. comment: generated by t_lint_didnotconverge_bad
|
||||
.. code-block::
|
||||
|
||||
-V{t#,#}+ Vt_lint_didnotconverge_bad___024root___change_request
|
||||
-V{t#,#}+ Vt_lint_didnotconverge_bad___024root___change_request_1
|
||||
-V{t#,#} CHANGE: t/t_lint_didnotconverge_bad.v:14: a
|
||||
%Error: t/t_lint_didnotconverge_bad.v:7: Verilated model didn't converge
|
||||
@@ -0,0 +1,4 @@
|
||||
.. comment: generated by t_lint_didnotconverge_nodbg_bad
|
||||
.. code-block::
|
||||
|
||||
%Error: t/t_lint_didnotconverge_bad.v:7: Verilated model didn't converge
|
||||
@@ -0,0 +1,5 @@
|
||||
.. comment: generated by t_lint_stmtdly_bad
|
||||
.. code-block:: sv
|
||||
:emphasize-lines: 1
|
||||
|
||||
#100 $finish; //<--- Warning
|
||||
@@ -0,0 +1,4 @@
|
||||
.. comment: generated by t_lint_stmtdly_bad
|
||||
.. code-block::
|
||||
|
||||
%Warning-STMTDLY: example.v:1:8 Unsupported: Ignoring delay on this delayed statement.
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
****************
|
||||
|
||||
+2
-2
@@ -1,4 +1,4 @@
|
||||
# pylint: disable=C0103,C0114,C0116,E0402,W0622
|
||||
# pylint: disable=C0103,C0114,C0116,C0301,E0402,W0622
|
||||
#
|
||||
# Configuration file for Verilator's Sphinx documentation builder.
|
||||
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
@@ -36,7 +36,7 @@ def setup(app):
|
||||
# -- Project information
|
||||
|
||||
project = 'Verilator'
|
||||
copyright = '2021 by Wilson Snyder, under LGPL-3.0 or Artistic-2.0'
|
||||
copyright = '2022 by Wilson Snyder, under LGPL-3.0 or Artistic-2.0'
|
||||
author = 'Wilson Snyder'
|
||||
|
||||
# The master toctree document.
|
||||
|
||||
+22
-60
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Connecting:
|
||||
@@ -86,58 +86,17 @@ Connecting to C++
|
||||
In C++ output mode (:vlopt:`--cc`), the Verilator generated model class is a
|
||||
simple C++ class. The user must write a C++ wrapper and main loop for the
|
||||
simulation, which instantiates the model class, and link with the Verilated
|
||||
model. Here is a simple example:
|
||||
model.
|
||||
|
||||
.. code-block:: C++
|
||||
Refer to ``examples/make_tracing_c`` in the distribution for a detailed
|
||||
commented example.
|
||||
|
||||
#include <verilated.h> // Defines common routines
|
||||
#include <iostream> // Need std::cout
|
||||
#include "Vtop.h" // From Verilating "top.v"
|
||||
Top level IO signals are read and written as members of the model. You
|
||||
call the model's :code:`eval()` method to evaluate the model. When the
|
||||
simulation is complete call the model's :code:`final()` method to execute
|
||||
any SystemVerilog final blocks, and complete any assertions. See
|
||||
:ref:`Evaluation Loop`.
|
||||
|
||||
Vtop *top; // Instantiation of model
|
||||
|
||||
vluint64_t main_time = 0; // Current simulation time
|
||||
// This is a 64-bit integer to reduce wrap over issues and
|
||||
// allow modulus. This is in units of the timeprecision
|
||||
// used in Verilog (or from --timescale-override)
|
||||
|
||||
double sc_time_stamp() { // Called by $time in Verilog
|
||||
return main_time; // converts to double, to match
|
||||
// what SystemC does
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
Verilated::commandArgs(argc, argv); // Remember args
|
||||
|
||||
top = new Vtop; // Create model
|
||||
|
||||
top->reset_l = 0; // Set some inputs
|
||||
|
||||
while (!Verilated::gotFinish()) {
|
||||
if (main_time > 10) {
|
||||
top->reset_l = 1; // Deassert reset
|
||||
}
|
||||
if ((main_time % 10) == 1) {
|
||||
top->clk = 1; // Toggle clock
|
||||
}
|
||||
if ((main_time % 10) == 6) {
|
||||
top->clk = 0;
|
||||
}
|
||||
top->eval(); // Evaluate model
|
||||
cout << top->out << endl; // Read a output
|
||||
main_time++; // Time passes...
|
||||
}
|
||||
|
||||
top->final(); // Done simulating
|
||||
// // (Though this example doesn't get here)
|
||||
delete top;
|
||||
}
|
||||
|
||||
|
||||
Note top level IO signals are read and written as members of the model. You
|
||||
call the :code:`eval()` method to evaluate the model. When the simulation is
|
||||
complete call the :code:`final()` method to execute any SystemVerilog final
|
||||
blocks, and complete any assertions. See :ref:`Evaluation Loop`.
|
||||
|
||||
|
||||
Connecting to SystemC
|
||||
@@ -150,7 +109,7 @@ netlist as an instantiation.
|
||||
The SC_MODULE gets the same pinout as the Verilog module, with the
|
||||
following type conversions: Pins of a single bit become bool. Pins 2-32
|
||||
bits wide become uint32_t's. Pins 33-64 bits wide become sc_bv's or
|
||||
vluint64_t's depending on the :vlopt:`--no-pins64` option. Wider pins
|
||||
uint64_t's depending on the :vlopt:`--no-pins64` option. Wider pins
|
||||
become sc_bv's. (Uints simulate the fastest so are used where possible.)
|
||||
|
||||
Model internals, including lower level sub-modules are not pure SystemC
|
||||
@@ -200,7 +159,7 @@ DPI System Task/Functions
|
||||
-------------------------
|
||||
|
||||
Verilator extends the DPI format to allow using the same scheme to
|
||||
efficiently add system functions. Simply use a dollar-sign prefixed system
|
||||
efficiently add system functions. Use a dollar-sign prefixed system
|
||||
function name for the import, but note it must be escaped.
|
||||
|
||||
.. code-block:: sv
|
||||
@@ -257,7 +216,9 @@ with respect to that top level module, then the scope could be set with
|
||||
|
||||
#include "svdpi.h"
|
||||
...
|
||||
svSetScope(svGetScopeFromName("TOP.dut"));
|
||||
const svScope scope = svGetScopeFromName("TOP.dut");
|
||||
assert(scope); // Check for nullptr if scope not found
|
||||
svSetScope(scope);
|
||||
|
||||
(Remember that Verilator adds a "TOP" to the top of the module hierarchy.)
|
||||
|
||||
@@ -422,12 +383,12 @@ accesses the above signal "readme" would be:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
cat >sim_main.cpp <<'<<EOF'
|
||||
cat >sim_main.cpp <<'EOF'
|
||||
#include "Vour.h"
|
||||
#include "verilated.h"
|
||||
#include "verilated_vpi.h" // Required to get definitions
|
||||
|
||||
vluint64_t main_time = 0; // See comments in first example
|
||||
uint64_t main_time = 0; // See comments in first example
|
||||
double sc_time_stamp() { return main_time; }
|
||||
|
||||
void read_and_check() {
|
||||
@@ -444,14 +405,15 @@ accesses the above signal "readme" would be:
|
||||
|
||||
int main(int argc, char** argv, char** env) {
|
||||
Verilated::commandArgs(argc, argv);
|
||||
Vour* top = new Vour;
|
||||
Verilated::internalsDump(); // See scopes to help debug
|
||||
while (!Verilated::gotFinish()) {
|
||||
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
|
||||
const std::unique_ptr<Vour> top{new Vour{contextp.get()}};
|
||||
|
||||
contextp->internalsDump(); // See scopes to help debug
|
||||
while (!contextp->gotFinish()) {
|
||||
top->eval();
|
||||
VerilatedVpi::callValueCbs(); // For signal callbacks
|
||||
read_and_check();
|
||||
}
|
||||
delete top;
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
@@ -506,7 +468,7 @@ structure. If a ``VerilatedContext`` is not created prior to creating a
|
||||
model, a default global one is created automatically.
|
||||
|
||||
The ``Verilated::`` methods, including the ``Verilated::commandArgs`` call
|
||||
shown above, simply call VerilatedContext methods using the default global
|
||||
shown above, call VerilatedContext methods using the default global
|
||||
VerilatedContext. (Technically they operate on the last one used by a
|
||||
given thread.) If you are using multiple simulation contexts you should
|
||||
not use the Verilated:: methods, and instead always use VerilatedContext
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
*******************************
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
************************
|
||||
@@ -13,7 +13,8 @@ When possible, please instead report bugs at `Verilator Issues
|
||||
|
||||
Primary author is Wilson Snyder <[email protected]>.
|
||||
|
||||
Major concepts by Paul Wasson, Duane Galbi, John Coiner and Jie Xu.
|
||||
Major concepts by Paul Wasson, Duane Galbi, John Coiner, Geza Lore, Yutetsu
|
||||
Takatsukasa, and Jie Xu.
|
||||
|
||||
|
||||
Contributors
|
||||
@@ -22,14 +23,14 @@ Contributors
|
||||
Many people have provided ideas and other assistance with Verilator.
|
||||
|
||||
Verilator is receiving major development support from the `CHIPS Alliance
|
||||
<https://chipsalliance.org>`_.
|
||||
<https://chipsalliance.org>`_ and `Shunyao CAD <https://shunyaocad.com>`_.
|
||||
|
||||
Previous major corporate sponsors of Verilator, by providing significant
|
||||
contributions of time or funds included include: Atmel Corporation, Cavium
|
||||
Inc., Compaq Corporation, Digital Equipment Corporation, Embecosm Ltd.,
|
||||
Hicamp Systems, Intel Corporation, Mindspeed Technologies Inc., MicroTune
|
||||
Inc., picoChip Designs Ltd., Sun Microsystems Inc., Nauticus Networks Inc.,
|
||||
and SiCortex Inc.
|
||||
SiCortex Inc, and Shunyao CAD.
|
||||
|
||||
The people who have contributed major functionality are: Byron Bradley,
|
||||
Jeremy Bennett, Lane Brooks, John Coiner, Duane Galbi, Geza Lore, Todd
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
*********
|
||||
@@ -8,7 +8,7 @@ Copyright
|
||||
The latest version of Verilator is available from `https://verilator.org
|
||||
<https://verilator.org>`_.
|
||||
|
||||
Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
||||
Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||
can redistribute it and/or modify the Verilator internals under the terms
|
||||
of either the GNU Lesser General Public License Version 3 or the Perl
|
||||
Artistic License Version 2.0.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
Deprecations
|
||||
@@ -9,12 +9,29 @@ The following deprecated items are scheduled for future removal:
|
||||
C++11 compiler support
|
||||
Verilator currently requires C++11 or newer compilers. Verilator will
|
||||
require C++14 or newer compilers for both compiling Verilator and
|
||||
compiling Verilated models no sooner than January 2022.
|
||||
compiling Verilated models no sooner than January 2023.
|
||||
|
||||
Configuration File -msg
|
||||
The :vlopt:`lint_off` "-msg" option has been replaced with the "-rule"
|
||||
option. "-msg" is planned for removal no sooner than January 2021.
|
||||
Verilated_heavy.h
|
||||
The legacy "verilated_heavy.h" include was replaced with just including
|
||||
"verilated.h". Verilated_heavy.h is planned for removal no sooner than
|
||||
July 2022.
|
||||
|
||||
XML locations
|
||||
The XML "fl" attribute has been replaced with the "loc" attribute. "fl"
|
||||
is planned for removal no sooner than January 2021.
|
||||
Option `--cdc`
|
||||
The experimental `--cdc` option is believed to be generally unused and is
|
||||
planned for removal no sooner than January 2023.
|
||||
|
||||
Option `-O<letter>`
|
||||
The debug `-O<letter>` options have been replaced with
|
||||
`-fno-<optimization>` debug options to match GCC. The old options are
|
||||
planned for removal no sooner than June 2023.
|
||||
|
||||
Option `--prof-threads`
|
||||
The `--prof-threads` option has been superseded by the `--prof-exec` and
|
||||
`--prof-pgo` options and is planned for removal no sooner than April 2023.
|
||||
|
||||
Verilated model options `+verilator+prof+threads+*`
|
||||
The `+verilator+prof+threads+start`, `+verilator+prof+threads+window` and
|
||||
`+verilator+prof+threads+file` options have been superseded by the
|
||||
`+verilator+prof+exec+start`, `+verilator+prof+exec+window` and
|
||||
`+verilator+prof+exec+file` options respectively and are planned for removal
|
||||
no sooner than April 2023.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
Environment
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Example C++ Execution:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
First you need Verilator installed, see :ref:`Installation`. In brief, if
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Examples in the Distribution:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Example SystemC Execution:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Examples:
|
||||
|
||||
+29
-11
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Simulation Runtime Arguments:
|
||||
@@ -8,7 +8,7 @@ Simulation Runtime Arguments
|
||||
|
||||
The following are the arguments that may be passed to a Verilated
|
||||
executable, provided that executable calls
|
||||
:code:`Verilated::commandArgs()`.
|
||||
:code:`VerilatedContext*->commandArgs(argc, argv)`.
|
||||
|
||||
All simulation runtime arguments begin with "+verilator", so that the
|
||||
user's executable may skip over all "+verilator" arguments when parsing its
|
||||
@@ -38,30 +38,48 @@ Summary:
|
||||
|
||||
Display help and exit.
|
||||
|
||||
.. option:: +verilator+prof+threads+file+<filename>
|
||||
.. option:: +verilator+prof+exec+file+<filename>
|
||||
|
||||
When a model was Verilated using :vlopt:`--prof-threads`, sets the
|
||||
When a model was Verilated using :vlopt:`--prof-exec`, sets the
|
||||
simulation runtime filename to dump to. Defaults to
|
||||
:file:`profile_threads.dat`.
|
||||
:file:`profile_exec.dat`.
|
||||
|
||||
.. option:: +verilator+prof+threads+start+<value>
|
||||
.. option:: +verilator+prof+exec+start+<value>
|
||||
|
||||
When a model was Verilated using :vlopt:`--prof-threads`, the simulation
|
||||
When a model was Verilated using :vlopt:`--prof-exec`, the simulation
|
||||
runtime will wait until $time is at this value (expressed in units of
|
||||
the time precision), then start the profiling warmup, then
|
||||
capturing. Generally this should be set to some time that is well within
|
||||
the normal operation of the simulation, i.e. outside of reset. If 0, the
|
||||
dump is disabled. Defaults to 1.
|
||||
|
||||
.. option:: +verilator+prof+threads+window+<value>
|
||||
.. option:: +verilator+prof+exec+window+<value>
|
||||
|
||||
When a model was Verilated using :vlopt:`--prof-threads`, after $time
|
||||
reaches :vlopt:`+verilator+prof+threads+start+\<value\>`, Verilator will
|
||||
When a model was Verilated using :vlopt:`--prof-exec`, after $time
|
||||
reaches :vlopt:`+verilator+prof+exec+start+\<value\>`, Verilator will
|
||||
warm up the profiling for this number of eval() calls, then will capture
|
||||
the profiling of this number of eval() calls. Defaults to 2, which
|
||||
makes sense for a single-clock-domain module where it's typical to want
|
||||
to capture one posedge eval() and one negedge eval().
|
||||
|
||||
.. option:: +verilator+prof+threads+file+<filename>
|
||||
|
||||
Deprecated. Alias for :vlopt:`+verilator+prof+exec+file+\<filename\>`
|
||||
|
||||
.. option:: +verilator+prof+threads+start+<value>
|
||||
|
||||
Deprecated. Alias for :vlopt:`+verilator+prof+exec+start+\<value\>`
|
||||
|
||||
.. option:: +verilator+prof+threads+window+<value>
|
||||
|
||||
Deprecated. Alias for :vlopt:`+verilator+prof+exec+window+\<filename\>`
|
||||
|
||||
.. option:: +verilator+prof+vlt+file+<filename>
|
||||
|
||||
When a model was Verilated using :vlopt:`--prof-pgo`, sets the
|
||||
profile-guided optimization data runtime filename to dump to. Defaults
|
||||
to :file:`profile.vlt`.
|
||||
|
||||
.. option:: +verilator+rand+reset+<value>
|
||||
|
||||
When a model was Verilated using :vlopt:`--x-initial unique
|
||||
@@ -78,7 +96,7 @@ Summary:
|
||||
.. option:: +verilator+noassert
|
||||
|
||||
Disable assert checking per runtime argument. This is the same as
|
||||
calling :code:`Verilated::assertOn(false)` in the model.
|
||||
calling :code:`VerilatedContext*->assertOn(false)` in the model.
|
||||
|
||||
.. option:: +verilator+V
|
||||
|
||||
|
||||
+296
-166
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
verilator Arguments
|
||||
@@ -99,10 +99,10 @@ Summary:
|
||||
.. option:: --bbox-sys
|
||||
|
||||
Black box any unknown $system task or function calls. System tasks will
|
||||
simply become no-operations, and system functions will be replaced with
|
||||
unsized zero. Arguments to such functions will be parsed, but not
|
||||
otherwise checked. This prevents errors when linting in the presence of
|
||||
company specific PLI calls.
|
||||
become no-operations, and system functions will be replaced with unsized
|
||||
zero. Arguments to such functions will be parsed, but not otherwise
|
||||
checked. This prevents errors when linting in the presence of company
|
||||
specific PLI calls.
|
||||
|
||||
Using this argument will likely cause incorrect simulation.
|
||||
|
||||
@@ -129,16 +129,6 @@ Summary:
|
||||
is also used). Verilator manages the build itself, and for this --build
|
||||
requires GNU Make to be available on the platform.
|
||||
|
||||
.. option:: -CFLAGS <flags>
|
||||
|
||||
Add specified C compiler argument to the generated makefiles. For
|
||||
multiple flags either pass them as a single argument with space
|
||||
separators quoted in the shell (:command:`-CFLAGS "-a -b"`), or use
|
||||
multiple -CFLAGS options (:command:`-CFLAGS -a -CFLAGS -b`).
|
||||
|
||||
When make is run on the generated makefile these will be passed to the
|
||||
C++ compiler (g++/clang++/msvc++).
|
||||
|
||||
.. option:: --cc
|
||||
|
||||
Specifies C++ without SystemC output mode; see also :vlopt:`--sc`
|
||||
@@ -156,43 +146,43 @@ Summary:
|
||||
have interest in adding more traditional CDC checks, please contact the
|
||||
authors.
|
||||
|
||||
.. option:: -CFLAGS <flags>
|
||||
|
||||
Add specified C compiler argument to the generated makefiles. For
|
||||
multiple flags either pass them as a single argument with space
|
||||
separators quoted in the shell (:command:`-CFLAGS "-a -b"`), or use
|
||||
multiple -CFLAGS options (:command:`-CFLAGS -a -CFLAGS -b`).
|
||||
|
||||
When make is run on the generated makefile these will be passed to the
|
||||
C++ compiler (g++/clang++/msvc++).
|
||||
|
||||
.. option:: --clk <signal-name>
|
||||
|
||||
Sometimes it is quite difficult for Verilator to distinguish clock
|
||||
signals from other data signals. Occasionally the clock signals can end
|
||||
up in the checking list of signals which determines if further
|
||||
evaluation is needed. This will heavily degrade the performance of a
|
||||
Verilated model.
|
||||
|
||||
With :vlopt:`--clk`, the specified signal-name is taken as a root clock
|
||||
into the model, then Verilator will mark the signal as clocker and
|
||||
propagate the clocker attribute automatically to other signals derived
|
||||
from that. In this way, Verilator will try to avoid taking the clocker
|
||||
signal into checking list.
|
||||
into the model; Verilator will mark the signal as clocker and
|
||||
propagate the clocker attribute automatically to other signals downstream in
|
||||
that clock tree.
|
||||
|
||||
Note signal-name is specified by the RTL hierarchy path. For example,
|
||||
v.foo.bar. If the signal is the input to top-module, the directly the
|
||||
signal name. If you find it difficult to find the exact name, try to use
|
||||
a :option:`/*verilator&32;clocker*/` metacomment in RTL file to mark the
|
||||
The provided signal-name is specified using a RTL hierarchy path. For
|
||||
example, v.foo.bar. If the signal is the input to top-module, then
|
||||
directly provide the signal name. Alternatively, use a
|
||||
:option:`/*verilator&32;clocker*/` metacomment in RTL file to mark the
|
||||
signal directly.
|
||||
|
||||
If clock signals are assigned to vectors and then later used
|
||||
individually, Verilator will attempt to decompose the vector and connect
|
||||
the single-bit clock signals directly. This should be transparent to
|
||||
the user.
|
||||
If clock signals are assigned to vectors and then later used as
|
||||
individual bits, Verilator will attempt to decompose the vector and
|
||||
connect the single-bit clock signals.
|
||||
|
||||
.. option:: --make <build-tool>
|
||||
The clocker attribute is useful in cases where Verilator does not
|
||||
properly distinguish clock signals from other data signals. Using
|
||||
clocker will cause the signal indicated to be considered a clock, and
|
||||
remove it from the combinatorial logic reevaluation checking code. This
|
||||
may greatly improve performance.
|
||||
|
||||
Generates a script for the specified build tool.
|
||||
.. option:: --no-clk <signal-name>
|
||||
|
||||
Supported values are ``gmake`` for GNU Make and ``cmake`` for CMake.
|
||||
Both can be specified together. If no build tool is specified, gmake is
|
||||
assumed. The executable of gmake can be configured via environment
|
||||
variable "MAKE".
|
||||
|
||||
When using :vlopt:`--build` Verilator takes over the responsibility of
|
||||
building the model library/executable. For this reason :option:`--make`
|
||||
cannot be specified when using :vlopt:`--build`.
|
||||
Prevent the specified signal from being marked as clock. See
|
||||
:vlopt:`--clk`.
|
||||
|
||||
.. option:: --compiler <compiler-name>
|
||||
|
||||
@@ -303,6 +293,13 @@ Summary:
|
||||
<--debugi>`). Higher levels produce more detailed messages. See
|
||||
:vlopt:`--debug` for other implications of enabling debug.
|
||||
|
||||
.. option:: --no-decoration
|
||||
|
||||
When creating output Verilated code, minimize comments, white space,
|
||||
symbol names and other decorative items, at the cost of greatly reduced
|
||||
readability. This may assist C++ compile times. This will not typically
|
||||
change the ultimate model's performance, but may in some cases.
|
||||
|
||||
.. option:: --default-language <value>
|
||||
|
||||
Select the language to be used by default when first processing each
|
||||
@@ -446,6 +443,78 @@ Summary:
|
||||
flattening large designs may require significant CPU time, memory and
|
||||
storage.
|
||||
|
||||
.. option:: -fno-acyc-simp
|
||||
|
||||
.. option:: -fno-assemble
|
||||
|
||||
.. option:: -fno-case
|
||||
|
||||
.. option:: -fno-combine
|
||||
|
||||
.. option:: -fno-const
|
||||
|
||||
.. option:: -fno-const-bit-op-tree
|
||||
|
||||
.. option:: -fno-dedup
|
||||
|
||||
.. option:: -fno-expand
|
||||
|
||||
.. option:: -fno-gate
|
||||
|
||||
.. option:: -fno-inline
|
||||
|
||||
.. option:: -fno-life
|
||||
|
||||
.. option:: -fno-life-post
|
||||
|
||||
.. option:: -fno-localize
|
||||
|
||||
.. option:: -fno-merge-cond
|
||||
|
||||
.. option:: -fno-merge-cond-motion
|
||||
|
||||
.. option:: -fno-merge-const-pool
|
||||
|
||||
.. option:: -fno-reloop
|
||||
|
||||
.. option:: -fno-reorder
|
||||
|
||||
.. option:: -fno-split
|
||||
|
||||
.. option:: -fno-subst
|
||||
|
||||
.. option:: -fno-subst-const
|
||||
|
||||
.. option:: -fno-table
|
||||
|
||||
Rarely needed. Disables one of the internal optimization steps. These
|
||||
are typically used only when recommended by a maintainer to help debug
|
||||
or work around an issue.
|
||||
|
||||
.. option:: -future0 <option>
|
||||
|
||||
Rarely needed. Suppress an unknown Verilator option for an option that
|
||||
takes no additional arguments. This is used to allow scripts written
|
||||
with pragmas for a later version of Verilator to run under a older
|
||||
version. e.g. :code:`-future0 option --option` would on older versions
|
||||
that do not understand :code:`--option` or :code:`+option` suppress what
|
||||
would otherwise be an invalid option error, and on newer versions that
|
||||
implement :code:`--option`, :code:`-future0 option --option` would have
|
||||
the :code:`-future0 option` ignored and the :code:`--option` would
|
||||
function appropriately.
|
||||
|
||||
.. option:: -future1 <option>
|
||||
|
||||
Rarely needed. Suppress an unknown Verilator option for an option that
|
||||
takes an additional argument. This is used to allow scripts written
|
||||
with pragmas for a later version of Verilator to run under a older
|
||||
version. e.g. :code:`-future1 option --option arg` would on older
|
||||
versions that do not understand :code:`--option arg` or :code:`+option
|
||||
arg` suppress what would otherwise be an invalid option error, and on
|
||||
newer versions that implement :code:`--option arg`, :code:`-future1
|
||||
option --option arg` would have the :code:`-future1 option` ignored and
|
||||
the :code:`--option arg` would function appropriately.
|
||||
|
||||
.. option:: -G<name>=<value>
|
||||
|
||||
Overwrites the given parameter of the toplevel module. The value is
|
||||
@@ -536,6 +605,14 @@ Summary:
|
||||
times, but potentially faster simulation speed. This setting is ignored
|
||||
for very small modules; they will always be inlined, if allowed.
|
||||
|
||||
.. option:: --instr-count-dpi <value>
|
||||
|
||||
Assumed dynamic instruction count of the average DPI import. This is used
|
||||
by the partitioning algorithm when creating a multithread model. The
|
||||
default value is 200. Adjusting this to an appropriate value can yield
|
||||
performance improvements in multithreaded models. Ignored when creating a
|
||||
single threaded model.
|
||||
|
||||
.. option:: -j [<value>]
|
||||
|
||||
Specify the level of parallelism for :vlopt:`--build`. The <value> must
|
||||
@@ -544,21 +621,6 @@ Summary:
|
||||
to limit the number of parallel build jobs but attempt to execute all
|
||||
independent build steps in parallel.
|
||||
|
||||
.. option:: -LDFLAGS <flags>
|
||||
|
||||
Add specified C linker arguments to the generated makefiles. For multiple
|
||||
flags either pass them as a single argument with space separators quoted
|
||||
in the shell (``-LDFLAGS "-a -b"``), or use multiple -LDFLAGS arguments
|
||||
(``-LDFLAGS -a -LDFLAGS -b``).
|
||||
|
||||
When make is run on the generated makefile these will be passed to the
|
||||
C++ linker (ld) **after** the primary file being linked. This flag is
|
||||
called :vlopt:`-LDFLAGS` as that's the traditional name in simulators;
|
||||
it's would have been better called LDLIBS as that's the Makefile
|
||||
variable it controls. (In Make, LDFLAGS is before the first object,
|
||||
LDLIBS after. -L libraries need to be in the Make variable LDLIBS, not
|
||||
LDFLAGS.)
|
||||
|
||||
.. option:: --l2-name <value>
|
||||
|
||||
Instead of using the module name when showing Verilog scope, use the
|
||||
@@ -575,6 +637,38 @@ Summary:
|
||||
A synonym for :vlopt:`--default-language`, for compatibility with other
|
||||
tools and earlier versions of Verilator.
|
||||
|
||||
.. option:: -LDFLAGS <flags>
|
||||
|
||||
Add specified C linker arguments to the generated makefiles. For multiple
|
||||
flags either pass them as a single argument with space separators quoted
|
||||
in the shell (``-LDFLAGS "-a -b"``), or use multiple -LDFLAGS arguments
|
||||
(``-LDFLAGS -a -LDFLAGS -b``).
|
||||
|
||||
When make is run on the generated makefile these will be passed to the
|
||||
C++ linker (ld) **after** the primary file being linked. This flag is
|
||||
called :vlopt:`-LDFLAGS` as that's the traditional name in simulators;
|
||||
it's would have been better called LDLIBS as that's the Makefile
|
||||
variable it controls. (In Make, LDFLAGS is before the first object,
|
||||
LDLIBS after. -L libraries need to be in the Make variable LDLIBS, not
|
||||
LDFLAGS.)
|
||||
|
||||
.. option:: --lib-create <name>
|
||||
|
||||
Produces C++, Verilog wrappers and a Makefile which can in turn produce
|
||||
a DPI library which can be used by Verilator or other simulators along
|
||||
with the corresponding Verilog wrapper. The Makefile will build both a
|
||||
static and dynamic version of the library named :file:`lib<name>.a` and
|
||||
:file:`lib<name>.so` respectively. This is done because some simulators
|
||||
require a dynamic library, but the static library is arguably easier to
|
||||
use if possible. :vlopt:`--protect-lib` implies :vlopt:`--protect-ids`.
|
||||
|
||||
When using :vlopt:`--lib-create` it is advised to also use
|
||||
:vlopt:`--timescale-override /1fs <--timescale-override>` to ensure the
|
||||
model has a time resolution that is always compatible with the time
|
||||
precision of the upper instantiating module.
|
||||
|
||||
See also :vlopt:`--protect-lib`.
|
||||
|
||||
.. option:: +libext+<ext>[+<ext>][...]
|
||||
|
||||
Specify the extensions that should be used for finding modules. If for
|
||||
@@ -593,6 +687,19 @@ Summary:
|
||||
If the design is not to be completely Verilated see also the
|
||||
:vlopt:`--bbox-sys` and :vlopt:`--bbox-unsup` options.
|
||||
|
||||
.. option:: --make <build-tool>
|
||||
|
||||
Generates a script for the specified build tool.
|
||||
|
||||
Supported values are ``gmake`` for GNU Make and ``cmake`` for CMake.
|
||||
Both can be specified together. If no build tool is specified, gmake is
|
||||
assumed. The executable of gmake can be configured via environment
|
||||
variable "MAKE".
|
||||
|
||||
When using :vlopt:`--build` Verilator takes over the responsibility of
|
||||
building the model library/executable. For this reason :option:`--make`
|
||||
cannot be specified when using :vlopt:`--build`.
|
||||
|
||||
.. option:: -MAKEFLAGS <string>
|
||||
|
||||
When using :vlopt:`--build`, add the specified argument to the invoked
|
||||
@@ -607,17 +714,6 @@ Summary:
|
||||
Set the maximum number literal width (e.g. in 1024'd22 this it the
|
||||
1024). Defaults to 64K.
|
||||
|
||||
.. option:: --MMD =item --no-MMD
|
||||
|
||||
Enable/disable creation of .d dependency files, used for make dependency
|
||||
detection, similar to gcc -MMD option. By default this option is
|
||||
enabled for :vlopt:`--cc` or :vlopt:`--sc` modes.
|
||||
|
||||
.. option:: --MP
|
||||
|
||||
When creating .d dependency files with :vlopt:`--MMD` option, make phony
|
||||
targets. Similar to :command:`gcc -MP` option.
|
||||
|
||||
.. option:: --Mdir <directory>
|
||||
|
||||
Specifies the name of the Make object directory. All generated files
|
||||
@@ -625,40 +721,23 @@ Summary:
|
||||
The directory is created if it does not exist and the parent directories
|
||||
exist; otherwise manually create the Mdir before calling Verilator.
|
||||
|
||||
.. option:: --no-merge-const-pool
|
||||
.. option:: --MMD
|
||||
|
||||
Rarely needed. In order to minimize cache footprint, values of different
|
||||
data type, that are yet emitted identically in C++ are merged in the
|
||||
constant pool. This option disables this and causes every constant pool
|
||||
entry with a distinct data type to be emitted separately.
|
||||
.. option:: --no-MMD
|
||||
|
||||
Enable/disable creation of .d dependency files, used for make dependency
|
||||
detection, similar to gcc -MMD option. By default this option is
|
||||
enabled for :vlopt:`--cc` or :vlopt:`--sc` modes.
|
||||
|
||||
.. option:: --mod-prefix <topname>
|
||||
|
||||
Specifies the name to prepend to all lower level classes. Defaults to
|
||||
the same as :vlopt:`--prefix`.
|
||||
|
||||
.. option:: --no-clk <signal-name>
|
||||
.. option:: --MP
|
||||
|
||||
Prevent the specified signal from being marked as clock. See
|
||||
:vlopt:`--clk`.
|
||||
|
||||
.. option:: --no-decoration
|
||||
|
||||
When creating output Verilated code, minimize comments, white space,
|
||||
symbol names and other decorative items, at the cost of greatly reduced
|
||||
readability. This may assist C++ compile times. This will not typically
|
||||
change the ultimate model's performance, but may in some cases.
|
||||
|
||||
.. option:: --no-pins64
|
||||
|
||||
Backward compatible alias for :vlopt:`--pins-bv 33 <--pins-bv>`.
|
||||
|
||||
.. option:: --no-skip-identical =item --skip-identical
|
||||
|
||||
Rarely needed. Disables or enables skipping execution of Verilator if
|
||||
all source files are identical, and all output files exist with newer
|
||||
dates. By default this option is enabled for :vlopt:`--cc` or
|
||||
:vlopt:`--sc` modes only.
|
||||
When creating .d dependency files with :vlopt:`--MMD` option, make phony
|
||||
targets. Similar to :command:`gcc -MP` option.
|
||||
|
||||
.. option:: +notimingchecks
|
||||
|
||||
@@ -680,9 +759,9 @@ Summary:
|
||||
|
||||
Rarely needed. Enables or disables a specific optimizations, with the
|
||||
optimization selected based on the letter passed. A lowercase letter
|
||||
disables an optimization, an upper case letter enables it. This is
|
||||
intended for debugging use only; see the source code for
|
||||
version-dependent mappings of optimizations to -O letters.
|
||||
disables an optimization, an upper case letter enables it. This option
|
||||
is deprecated and the various `-f<optimization>` arguments should be
|
||||
used instead.
|
||||
|
||||
.. option:: -o <executable>
|
||||
|
||||
@@ -737,15 +816,10 @@ Summary:
|
||||
With :vlopt:`-E`, disable generation of :code:`&96;line` markers and
|
||||
blank lines, similar to :command:`gcc -P`.
|
||||
|
||||
.. option:: --pins64
|
||||
|
||||
Backward compatible alias for :vlopt:`--pins-bv 65 <--pins-bv>`. Note
|
||||
that's a 65, not a 64.
|
||||
|
||||
.. option:: --pins-bv <width>
|
||||
|
||||
Specifies SystemC inputs/outputs of greater than or equal to <width>
|
||||
bits wide should use sc_bv's instead of uint32/vluint64_t's. The
|
||||
bits wide should use sc_bv's instead of uint32/uint64_t's. The
|
||||
default is "--pins-bv 65", and the value must be less than or equal
|
||||
to 65. Versions before Verilator 3.671 defaulted to "--pins-bv 33".
|
||||
The more sc_bv is used, the worse for performance. Use the
|
||||
@@ -774,6 +848,15 @@ Summary:
|
||||
of uint32_t. Likewise pins of width 9-16 will use uint16_t instead of
|
||||
uint32_t.
|
||||
|
||||
.. option:: --pins64
|
||||
|
||||
Backward compatible alias for :vlopt:`--pins-bv 65 <--pins-bv>`. Note
|
||||
that's a 65, not a 64.
|
||||
|
||||
.. option:: --no-pins64
|
||||
|
||||
Backward compatible alias for :vlopt:`--pins-bv 33 <--pins-bv>`.
|
||||
|
||||
.. option:: --pipe-filter <command>
|
||||
|
||||
Rarely needed. Verilator will spawn the specified command as a
|
||||
@@ -803,12 +886,17 @@ Summary:
|
||||
prepended to the name of the :vlopt:`--top` option, or V prepended to
|
||||
the first Verilog filename passed on the command line.
|
||||
|
||||
.. option:: --private
|
||||
|
||||
Opposite of :vlopt:`--public`. Is the default; this option exists for
|
||||
backwards compatibility.
|
||||
|
||||
.. option:: --prof-c
|
||||
|
||||
When compiling the C++ code, enable the compiler's profiling flag
|
||||
(e.g. :code:`g++ -pg`). See :ref:`Profiling`.
|
||||
|
||||
Using :vlopt:`--prof-cfuncs` also enables :vlopt:`prof-c`.
|
||||
Using :vlopt:`--prof-cfuncs` also enables :vlopt:`--prof-c`.
|
||||
|
||||
.. option:: --prof-cfuncs
|
||||
|
||||
@@ -820,29 +908,21 @@ Summary:
|
||||
came from. This allows gprof or oprofile reports to be correlated with
|
||||
the original Verilog source statements. See :ref:`Profiling`.
|
||||
|
||||
Using :vlopt:`--prof-cfuncs` also enables :vlopt:`prof-c`.
|
||||
Using :vlopt:`--prof-cfuncs` also enables :vlopt:`--prof-c`.
|
||||
|
||||
.. option:: --prof-exec
|
||||
|
||||
Enable collection of execution trace, that can be converted into a gantt
|
||||
chart with verilator_gantt See :ref:`Execution Profiling`.
|
||||
|
||||
.. option:: --prof-pgo
|
||||
|
||||
Enable collection of profiling data for profile guided Verilation. Currently
|
||||
this is only useful with :vlopt:`--threads`. See :ref:`Thread PGO`.
|
||||
|
||||
.. option:: --prof-threads
|
||||
|
||||
Enable gantt chart data collection for threaded builds. See :ref:`Thread
|
||||
Profiling`.
|
||||
|
||||
.. option:: --protect-key <key>
|
||||
|
||||
Specifies the private key for :vlopt:`--protect-ids`. For best security
|
||||
this key should be 16 or more random bytes, a reasonable secure choice
|
||||
is the output of :command:`verilator --generate-key` . Typically, a key
|
||||
would be created by the user once for a given protected design library,
|
||||
then every Verilator run for subsequent versions of that library would
|
||||
be passed the same :vlopt:`--protect-key`. Thus, if the input Verilog is
|
||||
similar between library versions (Verilator runs), the Verilated code
|
||||
will likewise be mostly similar.
|
||||
|
||||
If :vlopt:`--protect-key` is not specified and a key is needed,
|
||||
Verilator will generate a new key for every Verilator run. As the key is
|
||||
not saved, this is best for security, but means every Verilator run will
|
||||
give vastly different output even for identical input, perhaps harming
|
||||
compile times (and certainly thrashing any "ccache").
|
||||
Deprecated. Same as --prof-exec and --prof-pgo together.
|
||||
|
||||
.. option:: --protect-ids
|
||||
|
||||
@@ -861,34 +941,37 @@ Summary:
|
||||
|
||||
Using DPI imports/exports is allowed and generally relatively safe in
|
||||
terms of information disclosed, which is limited to the DPI function
|
||||
prototyptes. Use of the VPI is not recommended as many design details
|
||||
prototypes. Use of the VPI is not recommended as many design details
|
||||
may be exposed, and an INSECURE warning will be issued.
|
||||
|
||||
.. option:: --protect-key <key>
|
||||
|
||||
Specifies the private key for :vlopt:`--protect-ids`. For best security
|
||||
this key should be 16 or more random bytes, a reasonable secure choice
|
||||
is the output of :command:`verilator --generate-key` . Typically, a key
|
||||
would be created by the user once for a given protected design library,
|
||||
then every Verilator run for subsequent versions of that library would
|
||||
be passed the same :vlopt:`--protect-key`. Thus, if the input Verilog is
|
||||
similar between library versions (Verilator runs), the Verilated code
|
||||
will likewise be mostly similar.
|
||||
|
||||
If :vlopt:`--protect-key` is not specified and a key is needed,
|
||||
Verilator will generate a new key for every Verilator run. As the key is
|
||||
not saved, this is best for security, but means every Verilator run will
|
||||
give vastly different output even for identical input, perhaps harming
|
||||
compile times (and certainly thrashing any "ccache").
|
||||
|
||||
.. option:: --protect-lib <name>
|
||||
|
||||
Produces C++, Verilog wrappers and a Makefile which can in turn produce
|
||||
a DPI library which can be used by Verilator or other simulators along
|
||||
with the corresponding Verilog wrapper. The Makefile will build both a
|
||||
static and dynamic version of the library named :file:`lib<name>.a` and
|
||||
:file:`lib<name>.so` respectively. This is done because some simulators
|
||||
require a dynamic library, but the static library is arguably easier to
|
||||
use if possible. :vlopt:`--protect-lib` implies :vlopt:`--protect-ids`.
|
||||
Produces a DPI library similar to :vlopt:`--lib-create`, but hides
|
||||
internal design details. :vlopt:`--protect-lib` implies
|
||||
:vlopt:`--protect-ids`, and :vlopt:`--lib-create`.
|
||||
|
||||
This allows for the secure delivery of sensitive IP without the need for
|
||||
encrypted RTL (i.e. IEEE P1735). See :file:`examples/make_protect_lib`
|
||||
in the distribution for a demonstration of how to build and use the DPI
|
||||
library.
|
||||
|
||||
When using :vlopt:`--protect-lib` it is advised to also use
|
||||
:vlopt:`--timescale-override /1fs <--timescale-override>` to ensure the
|
||||
model has a time resolution that is always compatible with the time
|
||||
precision of the upper instantiating module.
|
||||
|
||||
.. option:: --private
|
||||
|
||||
Opposite of :vlopt:`--public`. Is the default; this option exists for
|
||||
backwards compatibility.
|
||||
|
||||
.. option:: --public
|
||||
|
||||
This is only for historical debug use. Using it may result in
|
||||
@@ -981,6 +1064,15 @@ Summary:
|
||||
|
||||
Specifies SystemC output mode; see also :vlopt:`--cc` option.
|
||||
|
||||
.. option:: --skip-identical
|
||||
|
||||
.. option:: --no-skip-identical
|
||||
|
||||
Rarely needed. Disables or enables skipping execution of Verilator if
|
||||
all source files are identical, and all output files exist with newer
|
||||
dates. By default this option is enabled for :vlopt:`--cc` or
|
||||
:vlopt:`--sc` modes only.
|
||||
|
||||
.. option:: --stats
|
||||
|
||||
Creates a dump file with statistics on the design in
|
||||
@@ -1018,7 +1110,8 @@ Summary:
|
||||
is not thread safe. With "--threads 1", the generated model is single
|
||||
threaded but may run in a multithreaded environment. With "--threads N",
|
||||
where N >= 2, the model is generated to run multithreaded on up to N
|
||||
threads. See :ref:`Multithreading`.
|
||||
threads. See :ref:`Multithreading`. This option also applies to
|
||||
:vlopt:`--trace` (but not :vlopt:`--trace-fst`).
|
||||
|
||||
.. option:: --threads-dpi all
|
||||
|
||||
@@ -1044,6 +1137,8 @@ Summary:
|
||||
Verilator assumes DPI pure imports are threadsafe, but non-pure DPI
|
||||
imports are not.
|
||||
|
||||
See also :vlopt:`--instr-count-dpi` option.
|
||||
|
||||
.. option:: --threads-max-mtasks <value>
|
||||
|
||||
Rarely needed. When using :vlopt:`--threads`, specify the number of
|
||||
@@ -1094,7 +1189,8 @@ Summary:
|
||||
Having tracing compiled in may result in some small performance losses,
|
||||
even when tracing is not turned on during model execution.
|
||||
|
||||
See also :vlopt:`--trace-threads` option.
|
||||
When using :vlopt:`--threads`, VCD tracing is parallelized, using the
|
||||
same number of threads as passed to :vlopt:`--threads`.
|
||||
|
||||
.. option:: --trace-coverage
|
||||
|
||||
@@ -1148,18 +1244,18 @@ Summary:
|
||||
.. option:: --trace-threads *threads*
|
||||
|
||||
Enable waveform tracing using separate threads. This is typically faster
|
||||
in simulation runtime but uses more total compute. This option is
|
||||
independent of, and works with, both :vlopt:`--trace` and
|
||||
:vlopt:`--trace-fst`. Different trace formats can take advantage of
|
||||
more trace threads to varying degrees. Currently VCD tracing can utilize
|
||||
at most "--trace-threads 1", and FST tracing can utilize at most
|
||||
"--trace-threads 2". This overrides :vlopt:`--no-threads` .
|
||||
in simulation runtime but uses more total compute. This option only
|
||||
applies to :vlopt:`--trace-fst`. FST tracing can utilize at most
|
||||
"--trace-threads 2". This overrides :vlopt:`--no-threads`.
|
||||
|
||||
This option is accepted, but has absolutely no effect with
|
||||
:vlopt:`--trace`, which respects :vlopt:`--threads` instead.
|
||||
|
||||
.. option:: --trace-underscore
|
||||
|
||||
Enable tracing of signals that start with an underscore. Normally, these
|
||||
signals are not output during tracing. See also
|
||||
:vlopt:`--coverage-underscore` option.
|
||||
Enable tracing of signals or modules that start with an
|
||||
underscore. Normally, these signals are not output during tracing. See
|
||||
also :vlopt:`--coverage-underscore` option.
|
||||
|
||||
.. option:: -U<var>
|
||||
|
||||
@@ -1348,9 +1444,10 @@ Summary:
|
||||
.. note::
|
||||
|
||||
This option applies only to values which are explicitly written as X
|
||||
in the Verilog source code. Initial values of clocks are set to 0
|
||||
unless `--x-initial-edge` is specified. Initial values of all other
|
||||
state holding variables are controlled with `--x-initial`.
|
||||
in modules (not classes) 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`.
|
||||
|
||||
.. option:: --x-initial 0
|
||||
|
||||
@@ -1496,9 +1593,9 @@ The grammar of configuration commands is as follows:
|
||||
|
||||
.. option:: no_clocker -module "<modulename>" [-function "<funcname>"] -var "<signame>"
|
||||
|
||||
Indicate the signal is used as clock or not. This information is used by
|
||||
Verilator to mark the signal as clocker and propagate the clocker
|
||||
attribute automatically to derived signals. See :vlopt:`--clk`.
|
||||
Indicates that the signal is used as clock or not. This information is
|
||||
used by Verilator to mark the signal and any derived signals as
|
||||
clocker. See :vlopt:`--clk`.
|
||||
|
||||
Same as :option:`/*verilator&32;clocker*/` metacomment.
|
||||
|
||||
@@ -1512,6 +1609,14 @@ The grammar of configuration commands is as follows:
|
||||
|
||||
Same as :option:`/*verilator&32;coverage_block_off*/` metacomment.
|
||||
|
||||
.. option:: forceable -module "<modulename>" -var "<signame>"
|
||||
|
||||
Generate public `<signame>__VforceEn` and `<signame>__VforceVal` signals
|
||||
that can be used to force/release a signal from C++ code. The force control
|
||||
signals are created as :option:`public_flat` signals.
|
||||
|
||||
Same as :option:`/*verilator&32;forceable*/` metacomment.
|
||||
|
||||
.. option:: full_case -file "<filename>" -lines <lineno>
|
||||
|
||||
.. option:: parallel_case -file "<filename>" -lines <lineno>
|
||||
@@ -1602,12 +1707,18 @@ The grammar of configuration commands is as follows:
|
||||
:option:`/*verilator&32;public_flat*/`, etc, metacomments. See
|
||||
e.g. :ref:`VPI Example`.
|
||||
|
||||
.. option:: profile_data -mtask "<mtask_hash>" -cost <cost_value>
|
||||
|
||||
Feeds profile-guided optimization data into the Verilator algorithms in
|
||||
order to improve model runtime performance. This option is not expected
|
||||
to be used by users directly. See :ref:`Thread PGO`.
|
||||
|
||||
.. option:: sc_bv -module "<modulename>" [-task "<taskname>"] -var "<signame>"
|
||||
|
||||
.. option:: sc_bv -module "<modulename>" [-function "<funcname>"] -var "<signame>"
|
||||
|
||||
Sets the port to be of :code:`sc_bv<{width}>` type, instead of bool,
|
||||
vluint32_t or vluint64_t. Same as :option:`/*verilator&32;sc_bv*/`
|
||||
uint32_t or uint64_t. Same as :option:`/*verilator&32;sc_bv*/`
|
||||
metacomment.
|
||||
|
||||
.. option:: sformat [-module "<modulename>"] [-task "<taskname>"] -var "<signame>"
|
||||
@@ -1636,9 +1747,28 @@ The grammar of configuration commands is as follows:
|
||||
|
||||
.. option:: tracing_off [-file "<filename>" [-lines <line> [ - <line> ]]]
|
||||
|
||||
Enable/disable waveform tracing for all future signals declared in the
|
||||
specified filename (or wildcard with '\*' or '?', or all files if
|
||||
omitted) and range of line numbers (or all lines if omitted).
|
||||
.. option:: tracing_on [-scope "<scopename>" [-levels <levels> ]]
|
||||
|
||||
For tracing_off, instances below any module in the files/ranges
|
||||
specified will also not be traced.
|
||||
.. option:: tracing_off [-scope "<scopename>" [-levels <levels> ]]
|
||||
|
||||
Enable/disable waveform tracing for all future signals declared in
|
||||
all files.
|
||||
|
||||
With -file, enable/disable waveform tracing in the specified
|
||||
filename (or wildcard with '\*' or '?'), and -line range of line
|
||||
numbers (or all lines if omitted).
|
||||
|
||||
For tracing_off with -file, instances below any module in the
|
||||
files/ranges specified will also not be traced. To overcome this
|
||||
feature, use tracing_on on the upper module declaration and on any
|
||||
cells, or use the -scope flavor of the command.
|
||||
|
||||
With -scope enable/disable waveform tracing for the specified scope (or
|
||||
wildcard with '\*' or '?'), and optional --levels number of levels
|
||||
below. These controls only take place after other file/line/module
|
||||
based controls have indicated the signal should be traced.
|
||||
|
||||
With -levels (used with -scope), the number of levels below that
|
||||
scope which the rule is to match, where 0 means all levels below, 1
|
||||
the exact level as the provided scope, and 2 meaning an additional
|
||||
level of children below the provided scope, etc.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
verilator_coverage
|
||||
@@ -67,7 +67,7 @@ which have low coverage are written to the output directory.
|
||||
|
||||
Specifies if the coverage point does not include the count number of
|
||||
coverage hits, then the coverage point will be considered above the
|
||||
threashold, and the coverage report will put a "%" to indicate the coverage
|
||||
threshold, and the coverage report will put a "%" to indicate the coverage
|
||||
is not sufficient. Defaults to 10.
|
||||
|
||||
.. option:: --help
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
verilator_gantt
|
||||
@@ -10,42 +10,60 @@ starts and ends, and showing when each thread is busy or idle.
|
||||
|
||||
For an overview of use of verilator_gantt, see :ref:`Profiling`.
|
||||
|
||||
Gantt Chart Contents
|
||||
--------------------
|
||||
Gantt Chart VCD
|
||||
---------------
|
||||
|
||||
The generated Gantt chart has time on the X-axis. Times shown are to the
|
||||
scale printed, i.e. a certain about of time for each character width. The
|
||||
Y-axis shows threads, each thread's execution is shown on one line. That
|
||||
line shows "[" at the position in time when it executes.
|
||||
Verilated_gantt creates a value change dump (VCD) format dump file which
|
||||
may be viewed in a waveform viewer (e.g. C<GTKWave>):
|
||||
|
||||
Following the "[" is the CPU number the task executed on, followed by zero
|
||||
or more "-" to make the width of the characters match the scaled execution
|
||||
time, followed by a "]". If the scale is too small, the CPU number and
|
||||
mtask number will not be printed. If the scale is very small, a "&"
|
||||
indicates multiple mtasks started at that time position.
|
||||
.. figure:: figures/fig_gantt_min.png
|
||||
|
||||
Example verilator_gantt output, as viewed with GTKWave.
|
||||
|
||||
The viewed waveform chart has time on the X-axis, with one unit for each
|
||||
time tick of the system's high-performance counter.
|
||||
|
||||
Also creates a value change dump (VCD) format dump file which may be viewed
|
||||
in a waveform viewer (e.g. C<GTKWave>). See below.
|
||||
|
||||
Gantt Chart VCD Signals
|
||||
-----------------------
|
||||
|
||||
In waveforms there are the following signals. Most signals the "decimal"
|
||||
format will remove the leading zeros and make the traces easier to read.
|
||||
In waveforms there are the following signals. In GTKWave, using a data
|
||||
format of "decimal" will remove the leading zeros and make the traces
|
||||
easier to read.
|
||||
|
||||
parallelism
|
||||
evals
|
||||
Increments each time when eval_step was measured to be active. This
|
||||
allow visualization of how much time eval_step was active.
|
||||
|
||||
eval_loop
|
||||
Increments each time when the evaluation loop within eval_step was
|
||||
measured to be active. For best performance there is only a single
|
||||
evaluation loop within each eval_step call, that is the eval_loop
|
||||
waveform looks identical to the evals waveform.
|
||||
|
||||
measured_parallelism
|
||||
The number of mtasks active at this time, for best performance this will
|
||||
match the thread count. You may want to use an "analog step" format to
|
||||
match the thread count. In GTKWave, use a data format of "analog step" to
|
||||
view this signal.
|
||||
|
||||
predicted_parallelism
|
||||
The number of mtasks Verilator predicted would be active at this time,
|
||||
for best performance this will match the thread count. In GTKWave, use a
|
||||
data format of "analog step" to view this signal.
|
||||
|
||||
cpu#_thread
|
||||
For the given CPU number, the thread number executing.
|
||||
For the given CPU number, the thread number measured to be executing.
|
||||
|
||||
mtask#_cpu
|
||||
For the given mtask id, the CPU it is executing on.
|
||||
For the given mtask id, the CPU it was measured to execute on.
|
||||
|
||||
thread#_mtask
|
||||
For the given thread number, the mtask id executing.
|
||||
For the given thread number, the mtask id it was executing.
|
||||
|
||||
predicted_thread#_mtask
|
||||
For the given thread number, the mtask id Verilator predicted would be
|
||||
executing.
|
||||
|
||||
|
||||
verilator_gantt Arguments
|
||||
-------------------------
|
||||
@@ -54,19 +72,12 @@ verilator_gantt Arguments
|
||||
|
||||
.. option:: <filename>
|
||||
|
||||
The filename to read data from, defaults to "profile_threads.dat".
|
||||
The filename to read data from, defaults to "profile_exec.dat".
|
||||
|
||||
.. option:: --help
|
||||
|
||||
Displays a help summary, the program version, and exits.
|
||||
|
||||
.. option:: --scale <n>
|
||||
|
||||
Sets the number of time units per character on the X-axis of the generated
|
||||
Gantt chart. (On x86, time units are rdtsc ticks.) Defaults to 0, which
|
||||
will automatically compute a reasonable scale where no two mtasks need to
|
||||
fit into same character width's worth of scaled time.
|
||||
|
||||
.. option:: --no-vcd
|
||||
|
||||
Disables creating a .vcd file.
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
verilator_profcfuncs
|
||||
====================
|
||||
verilator_profcfunc
|
||||
===================
|
||||
|
||||
Verilator_profcfunc reads a profile report created by gprof. The names of
|
||||
the functions are then transformed, assuming the user used Verilator's
|
||||
--prof-cfuncs, and a report printed showing the percentage of time, etc, in
|
||||
each Verilog block.
|
||||
|
||||
For an overview of use of verilator_profcfuncs, see :ref:`Profiling`.
|
||||
Due to rounding errors in gprof reports, the input report's percentages may
|
||||
not total to 100%. In the verilator_profcfunc report this will get
|
||||
reported as a rounding error.
|
||||
|
||||
verilator_profcfuncs Arguments
|
||||
------------------------------
|
||||
For an overview of use of verilator_profcfunc, see :ref:`Profiling`.
|
||||
|
||||
.. program:: verilator_profcfuncs
|
||||
verilator_profcfunc Arguments
|
||||
-----------------------------
|
||||
|
||||
.. program:: verilator_profcfunc
|
||||
|
||||
.. option:: <filename>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
*********************************
|
||||
@@ -15,5 +15,5 @@ options to each executable.
|
||||
exe_verilator.rst
|
||||
exe_verilator_coverage.rst
|
||||
exe_verilator_gantt.rst
|
||||
exe_verilator_profcfuncs.rst
|
||||
exe_verilator_profcfunc.rst
|
||||
exe_sim.rst
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
*******************
|
||||
@@ -48,6 +48,14 @@ or "`ifdef`"'s may break other tools.
|
||||
Verilog functions where the variable is flattened out, and also enable
|
||||
other optimizations.
|
||||
|
||||
Verilator does not use any text inside the quotes for
|
||||
ordering/scheduling. If you need the $c to be called at a specific
|
||||
time, e.g. when a variable changes, then the $c must be under an
|
||||
appropriate sensitivity statement, e.g. :code:`always @(posedge clk)
|
||||
$c("func()")` to call it on every edge, or e.g. :code:`always @*
|
||||
c("func(",a,")")` to call it when :code:`a` changes (the latter working
|
||||
because :code:`a` is outside the quotes).
|
||||
|
||||
If you will be reading or writing any Verilog variables inside the C++
|
||||
functions, the Verilog signals must be declared with
|
||||
:option:`/*verilator&32;public*/` metacomments.
|
||||
@@ -176,10 +184,9 @@ or "`ifdef`"'s may break other tools.
|
||||
|
||||
.. option:: /*verilator&32;no_clocker*/
|
||||
|
||||
Used after a signal declaration to indicate the signal is used as clock
|
||||
or not. This information is used by Verilator to mark the signal as
|
||||
clocker and propagate the clocker attribute automatically to derived
|
||||
signals. See :vlopt:`--clk`.
|
||||
Specifies that the signal is used as clock or not. This information is
|
||||
used by Verilator to mark the signal and any derived signals as
|
||||
clocker. See :vlopt:`--clk`.
|
||||
|
||||
Same as :option:`clocker` and :option:`no_clocker` in configuration
|
||||
files.
|
||||
@@ -202,6 +209,20 @@ or "`ifdef`"'s may break other tools.
|
||||
(if appropriate :vlopt:`--coverage` flags are passed) after being
|
||||
disabled earlier with :option:`/*verilator&32;coverage_off*/`.
|
||||
|
||||
.. option:: /*verilator&32;forceable*/
|
||||
|
||||
Specifies that the signal (net or variable) should be made forceable from
|
||||
C++ code by generating public `<signame>__VforceEn` and
|
||||
`<signame>__VforceVal` signals The force control signals are created as
|
||||
:option:`public_flat` signals.
|
||||
|
||||
To force a marked signal from C++, set the corresponding `__VforceVal`
|
||||
variable to the desired value, and the `__VforceEn` signal to the bit-mask
|
||||
indicating which bits of the signal to force. To force all bits of the
|
||||
target signal, set `__VforceEn` to all ones. To release the signal (or part
|
||||
thereof), set appropriate bits of the `__VforceEn` signal to zero.
|
||||
|
||||
Same as :option:`forceable` in configuration files.
|
||||
|
||||
.. _verilator_hier_block:
|
||||
|
||||
@@ -424,7 +445,7 @@ or "`ifdef`"'s may break other tools.
|
||||
.. option:: /*verilator&32;sc_bv*/
|
||||
|
||||
Used after a port declaration. It sets the port to be of
|
||||
:code:`sc_bv<{width}>` type, instead of bool, vluint32_t or vluint64_t.
|
||||
:code:`sc_bv<{width}>` type, instead of bool, uint32_t or uint64_t.
|
||||
This may be useful if the port width is parameterized and the
|
||||
instantiating C++ code wants to always have a sc_bv so it can accept any
|
||||
width. In general you should avoid using this attribute when not
|
||||
@@ -482,6 +503,13 @@ or "`ifdef`"'s may break other tools.
|
||||
Verilator) text that should be passed through to the XML output as a tag,
|
||||
for use by downstream applications.
|
||||
|
||||
.. option:: /*verilator&32;trace_init_task*/
|
||||
|
||||
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`
|
||||
or :vlopt:`--hierarchical` is used along with :vlopt:`--trace`.
|
||||
|
||||
.. option:: /*verilator&32;tracing_off*/
|
||||
|
||||
Disable waveform tracing for all future signals that are declared in
|
||||
|
||||
+41
-23
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
******************************
|
||||
@@ -35,15 +35,17 @@ simulators.
|
||||
Does Verilator run under Windows?
|
||||
"""""""""""""""""""""""""""""""""
|
||||
|
||||
Yes, using Cygwin. Verilated output also compiles under Microsoft Visual
|
||||
C++, but this is not tested every release.
|
||||
Yes, ideally run Ubuntu under Windows Subsystem for Linux (WSL2).
|
||||
Alternatively use Cygwin, though this tends to be slower and is not
|
||||
regularly tested. Verilated output also compiles under Microsoft Visual
|
||||
C++, but this is also not regularly tested.
|
||||
|
||||
|
||||
Can you provide binaries?
|
||||
"""""""""""""""""""""""""
|
||||
|
||||
You can install Verilator via the system package manager (apt, yum, etc.)
|
||||
on many Linux distributions, including Debian, Ubuntu, SuSE, RedHat, and
|
||||
on many Linux distributions, including Debian, Ubuntu, SuSE, Red Hat, and
|
||||
others. These packages are provided by the Linux distributions and
|
||||
generally will lag the version of the mainline Verilator repository. If no
|
||||
binary package is available for your distribution, how about you set one
|
||||
@@ -70,23 +72,38 @@ a good thing for getting working silicon.
|
||||
Will Verilator output remain under my own license/copyright?
|
||||
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
Yes, it's just like using GCC on your programs; this is why Verilator uses
|
||||
the "GNU **Lesser** Public License Version 3" instead of the more typical
|
||||
"GNU Public License". See the licenses for details, but in brief, if you
|
||||
change Verilator itself or the header files Verilator includes, you must
|
||||
make the source code available under the GNU Lesser Public License.
|
||||
However, Verilator output (the Verilated code) only "include"s the licensed
|
||||
files, and so you are **not** required to open-source release any output
|
||||
from Verilator.
|
||||
Your SystemVerilog, VPI/DPI, or main() C++ code remains under your own license.
|
||||
|
||||
It's just like how using GCC on your programs does not change the copyright
|
||||
of your program; this is why Verilator uses the "GNU **Lesser** Public
|
||||
License Version 3" instead of the more typical "GNU Public License". See
|
||||
the licenses for details.
|
||||
|
||||
Some examples:
|
||||
|
||||
* Any SystemVerilog or other input fed into Verilator remain your own.
|
||||
|
||||
* Any of your VPI/DPI C++ routines that Verilator calls remain your own.
|
||||
|
||||
* Any of your main() C++ code that calls into Verilator remain your own.
|
||||
|
||||
* If you change Verilator itself, for example changing or adding a file
|
||||
under the src/ directory in the repository, you must make the source code
|
||||
available under the GNU Lesser Public License.
|
||||
|
||||
* If you change a header Verilator provides, for example under include/ in
|
||||
the repository, you must make the source code available under the GNU
|
||||
Lesser Public License.
|
||||
|
||||
You also have the option of using the Perl Artistic License, which again
|
||||
does not require you to release your Verilog or generated code, and also
|
||||
allows you to modify Verilator for internal use without distributing the
|
||||
modified version. But please contribute back to the community!
|
||||
does not require you to release your Verilog, C++, or generated code. This
|
||||
license also allows you to modify Verilator for internal use without
|
||||
distributing the modified version. But please contribute back to the
|
||||
community!
|
||||
|
||||
One limit is that you cannot under either license release a closed-source
|
||||
Verilog simulation product incorporating Verilator. That is you can have a
|
||||
commercial product, but must make the source code available.
|
||||
Under both license you can offer a commercial product that is based on
|
||||
Verilator either directly or embedded within. However under both licenses,
|
||||
any changes you make to Verilator for such a product must be open sourced.
|
||||
|
||||
As is standard with Open Source, contributions back to Verilator will be
|
||||
placed under the Verilator copyright and LGPL/Artistic license. Small test
|
||||
@@ -132,7 +149,8 @@ B. Or, for finer-grained control, or C++ files with multiple Verilated
|
||||
...
|
||||
Verilated::traceEverOn(true);
|
||||
VerilatedVcdC* tfp = new VerilatedVcdC;
|
||||
topp->trace(tfp, 99); // Trace 99 levels of hierarchy
|
||||
topp->trace(tfp, 99); // Trace 99 levels of hierarchy (or see below)
|
||||
// tfp->dumpvars(1, "t"); // trace 1 level under "t"
|
||||
tfp->open("obj_dir/t_trace_ena_cc/simx.vcd");
|
||||
...
|
||||
while (contextp->time() < sim_time && !contextp->gotFinish()) {
|
||||
@@ -351,8 +369,8 @@ also use the "import DPI" SystemVerilog feature to call C code (see the
|
||||
chapter above). There is also limited VPI access to public signals.
|
||||
|
||||
If you want something more complex, since Verilator emits standard C++
|
||||
code, you can simply write your own C++ routines that can access and modify
|
||||
signal values without needing any PLI interface code, and call it with
|
||||
code, you can write your own C++ routines that can access and modify signal
|
||||
values without needing any PLI interface code, and call it with
|
||||
$c("{any_c++_statement}").
|
||||
|
||||
See the :ref:`Connecting` section.
|
||||
@@ -442,7 +460,7 @@ the signal, as you would any other member variable.
|
||||
Signals are the smallest of 8-bit unsigned chars (equivalent to uint8_t),
|
||||
16-bit unsigned shorts (uint16_t), 32-bit unsigned longs (uint32_t), or
|
||||
64-bit unsigned long longs (uint64_t) that fits the width of the signal.
|
||||
Generally, you can use just uint32_t's for 1 to 32 bits, or vluint64_t for
|
||||
Generally, you can use just uint32_t's for 1 to 32 bits, or uint64_t for
|
||||
1 to 64 bits, and the compiler will properly up-convert smaller entities.
|
||||
Note even signed ports are declared as unsigned; you must sign extend
|
||||
yourself to the appropriate signal width.
|
||||
@@ -479,7 +497,7 @@ by your code or you'll get strange results.
|
||||
Should a module be in Verilog or SystemC?
|
||||
"""""""""""""""""""""""""""""""""""""""""
|
||||
|
||||
Sometimes there is a block that just interconnects instances, and have a
|
||||
Sometimes there is a block that only interconnects instances, and have a
|
||||
choice as to if you write it in Verilog or SystemC. Everything else being
|
||||
equal, best performance is when Verilator sees all of the design. So, look
|
||||
at the hierarchy of your design, labeling instances as to if they are
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 37 KiB |
+35
-9
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
*****
|
||||
@@ -50,7 +50,7 @@ For --cc/--sc, it creates:
|
||||
- Make include file with class names (from --make gmake)
|
||||
* - *{prefix}*\ _hier.mk
|
||||
- Make file for hierarchy blocks (from --make gmake)
|
||||
* - *{prefix|*\ _hierMkArgs.f
|
||||
* - *{prefix}*\ _hierMkArgs.f
|
||||
- Arguments for hierarchical Verilation (from --make gmake)
|
||||
* - *{prefix}*\ _hierCMakeArgs.f
|
||||
- Arguments for hierarchical Verilation (from --make cmake)
|
||||
@@ -62,19 +62,23 @@ For --cc/--sc, it creates:
|
||||
- Top level (SystemVerilog $root) internal header file
|
||||
* - *{prefix}*\ ___024root.cpp
|
||||
- Top level (SystemVerilog $root) internal C++ file
|
||||
* - *{prefix}*___024root*{__n}*\ .cpp
|
||||
- Additional top level internal C++ files (from --output-split)
|
||||
* - *{prefix}*\ ___024root\ *{__n}*\ .cpp
|
||||
- Additional top level internal C++ files
|
||||
* - *{prefix}*\ ___024root\ *{__DepSet_hash__n}*\ .cpp
|
||||
- Additional top level internal C++ files (hashed to reduce build times)
|
||||
* - *{prefix}*\ ___024root__Slow\ *{__n}*\ .cpp
|
||||
- Infrequent cold routines
|
||||
* - *{prefix}*\ ___024root__Trace{__n}*\ .cpp
|
||||
* - *{prefix}*\ ___024root\ *{__DepSet_hash__n}*\ .cpp
|
||||
- Infrequent cold routines (hashed to reduce build times)
|
||||
* - *{prefix}*\ ___024root__Trace\ *{__n}*\ .cpp
|
||||
- Wave file generation code (from --trace)
|
||||
* - *{prefix}*\ ___024root__Trace__Slow{__n}*\ .cpp
|
||||
* - *{prefix}*\ ___024root__Trace__Slow\ *{__n}*\ .cpp
|
||||
- Wave file generation code (from --trace)
|
||||
* - *{prefix}*\ __Dpi.h
|
||||
- DPI import and export declarations (from --dpi)
|
||||
* - *{prefix}*\ __Dpi.cpp
|
||||
- Global DPI export wrappers (from --dpi)
|
||||
* - *{prefix}*\ __Dpi_Export\ *{__n}\ .cpp
|
||||
* - *{prefix}*\ __Dpi_Export\ *{__n}*\ .cpp
|
||||
- DPI export wrappers scoped to this particular model (from --dpi)
|
||||
* - *{prefix}*\ __Inlines.h
|
||||
- Inline support functions
|
||||
@@ -87,7 +91,9 @@ For --cc/--sc, it creates:
|
||||
* - *{prefix}{each_verilog_module}*\ .cpp
|
||||
- Lower level internal C++ files
|
||||
* - *{prefix}{each_verilog_module}{__n}*\ .cpp
|
||||
- Additional lower C++ files (from --output-split)
|
||||
- Additional lower C++ files
|
||||
* - *{prefix}{each_verilog_module}{__DepSet_hash__n}*\ .cpp
|
||||
- Additional lower C++ files (hased to reduce build times)
|
||||
|
||||
For --hierarchy mode, it creates:
|
||||
|
||||
@@ -120,7 +126,7 @@ In certain debug and other modes, it also creates:
|
||||
- Debugging graph files (from --debug)
|
||||
* - *{prefix}{misc}*\ .tree
|
||||
- Debugging files (from --debug)
|
||||
* - {mod_prefix}_{each_verilog_module}*{__n}*\ .vpp
|
||||
* - {mod_prefix}_{each_verilog_base_filename}*\ .vpp
|
||||
- Pre-processed verilog (from --debug)
|
||||
|
||||
After running Make, the C++ compiler may produce the following:
|
||||
@@ -145,3 +151,23 @@ After running Make, the C++ compiler may produce the following:
|
||||
- Intermediate dependencies
|
||||
* - *{prefix}{misc}*\ .o
|
||||
- Intermediate objects
|
||||
|
||||
The Verilated executable may produce the following:
|
||||
|
||||
.. list-table::
|
||||
|
||||
* - coverage.dat
|
||||
- Code coverage output, and default input filename for :command:`verilator_coverage`
|
||||
* - gmon.out
|
||||
- GCC/clang code profiler output, often fed into :command:`verilator_profcfunc`
|
||||
* - profile.vlt
|
||||
- --prof-pgo data file for :ref:`Thread PGO`
|
||||
* - profile_exec.dat
|
||||
- --prof-exec data file for :command:`verilator_gantt`
|
||||
|
||||
Verilator_gantt may produce the following:
|
||||
|
||||
.. list-table::
|
||||
|
||||
* - profile_exec.vcd
|
||||
- Gantt report waveform output
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
######################
|
||||
|
||||
+27
-18
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Installation:
|
||||
@@ -23,6 +23,8 @@ package:
|
||||
|
||||
apt-get install verilator # On Ubuntu
|
||||
|
||||
For other distributions refer to `Repology Verilator Distro Packages
|
||||
<https://repology.org/project/verilator>`__.
|
||||
|
||||
.. _Git Install:
|
||||
|
||||
@@ -44,21 +46,20 @@ In brief, to install from git:
|
||||
#sudo apt-get install zlibc zlib1g zlib1g-dev # Ubuntu only (ignore if gives error)
|
||||
|
||||
git clone https://github.com/verilator/verilator # Only first time
|
||||
## Note the URL above is not a page you can see with a browser, it's for git only
|
||||
|
||||
# Every time you need to build:
|
||||
unsetenv VERILATOR_ROOT # For csh; ignore error if on bash
|
||||
unset VERILATOR_ROOT # For bash
|
||||
cd verilator
|
||||
git pull # Make sure git repository is up-to-date
|
||||
git tag # See what versions exist
|
||||
git pull # Make sure git repository is up-to-date
|
||||
git tag # See what versions exist
|
||||
#git checkout master # Use development branch (e.g. recent bug fixes)
|
||||
#git checkout stable # Use most recent stable release
|
||||
#git checkout v{version} # Switch to specified release version
|
||||
|
||||
autoconf # Create ./configure script
|
||||
./configure # Configure and create Makefile
|
||||
make -j # Build Verilator itself
|
||||
autoconf # Create ./configure script
|
||||
./configure # Configure and create Makefile
|
||||
make -j `nproc` # Build Verilator itself (if error, try just 'make')
|
||||
sudo make install
|
||||
|
||||
|
||||
@@ -76,17 +77,17 @@ OS Requirements
|
||||
---------------
|
||||
|
||||
Verilator is developed and has primary testing on Ubuntu, with additional
|
||||
testing on FreeBSD and Apple OS-X. Versions have also built on Redhat
|
||||
Linux, HPUX and Solaris. It should run with minor porting on any
|
||||
GNU/Linux-ish platform. Verilator also works on Windows under Cygwin, and
|
||||
Windows under MinGW (gcc -mno-cygwin). Verilated output (not Verilator
|
||||
itself) compiles under all the options above, plus using MSVC++.
|
||||
testing on FreeBSD and Apple OS-X. Versions have also built on Red Hat
|
||||
Linux, and other flavors of GNU/Linux-ish platforms. Verilator also works
|
||||
on Windows Subsystem for Linux (WSL2), Windows under Cygwin, and Windows
|
||||
under MinGW (gcc -mno-cygwin). Verilated output (not Verilator itself)
|
||||
compiles under all the options above, plus using MSVC++.
|
||||
|
||||
|
||||
Install Prerequisites
|
||||
---------------------
|
||||
|
||||
To build or run Verilator you need these standard packages:
|
||||
To build or run Verilator, you need these standard packages:
|
||||
|
||||
::
|
||||
|
||||
@@ -97,13 +98,20 @@ To build or run Verilator you need these standard packages:
|
||||
sudo apt-get install libfl-dev # Ubuntu only (ignore if gives error)
|
||||
sudo apt-get install zlibc zlib1g zlib1g-dev # Ubuntu only (ignore if gives error)
|
||||
|
||||
To build or run the following are optional but should be installed for good
|
||||
performance:
|
||||
To build or run Verilator, the following are optional but should be installed
|
||||
for good performance:
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install ccache # If present at build, needed for run
|
||||
sudo apt-get install libgoogle-perftools-dev numactl perl-doc
|
||||
sudo apt-get install libgoogle-perftools-dev numactl
|
||||
|
||||
The following is optional but is recommended for nicely rendered command line
|
||||
help when running Verilator:
|
||||
|
||||
::
|
||||
|
||||
sudo apt-get install perl-doc
|
||||
|
||||
To build Verilator you will need to install these packages; these do not
|
||||
need to be present to run Verilator:
|
||||
@@ -117,7 +125,8 @@ Those developing Verilator itself may also want these (see internals.rst):
|
||||
::
|
||||
|
||||
sudo apt-get install gdb graphviz cmake clang clang-format-11 gprof lcov
|
||||
sudo pip3 install sphinx sphinx_rtd_theme breathe
|
||||
sudo apt-get install yapf3
|
||||
sudo pip3 install sphinx sphinx_rtd_theme sphinxcontrib-spelling breathe
|
||||
cpan install Pod::Perldoc
|
||||
cpan install Parallel::Forker
|
||||
|
||||
@@ -286,7 +295,7 @@ Compile Verilator:
|
||||
|
||||
::
|
||||
|
||||
make -j
|
||||
make -j `nproc` # Or if error on `nproc`, the number of CPUs in system
|
||||
|
||||
|
||||
Test
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
***************
|
||||
@@ -92,7 +92,7 @@ appropriate code to detect failing cases at simulation runtime and print an
|
||||
|
||||
Verilator likewise also asserts any "unique" or "priority" SystemVerilog
|
||||
keywords on case statement, as well as "unique" on if statements. However,
|
||||
"priority if" is currently simply ignored.
|
||||
"priority if" is currently ignored.
|
||||
|
||||
|
||||
.. _Language Limitations:
|
||||
@@ -136,7 +136,7 @@ ___05F (5F is the hex code of an underscore.)
|
||||
Bind
|
||||
----
|
||||
|
||||
sVerilator only supports bind to a target module name, not to an
|
||||
Verilator only supports bind to a target module name, not to an
|
||||
instance path.
|
||||
|
||||
|
||||
@@ -174,9 +174,9 @@ Structures and Unions
|
||||
---------------------
|
||||
|
||||
Presently Verilator only supports packed structs and packed unions. Rand
|
||||
and randc tags on members are simply ignored. All structures and unions
|
||||
are represented as a single vector, which means that generating one member
|
||||
of a structure from blocking, and another from non-blocking assignments is
|
||||
and randc tags on members are ignored. All structures and unions are
|
||||
represented as a single vector, which means that generating one member of a
|
||||
structure from blocking, and another from non-blocking assignments is
|
||||
unsupported.
|
||||
|
||||
|
||||
@@ -336,6 +336,24 @@ Verilator does not support SEREs yet. All assertion and coverage
|
||||
statements must be simple expressions that complete in one cycle.
|
||||
|
||||
|
||||
Force statement
|
||||
---------------
|
||||
|
||||
Verilator supports the procedural `force` (and corresponding `release`)
|
||||
statement. The behavior of the `force` statement however does not entirely
|
||||
comply with the IEEE 1800 SystemVerilog standard. According to the standard,
|
||||
when a procedural statement of the form `force a = b;` is executed, the
|
||||
simulation should behave as if from that point forwards, a continuous
|
||||
assignment `assign a = b;` have been added to override the drivers of `a`.
|
||||
More specifically: the value of `a` should be updated, whenever the value of
|
||||
`b` changes, all the way until a `release a;` statement is executed.
|
||||
Verilator instead evaluates the current value of `b` at the time the `force`
|
||||
statement is executed, and forces `a` to that value, without updating it
|
||||
until a new `force` or `release` statement is encountered that applies to
|
||||
`a`. This non-standard behavior is nevertheless consistent with some other
|
||||
simulators.
|
||||
|
||||
|
||||
Encrypted Verilog
|
||||
-----------------
|
||||
|
||||
@@ -471,7 +489,7 @@ $test$plusargs, $value$plusargs
|
||||
|
||||
.. code-block:: C++
|
||||
|
||||
Verilated::commandArgs(argc, argv);
|
||||
{VerilatedContext*} ->commandArgs(argc, argv);
|
||||
|
||||
to register the command line before calling $test$plusargs or
|
||||
$value$plusargs.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
********
|
||||
|
||||
+138
-18
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
.. _Simulating:
|
||||
@@ -26,7 +26,8 @@ risk of reset bugs in trade for performance; see the above documentation
|
||||
for these options.
|
||||
|
||||
If using Verilated multithreaded, use ``numactl`` to ensure you are using
|
||||
non-conflicting hardware resources. See :ref:`Multithreading`.
|
||||
non-conflicting hardware resources. See :ref:`Multithreading`. Also
|
||||
consider using profile-guided optimization, see :ref:`Thread PGO`.
|
||||
|
||||
Minor Verilog code changes can also give big wins. You should not have any
|
||||
UNOPTFLAT warnings from Verilator. Fixing these warnings can result in
|
||||
@@ -93,9 +94,7 @@ cases, for example regressions, it is usually worth spending extra
|
||||
compilation time to reduce total CPU time.
|
||||
|
||||
If you will be running many simulations on a single model, you can
|
||||
investigate profile guided optimization. With GCC, using GCC's
|
||||
"-fprofile-arcs", then GCC's "-fbranch-probabilities" will yield another
|
||||
15% or so.
|
||||
investigate profile guided optimization. See :ref:`Compiler PGO`.
|
||||
|
||||
Modern compilers also support link-time optimization (LTO), which can help
|
||||
especially if you link in DPI code. To enable LTO on GCC, pass "-flto" in
|
||||
@@ -230,7 +229,7 @@ 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::coveragep()->write` with an argument of the filename for
|
||||
: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").
|
||||
|
||||
@@ -280,23 +279,25 @@ To use profiling:
|
||||
is being spent.
|
||||
|
||||
|
||||
.. _Thread Profiling:
|
||||
.. _Execution Profiling:
|
||||
|
||||
Thread Profiling
|
||||
================
|
||||
Execution Profiling
|
||||
===================
|
||||
|
||||
When using multithreaded mode (:vlopt:`--threads`), it is useful to see
|
||||
statistics and visualize how well the multiple CPUs are being utilized.
|
||||
For performance optimization, it is useful to see statistics and visualize how
|
||||
execution time is distributed in a verilated model.
|
||||
|
||||
With the :vlopt:`--prof-threads` option, Verilator will:
|
||||
With the :vlopt:`--prof-exec` option, Verilator will:
|
||||
|
||||
* Add code to the Verilated model to record the start and end time of each
|
||||
macro-task across a number of calls to eval. (What is a macro-task? See
|
||||
the Verilator internals document (:file:`docs/internals.rst` in the
|
||||
distribution.)
|
||||
* Add code to the Verilated model to record execution flow.
|
||||
|
||||
* Add code to save profiling data in non-human-friendly form to the file
|
||||
specified with :vlopt:`+verilator+prof+threads+file+\<filename\>`.
|
||||
specified with :vlopt:`+verilator+prof+exec+file+\<filename\>`.
|
||||
|
||||
* In multi-threaded models, add code to record the start and end time of each
|
||||
macro-task across a number of calls to eval. (What is a macro-task? See the
|
||||
Verilator internals document (:file:`docs/internals.rst` in the
|
||||
distribution.)
|
||||
|
||||
The :command:`verilator_gantt` program may then be run to transform the
|
||||
saved profiling file into a nicer visual format and produce some related
|
||||
@@ -306,7 +307,7 @@ statistics.
|
||||
|
||||
Example verilator_gantt output, as viewed with GTKWave.
|
||||
|
||||
The parallelism shows the number of CPUs being used at a given moment.
|
||||
The measured_parallelism shows the number of CPUs being used at a given moment.
|
||||
|
||||
The cpu_thread section shows which thread is executing on each of the physical CPUs.
|
||||
|
||||
@@ -314,6 +315,7 @@ statistics.
|
||||
|
||||
For more information see :command:`verilator_gantt`.
|
||||
|
||||
|
||||
.. _Profiling ccache efficiency:
|
||||
|
||||
Profiling ccache efficiency
|
||||
@@ -377,3 +379,121 @@ For example:
|
||||
os >> main_time;
|
||||
os >> *topp;
|
||||
}
|
||||
|
||||
|
||||
Profile-Guided Optimization
|
||||
===========================
|
||||
|
||||
Profile-guided optimization is the technique where profiling data is
|
||||
collected by running your simulation executable, then this information is
|
||||
used to guide the next Verilation or compilation.
|
||||
|
||||
There are two forms of profile-guided optimizations. Unfortunately for
|
||||
best results they must each be performed from the highest level code to the
|
||||
lowest, which means performing them separately and in this order:
|
||||
|
||||
* :ref:`Thread PGO`
|
||||
* :ref:`Compiler PGO`
|
||||
|
||||
Other forms of PGO may be supported in the future, such as clock and reset
|
||||
toggle rate PGO, branch prediction PGO, statement execution time PGO, or
|
||||
others as they prove beneficial.
|
||||
|
||||
|
||||
.. _Thread PGO:
|
||||
|
||||
Thread Profile-Guided Optimization
|
||||
----------------------------------
|
||||
|
||||
Verilator supports profile-guided optimization (Verilation) of multi-threaded
|
||||
models (Thread PGO) to improve performance.
|
||||
|
||||
When using multithreading, Verilator computes how long macro tasks take and
|
||||
tries to balance those across threads. (What is a macro-task? See the
|
||||
Verilator internals document (:file:`docs/internals.rst` in the
|
||||
distribution.) If the estimations are incorrect, the threads will not be
|
||||
balanced, leading to decreased performance. Thread PGO allows collecting
|
||||
profiling data to replace the estimates and better optimize these
|
||||
decisions.
|
||||
|
||||
To use Thread PGO, Verilate the model with the :vlopt:`--prof-pgo` option. This
|
||||
will code to the verilated model to save profiling data for profile-guided
|
||||
optimization.
|
||||
|
||||
Run the model executable. When the executable exits, it will create a
|
||||
profile.vlt file.
|
||||
|
||||
Rerun Verilator, optionally omitting the :vlopt:`--prof-pgo` option,
|
||||
and adding the profile.vlt generated earlier to the command line.
|
||||
|
||||
Note there is no Verilator equivalent to GCC's --fprofile-use. Verilator's
|
||||
profile data file (profile.vlt) can be placed on the verilator command line
|
||||
directly without any prefix.
|
||||
|
||||
If results from multiple simulations are to be used in generating the
|
||||
optimization, multiple simulation's profile.vlt may be concatenated
|
||||
externally, or each of the files may be fed as separate command line
|
||||
options into Verilator. Verilator will sum the profile results, so a
|
||||
longer running test will have proportionally more weight for optimization
|
||||
than a shorter running test.
|
||||
|
||||
If you provide any profile feedback data to Verilator, and it cannot use
|
||||
it, it will issue the :option:`PROFOUTOFDATE` warning that threads were
|
||||
scheduled using estimated costs. This usually indicates that the profile
|
||||
data was generated from different Verilog source code than Verilator is
|
||||
currently running against. Therefore, repeat the data collection phase to
|
||||
create new profiling data, then rerun Verilator with the same input source
|
||||
files and that new profiling data.
|
||||
|
||||
|
||||
.. _Compiler PGO:
|
||||
|
||||
Compiler Profile-Guided Optimization
|
||||
------------------------------------
|
||||
|
||||
GCC and Clang support compiler profile-guided optimization (PGO). This
|
||||
optimizes any C/C++ program including Verilated code. Using compiler PGO
|
||||
typically yields improvements of 5-15% on both single-threaded and
|
||||
multi-threaded models.
|
||||
|
||||
To use compiler PGO with GCC or Clang, please see the appropriate compiler
|
||||
documentation. The process in GCC 10 was as follows:
|
||||
|
||||
1. Compile the Verilated model with the compiler's "-fprofile-generate"
|
||||
flag:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
verilator [whatever_flags] --make \
|
||||
-CFLAGS -fprofile-generate -LDFLAGS -fprofile-generate
|
||||
|
||||
or, if calling make yourself, add -fprofile-generate appropriately to your
|
||||
Makefile.
|
||||
|
||||
2. Run your simulation. This will create \*.gcda file(s) in the same
|
||||
directory as the source files.
|
||||
|
||||
3. Recompile the model with -fprofile-use. The compiler will read the
|
||||
\*.gcda file(s).
|
||||
|
||||
For GCC:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
verilator [whatever_flags] --build \
|
||||
-CFLAGS "-fprofile-use -fprofile-correction"
|
||||
|
||||
For Clang:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
llvm-profdata merge -output default.profdata *.profraw
|
||||
verilator [whatever_flags] --build \
|
||||
-CFLAGS "-fprofile-use -fprofile-correction"
|
||||
|
||||
or, if calling make yourself, add these CFLAGS switches appropriately to
|
||||
your Makefile.
|
||||
|
||||
Clang and GCC also support -fauto-profile which uses sample-based
|
||||
feedback-directed optimization. See the appropriate compiler
|
||||
documentation.
|
||||
|
||||
+26
-17
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
**********
|
||||
@@ -68,12 +68,11 @@ multi-core SoC.
|
||||
|
||||
Verilator is run in hierarchical mode on the whole SoC. Verilator will
|
||||
make two models, one for the CPU hierarchy block, and one for the SoC. The
|
||||
Verialted code for the SoC will automatically call the CPU Verilated model.
|
||||
Verilated code for the SoC will automatically call the CPU Verilated model.
|
||||
|
||||
The current hierarchical Verilation is based on protect-lib. Each hierarchy
|
||||
block is Verilated to a protect-lib. User modules of the hierarchy blocks
|
||||
will see a tiny wrapper generated by protect-lib instead of the actual
|
||||
design.
|
||||
The current hierarchical Verilation is based on :vlopt:`--lib-create`. Each
|
||||
hierarchy block is Verilated into a library. User modules of the hierarchy
|
||||
blocks will see a tiny wrapper generated by :vlopt:`--lib-create`.
|
||||
|
||||
|
||||
Usage
|
||||
@@ -216,9 +215,19 @@ be done by a "main thread". In most cases the eval thread and main thread
|
||||
are the same thread (i.e. the user's top C++ testbench runs on a single
|
||||
thread), but this is not required.
|
||||
|
||||
The :vlopt:`--trace-threads` options can be used to produce trace dumps
|
||||
using multiple threads. If :vlopt:`--trace-threads` is set without
|
||||
:vlopt:`--threads`, then :vlopt:`--trace-threads` will imply
|
||||
When making frequent use of DPI imported functions in a multi-threaded
|
||||
model, it may be beneficial to performance to adjust the
|
||||
:vlopt:`--instr-count-dpi` option based on some experimentation. This
|
||||
influences the partitioning of the model by adjusting the assumed execution
|
||||
time of DPI imports.
|
||||
|
||||
When using :vlopt:`--trace` to perform VCD tracing, the VCD trace
|
||||
construction is parallelized using the same number of threads as specified
|
||||
with :vlopt:`--threads`, and is executed on the same thread pool as the model.
|
||||
|
||||
The :vlopt:`--trace-threads` options can be used with :vlopt:`--trace-fst`
|
||||
to offload FST tracing using multiple threads. If :vlopt:`--trace-threads` is
|
||||
given without :vlopt:`--threads`, then :vlopt:`--trace-threads` will imply
|
||||
:vlopt:`--threads 1 <--threads>`, i.e.: the support libraries will be
|
||||
thread safe.
|
||||
|
||||
@@ -226,12 +235,12 @@ With :vlopt:`--trace-threads 0 <--trace-threads>`, trace dumps are produced
|
||||
on the main thread. This again gives the highest single thread performance.
|
||||
|
||||
With :vlopt:`--trace-threads {N} <--trace-threads>`, where N is at least 1,
|
||||
N additional threads will be created and managed by the trace files (e.g.:
|
||||
VerilatedVcdC or VerilatedFstC), to generate the trace dump. The main
|
||||
thread will be released to proceed with execution as soon as possible,
|
||||
though some blocking of the main thread is still necessary while capturing
|
||||
the trace. Different trace formats can utilize a various number of
|
||||
threads. See the :vlopt:`--trace-threads` option.
|
||||
up to N additional threads will be created and managed by the trace files
|
||||
(e.g.: VerilatedFstC), to offload construction of the trace dump. The main
|
||||
thread will be released to proceed with execution as soon as possible, though
|
||||
some blocking of the main thread is still necessary while capturing the
|
||||
trace. FST tracing can utilize up to 2 offload threads, so there is no use
|
||||
of setting :vlopt:`--trace-threads` higher than 2 at the moment.
|
||||
|
||||
When running a multithreaded model, the default Linux task scheduler often
|
||||
works against the model, by assuming threads are short lived, and thus
|
||||
@@ -260,7 +269,7 @@ This will limit memory to socket 0, and threads to cores 0, 1, 2, 3,
|
||||
(presumably on socket 0) optimizing performance. Of course this must be
|
||||
adjusted if you want another simulator using e.g. socket 1, or if you
|
||||
Verilated with a different number of threads. To see what CPUs are
|
||||
actually used, use :vlopt:`--prof-threads`.
|
||||
actually used, use :vlopt:`--prof-exec`.
|
||||
|
||||
|
||||
Multithreaded Verilog and Library Support
|
||||
@@ -436,7 +445,7 @@ SystemC include directories and link to the SystemC libraries.
|
||||
|
||||
.. describe:: TRACE_THREADS
|
||||
|
||||
Optional. Generated multi-threaded trace dumping, same as
|
||||
Optional. Generated multi-threaded FST trace dumping, same as
|
||||
"--trace-threads".
|
||||
|
||||
.. describe:: TOP_MODULE
|
||||
|
||||
+92
-43
@@ -1,4 +1,4 @@
|
||||
.. Copyright 2003-2021 by Wilson Snyder.
|
||||
.. Copyright 2003-2022 by Wilson Snyder.
|
||||
.. SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
|
||||
*******************
|
||||
@@ -12,7 +12,7 @@ Disabling Warnings
|
||||
Warnings may be disabled in multiple ways:
|
||||
|
||||
#. Disable the warning in the source code. When the warning is printed it
|
||||
will include a warning code. Simply surround the offending line with a
|
||||
will include a warning code. Surround the offending line with a
|
||||
:code:`/*verilator&32;lint_off*/` and :code:`/*verilator&32;lint_on*/`
|
||||
metacomment pair:
|
||||
|
||||
@@ -130,9 +130,10 @@ List Of Warnings
|
||||
|
||||
.. option:: BADSTDPRAGMA
|
||||
|
||||
Error that a pragma is badly formed, when that pragma is defined by IEEE1800-2017.
|
||||
For example, an empty `pragma line, or an incorrect specified '`pragma protect'.
|
||||
Note that 3rd party pragmas not defined by IEEE1800-2017 are ignored.
|
||||
Error that a pragma is badly formed, when that pragma is defined by IEEE
|
||||
1800-2017. For example, an empty pragma line, or an incorrect specified
|
||||
'pragma protect'. Note that 3rd party pragmas not defined by IEEE
|
||||
1800-2017 are ignored.
|
||||
|
||||
|
||||
.. option:: BLKANDNBLK
|
||||
@@ -161,7 +162,7 @@ List Of Warnings
|
||||
always @(posedge clk) foo[0] <= ...
|
||||
always_comb foo[1] = ...
|
||||
|
||||
Simply use a different register for the flop:
|
||||
Instead use a different register for the flop:
|
||||
|
||||
.. code-block:: sv
|
||||
|
||||
@@ -283,7 +284,7 @@ List Of Warnings
|
||||
|
||||
.. TODO better example
|
||||
|
||||
Warns that it is simply better style to use casez, and "?" in place of
|
||||
Warns that it is better style to use casez, and "?" in place of
|
||||
"x"'s. See
|
||||
`http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf
|
||||
<http://www.sunburst-design.com/papers/CummingsSNUG1999Boston_FullParallelCase_rev1_1.pdf>`_
|
||||
@@ -446,7 +447,7 @@ List Of Warnings
|
||||
p0();
|
||||
endmodule
|
||||
|
||||
Other tools with similar warnings: Veriable's forbid_defparam_rule.
|
||||
Other tools with similar warnings: Verible's forbid_defparam_rule.
|
||||
|
||||
|
||||
.. option:: DEPRECATED
|
||||
@@ -481,39 +482,44 @@ List Of Warnings
|
||||
|
||||
Faulty example:
|
||||
|
||||
.. code-block:: sv
|
||||
.. include:: ../../docs/gen/ex_DIDNOTCONVERGE_faulty.rst
|
||||
|
||||
always_comb b = ~a;
|
||||
always_comb a = b
|
||||
Results in at runtime (not when Verilated):
|
||||
|
||||
This code will toggle forever, and thus to prevent an infinite loop, the
|
||||
executable will give the didn't converge error.
|
||||
.. include:: ../../docs/gen/ex_DIDNOTCONVERGE_nodbg_msg.rst
|
||||
|
||||
To debug this, first review any UNOPTFLAT warnings that were ignored.
|
||||
Though typically it is safe to ignore UNOPTFLAT (at a performance cost),
|
||||
at the time of issuing a UNOPTFLAT Verilator did not know if the logic
|
||||
would eventually converge and assumed it would.
|
||||
This is because the signals keep toggling even with out time
|
||||
passing. Thus to prevent an infinite loop, the Verilated executable
|
||||
gives the DIDNOTCONVERGE error.
|
||||
|
||||
To debug this, first review any UNOPT or UNOPTFLAT warnings that were
|
||||
ignored. Though typically it is safe to ignore UNOPTFLAT (at a
|
||||
performance cost), at the time of issuing a UNOPTFLAT Verilator did not
|
||||
know if the logic would eventually converge and assumed it would.
|
||||
|
||||
Next, run Verilator with :vlopt:`--prof-cfuncs -CFLAGS -DVL_DEBUG
|
||||
<--prof-cfuncs>`. Rerun the test. Now just before the convergence
|
||||
error you should see additional output similar to this:
|
||||
|
||||
.. code-block::
|
||||
.. include:: ../../docs/gen/ex_DIDNOTCONVERGE_msg.rst
|
||||
|
||||
CHANGE: filename.v:1: b
|
||||
CHANGE: filename.v:2: a
|
||||
|
||||
This means that signal b and signal a keep changing, inspect the code
|
||||
that modifies these signals. Note if many signals are getting printed
|
||||
then most likely all of them are oscillating. It may also be that
|
||||
e.g. "a" may be oscillating, then "a" feeds signal "c" which then is
|
||||
also reported as oscillating.
|
||||
The CHANGE line means that on the given filename and line number that
|
||||
drove a signal, the signal 'a' kept changing. Inspect the code that
|
||||
modifies these signals. Note if many signals are getting printed then
|
||||
most likely all of them are oscillating. It may also be that e.g. "a"
|
||||
may be oscillating, then "a" feeds signal "c" which then is also
|
||||
reported as oscillating.
|
||||
|
||||
One way DIDNOTCONVERGE may occur is flops are built out of gate
|
||||
primitives. error. Verilator does not support building flops or latches
|
||||
out of gate primitives, and any such code must change to use behavioral
|
||||
primitives. Verilator does not support building flops or latches out of
|
||||
gate primitives, and any such code must change to use behavioral
|
||||
constructs (e.g. always_ff and always_latch).
|
||||
|
||||
Another way DIDNOTCONVERGE may occur is if # delays are used to generate
|
||||
clocks. Verilator ignores the delays and gives an :option:`ASSIGNDLY`
|
||||
or :option:`STMTDLY` warning. If these were suppressed, due to the
|
||||
absence of the delay, the code may now oscillate.
|
||||
|
||||
Finally, rare, more difficult cases can be debugged like a C++ program;
|
||||
either enter :command:`gdb` and use its tracing facilities, or edit the
|
||||
generated C++ code to add appropriate prints to see what is going on.
|
||||
@@ -522,7 +528,7 @@ List Of Warnings
|
||||
.. option:: ENDCAPSULATED
|
||||
|
||||
Warns that a class member is declared is local or protected, but is
|
||||
being accessed from outside that class (if local) or a derrived class
|
||||
being accessed from outside that class (if local) or a derived class
|
||||
(if protected).
|
||||
|
||||
Ignoring this warning will only suppress the lint check, it will
|
||||
@@ -572,7 +578,7 @@ List Of Warnings
|
||||
must end in newline, as otherwise for example :command:`cat` with the
|
||||
file as an argument may produce undesirable results.
|
||||
|
||||
Repair by adding a newline to the end of the file.
|
||||
Repair by appending a newline to the end of the file.
|
||||
|
||||
Disabled by default as this is a code style warning; it will simulate
|
||||
correctly.
|
||||
@@ -792,8 +798,8 @@ List Of Warnings
|
||||
.. TODO better example
|
||||
|
||||
Warns that a module has multiple definitions. Generally this indicates
|
||||
a coding error, or a mistake in a library file and it's good practice to
|
||||
have one module per file (and only put each file once on the command
|
||||
a coding error, or a mistake in a library file, and it's good practice
|
||||
to have one module per file (and only put each file once on the command
|
||||
line) to avoid these issues. For some gate level netlists duplicates
|
||||
are sometimes unavoidable, and MODDUP should be disabled.
|
||||
|
||||
@@ -918,7 +924,7 @@ List Of Warnings
|
||||
simulate correctly.
|
||||
|
||||
Other tools with similar warnings: Icarus Verilog's portbind, "warning:
|
||||
Instantiating module ... with dangling impot port (...)". Slang's
|
||||
Instantiating module ... with dangling input port (...)". Slang's
|
||||
unconnected-port, "port '...' has no connection".
|
||||
|
||||
|
||||
@@ -1005,9 +1011,25 @@ List Of Warnings
|
||||
a var/reg must be used as the target of procedural assignments.
|
||||
|
||||
|
||||
.. option:: PROFOUTOFDATE
|
||||
|
||||
Warns that threads were scheduled using estimated costs, despite the
|
||||
fact that data was provided from profile-guided optimization (see
|
||||
:ref:`Thread PGO`) as fed into Verilator using the
|
||||
:option:`profile_data` configuration file option. This usually
|
||||
indicates that the profile data was generated from different Verilog
|
||||
source code than Verilator is currently running against.
|
||||
|
||||
It is recommended to create new profiling data, then rerun Verilator
|
||||
with the same input source files and that new profiling data.
|
||||
|
||||
Ignoring this warning may only slow simulations, it will simulate
|
||||
correctly.
|
||||
|
||||
|
||||
.. option:: PROTECTED
|
||||
|
||||
Warning that a '`pragma protected' section was encountered. The code
|
||||
Warning that a 'pragma protected' section was encountered. The code
|
||||
inside the protected region will be partly checked for correctness, but is
|
||||
otherwise ignored.
|
||||
|
||||
@@ -1183,9 +1205,25 @@ List Of Warnings
|
||||
|
||||
Faulty example:
|
||||
|
||||
.. code-block:: sv
|
||||
.. include:: ../../docs/gen/ex_STMTDLY_faulty.rst
|
||||
|
||||
#100 $finish; //<--- Warning
|
||||
Results in:
|
||||
|
||||
.. include:: ../../docs/gen/ex_STMTDLY_msg.rst
|
||||
|
||||
This is a warning because Verilator does not support delayed statements.
|
||||
It will ignore all such delays. In many cases ignoring a delay might be
|
||||
harmless, but if the delayed statement is, as in this example, used to
|
||||
cause some important action at a later time, it might be an important
|
||||
difference.
|
||||
|
||||
Some possible workarounds:
|
||||
|
||||
* Move the delayed statement into the C++ wrapper file, where the
|
||||
stimulus and clock generation can be done in C++.
|
||||
|
||||
* Convert the statement into a FSM, or other statement that tests
|
||||
against $time.
|
||||
|
||||
|
||||
.. option:: SYMRSVDWORD
|
||||
@@ -1353,7 +1391,9 @@ List Of Warnings
|
||||
|
||||
Often UNOPTFLAT is caused by logic that isn't truly circular as viewed by
|
||||
synthesis which analyzes interconnection per-bit, but is circular to
|
||||
simulation which analyzes per-bus:
|
||||
simulation which analyzes per-bus.
|
||||
|
||||
Faulty example:
|
||||
|
||||
.. code-block:: sv
|
||||
|
||||
@@ -1466,9 +1506,16 @@ List Of Warnings
|
||||
Error that a construct might be legal according to IEEE but is not
|
||||
currently supported by Verilator.
|
||||
|
||||
A typical workaround is to rewrite the construct into a simpler and more
|
||||
common alternative language construct.
|
||||
|
||||
Alternatively, check if the construct is supported by other tools, and
|
||||
if so please consider submitting a github pull request against the
|
||||
Verilator sources to implement the missing unsupported feature.
|
||||
|
||||
This error may be ignored with :vlopt:`--bbox-unsup`, however this will
|
||||
make the design simulate incorrectly; see the details under
|
||||
:vlopt:`--bbox-unsup`.
|
||||
make the design simulate incorrectly and is only intended for lint
|
||||
usage; see the details under :vlopt:`--bbox-unsup`.
|
||||
|
||||
|
||||
.. option:: UNUSED
|
||||
@@ -1598,7 +1645,7 @@ List Of Warnings
|
||||
* A part select has a different size then needed to index into the
|
||||
packed or unpacked array (etc).
|
||||
|
||||
Verilator for attempts to track the minimum width of unsized constants
|
||||
Verilator attempts to track the minimum width of unsized constants
|
||||
and will suppress the warning when the minimum width is appropriate to
|
||||
fit the required size.
|
||||
|
||||
@@ -1607,11 +1654,13 @@ List Of Warnings
|
||||
|
||||
The recommendation is to fix these issues by:
|
||||
|
||||
* Resizing the variable or constant. E.g. :code:`2'd2` instead of :code:`3'd2`.
|
||||
* Resizing the variable or constant to match the needed size for the
|
||||
expression. E.g. :code:`2'd2` instead of :code:`3'd2`.
|
||||
|
||||
* Using :code:`'0` or :code:`'1`.
|
||||
* Using :code:`'0` or :code:`'1` which automatically resize in an
|
||||
expression.
|
||||
|
||||
* Using part select to narrow a variable. E.g. :code:`too_wide[1:0]`.
|
||||
* Using part selects to narrow a variable. E.g. :code:`too_wide[1:0]`.
|
||||
|
||||
* Using concatenate to widen a variable. E.g. :code:`{1'b1, too_narrow}`.
|
||||
|
||||
|
||||
+21
-18
@@ -114,11 +114,11 @@ By convention, each function/method uses the variable ``nodep`` as a
|
||||
pointer to the ``AstNode`` currently being processed.
|
||||
|
||||
|
||||
``AstNVisitor``
|
||||
``VNVisitor``
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
The passes are implemented by AST visitor classes. These are implemented by
|
||||
subclasses of the abstract class, ``AstNVisitor``. Each pass creates an
|
||||
subclasses of the abstract class, ``VNVisitor``. Each pass creates an
|
||||
instance of the visitor class, which in turn implements a method to perform
|
||||
the pass.
|
||||
|
||||
@@ -268,13 +268,13 @@ Estimating Logic Costs
|
||||
|
||||
To compute the cost of any given path through the graph, Verilator
|
||||
estimates an execution cost for each task. Each macro-task has an execution
|
||||
cost which is simply the sum of its tasks' costs. We assume that
|
||||
communication overhead and synchronization overhead are zero, so the cost
|
||||
of any given path through the graph is simply the sum of macro-task
|
||||
execution costs. Sarkar does almost the same thing, except that he has
|
||||
nonzero estimates for synchronization costs.
|
||||
cost which is the sum of its tasks' costs. We assume that communication
|
||||
overhead and synchronization overhead are zero, so the cost of any given
|
||||
path through the graph is the sum of macro-task execution costs. Sarkar
|
||||
does almost the same thing, except that he has nonzero estimates for
|
||||
synchronization costs.
|
||||
|
||||
Verilator's cost estimates are assigned by ``InstrCountCostVisitor``. This
|
||||
Verilator's cost estimates are assigned by ``InstrCountVisitor``. This
|
||||
class is perhaps the most fragile piece of the multithread
|
||||
implementation. It's easy to have a bug where you count something cheap
|
||||
(eg. accessing one element of a huge array) as if it were expensive (eg.
|
||||
@@ -301,7 +301,7 @@ prerequisites on other threads have finished.
|
||||
|
||||
The synchronization cost is cheap if the prereqs are done. If they're not,
|
||||
fragmentation (idle CPU cores waiting) is possible. This is the major
|
||||
source of overhead in this approach. The ``--prof-threads`` switch and the
|
||||
source of overhead in this approach. The ``--prof-exec`` switch and the
|
||||
``verilator_gantt`` script can visualize the time lost to such
|
||||
fragmentation.
|
||||
|
||||
@@ -405,6 +405,9 @@ routines in the sources to rely more heavily on randomness, and
|
||||
generally try harder not to keep input nodes together when we have the
|
||||
option to scramble things.
|
||||
|
||||
Profile-guided optimization make this a bit better, by adjusting mtask
|
||||
scheduling, but this does not yet guide the packing into mtasks.
|
||||
|
||||
|
||||
Performance Regression
|
||||
""""""""""""""""""""""
|
||||
@@ -520,10 +523,10 @@ optimization passes. This allows separation of the pass algorithm from the
|
||||
AST on which it operates. Wikipedia provides an introduction to the concept
|
||||
at https://en.wikipedia.org/wiki/Visitor_pattern.
|
||||
|
||||
As noted above, all visitors are derived classes of ``AstNVisitor``. All
|
||||
As noted above, all visitors are derived classes of ``VNVisitor``. All
|
||||
derived classes of ``AstNode`` implement the ``accept`` method, which takes
|
||||
as argument a reference to an instance or a ``AstNVisitor`` derived class
|
||||
and applies the visit method of the ``AstNVisitor`` to the invoking AstNode
|
||||
as argument a reference to an instance or a ``VNVisitor`` derived class
|
||||
and applies the visit method of the ``VNVisitor`` to the invoking AstNode
|
||||
instance (i.e. ``this``).
|
||||
|
||||
One possible difficulty is that a call to ``accept`` may perform an edit
|
||||
@@ -601,8 +604,8 @@ There are three ways data is passed between visitor functions.
|
||||
Iterators
|
||||
---------
|
||||
|
||||
``AstNVisitor`` provides a set of iterators to facilitate walking over
|
||||
the tree. Each operates on the current ``AstNVisitor`` class (as this)
|
||||
``VNVisitor`` provides a set of iterators to facilitate walking over
|
||||
the tree. Each operates on the current ``VNVisitor`` class (as this)
|
||||
and takes an argument type ``AstNode*``.
|
||||
|
||||
``iterate``
|
||||
@@ -814,7 +817,7 @@ which you can install using cpan.
|
||||
|
||||
There are some traps to avoid when running regression tests
|
||||
|
||||
- When checking the MANIFEST, the test will barf on unexpected code in the
|
||||
- When checking the MANIFEST, the test will fail on unexpected code in the
|
||||
Verilator tree. So make sure to keep any such code outside the tree.
|
||||
|
||||
- Not all Linux systems install Perldoc by default. This is needed for the
|
||||
@@ -1180,10 +1183,10 @@ Verilator ideally would support all of IEEE, and has the goal to get close
|
||||
to full support. However the following IEEE sections and features are not
|
||||
anticipated to be ever implemented for the reasons indicated.
|
||||
|
||||
IEEE 1800-2017 3.3 recursive modules
|
||||
IEEE 1800-2017 3.3 modules within modules
|
||||
Little/no tool support, and arguably not a good practice.
|
||||
IEEE 1800-2017 6.12 "shortreal"
|
||||
Little/no tool support, and easily simply promoted to real.
|
||||
Little/no tool support, and easily promoted to real.
|
||||
IEEE 1800-2017 11.11 Min, typ, max
|
||||
No SDF support so will always use typical.
|
||||
IEEE 1800-2017 11.12 "let"
|
||||
@@ -1205,7 +1208,7 @@ IEEE 1800-2017 33 Config
|
||||
Distribution
|
||||
============
|
||||
|
||||
Copyright 2008-2021 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2008-2022 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
|
||||
+55
-1
@@ -2,9 +2,11 @@ ABCp
|
||||
Accellera
|
||||
Affe
|
||||
Aleksander
|
||||
Alexandre
|
||||
Ami
|
||||
Amir
|
||||
Anastasiadis
|
||||
Anikin
|
||||
Antonin
|
||||
Antwerpen
|
||||
Arasanipalai
|
||||
@@ -70,6 +72,7 @@ Eda
|
||||
Eddleston
|
||||
Egbert
|
||||
Egil
|
||||
Ehab
|
||||
Eiler
|
||||
Eivind
|
||||
El
|
||||
@@ -82,6 +85,7 @@ Fabrizio
|
||||
Fekete
|
||||
Ferrandi
|
||||
Flachs
|
||||
Flavien
|
||||
Foletto
|
||||
Forker
|
||||
Francillon
|
||||
@@ -104,6 +108,7 @@ Goessling
|
||||
Gonnen
|
||||
Goorah
|
||||
Gossner
|
||||
Graybeal
|
||||
Grobman
|
||||
Gunter
|
||||
Guo
|
||||
@@ -121,6 +126,7 @@ Hornung
|
||||
Hossell
|
||||
Hsu
|
||||
Hyperthreading
|
||||
Ibrahim
|
||||
Iles
|
||||
Inlines
|
||||
Inout
|
||||
@@ -134,6 +140,7 @@ Jannis
|
||||
Jens
|
||||
Jeras
|
||||
Jiuyang
|
||||
Joannou
|
||||
Joly
|
||||
Jullien
|
||||
Junji
|
||||
@@ -147,6 +154,7 @@ Kamendje
|
||||
Kandadi
|
||||
Kaplan
|
||||
Karge
|
||||
Karlsson
|
||||
Katz
|
||||
Katzman
|
||||
Keren
|
||||
@@ -161,6 +169,7 @@ Kolecki
|
||||
Koonce
|
||||
Korteland
|
||||
Koszek
|
||||
Kouping
|
||||
Kravitz
|
||||
Krolnik
|
||||
Kruse
|
||||
@@ -194,6 +203,7 @@ Mednick
|
||||
Michiels
|
||||
Microsystems
|
||||
Milanovic
|
||||
Millis
|
||||
MinW
|
||||
Mindspeed
|
||||
Miodrag
|
||||
@@ -224,12 +234,14 @@ Petr
|
||||
Piechotka
|
||||
Piersall
|
||||
Plunkett
|
||||
Popolon
|
||||
Popov
|
||||
Prabhat
|
||||
Prabhu
|
||||
Prateek
|
||||
Pre
|
||||
Preprocess
|
||||
Pretet
|
||||
Priyadharshini
|
||||
Pullup
|
||||
Pulver
|
||||
@@ -262,12 +274,15 @@ Shi
|
||||
Shinkarovsky
|
||||
Shirakawa
|
||||
Shuba
|
||||
Shunyao
|
||||
Slatter
|
||||
SoC
|
||||
Sobhan
|
||||
Sokorac
|
||||
Solaris
|
||||
Solomatnikov
|
||||
Solt
|
||||
Southwell
|
||||
Srini
|
||||
Stamness
|
||||
Stephane
|
||||
@@ -286,6 +301,7 @@ SystemVerilog
|
||||
Takatsukasa
|
||||
Tambe
|
||||
Tariq
|
||||
Tejada
|
||||
Tengstrand
|
||||
Terpstra
|
||||
Thiede
|
||||
@@ -293,8 +309,10 @@ Thierry
|
||||
Thyer
|
||||
Tichelaar
|
||||
Tomov
|
||||
Tood
|
||||
Topa
|
||||
Tota
|
||||
Trefor
|
||||
Tresidder
|
||||
Tri
|
||||
Tristate
|
||||
@@ -304,11 +322,13 @@ Ubixum
|
||||
Uints
|
||||
Undefines
|
||||
Unsized
|
||||
Urbach
|
||||
Uselib
|
||||
Usha
|
||||
Usuario
|
||||
VERILATOR
|
||||
Vasu
|
||||
Vdeeptemp
|
||||
Vdly
|
||||
Vemumtab
|
||||
Vemuri
|
||||
@@ -351,7 +371,9 @@ Zhang
|
||||
abirkmanis
|
||||
accessor
|
||||
accessors
|
||||
adrienlemasle
|
||||
agrobman
|
||||
ahouska
|
||||
al
|
||||
ala
|
||||
andit
|
||||
@@ -372,8 +394,12 @@ backtrace
|
||||
backtraces
|
||||
basename
|
||||
bbox
|
||||
benchmarking
|
||||
biguint
|
||||
biops
|
||||
bitOpTree
|
||||
bitOpTree
|
||||
bitop
|
||||
bitstoreal
|
||||
blackbox
|
||||
bokke
|
||||
@@ -389,6 +415,7 @@ casez
|
||||
casted
|
||||
cb
|
||||
ccache
|
||||
ccall
|
||||
cdc
|
||||
ceil
|
||||
celldefine
|
||||
@@ -411,6 +438,8 @@ concat
|
||||
concats
|
||||
config
|
||||
const
|
||||
constexpr
|
||||
constpool
|
||||
coredump
|
||||
countbits
|
||||
countones
|
||||
@@ -426,6 +455,7 @@ da
|
||||
dat
|
||||
datadir
|
||||
datafiles
|
||||
david
|
||||
ddd
|
||||
deassign
|
||||
debugi
|
||||
@@ -434,6 +464,7 @@ defname
|
||||
defparam
|
||||
demangling
|
||||
der
|
||||
dereference
|
||||
desassign
|
||||
destructor
|
||||
detections
|
||||
@@ -462,6 +493,7 @@ dumpvars
|
||||
dut
|
||||
dx
|
||||
elab
|
||||
elike
|
||||
elsif
|
||||
endcase
|
||||
endcelldefine
|
||||
@@ -480,15 +512,18 @@ enums
|
||||
env
|
||||
envvar
|
||||
eof
|
||||
errae
|
||||
erroring
|
||||
et
|
||||
eval
|
||||
evals
|
||||
exe
|
||||
executables
|
||||
expr
|
||||
extern
|
||||
fanin
|
||||
fasttrace
|
||||
fauto
|
||||
fbranch
|
||||
fclose
|
||||
fdisplay
|
||||
@@ -503,6 +538,7 @@ filt
|
||||
flto
|
||||
flushCall
|
||||
fopen
|
||||
forceable
|
||||
foreach
|
||||
fprintf
|
||||
fprofile
|
||||
@@ -521,6 +557,7 @@ funcs
|
||||
fwrite
|
||||
gantt
|
||||
gcc
|
||||
gcda
|
||||
gdb
|
||||
genblk
|
||||
genvar
|
||||
@@ -552,6 +589,7 @@ incdir
|
||||
includer
|
||||
inferfaces
|
||||
inhibitSim
|
||||
initarray
|
||||
initializer
|
||||
initializers
|
||||
inits
|
||||
@@ -570,6 +608,7 @@ killua
|
||||
lang
|
||||
lcov
|
||||
ld
|
||||
leavinel
|
||||
len
|
||||
libext
|
||||
libgoogle
|
||||
@@ -584,6 +623,7 @@ ln
|
||||
loc
|
||||
localparam
|
||||
localparams
|
||||
localtime
|
||||
logicals
|
||||
longint
|
||||
lsb
|
||||
@@ -618,6 +658,7 @@ multithreaded
|
||||
multithreading
|
||||
mutexes
|
||||
mux
|
||||
myftptoyman
|
||||
mysignal
|
||||
namespace
|
||||
nand
|
||||
@@ -642,15 +683,19 @@ onehot
|
||||
ooo
|
||||
oprofile
|
||||
oversubscription
|
||||
parallelized
|
||||
param
|
||||
parameterized
|
||||
params
|
||||
parens
|
||||
pawel
|
||||
pc
|
||||
pdf
|
||||
perf
|
||||
perftools
|
||||
pgo
|
||||
picoChip
|
||||
pinIndex
|
||||
pinout
|
||||
plusargs
|
||||
pmos
|
||||
@@ -676,7 +721,7 @@ prev
|
||||
printf
|
||||
printtimescale
|
||||
profcfunc
|
||||
profcfuncs
|
||||
profiler
|
||||
prototyptes
|
||||
ps
|
||||
pthread
|
||||
@@ -704,12 +749,14 @@ regs
|
||||
reloop
|
||||
resetall
|
||||
respecified
|
||||
rodata
|
||||
rr
|
||||
rst
|
||||
runtime
|
||||
runtimes
|
||||
rw
|
||||
sVerilator
|
||||
sawatzke
|
||||
sc
|
||||
scalared
|
||||
sccanf
|
||||
@@ -725,6 +772,7 @@ specparam
|
||||
splitme
|
||||
spp
|
||||
sqrt
|
||||
src
|
||||
srcdir
|
||||
srcfile
|
||||
sscanf
|
||||
@@ -744,6 +792,7 @@ subcells
|
||||
subexpressions
|
||||
submodule
|
||||
submodules
|
||||
substring
|
||||
sv
|
||||
svBitVal
|
||||
svBitVecVal
|
||||
@@ -778,6 +827,7 @@ trunc
|
||||
txt
|
||||
typ
|
||||
typedef
|
||||
typedef'ed
|
||||
typedefed
|
||||
typedefs
|
||||
typename
|
||||
@@ -791,6 +841,7 @@ uniquified
|
||||
unistd
|
||||
unlink
|
||||
unlinked
|
||||
unnamedblk
|
||||
unopt
|
||||
unoptflat
|
||||
unoptimizable
|
||||
@@ -840,11 +891,14 @@ writeme
|
||||
writemem
|
||||
writememb
|
||||
writememh
|
||||
xiak
|
||||
xin
|
||||
xml
|
||||
xnor
|
||||
xout
|
||||
xuejiazidi
|
||||
yanx
|
||||
ypq
|
||||
yurivict
|
||||
zdave
|
||||
Øyvind
|
||||
|
||||
+1
-4
@@ -46,9 +46,6 @@ The XML document consists of 4 sections within the top level
|
||||
hierarchy. Each instance is represented with the ``<cell>`` element
|
||||
with the following attributes:
|
||||
|
||||
- ``fl`` (deprecated): The file id and line number where the module
|
||||
was instanced. Use ``loc`` instead.
|
||||
|
||||
- ``loc``: The file id, first line number, last line number, first
|
||||
column number and last column number of the identifier where the
|
||||
module was instanced, separated by commas.
|
||||
@@ -73,7 +70,7 @@ The XML document consists of 4 sections within the top level
|
||||
Distribution
|
||||
============
|
||||
|
||||
Copyright 2020-2021 by Wilson Snyder. Verilator is free software; you can
|
||||
Copyright 2020-2022 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ run:
|
||||
|
||||
@echo "-- DONE --------------------"
|
||||
@echo "Note: Once this example is understood, see examples/cmake_tracing_sc."
|
||||
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
|
||||
@echo "Note: See also https://verilator.org/guide/latest/examples.html"
|
||||
|
||||
clean mostlyclean distclean maintainer-clean:
|
||||
@rm -rf build logs
|
||||
|
||||
@@ -33,5 +33,5 @@ add_executable(example ../make_tracing_c/sim_main.cpp)
|
||||
# Add the Verilated circuit to the target
|
||||
verilate(example COVERAGE TRACE
|
||||
INCLUDE_DIRS "../make_tracing_c"
|
||||
VERILATOR_ARGS -f ../make_tracing_c/input.vc -Os -x-assign 0
|
||||
VERILATOR_ARGS -f ../make_tracing_c/input.vc -x-assign fast
|
||||
SOURCES ../make_tracing_c/top.v)
|
||||
|
||||
@@ -45,7 +45,7 @@ set_property(
|
||||
# Add the Verilated circuit to the target
|
||||
verilate(example SYSTEMC COVERAGE TRACE
|
||||
INCLUDE_DIRS "../make_tracing_sc"
|
||||
VERILATOR_ARGS -f ../make_tracing_sc/input.vc -Os -x-assign 0
|
||||
VERILATOR_ARGS -f ../make_tracing_sc/input.vc -x-assign fast
|
||||
SOURCES ../make_tracing_sc/top.v)
|
||||
|
||||
verilator_link_systemc(example)
|
||||
|
||||
@@ -40,7 +40,7 @@ default:
|
||||
obj_dir/Vtop
|
||||
@echo "-- DONE --------------------"
|
||||
@echo "Note: Once this example is understood, see examples/make_tracing_c."
|
||||
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
|
||||
@echo "Note: See also https://verilator.org/guide/latest/examples.html"
|
||||
|
||||
######################################################################
|
||||
|
||||
|
||||
@@ -21,11 +21,14 @@ int main(int argc, char** argv, char** env) {
|
||||
// Prevent unused variable warnings
|
||||
if (false && argc && argv && env) {}
|
||||
|
||||
// Construct a VerilatedContext to hold simulation time, etc.
|
||||
VerilatedContext* contextp = new VerilatedContext;
|
||||
|
||||
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
|
||||
Vtop* top = new Vtop;
|
||||
Vtop* top = new Vtop{contextp};
|
||||
|
||||
// Simulate until $finish
|
||||
while (!Verilated::gotFinish()) {
|
||||
while (!contextp->gotFinish()) {
|
||||
|
||||
// Evaluate model
|
||||
top->eval();
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
// any use, without warranty, 2017 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// See also the EXAMPLE section in the verilator manpage/document.
|
||||
// See also https://verilator.org/guide/latest/examples.html"
|
||||
|
||||
module top;
|
||||
initial begin
|
||||
$display("Hello World!");
|
||||
|
||||
@@ -49,7 +49,7 @@ run:
|
||||
obj_dir/Vtop
|
||||
@echo "-- DONE --------------------"
|
||||
@echo "Note: Once this example is understood, see examples/make_tracing_sc."
|
||||
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
|
||||
@echo "Note: See also https://verilator.org/guide/latest/examples.html"
|
||||
|
||||
######################################################################
|
||||
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
// any use, without warranty, 2017 by Wilson Snyder.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// See also the EXAMPLE section in the verilator manpage/document.
|
||||
// See also https://verilator.org/guide/latest/examples.html"
|
||||
|
||||
module top;
|
||||
initial begin
|
||||
$display("Hello World!");
|
||||
|
||||
@@ -33,7 +33,7 @@ VERILATOR_FLAGS =
|
||||
# Generate C++
|
||||
VERILATOR_FLAGS += -cc
|
||||
# Optimize
|
||||
VERILATOR_FLAGS += -Os -x-assign 0
|
||||
VERILATOR_FLAGS += -x-assign fast
|
||||
# Warn abount lint issues; may not want this on less solid designs
|
||||
VERILATOR_FLAGS += -Wall
|
||||
# This example does not use vl_time_stamp but rather
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
// any use, without warranty, 2019 by Todd Strader.
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
// See also the EXAMPLE section in the verilator manpage/document.
|
||||
// See also https://verilator.org/guide/latest/examples.html"
|
||||
|
||||
module top (input clk);
|
||||
|
||||
integer cyc = 0;
|
||||
|
||||
@@ -36,7 +36,7 @@ VERILATOR_FLAGS += -cc --exe
|
||||
# Generate makefile dependencies (not shown as complicates the Makefile)
|
||||
#VERILATOR_FLAGS += -MMD
|
||||
# Optimize
|
||||
VERILATOR_FLAGS += -Os -x-assign 0
|
||||
VERILATOR_FLAGS += -x-assign fast
|
||||
# Warn abount lint issues; may not want this on less solid designs
|
||||
VERILATOR_FLAGS += -Wall
|
||||
# Make waveforms
|
||||
|
||||
@@ -34,6 +34,8 @@ int main(int argc, char** argv, char** env) {
|
||||
// Using unique_ptr is similar to
|
||||
// "VerilatedContext* contextp = new VerilatedContext" then deleting at end.
|
||||
const std::unique_ptr<VerilatedContext> contextp{new VerilatedContext};
|
||||
// Do not instead make Vtop as a file-scope static variable, as the
|
||||
// "C++ static initialization order fiasco" may cause a crash
|
||||
|
||||
// Set debug level, 0 is off, 9 is highest presently used
|
||||
// May be overridden by commandArgs argument parsing
|
||||
@@ -69,7 +71,7 @@ int main(int argc, char** argv, char** env) {
|
||||
// Historical note, before Verilator 4.200 Verilated::gotFinish()
|
||||
// was used above in place of contextp->gotFinish().
|
||||
// Most of the contextp-> calls can use Verilated:: calls instead;
|
||||
// the Verilated:: versions simply assume there's a single context
|
||||
// the Verilated:: versions just assume there's a single context
|
||||
// being used (per thread). It's faster and clearer to use the
|
||||
// newer contextp-> versions.
|
||||
|
||||
@@ -103,8 +105,8 @@ int main(int argc, char** argv, char** env) {
|
||||
top->eval();
|
||||
|
||||
// Read outputs
|
||||
VL_PRINTF("[%" VL_PRI64 "d] clk=%x rstl=%x iquad=%" VL_PRI64 "x"
|
||||
" -> oquad=%" VL_PRI64 "x owide=%x_%08x_%08x\n",
|
||||
VL_PRINTF("[%" PRId64 "] clk=%x rstl=%x iquad=%" PRIx64 " -> oquad=%" PRIx64
|
||||
" owide=%x_%08x_%08x\n",
|
||||
contextp->time(), top->clk, top->reset_l, top->in_quad, top->out_quad,
|
||||
top->out_wide[2], top->out_wide[1], top->out_wide[0]);
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ VERILATOR_FLAGS += -sc --exe
|
||||
# Generate makefile dependencies (not shown as complicates the Makefile)
|
||||
#VERILATOR_FLAGS += -MMD
|
||||
# Optimize
|
||||
VERILATOR_FLAGS += -Os -x-assign 0
|
||||
VERILATOR_FLAGS += -x-assign fast
|
||||
# Warn abount lint issues; may not want this on less solid designs
|
||||
VERILATOR_FLAGS += -Wall
|
||||
# Make waveforms
|
||||
|
||||
@@ -58,11 +58,11 @@ int sc_main(int argc, char* argv[]) {
|
||||
|
||||
// Define interconnect
|
||||
sc_signal<bool> reset_l;
|
||||
sc_signal<vluint32_t> in_small;
|
||||
sc_signal<vluint64_t> in_quad;
|
||||
sc_signal<uint32_t> in_small;
|
||||
sc_signal<uint64_t> in_quad;
|
||||
sc_signal<sc_bv<70>> in_wide;
|
||||
sc_signal<vluint32_t> out_small;
|
||||
sc_signal<vluint64_t> out_quad;
|
||||
sc_signal<uint32_t> out_small;
|
||||
sc_signal<uint64_t> out_quad;
|
||||
sc_signal<sc_bv<70>> out_wide;
|
||||
|
||||
// Construct the Verilated model, from inside Vtop.h
|
||||
|
||||
@@ -140,6 +140,10 @@ void **JenkinsIns(void *base_i, const unsigned char *mem, uint32_t length, uint3
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
|
||||
#if defined(FST_MACOSX) || defined(__MINGW32__) || defined(__OpenBSD__) || defined(__FreeBSD__)
|
||||
#define FST_UNBUFFERED_IO
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
/* Boolean expression more often true than false */
|
||||
#define FST_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
@@ -4577,12 +4581,11 @@ if(sectype == FST_BL_ZWRAPPER)
|
||||
if(!fcomp) { tmpfile_close(&fcomp, &xc->f_nam); return(0); }
|
||||
}
|
||||
|
||||
#if defined(FST_MACOSX)
|
||||
#if defined(FST_UNBUFFERED_IO)
|
||||
setvbuf(fcomp, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
setvbuf(fcomp, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */
|
||||
xc->filename_unpacked = hf;
|
||||
#else
|
||||
if(hf)
|
||||
@@ -4880,7 +4883,7 @@ if((!nam)||(!(xc->f=fopen(nam, "rb"))))
|
||||
char *hf = (char *)calloc(1, flen + 6);
|
||||
int rc;
|
||||
|
||||
#if defined(__MINGW32__) || defined(FST_MACOSX)
|
||||
#if defined(FST_UNBUFFERED_IO)
|
||||
setvbuf(xc->f, (char *)NULL, _IONBF, 0); /* keeps gzip from acting weird in tandem with fopen */
|
||||
#endif
|
||||
|
||||
@@ -4989,9 +4992,7 @@ unsigned int secnum = 0;
|
||||
int blocks_skipped = 0;
|
||||
fst_off_t blkpos = 0;
|
||||
uint64_t seclen, beg_tim;
|
||||
#ifdef FST_DEBUG
|
||||
uint64_t end_tim;
|
||||
#endif
|
||||
uint64_t frame_uclen, frame_clen, frame_maxhandle, vc_maxhandle;
|
||||
fst_off_t vc_start;
|
||||
fst_off_t indx_pntr, indx_pos;
|
||||
@@ -5058,14 +5059,11 @@ for(;;)
|
||||
if(!seclen) break;
|
||||
|
||||
beg_tim = fstReaderUint64(xc->f);
|
||||
#ifdef FST_DEBUG
|
||||
end_tim =
|
||||
#endif
|
||||
fstReaderUint64(xc->f);
|
||||
end_tim = fstReaderUint64(xc->f);
|
||||
|
||||
if(xc->limit_range_valid)
|
||||
{
|
||||
if(beg_tim < xc->limit_range_start)
|
||||
if(end_tim < xc->limit_range_start)
|
||||
{
|
||||
blocks_skipped++;
|
||||
blkpos += seclen;
|
||||
|
||||
+427
-304
File diff suppressed because it is too large
Load Diff
+128
-2184
File diff suppressed because it is too large
Load Diff
+13
-26
@@ -2,7 +2,7 @@
|
||||
######################################################################
|
||||
# DESCRIPTION: Makefile commands for all verilated target files
|
||||
#
|
||||
# Copyright 2003-2021 by Wilson Snyder. This program is free software; you
|
||||
# Copyright 2003-2022 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
@@ -23,8 +23,6 @@ CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
|
||||
CFG_CXXFLAGS_PROFILE = @CFG_CXXFLAGS_PROFILE@
|
||||
# Select newest language
|
||||
CFG_CXXFLAGS_STD_NEWEST = @CFG_CXXFLAGS_STD_NEWEST@
|
||||
# Select oldest language (for Verilator internal testing only)
|
||||
CFG_CXXFLAGS_STD_OLDEST = @CFG_CXXFLAGS_STD_OLDEST@
|
||||
# Compiler flags to use to turn off unused and generated code warnings, such as -Wno-div-by-zero
|
||||
CFG_CXXFLAGS_NO_UNUSED = @CFG_CXXFLAGS_NO_UNUSED@
|
||||
# Compiler flags that turn on extra warnings
|
||||
@@ -58,6 +56,7 @@ VK_CPPFLAGS_ALWAYS += \
|
||||
-DVM_SC=$(VM_SC) \
|
||||
-DVM_TRACE=$(VM_TRACE) \
|
||||
-DVM_TRACE_FST=$(VM_TRACE_FST) \
|
||||
-DVM_TRACE_VCD=$(VM_TRACE_VCD) \
|
||||
$(CFG_CXXFLAGS_NO_UNUSED) \
|
||||
|
||||
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||
@@ -143,26 +142,6 @@ ifneq ($(VM_THREADS),0)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(VM_TRACE_THREADS),0)
|
||||
ifneq ($(VM_TRACE_THREADS),)
|
||||
ifeq ($(findstring -DVL_THREADED,$(CPPFLAGS)),)
|
||||
$(error VM_TRACE_THREADS requires VM_THREADS)
|
||||
endif
|
||||
CPPFLAGS += -DVL_TRACE_THREADED
|
||||
VK_C11=1
|
||||
VK_LIBS_THREADED=1
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
ifneq ($(VM_TRACE_FST_WRITER_THREAD),0)
|
||||
ifneq ($(VM_TRACE_FST_WRITER_THREAD),)
|
||||
CPPFLAGS += -DVL_TRACE_FST_WRITER_THREAD
|
||||
VK_C11=1
|
||||
VK_LIBS_THREADED=1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(VK_C11),0)
|
||||
ifneq ($(VK_C11),)
|
||||
# Need C++11 at least, so always default to newest
|
||||
@@ -188,13 +167,17 @@ VM_SLOW += $(VM_CLASSES_SLOW) $(VM_SUPPORT_SLOW)
|
||||
VK_FAST_OBJS = $(addsuffix .o, $(VM_FAST))
|
||||
VK_SLOW_OBJS = $(addsuffix .o, $(VM_SLOW))
|
||||
|
||||
VK_USER_OBJS = $(addsuffix .o, $(VM_USER_CLASSES))
|
||||
VK_USER_OBJS = $(addsuffix .o, $(VM_USER_CLASSES))
|
||||
|
||||
# Note VM_GLOBAL_FAST and VM_GLOBAL_SLOW holds the files required from the
|
||||
# run-time library. In practice everything is actually in VM_GLOBAL_FAST,
|
||||
# but keeping the distinction for compatibility for now.
|
||||
VK_GLOBAL_OBJS = $(addsuffix .o, $(VM_GLOBAL_FAST) $(VM_GLOBAL_SLOW))
|
||||
|
||||
# Need to re-build if the generated makefile changes, as compiler options might
|
||||
# have changed.
|
||||
$(VK_GLOBAL_OBJS): $(VM_PREFIX).mk
|
||||
|
||||
ifneq ($(VM_PARALLEL_BUILDS),1)
|
||||
# Fast build for small designs: All .cpp files in one fell swoop. This
|
||||
# saves total compute, but can be slower if only a little changes. It is
|
||||
@@ -225,7 +208,9 @@ endif
|
||||
$(info Archive $(AR) -rcs $@ $^)
|
||||
$(foreach L, $(filter-out %.a,$^), $(shell echo $L >>[email protected]_deplist.tmp))
|
||||
@if test $(words $(filter %.a,$^)) -eq 0; then \
|
||||
$(AR) -rcs $@ @[email protected]_deplist.tmp; \
|
||||
$(RM) -f $@; \
|
||||
cat [email protected]_deplist.tmp | xargs $(AR) -rc $@; \
|
||||
$(AR) -s $@; \
|
||||
else \
|
||||
$(RM) -rf [email protected]; \
|
||||
for archive in $(filter %.a,$^); do \
|
||||
@@ -234,7 +219,9 @@ endif
|
||||
$(AR) -x ../../$${archive}; \
|
||||
cd ../..; \
|
||||
done; \
|
||||
$(AR) -rcs $@ @[email protected]_deplist.tmp [email protected]/*/*.o; \
|
||||
$(RM) -f $@; \
|
||||
cat [email protected]_deplist.tmp | xargs $(AR) -rc $@; \
|
||||
$(AR) -rcs $@ [email protected]/*/*.o; \
|
||||
fi \
|
||||
; $(RM) -rf [email protected]_deplist.tmp [email protected]
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -20,6 +20,11 @@
|
||||
// Autoconf substitutes this with the strings from AC_INIT.
|
||||
#define VERILATOR_PRODUCT "@PACKAGE_NAME@"
|
||||
|
||||
/// Verilator version name, e.g. "1.000 2000-01-01"
|
||||
/// Verilator version name, e.g. "1.002 2000-01-01"
|
||||
// Autoconf substitutes this with the strings from AC_INIT.
|
||||
#define VERILATOR_VERSION "@PACKAGE_VERSION@"
|
||||
|
||||
/// Verilator version number as integer
|
||||
/// As major * 100000 + minor * 1000, e.g. 1002000 == 1.002
|
||||
// Autoconf substitutes this with the strings from AC_INIT.
|
||||
#define VERILATOR_VERSION_INTEGER @VERILATOR_VERSION_INTEGER@
|
||||
|
||||
+58
-52
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||
// can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -22,13 +22,16 @@
|
||||
//=============================================================================
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h"
|
||||
|
||||
#include "verilated_cov.h"
|
||||
|
||||
#include "verilated.h"
|
||||
#include "verilated_cov_key.h"
|
||||
|
||||
#include <deque>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedCovConst
|
||||
@@ -58,7 +61,7 @@ public: // But only local to this file
|
||||
}
|
||||
}
|
||||
virtual ~VerilatedCovImpItem() = default;
|
||||
virtual vluint64_t count() const = 0;
|
||||
virtual uint64_t count() const = 0;
|
||||
virtual void zero() const = 0;
|
||||
};
|
||||
|
||||
@@ -68,22 +71,23 @@ public: // But only local to this file
|
||||
// This isn't in the header file for auto-magic conversion because it
|
||||
// inlines to too much code and makes compilation too slow.
|
||||
|
||||
template <class T> class VerilatedCoverItemSpec final : public VerilatedCovImpItem {
|
||||
template <class T>
|
||||
class VerilatedCoverItemSpec final : public VerilatedCovImpItem {
|
||||
private:
|
||||
// MEMBERS
|
||||
T* m_countp; // Count value
|
||||
public:
|
||||
// METHODS
|
||||
// cppcheck-suppress truncLongCastReturn
|
||||
virtual vluint64_t count() const override { return *m_countp; }
|
||||
virtual void zero() const override { *m_countp = 0; }
|
||||
uint64_t count() const override { return *m_countp; }
|
||||
void zero() const override { *m_countp = 0; }
|
||||
// CONSTRUCTORS
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
explicit VerilatedCoverItemSpec(T* countp)
|
||||
: m_countp{countp} {
|
||||
*m_countp = 0;
|
||||
}
|
||||
virtual ~VerilatedCoverItemSpec() override = default;
|
||||
~VerilatedCoverItemSpec() override = default;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
@@ -102,7 +106,7 @@ private:
|
||||
using ItemList = std::deque<VerilatedCovImpItem*>;
|
||||
|
||||
// MEMBERS
|
||||
VerilatedMutex m_mutex; // Protects all members
|
||||
mutable VerilatedMutex m_mutex; // Protects all members
|
||||
ValueIndexMap m_valueIndexes VL_GUARDED_BY(m_mutex); // Unique arbitrary value for values
|
||||
IndexValueMap m_indexValues VL_GUARDED_BY(m_mutex); // Unique arbitrary value for keys
|
||||
ItemList m_items VL_GUARDED_BY(m_mutex); // List of all items
|
||||
@@ -121,18 +125,14 @@ public:
|
||||
|
||||
protected:
|
||||
friend class VerilatedCovContext;
|
||||
virtual ~VerilatedCovImp() override { clearGuts(); }
|
||||
static VerilatedCovImp& imp() VL_MT_SAFE {
|
||||
static VerilatedCovImp s_singleton;
|
||||
return s_singleton;
|
||||
}
|
||||
~VerilatedCovImp() override { clearGuts(); }
|
||||
|
||||
private:
|
||||
// PRIVATE METHODS
|
||||
int valueIndex(const std::string& value) VL_REQUIRES(m_mutex) {
|
||||
const auto iter = m_valueIndexes.find(value);
|
||||
if (iter != m_valueIndexes.end()) return iter->second;
|
||||
m_nextIndex++;
|
||||
++m_nextIndex;
|
||||
assert(m_nextIndex > 0); // Didn't rollover
|
||||
m_valueIndexes.emplace(value, m_nextIndex);
|
||||
m_indexValues.emplace(m_nextIndex, value);
|
||||
@@ -143,8 +143,9 @@ private:
|
||||
std::string rtn;
|
||||
for (const char* pos = text.c_str(); *pos; ++pos) {
|
||||
if (!std::isprint(*pos) || *pos == '%' || *pos == '"') {
|
||||
char hex[10];
|
||||
VL_SNPRINTF(hex, 10, "%%%02X", pos[0]);
|
||||
constexpr size_t LEN_MAX_HEX = 20;
|
||||
char hex[LEN_MAX_HEX];
|
||||
VL_SNPRINTF(hex, LEN_MAX_HEX, "%%%02X", pos[0]);
|
||||
rtn += hex;
|
||||
} else {
|
||||
rtn += *pos;
|
||||
@@ -165,11 +166,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 += std::string{"\001"} + key;
|
||||
} else {
|
||||
name += std::string("\001") + dequote(key);
|
||||
name += std::string{"\001"} + dequote(key);
|
||||
}
|
||||
name += std::string("\002") + dequote(value);
|
||||
name += std::string{"\002"} + dequote(value);
|
||||
return name;
|
||||
}
|
||||
static std::string combineHier(const std::string& old, const std::string& add) VL_PURE {
|
||||
@@ -180,31 +181,32 @@ private:
|
||||
if (old.empty()) return add;
|
||||
if (add.empty()) return old;
|
||||
|
||||
const char* a = old.c_str();
|
||||
const char* b = add.c_str();
|
||||
const char* const a = old.c_str();
|
||||
const char* const b = add.c_str();
|
||||
|
||||
// Scan forward to first mismatch
|
||||
const char* apre = a;
|
||||
const char* bpre = b;
|
||||
while (*apre == *bpre) {
|
||||
apre++;
|
||||
bpre++;
|
||||
++apre;
|
||||
++bpre;
|
||||
}
|
||||
|
||||
// We used to backup and split on only .'s but it seems better to be verbose
|
||||
// and not assume . is the separator
|
||||
const std::string prefix = std::string(a, apre - a);
|
||||
const size_t prefix_len = apre - a;
|
||||
const std::string prefix = std::string{a, prefix_len};
|
||||
|
||||
// Scan backward to last mismatch
|
||||
const char* apost = a + std::strlen(a) - 1;
|
||||
const char* bpost = b + std::strlen(b) - 1;
|
||||
while (*apost == *bpost && apost > apre && bpost > bpre) {
|
||||
apost--;
|
||||
bpost--;
|
||||
--apost;
|
||||
--bpost;
|
||||
}
|
||||
|
||||
// Forward to . so we have a whole word
|
||||
std::string suffix = *bpost ? std::string(bpost + 1) : "";
|
||||
const std::string suffix = *bpost ? std::string{bpost + 1} : "";
|
||||
|
||||
std::string out = prefix + "*" + suffix;
|
||||
|
||||
@@ -217,7 +219,7 @@ private:
|
||||
for (int i = 0; i < VerilatedCovConst::MAX_KEYS; ++i) {
|
||||
if (itemp->m_keys[i] != VerilatedCovConst::KEY_UNDEF) {
|
||||
// We don't compare keys, only values
|
||||
std::string val = m_indexValues[itemp->m_vals[i]];
|
||||
const std::string val = m_indexValues[itemp->m_vals[i]];
|
||||
if (std::string::npos != val.find(match)) { // Found
|
||||
return true;
|
||||
}
|
||||
@@ -229,7 +231,7 @@ private:
|
||||
// Little selftest
|
||||
#define SELF_CHECK(got, exp) \
|
||||
do { \
|
||||
if ((got) != (exp)) VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: selftest\n"); \
|
||||
if ((got) != (exp)) VL_FATAL_MT(__FILE__, __LINE__, "", "%Error: selftest"); \
|
||||
} while (0)
|
||||
SELF_CHECK(combineHier("a.b.c", "a.b.c"), "a.b.c");
|
||||
SELF_CHECK(combineHier("a.b.c", "a.b"), "a.b*");
|
||||
@@ -253,17 +255,17 @@ public:
|
||||
// PUBLIC METHODS
|
||||
void forcePerInstance(const bool flag) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
Verilated::quiesce();
|
||||
const VerilatedLockGuard lock(m_mutex);
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
m_forcePerInstance = flag;
|
||||
}
|
||||
void clear() VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
Verilated::quiesce();
|
||||
const VerilatedLockGuard lock(m_mutex);
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
clearGuts();
|
||||
}
|
||||
void clearNonMatch(const char* const matchp) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
Verilated::quiesce();
|
||||
const VerilatedLockGuard lock(m_mutex);
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
if (matchp && matchp[0]) {
|
||||
ItemList newlist;
|
||||
for (const auto& itemp : m_items) {
|
||||
@@ -278,29 +280,29 @@ public:
|
||||
}
|
||||
void zero() VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
Verilated::quiesce();
|
||||
const VerilatedLockGuard lock(m_mutex);
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
for (const auto& itemp : m_items) itemp->zero();
|
||||
}
|
||||
|
||||
// We assume there's always call to i/f/p in that order
|
||||
void inserti(VerilatedCovImpItem* itemp) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
const VerilatedLockGuard lock(m_mutex);
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
assert(!m_insertp);
|
||||
m_insertp = itemp;
|
||||
}
|
||||
void insertf(const char* const filenamep, const int lineno) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
const VerilatedLockGuard lock(m_mutex);
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
m_insertFilenamep = filenamep;
|
||||
m_insertLineno = lineno;
|
||||
}
|
||||
void insertp(const char* ckeyps[VerilatedCovConst::MAX_KEYS],
|
||||
const char* valps[VerilatedCovConst::MAX_KEYS]) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
const VerilatedLockGuard lock(m_mutex);
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
assert(m_insertp);
|
||||
// First two key/vals are filename
|
||||
ckeyps[0] = "filename";
|
||||
valps[0] = m_insertFilenamep;
|
||||
std::string linestr = vlCovCvtToStr(m_insertLineno);
|
||||
const std::string linestr = vlCovCvtToStr(m_insertLineno);
|
||||
ckeyps[1] = "lineno";
|
||||
valps[1] = linestr.c_str();
|
||||
// Default page if not specified
|
||||
@@ -308,7 +310,8 @@ public:
|
||||
while (const char* foundp = std::strchr(fnstartp, '/')) fnstartp = foundp + 1;
|
||||
const char* fnendp = fnstartp;
|
||||
for (; *fnendp && *fnendp != '.'; fnendp++) {}
|
||||
std::string page_default = "sp_user/" + std::string(fnstartp, fnendp - fnstartp);
|
||||
const size_t page_len = fnendp - fnstartp;
|
||||
const std::string page_default = "sp_user/" + std::string{fnstartp, page_len};
|
||||
ckeyps[2] = "page";
|
||||
valps[2] = page_default.c_str();
|
||||
|
||||
@@ -337,9 +340,9 @@ public:
|
||||
// cout<<" "<<__FUNCTION__<<" "<<key<<" = "<<val<<endl;
|
||||
m_insertp->m_keys[addKeynum] = valueIndex(key);
|
||||
m_insertp->m_vals[addKeynum] = valueIndex(val);
|
||||
addKeynum++;
|
||||
++addKeynum;
|
||||
if (VL_UNCOVERABLE(!legalKey(key))) {
|
||||
std::string msg
|
||||
const std::string msg
|
||||
= ("%Error: Coverage keys of one character, or letter+digit are illegal: "
|
||||
+ key); // LCOV_EXCL_LINE
|
||||
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||
@@ -353,22 +356,22 @@ public:
|
||||
|
||||
void write(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
Verilated::quiesce();
|
||||
const VerilatedLockGuard lock(m_mutex);
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
#ifndef VM_COVERAGE
|
||||
VL_FATAL_MT("", 0, "", "%Error: Called VerilatedCov::write when VM_COVERAGE disabled\n");
|
||||
VL_FATAL_MT("", 0, "", "%Error: Called VerilatedCov::write when VM_COVERAGE disabled");
|
||||
#endif
|
||||
selftest();
|
||||
|
||||
std::ofstream os(filename);
|
||||
std::ofstream os{filename};
|
||||
if (os.fail()) {
|
||||
std::string msg = std::string("%Error: Can't write '") + filename + "'";
|
||||
const std::string msg = std::string{"%Error: Can't write '"} + filename + "'";
|
||||
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||
return;
|
||||
}
|
||||
os << "# SystemC::Coverage-3\n";
|
||||
|
||||
// Build list of events; totalize if collapsing hierarchy
|
||||
std::map<const std::string, std::pair<std::string, vluint64_t>> eventCounts;
|
||||
std::map<const std::string, std::pair<std::string, uint64_t>> eventCounts;
|
||||
for (const auto& itemp : m_items) {
|
||||
std::string name;
|
||||
std::string hier;
|
||||
@@ -377,8 +380,9 @@ public:
|
||||
|
||||
for (int i = 0; i < VerilatedCovConst::MAX_KEYS; ++i) {
|
||||
if (itemp->m_keys[i] != VerilatedCovConst::KEY_UNDEF) {
|
||||
std::string key = VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]);
|
||||
std::string val = m_indexValues[itemp->m_vals[i]];
|
||||
const std::string key
|
||||
= VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]);
|
||||
const std::string val = m_indexValues[itemp->m_vals[i]];
|
||||
if (key == VL_CIK_PER_INSTANCE) {
|
||||
if (val != "0") per_instance = true;
|
||||
}
|
||||
@@ -434,11 +438,11 @@ void VerilatedCovContext::clearNonMatch(const char* matchp) VL_MT_SAFE {
|
||||
}
|
||||
void VerilatedCovContext::zero() VL_MT_SAFE { impp()->zero(); }
|
||||
void VerilatedCovContext::write(const char* filenamep) VL_MT_SAFE { impp()->write(filenamep); }
|
||||
void VerilatedCovContext::_inserti(vluint32_t* itemp) VL_MT_SAFE {
|
||||
impp()->inserti(new VerilatedCoverItemSpec<vluint32_t>(itemp));
|
||||
void VerilatedCovContext::_inserti(uint32_t* itemp) VL_MT_SAFE {
|
||||
impp()->inserti(new VerilatedCoverItemSpec<uint32_t>{itemp});
|
||||
}
|
||||
void VerilatedCovContext::_inserti(vluint64_t* itemp) VL_MT_SAFE {
|
||||
impp()->inserti(new VerilatedCoverItemSpec<vluint64_t>(itemp));
|
||||
void VerilatedCovContext::_inserti(uint64_t* itemp) VL_MT_SAFE {
|
||||
impp()->inserti(new VerilatedCoverItemSpec<uint64_t>{itemp});
|
||||
}
|
||||
void VerilatedCovContext::_insertf(const char* filename, int lineno) VL_MT_SAFE {
|
||||
impp()->insertf(filename, lineno);
|
||||
@@ -510,8 +514,10 @@ VerilatedCovContext* VerilatedCov::threadCovp() VL_MT_SAFE {
|
||||
|
||||
VerilatedCovContext* VerilatedContext::coveragep() VL_MT_SAFE {
|
||||
static VerilatedMutex s_mutex;
|
||||
// cppcheck-suppress identicalInnerCondition
|
||||
if (VL_UNLIKELY(!m_coveragep)) {
|
||||
const VerilatedLockGuard lock(s_mutex);
|
||||
const VerilatedLockGuard lock{s_mutex};
|
||||
// cppcheck-suppress identicalInnerCondition
|
||||
if (VL_LIKELY(!m_coveragep)) { // Not redundant, prevents race
|
||||
m_coveragep.reset(new VerilatedCovImp);
|
||||
}
|
||||
|
||||
+11
-8
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||
// can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -26,6 +26,7 @@
|
||||
#define VERILATOR_VERILATED_COV_H_
|
||||
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include "verilated.h"
|
||||
|
||||
#include <iostream>
|
||||
@@ -72,7 +73,7 @@ class VerilatedCovImp;
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// vluint32_t m_cases[10]; // Storage for coverage data
|
||||
/// uint32_t m_cases[10]; // Storage for coverage data
|
||||
/// constructor() {
|
||||
/// // Initialize
|
||||
/// for (int i = 0; i < 10; ++i) m_cases[i] = 0;
|
||||
@@ -88,7 +89,8 @@ class VerilatedCovImp;
|
||||
//=============================================================================
|
||||
// Convert VL_COVER_INSERT value arguments to strings, is \internal
|
||||
|
||||
template <class T> std::string vlCovCvtToStr(const T& t) VL_PURE {
|
||||
template <class T>
|
||||
std::string vlCovCvtToStr(const T& t) VL_PURE {
|
||||
std::ostringstream os;
|
||||
os << t;
|
||||
return os.str();
|
||||
@@ -120,14 +122,15 @@ public:
|
||||
/// Zero coverage points
|
||||
void zero() VL_MT_SAFE;
|
||||
|
||||
public: // But Internal use only
|
||||
// METHODS - public but Internal use only
|
||||
|
||||
// Insert a coverage item
|
||||
// We accept from 1-30 key/value pairs, all as strings.
|
||||
// Call _insert1, followed by _insert2 and _insert3
|
||||
// Do not call directly; use VL_COVER_INSERT or higher level macros instead
|
||||
// _insert1: Remember item pointer with count. (Not const, as may add zeroing function)
|
||||
void _inserti(vluint32_t* itemp) VL_MT_SAFE;
|
||||
void _inserti(vluint64_t* itemp) VL_MT_SAFE;
|
||||
void _inserti(uint32_t* itemp) VL_MT_SAFE;
|
||||
void _inserti(uint64_t* itemp) VL_MT_SAFE;
|
||||
// _insert2: Set default filename and line number
|
||||
void _insertf(const char* filename, int lineno) VL_MT_SAFE;
|
||||
// _insert3: Set parameters
|
||||
@@ -157,8 +160,8 @@ protected:
|
||||
friend class VerilatedCovImp;
|
||||
// CONSTRUCTORS
|
||||
// Internal: Only made as part of VerilatedCovImp
|
||||
VerilatedCovContext() {}
|
||||
virtual ~VerilatedCovContext() {}
|
||||
VerilatedCovContext() = default;
|
||||
~VerilatedCovContext() override = default;
|
||||
|
||||
// METHODS
|
||||
// Internal: access to implementation class
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||
// can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
+38
-36
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2009-2021 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2022 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -28,7 +28,9 @@
|
||||
#define VERILATOR_VERILATED_DPI_CPP_
|
||||
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include "verilated_dpi.h"
|
||||
|
||||
#include "verilated_imp.h"
|
||||
|
||||
// On MSVC++ we need svdpi.h to declare exports, not imports
|
||||
@@ -68,7 +70,7 @@ svLogic svGetBitselLogic(const svLogicVecVal* sp, int bit) {
|
||||
| (((sp[VL_BITWORD_I(bit)].bval >> VL_BITBIT_I(bit)) & 1) << 1));
|
||||
}
|
||||
|
||||
void svPutBitselBit(svBitVecVal* dp, int bit, svBit s) { VL_ASSIGNBIT_WI(32, bit, dp, s); }
|
||||
void svPutBitselBit(svBitVecVal* dp, int bit, svBit s) { VL_ASSIGNBIT_WI(bit, dp, s); }
|
||||
void svPutBitselLogic(svLogicVecVal* dp, int bit, svLogic s) {
|
||||
// Verilator doesn't support X/Z so only aval
|
||||
dp[VL_BITWORD_I(bit)].aval = ((dp[VL_BITWORD_I(bit)].aval & ~(VL_UL(1) << VL_BITBIT_I(bit)))
|
||||
@@ -184,7 +186,7 @@ static inline const VerilatedDpiOpenVar* _vl_openhandle_varp(const svOpenArrayHa
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||
"%%Error: DPI svOpenArrayHandle function called with nullptr handle");
|
||||
}
|
||||
const VerilatedDpiOpenVar* varp = reinterpret_cast<const VerilatedDpiOpenVar*>(h);
|
||||
const VerilatedDpiOpenVar* const varp = reinterpret_cast<const VerilatedDpiOpenVar*>(h);
|
||||
if (VL_UNLIKELY(!varp->magicOk())) {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||
"%%Error: DPI svOpenArrayHandle function called with non-Verilator handle");
|
||||
@@ -205,13 +207,13 @@ int svDimensions(const svOpenArrayHandle h) { return _vl_openhandle_varp(h)->udi
|
||||
|
||||
// Return pointer to open array data, or nullptr if not in IEEE standard C layout
|
||||
void* svGetArrayPtr(const svOpenArrayHandle h) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(h);
|
||||
if (VL_UNLIKELY(!varp->isDpiStdLayout())) return nullptr;
|
||||
return varp->datap();
|
||||
}
|
||||
// Return size of open array, or 0 if not in IEEE standard C layout
|
||||
int svSizeOfArray(const svOpenArrayHandle h) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(h);
|
||||
if (VL_UNLIKELY(!varp->isDpiStdLayout())) return 0;
|
||||
// Truncate 64 bits to int; DPI is limited to 4GB
|
||||
return static_cast<int>(varp->totalSize());
|
||||
@@ -264,15 +266,15 @@ static void* _vl_svGetArrElemPtr(const svOpenArrayHandle h, int nargs, int indx1
|
||||
int indx3) VL_MT_SAFE {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h);
|
||||
if (VL_UNLIKELY(!varp->isDpiStdLayout())) return nullptr;
|
||||
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
return datap;
|
||||
}
|
||||
|
||||
// Copy to user bit array from simulator open array
|
||||
static void _vl_svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s, int nargs,
|
||||
int indx1, int indx2, int indx3) VL_MT_SAFE {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
|
||||
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
|
||||
void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
if (VL_UNLIKELY(!datap)) return;
|
||||
switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
|
||||
case VLVT_UINT8: d[0] = *(reinterpret_cast<CData*>(datap)); return;
|
||||
@@ -299,8 +301,8 @@ static void _vl_svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s,
|
||||
// Copy to user logic array from simulator open array
|
||||
static void _vl_svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s, int nargs,
|
||||
int indx1, int indx2, int indx3) VL_MT_SAFE {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
|
||||
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
|
||||
void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
if (VL_UNLIKELY(!datap)) return;
|
||||
switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
|
||||
case VLVT_UINT8:
|
||||
@@ -342,8 +344,8 @@ static void _vl_svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandl
|
||||
// Copy to simulator open array from from user bit array
|
||||
static void _vl_svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s, int nargs,
|
||||
int indx1, int indx2, int indx3) VL_MT_SAFE {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
|
||||
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
|
||||
void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
if (VL_UNLIKELY(!datap)) return;
|
||||
switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
|
||||
case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = s[0]; return;
|
||||
@@ -364,8 +366,8 @@ static void _vl_svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecV
|
||||
// Copy to simulator open array from from user logic array
|
||||
static void _vl_svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
|
||||
int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
|
||||
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
|
||||
void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
if (VL_UNLIKELY(!datap)) return;
|
||||
switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
|
||||
case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = s[0].aval; return;
|
||||
@@ -386,10 +388,10 @@ static void _vl_svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogic
|
||||
|
||||
// Return bit from simulator open array
|
||||
static svBit _vl_svGetBitArrElem(const svOpenArrayHandle s, int nargs, int indx1, int indx2,
|
||||
int indx3, int indx4) VL_MT_SAFE {
|
||||
int indx3, int) VL_MT_SAFE {
|
||||
// One extra index supported, as need bit number
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
|
||||
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
|
||||
void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
if (VL_UNLIKELY(!datap)) return 0;
|
||||
switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
|
||||
case VLVT_UINT8: return (*(reinterpret_cast<CData*>(datap))) & 1;
|
||||
@@ -401,11 +403,11 @@ static svBit _vl_svGetBitArrElem(const svOpenArrayHandle s, int nargs, int indx1
|
||||
}
|
||||
// Update simulator open array from bit
|
||||
static void _vl_svPutBitArrElem(const svOpenArrayHandle d, svBit value, int nargs, int indx1,
|
||||
int indx2, int indx3, int indx4) VL_MT_SAFE {
|
||||
int indx2, int indx3, int) VL_MT_SAFE {
|
||||
// One extra index supported, as need bit number
|
||||
value &= 1; // Make sure clean
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
|
||||
void* datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
|
||||
void* const datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
if (VL_UNLIKELY(!datap)) return;
|
||||
switch (varp->vltype()) { // LCOV_EXCL_BR_LINE
|
||||
case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = value; return;
|
||||
@@ -417,10 +419,10 @@ static void _vl_svPutBitArrElem(const svOpenArrayHandle d, svBit value, int narg
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// DPI accessors that simply call above functions
|
||||
// DPI accessors that call above functions
|
||||
|
||||
void* svGetArrElemPtr(const svOpenArrayHandle h, int indx1, ...) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(h);
|
||||
void* datap;
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
@@ -428,13 +430,13 @@ void* svGetArrElemPtr(const svOpenArrayHandle h, int indx1, ...) {
|
||||
switch (varp->udims()) {
|
||||
case 1: datap = _vl_svGetArrElemPtr(h, 1, indx1, 0, 0); break;
|
||||
case 2: {
|
||||
int indx2 = va_arg(ap, int);
|
||||
const int indx2 = va_arg(ap, int);
|
||||
datap = _vl_svGetArrElemPtr(h, 2, indx1, indx2, 0);
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
int indx2 = va_arg(ap, int);
|
||||
int indx3 = va_arg(ap, int);
|
||||
const int indx2 = va_arg(ap, int);
|
||||
const int indx3 = va_arg(ap, int);
|
||||
datap = _vl_svGetArrElemPtr(h, 3, indx1, indx2, indx3);
|
||||
break;
|
||||
}
|
||||
@@ -454,7 +456,7 @@ void* svGetArrElemPtr3(const svOpenArrayHandle h, int indx1, int indx2, int indx
|
||||
}
|
||||
|
||||
void svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s, int indx1, ...) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
switch (varp->udims()) {
|
||||
@@ -486,7 +488,7 @@ void svPutBitArrElem3VecVal(const svOpenArrayHandle d, const svBitVecVal* s, int
|
||||
_vl_svPutBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
|
||||
}
|
||||
void svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s, int indx1, ...) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
switch (varp->udims()) {
|
||||
@@ -522,7 +524,7 @@ void svPutLogicArrElem3VecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
|
||||
// From simulator storage into user space
|
||||
|
||||
void svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1, ...) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
switch (varp->udims()) {
|
||||
@@ -553,7 +555,7 @@ void svGetBitArrElem3VecVal(svBitVecVal* d, const svOpenArrayHandle s, int indx1
|
||||
_vl_svGetBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
|
||||
}
|
||||
void svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s, int indx1, ...) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
switch (varp->udims()) {
|
||||
@@ -585,7 +587,7 @@ void svGetLogicArrElem3VecVal(svLogicVecVal* d, const svOpenArrayHandle s, int i
|
||||
}
|
||||
|
||||
svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
|
||||
svBit out;
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
@@ -618,7 +620,7 @@ svBit svGetBitArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx
|
||||
}
|
||||
svLogic svGetLogicArrElem(const svOpenArrayHandle s, int indx1, ...) {
|
||||
// Verilator doesn't support X/Z so can just call Bit version
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(s);
|
||||
svBit out;
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
@@ -654,7 +656,7 @@ svLogic svGetLogicArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int
|
||||
}
|
||||
|
||||
void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
switch (varp->udims()) {
|
||||
@@ -685,7 +687,7 @@ void svPutBitArrElem3(const svOpenArrayHandle d, svBit value, int indx1, int ind
|
||||
}
|
||||
void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1, ...) {
|
||||
// Verilator doesn't support X/Z so can just call Bit version
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
|
||||
const VerilatedDpiOpenVar* const varp = _vl_openhandle_varp(d);
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
switch (varp->udims()) {
|
||||
@@ -732,15 +734,15 @@ svScope svGetScope() {
|
||||
}
|
||||
|
||||
svScope svSetScope(const svScope scope) {
|
||||
const VerilatedScope* prevScopep = Verilated::dpiScope();
|
||||
const VerilatedScope* vscopep = reinterpret_cast<const VerilatedScope*>(scope);
|
||||
const VerilatedScope* const prevScopep = Verilated::dpiScope();
|
||||
const VerilatedScope* const vscopep = reinterpret_cast<const VerilatedScope*>(scope);
|
||||
Verilated::dpiScope(vscopep);
|
||||
// NOLINTNEXTLINE(google-readability-casting)
|
||||
return (svScope)(prevScopep);
|
||||
}
|
||||
|
||||
const char* svGetNameFromScope(const svScope scope) {
|
||||
const VerilatedScope* vscopep = reinterpret_cast<const VerilatedScope*>(scope);
|
||||
const VerilatedScope* const vscopep = reinterpret_cast<const VerilatedScope*>(scope);
|
||||
return vscopep->name();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -27,8 +27,8 @@
|
||||
#define VERILATOR_VERILATED_DPI_H_
|
||||
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include "verilated.h" // Also presumably included by caller
|
||||
#include "verilated_heavy.h" // Also presumably included by caller
|
||||
#include "verilated_sym_props.h"
|
||||
|
||||
#include "svdpi.h"
|
||||
|
||||
+106
-60
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||
// can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "verilated_fst_c.h"
|
||||
|
||||
// GTKWave configuration
|
||||
#ifdef VL_TRACE_FST_WRITER_THREAD
|
||||
#ifdef VL_THREADED
|
||||
# define HAVE_LIBPTHREAD
|
||||
# define FST_WRITER_PARALLEL
|
||||
#endif
|
||||
@@ -53,43 +53,46 @@
|
||||
|
||||
//=============================================================================
|
||||
// Check that vltscope_t matches fstScopeType
|
||||
static_assert((int)FST_ST_VCD_MODULE == (int)VLT_TRACE_SCOPE_MODULE,
|
||||
|
||||
static_assert(static_cast<int>(FST_ST_VCD_MODULE) == static_cast<int>(VLT_TRACE_SCOPE_MODULE),
|
||||
"VLT_TRACE_SCOPE_MODULE mismatches");
|
||||
static_assert((int)FST_ST_VCD_TASK == (int)VLT_TRACE_SCOPE_TASK,
|
||||
static_assert(static_cast<int>(FST_ST_VCD_TASK) == static_cast<int>(VLT_TRACE_SCOPE_TASK),
|
||||
"VLT_TRACE_SCOPE_TASK mismatches");
|
||||
static_assert((int)FST_ST_VCD_FUNCTION == (int)VLT_TRACE_SCOPE_FUNCTION,
|
||||
static_assert(static_cast<int>(FST_ST_VCD_FUNCTION) == static_cast<int>(VLT_TRACE_SCOPE_FUNCTION),
|
||||
"VLT_TRACE_SCOPE_FUNCTION mismatches");
|
||||
static_assert((int)FST_ST_VCD_BEGIN == (int)VLT_TRACE_SCOPE_BEGIN,
|
||||
static_assert(static_cast<int>(FST_ST_VCD_BEGIN) == static_cast<int>(VLT_TRACE_SCOPE_BEGIN),
|
||||
"VLT_TRACE_SCOPE_BEGIN mismatches");
|
||||
static_assert((int)FST_ST_VCD_FORK == (int)VLT_TRACE_SCOPE_FORK,
|
||||
static_assert(static_cast<int>(FST_ST_VCD_FORK) == static_cast<int>(VLT_TRACE_SCOPE_FORK),
|
||||
"VLT_TRACE_SCOPE_FORK mismatches");
|
||||
static_assert((int)FST_ST_VCD_GENERATE == (int)VLT_TRACE_SCOPE_GENERATE,
|
||||
static_assert(static_cast<int>(FST_ST_VCD_GENERATE) == static_cast<int>(VLT_TRACE_SCOPE_GENERATE),
|
||||
"VLT_TRACE_SCOPE_GENERATE mismatches");
|
||||
static_assert((int)FST_ST_VCD_STRUCT == (int)VLT_TRACE_SCOPE_STRUCT,
|
||||
static_assert(static_cast<int>(FST_ST_VCD_STRUCT) == static_cast<int>(VLT_TRACE_SCOPE_STRUCT),
|
||||
"VLT_TRACE_SCOPE_STRUCT mismatches");
|
||||
static_assert((int)FST_ST_VCD_UNION == (int)VLT_TRACE_SCOPE_UNION,
|
||||
static_assert(static_cast<int>(FST_ST_VCD_UNION) == static_cast<int>(VLT_TRACE_SCOPE_UNION),
|
||||
"VLT_TRACE_SCOPE_UNION mismatches");
|
||||
static_assert((int)FST_ST_VCD_CLASS == (int)VLT_TRACE_SCOPE_CLASS,
|
||||
static_assert(static_cast<int>(FST_ST_VCD_CLASS) == static_cast<int>(VLT_TRACE_SCOPE_CLASS),
|
||||
"VLT_TRACE_SCOPE_CLASS mismatches");
|
||||
static_assert((int)FST_ST_VCD_INTERFACE == (int)VLT_TRACE_SCOPE_INTERFACE,
|
||||
static_assert(static_cast<int>(FST_ST_VCD_INTERFACE)
|
||||
== static_cast<int>(VLT_TRACE_SCOPE_INTERFACE),
|
||||
"VLT_TRACE_SCOPE_INTERFACE mismatches");
|
||||
static_assert((int)FST_ST_VCD_PACKAGE == (int)VLT_TRACE_SCOPE_PACKAGE,
|
||||
static_assert(static_cast<int>(FST_ST_VCD_PACKAGE) == static_cast<int>(VLT_TRACE_SCOPE_PACKAGE),
|
||||
"VLT_TRACE_SCOPE_PACKAGE mismatches");
|
||||
static_assert((int)FST_ST_VCD_PROGRAM == (int)VLT_TRACE_SCOPE_PROGRAM,
|
||||
static_assert(static_cast<int>(FST_ST_VCD_PROGRAM) == static_cast<int>(VLT_TRACE_SCOPE_PROGRAM),
|
||||
"VLT_TRACE_SCOPE_PROGRAM mismatches");
|
||||
|
||||
//=============================================================================
|
||||
// Specialization of the generics for this trace format
|
||||
|
||||
#define VL_DERIVED_T VerilatedFst
|
||||
#include "verilated_trace_imp.cpp"
|
||||
#undef VL_DERIVED_T
|
||||
#define VL_SUB_T VerilatedFst
|
||||
#define VL_BUF_T VerilatedFstBuffer
|
||||
#include "verilated_trace_imp.h"
|
||||
#undef VL_SUB_T
|
||||
#undef VL_BUF_T
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedFst
|
||||
|
||||
VerilatedFst::VerilatedFst(void* fst)
|
||||
: m_fst{fst} {}
|
||||
VerilatedFst::VerilatedFst(void* /*fst*/) {}
|
||||
|
||||
VerilatedFst::~VerilatedFst() {
|
||||
if (m_fst) fstWriterClose(m_fst);
|
||||
@@ -98,18 +101,16 @@ VerilatedFst::~VerilatedFst() {
|
||||
}
|
||||
|
||||
void VerilatedFst::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
const VerilatedLockGuard lock(m_mutex);
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
m_fst = fstWriterCreate(filename, 1);
|
||||
fstWriterSetPackType(m_fst, FST_WR_PT_LZ4);
|
||||
fstWriterSetTimescaleFromString(m_fst, timeResStr().c_str()); // lintok-begin-on-ref
|
||||
#ifdef VL_TRACE_FST_WRITER_THREAD
|
||||
fstWriterSetParallelMode(m_fst, 1);
|
||||
#endif
|
||||
if (m_useFstWriterThread) fstWriterSetParallelMode(m_fst, 1);
|
||||
fullDump(true); // First dump must be full for fst
|
||||
|
||||
m_curScope.clear();
|
||||
|
||||
VerilatedTrace<VerilatedFst>::traceInit();
|
||||
Super::traceInit();
|
||||
|
||||
// Clear the scope stack
|
||||
auto it = m_curScope.begin();
|
||||
@@ -120,7 +121,7 @@ void VerilatedFst::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
|
||||
// convert m_code2symbol into an array for fast lookup
|
||||
if (!m_symbolp) {
|
||||
m_symbolp = new fstHandle[nextCode()];
|
||||
m_symbolp = new fstHandle[nextCode()]{0};
|
||||
for (const auto& i : m_code2symbol) m_symbolp[i.first] = i.second;
|
||||
}
|
||||
m_code2symbol.clear();
|
||||
@@ -130,24 +131,24 @@ void VerilatedFst::open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
}
|
||||
|
||||
void VerilatedFst::close() VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
const VerilatedLockGuard lock(m_mutex);
|
||||
VerilatedTrace<VerilatedFst>::closeBase();
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
Super::closeBase();
|
||||
fstWriterClose(m_fst);
|
||||
m_fst = nullptr;
|
||||
}
|
||||
|
||||
void VerilatedFst::flush() VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
const VerilatedLockGuard lock(m_mutex);
|
||||
VerilatedTrace<VerilatedFst>::flushBase();
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
Super::flushBase();
|
||||
fstWriterFlushContext(m_fst);
|
||||
}
|
||||
|
||||
void VerilatedFst::emitTimeChange(vluint64_t timeui) { fstWriterEmitTimeChange(m_fst, timeui); }
|
||||
void VerilatedFst::emitTimeChange(uint64_t timeui) { fstWriterEmitTimeChange(m_fst, timeui); }
|
||||
|
||||
//=============================================================================
|
||||
// Decl
|
||||
|
||||
void VerilatedFst::declDTypeEnum(int dtypenum, const char* name, vluint32_t elements,
|
||||
void VerilatedFst::declDTypeEnum(int dtypenum, const char* name, uint32_t elements,
|
||||
unsigned int minValbits, const char** itemNamesp,
|
||||
const char** itemValuesp) {
|
||||
const fstEnumHandle enumNum
|
||||
@@ -155,19 +156,21 @@ void VerilatedFst::declDTypeEnum(int dtypenum, const char* name, vluint32_t elem
|
||||
m_local2fstdtype[dtypenum] = enumNum;
|
||||
}
|
||||
|
||||
void VerilatedFst::declare(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
||||
void VerilatedFst::declare(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, bool bussed, int msb,
|
||||
int lsb) {
|
||||
const int bits = ((msb > lsb) ? (msb - lsb) : (lsb - msb)) + 1;
|
||||
|
||||
VerilatedTrace<VerilatedFst>::declCode(code, bits, false);
|
||||
const bool enabled = Super::declCode(code, name, bits, false);
|
||||
if (!enabled) return;
|
||||
|
||||
std::istringstream nameiss(name);
|
||||
std::string nameasstr = namePrefix() + name;
|
||||
std::istringstream nameiss{nameasstr};
|
||||
std::istream_iterator<std::string> beg(nameiss);
|
||||
std::istream_iterator<std::string> end;
|
||||
std::list<std::string> tokens(beg, end); // Split name
|
||||
std::string symbol_name(tokens.back());
|
||||
std::string symbol_name{tokens.back()};
|
||||
tokens.pop_back(); // Remove symbol name from hierarchy
|
||||
tokens.insert(tokens.begin(), moduleName()); // Add current module to the hierarchy
|
||||
std::string tmpModName;
|
||||
|
||||
// Find point where current and new scope diverge
|
||||
@@ -191,18 +194,19 @@ void VerilatedFst::declare(vluint32_t code, const char* name, int dtypenum, fstV
|
||||
tmpModName = *new_it;
|
||||
tmpModName.pop_back();
|
||||
// If the scope ends with a non-ascii character, it will be 0x80 + fstScopeType
|
||||
fstWriterSetScope(m_fst, (fstScopeType)(new_it->back() & 0x7f), tmpModName.c_str(),
|
||||
nullptr);
|
||||
} else
|
||||
fstWriterSetScope(m_fst, static_cast<fstScopeType>(new_it->back() & 0x7f),
|
||||
tmpModName.c_str(), nullptr);
|
||||
} else {
|
||||
fstWriterSetScope(m_fst, FST_ST_VCD_SCOPE, new_it->c_str(), nullptr);
|
||||
|
||||
}
|
||||
m_curScope.push_back(*new_it);
|
||||
new_it = tokens.erase(new_it);
|
||||
}
|
||||
|
||||
std::stringstream name_ss;
|
||||
name_ss << symbol_name;
|
||||
if (array) name_ss << "(" << arraynum << ")";
|
||||
if (array) name_ss << "[" << arraynum << "]";
|
||||
if (bussed) name_ss << " [" << msb << ":" << lsb << "]";
|
||||
std::string name_str = name_ss.str();
|
||||
|
||||
if (dtypenum > 0) {
|
||||
@@ -219,66 +223,108 @@ void VerilatedFst::declare(vluint32_t code, const char* name, int dtypenum, fstV
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatedFst::declBit(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void VerilatedFst::declBit(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, 0, 0);
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, false, 0, 0);
|
||||
}
|
||||
void VerilatedFst::declBus(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void VerilatedFst::declBus(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, msb, lsb);
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, true, msb, lsb);
|
||||
}
|
||||
void VerilatedFst::declQuad(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void VerilatedFst::declQuad(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, msb, lsb);
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, true, msb, lsb);
|
||||
}
|
||||
void VerilatedFst::declArray(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void VerilatedFst::declArray(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, msb, lsb);
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, true, msb, lsb);
|
||||
}
|
||||
void VerilatedFst::declDouble(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void VerilatedFst::declDouble(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum) {
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, 63, 0);
|
||||
declare(code, name, dtypenum, vardir, vartype, array, arraynum, false, 63, 0);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Get/commit trace buffer
|
||||
|
||||
VerilatedFst::Buffer* VerilatedFst::getTraceBuffer() {
|
||||
#ifdef VL_THREADED
|
||||
if (offload()) return new OffloadBuffer{*this};
|
||||
#endif
|
||||
return new Buffer{*this};
|
||||
}
|
||||
|
||||
void VerilatedFst::commitTraceBuffer(VerilatedFst::Buffer* bufp) {
|
||||
#ifdef VL_THREADED
|
||||
if (offload()) {
|
||||
OffloadBuffer* const offloadBufferp = static_cast<OffloadBuffer*>(bufp);
|
||||
if (offloadBufferp->m_offloadBufferWritep) {
|
||||
m_offloadBufferWritep = offloadBufferp->m_offloadBufferWritep;
|
||||
return; // Buffer will be deleted by the offload thread
|
||||
}
|
||||
}
|
||||
#endif
|
||||
delete bufp;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Configure
|
||||
|
||||
void VerilatedFst::configure(const VerilatedTraceConfig& config) {
|
||||
// If at least one model requests the FST writer thread, then use it
|
||||
m_useFstWriterThread |= config.m_useFstWriterThread;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedFstBuffer implementation
|
||||
|
||||
//=============================================================================
|
||||
// Trace rendering primitives
|
||||
|
||||
// Note: emit* are only ever called from one place (full* in
|
||||
// verilated_trace_imp.cpp, which is included in this file at the top),
|
||||
// verilated_trace_imp.h, which is included in this file at the top),
|
||||
// so always inline them.
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedFst::emitBit(vluint32_t code, CData newval) {
|
||||
void VerilatedFstBuffer::emitBit(uint32_t code, CData newval) {
|
||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
|
||||
fstWriterEmitValueChange(m_fst, m_symbolp[code], newval ? "1" : "0");
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedFst::emitCData(vluint32_t code, CData newval, int bits) {
|
||||
void VerilatedFstBuffer::emitCData(uint32_t code, CData newval, int bits) {
|
||||
char buf[VL_BYTESIZE];
|
||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
|
||||
cvtCDataToStr(buf, newval << (VL_BYTESIZE - bits));
|
||||
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedFst::emitSData(vluint32_t code, SData newval, int bits) {
|
||||
void VerilatedFstBuffer::emitSData(uint32_t code, SData newval, int bits) {
|
||||
char buf[VL_SHORTSIZE];
|
||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
|
||||
cvtSDataToStr(buf, newval << (VL_SHORTSIZE - bits));
|
||||
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedFst::emitIData(vluint32_t code, IData newval, int bits) {
|
||||
void VerilatedFstBuffer::emitIData(uint32_t code, IData newval, int bits) {
|
||||
char buf[VL_IDATASIZE];
|
||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
|
||||
cvtIDataToStr(buf, newval << (VL_IDATASIZE - bits));
|
||||
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedFst::emitQData(vluint32_t code, QData newval, int bits) {
|
||||
void VerilatedFstBuffer::emitQData(uint32_t code, QData newval, int bits) {
|
||||
char buf[VL_QUADSIZE];
|
||||
VL_DEBUG_IFDEF(assert(m_symbolp[code]););
|
||||
cvtQDataToStr(buf, newval << (VL_QUADSIZE - bits));
|
||||
fstWriterEmitValueChange(m_fst, m_symbolp[code], buf);
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedFst::emitWData(vluint32_t code, const WData* newvalp, int bits) {
|
||||
void VerilatedFstBuffer::emitWData(uint32_t code, const WData* newvalp, int bits) {
|
||||
int words = VL_WORDS_I(bits);
|
||||
char* wp = m_strbuf;
|
||||
// Convert the most significant word
|
||||
@@ -294,6 +340,6 @@ void VerilatedFst::emitWData(vluint32_t code, const WData* newvalp, int bits) {
|
||||
}
|
||||
|
||||
VL_ATTR_ALWINLINE
|
||||
void VerilatedFst::emitDouble(vluint32_t code, double newval) {
|
||||
void VerilatedFstBuffer::emitDouble(uint32_t code, double newval) {
|
||||
fstWriterEmitValueChange(m_fst, m_symbolp[code], &newval);
|
||||
}
|
||||
|
||||
+96
-44
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||
// can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -31,60 +31,64 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class VerilatedFstBuffer;
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedFst
|
||||
// Base class to create a Verilator FST dump
|
||||
// This is an internally used class - see VerilatedFstC for what to call from applications
|
||||
|
||||
class VerilatedFst final : public VerilatedTrace<VerilatedFst> {
|
||||
class VerilatedFst final : public VerilatedTrace<VerilatedFst, VerilatedFstBuffer> {
|
||||
public:
|
||||
using Super = VerilatedTrace<VerilatedFst, VerilatedFstBuffer>;
|
||||
|
||||
private:
|
||||
// Give the superclass access to private bits (to avoid virtual functions)
|
||||
friend class VerilatedTrace<VerilatedFst>;
|
||||
friend VerilatedFstBuffer; // Give the buffer access to the private bits
|
||||
|
||||
//=========================================================================
|
||||
// FST specific internals
|
||||
|
||||
void* m_fst;
|
||||
std::map<vluint32_t, fstHandle> m_code2symbol;
|
||||
void* m_fst = nullptr;
|
||||
std::map<uint32_t, fstHandle> m_code2symbol;
|
||||
std::map<int, fstEnumHandle> m_local2fstdtype;
|
||||
std::list<std::string> m_curScope;
|
||||
fstHandle* m_symbolp = nullptr; // same as m_code2symbol, but as an array
|
||||
char* m_strbuf = nullptr; // String buffer long enough to hold maxBits() chars
|
||||
|
||||
bool m_useFstWriterThread = false; // Whether to use the separate FST writer thread
|
||||
|
||||
// CONSTRUCTORS
|
||||
VL_UNCOPYABLE(VerilatedFst);
|
||||
void declare(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
||||
void declare(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, bool bussed, int msb, int lsb);
|
||||
|
||||
protected:
|
||||
//=========================================================================
|
||||
// Implementation of VerilatedTrace interface
|
||||
|
||||
// Implementations of protected virtual methods for VerilatedTrace
|
||||
virtual void emitTimeChange(vluint64_t timeui) override;
|
||||
// Called when the trace moves forward to a new time point
|
||||
void emitTimeChange(uint64_t timeui) override;
|
||||
|
||||
// Hooks called from VerilatedTrace
|
||||
virtual bool preFullDump() override { return isOpen(); }
|
||||
virtual bool preChangeDump() override { return isOpen(); }
|
||||
bool preFullDump() override { return isOpen(); }
|
||||
bool preChangeDump() override { return isOpen(); }
|
||||
|
||||
// Implementations of duck-typed methods for VerilatedTrace. These are
|
||||
// called from only one place (namely full*) so always inline them.
|
||||
inline void emitBit(vluint32_t code, CData newval);
|
||||
inline void emitCData(vluint32_t code, CData newval, int bits);
|
||||
inline void emitSData(vluint32_t code, SData newval, int bits);
|
||||
inline void emitIData(vluint32_t code, IData newval, int bits);
|
||||
inline void emitQData(vluint32_t code, QData newval, int bits);
|
||||
inline void emitWData(vluint32_t code, const WData* newvalp, int bits);
|
||||
inline void emitDouble(vluint32_t code, double newval);
|
||||
// Trace buffer management
|
||||
Buffer* getTraceBuffer() override;
|
||||
void commitTraceBuffer(Buffer*) override;
|
||||
|
||||
// Configure sub-class
|
||||
void configure(const VerilatedTraceConfig&) override;
|
||||
|
||||
public:
|
||||
//=========================================================================
|
||||
// External interface to client code
|
||||
// (All must be threadsafe)
|
||||
|
||||
// CONSTRUCTOR
|
||||
explicit VerilatedFst(void* fst = nullptr);
|
||||
~VerilatedFst();
|
||||
|
||||
// METHODS - All must be thread safe
|
||||
// Open the file; call isOpen() to see if errors
|
||||
void open(const char* filename) VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||
// Close the file
|
||||
@@ -97,32 +101,75 @@ public:
|
||||
//=========================================================================
|
||||
// Internal interface to Verilator generated code
|
||||
|
||||
// Inside dumping routines, declare a data type
|
||||
void declDTypeEnum(int dtypenum, const char* name, vluint32_t elements,
|
||||
unsigned int minValbits, const char** itemNamesp, const char** itemValuesp);
|
||||
|
||||
// Inside dumping routines, declare a signal
|
||||
void declBit(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void declBit(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum);
|
||||
void declBus(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void declBus(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
||||
void declQuad(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void declQuad(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
||||
void declArray(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void declArray(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum, int msb, int lsb);
|
||||
void declDouble(vluint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
void declDouble(uint32_t code, const char* name, int dtypenum, fstVarDir vardir,
|
||||
fstVarType vartype, bool array, int arraynum);
|
||||
|
||||
void declDTypeEnum(int dtypenum, const char* name, uint32_t elements, unsigned int minValbits,
|
||||
const char** itemNamesp, const char** itemValuesp);
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN
|
||||
// Declare specialization here as it's used in VerilatedFstC just below
|
||||
template <> void VerilatedTrace<VerilatedFst>::dump(vluint64_t timeui);
|
||||
template <> void VerilatedTrace<VerilatedFst>::set_time_unit(const char* unitp);
|
||||
template <> void VerilatedTrace<VerilatedFst>::set_time_unit(const std::string& unit);
|
||||
template <> void VerilatedTrace<VerilatedFst>::set_time_resolution(const char* unitp);
|
||||
template <> void VerilatedTrace<VerilatedFst>::set_time_resolution(const std::string& unit);
|
||||
template <>
|
||||
void VerilatedFst::Super::dump(uint64_t time);
|
||||
template <>
|
||||
void VerilatedFst::Super::set_time_unit(const char* unitp);
|
||||
template <>
|
||||
void VerilatedFst::Super::set_time_unit(const std::string& unit);
|
||||
template <>
|
||||
void VerilatedFst::Super::set_time_resolution(const char* unitp);
|
||||
template <>
|
||||
void VerilatedFst::Super::set_time_resolution(const std::string& unit);
|
||||
template <>
|
||||
void VerilatedFst::Super::dumpvars(int level, const std::string& hier);
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedFstBuffer
|
||||
|
||||
class VerilatedFstBuffer VL_NOT_FINAL {
|
||||
// Give the trace file access to the private bits
|
||||
friend VerilatedFst;
|
||||
friend VerilatedFst::Super;
|
||||
friend VerilatedFst::Buffer;
|
||||
friend VerilatedFst::OffloadBuffer;
|
||||
|
||||
VerilatedFst& m_owner; // Trace file owning this buffer. Required by subclasses.
|
||||
|
||||
// The FST file handle
|
||||
void* const m_fst = m_owner.m_fst;
|
||||
// code to fstHande map, as an array
|
||||
const fstHandle* const m_symbolp = m_owner.m_symbolp;
|
||||
// String buffer long enough to hold maxBits() chars
|
||||
char* const m_strbuf = m_owner.m_strbuf;
|
||||
|
||||
// CONSTRUCTOR
|
||||
explicit VerilatedFstBuffer(VerilatedFst& owner)
|
||||
: m_owner{owner} {}
|
||||
virtual ~VerilatedFstBuffer() = default;
|
||||
|
||||
//=========================================================================
|
||||
// Implementation of VerilatedTraceBuffer interface
|
||||
|
||||
// Implementations of duck-typed methods for VerilatedTraceBuffer. These are
|
||||
// called from only one place (the full* methods), so always inline them.
|
||||
VL_ATTR_ALWINLINE inline void emitBit(uint32_t code, CData newval);
|
||||
VL_ATTR_ALWINLINE inline void emitCData(uint32_t code, CData newval, int bits);
|
||||
VL_ATTR_ALWINLINE inline void emitSData(uint32_t code, SData newval, int bits);
|
||||
VL_ATTR_ALWINLINE inline void emitIData(uint32_t code, IData newval, int bits);
|
||||
VL_ATTR_ALWINLINE inline void emitQData(uint32_t code, QData newval, int bits);
|
||||
VL_ATTR_ALWINLINE inline void emitWData(uint32_t code, const WData* newvalp, int bits);
|
||||
VL_ATTR_ALWINLINE inline void emitDouble(uint32_t code, double newval);
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedFstC
|
||||
/// Create a FST dump file in C standalone (no SystemC) simulations.
|
||||
@@ -139,7 +186,7 @@ public:
|
||||
explicit VerilatedFstC(void* filep = nullptr)
|
||||
: m_sptrace{filep} {}
|
||||
/// Destruct, flush, and close the dump
|
||||
~VerilatedFstC() { close(); }
|
||||
virtual ~VerilatedFstC() { close(); }
|
||||
|
||||
// METHODS - User called
|
||||
|
||||
@@ -154,12 +201,12 @@ public:
|
||||
/// Write one cycle of dump data
|
||||
/// Call with the current context's time just after eval'ed,
|
||||
/// e.g. ->dump(contextp->time())
|
||||
void dump(vluint64_t timeui) { m_sptrace.dump(timeui); }
|
||||
void dump(uint64_t timeui) { m_sptrace.dump(timeui); }
|
||||
/// Write one cycle of dump data - backward compatible and to reduce
|
||||
/// conversion warnings. It's better to use a vluint64_t time instead.
|
||||
void dump(double timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
|
||||
void dump(vluint32_t timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
|
||||
void dump(int timestamp) { dump(static_cast<vluint64_t>(timestamp)); }
|
||||
/// conversion warnings. It's better to use a uint64_t time instead.
|
||||
void dump(double timestamp) { dump(static_cast<uint64_t>(timestamp)); }
|
||||
void dump(uint32_t timestamp) { dump(static_cast<uint64_t>(timestamp)); }
|
||||
void dump(int timestamp) { dump(static_cast<uint64_t>(timestamp)); }
|
||||
|
||||
// METHODS - Internal/backward compatible
|
||||
// \protectedsection
|
||||
@@ -178,9 +225,14 @@ public:
|
||||
void set_time_resolution(const std::string& unit) VL_MT_SAFE {
|
||||
m_sptrace.set_time_resolution(unit);
|
||||
}
|
||||
// Set variables to dump, using $dumpvars format
|
||||
// If level = 0, dump everything and hier is then ignored
|
||||
void dumpvars(int level, const std::string& hier) VL_MT_SAFE {
|
||||
m_sptrace.dumpvars(level, hier);
|
||||
}
|
||||
|
||||
// Internal class access
|
||||
inline VerilatedFst* spTrace() { return &m_sptrace; };
|
||||
inline VerilatedFst* spTrace() { return &m_sptrace; }
|
||||
};
|
||||
|
||||
#endif // guard
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||
// can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -22,11 +22,23 @@
|
||||
//=============================================================================
|
||||
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include "verilated_fst_sc.h"
|
||||
|
||||
//======================================================================
|
||||
//======================================================================
|
||||
|
||||
void VerilatedFstSc::open(const char* filename) {
|
||||
if (!sc_core::sc_get_curr_simcontext()->elaboration_done()) {
|
||||
vl_fatal(__FILE__, __LINE__, "VerilatedFstSc",
|
||||
("%Error: VerilatedFstSc::open(\"" + std::string{filename}
|
||||
+ "\") is called before sc_core::sc_start(). "
|
||||
"Run sc_core::sc_start(sc_core::SC_ZERO_TIME) before opening a wave file.")
|
||||
.c_str());
|
||||
}
|
||||
VerilatedFstC::open(filename);
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// SystemC 2.1.v1
|
||||
// cppcheck-suppress unusedFunction
|
||||
@@ -52,9 +64,6 @@ void VerilatedFstSc::trace(const unsigned int&, const std::string&, const char**
|
||||
DECL_TRACE_METHOD_B( unsigned short )
|
||||
DECL_TRACE_METHOD_B( unsigned int )
|
||||
DECL_TRACE_METHOD_B( unsigned long )
|
||||
#ifdef SYSTEMC_64BIT_PATCHES
|
||||
DECL_TRACE_METHOD_B( unsigned long long)
|
||||
#endif
|
||||
DECL_TRACE_METHOD_B( char )
|
||||
DECL_TRACE_METHOD_B( short )
|
||||
DECL_TRACE_METHOD_B( int )
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -23,8 +23,11 @@
|
||||
#define _VERILATED_FST_SC_H_ 1
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated_sc.h"
|
||||
|
||||
#include "verilated_fst_c.h"
|
||||
#include "verilated_sc.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedFstSc
|
||||
@@ -49,7 +52,7 @@ public:
|
||||
}
|
||||
spTrace()->set_time_resolution(sc_get_time_resolution().to_string());
|
||||
}
|
||||
virtual ~VerilatedFstSc() { close(); }
|
||||
virtual ~VerilatedFstSc() /*override*/ { close(); }
|
||||
|
||||
// METHODS
|
||||
/// Called by SystemC simulate()
|
||||
@@ -57,6 +60,10 @@ public:
|
||||
if (!delta_cycle) { this->dump(sc_time_stamp().to_double()); }
|
||||
}
|
||||
|
||||
// Override VerilatedFstC. Must be called after starting simulation.
|
||||
// cppcheck-suppress missingOverride // GCC won't accept override
|
||||
virtual void open(const char* filename) /*override*/ VL_MT_SAFE;
|
||||
|
||||
private:
|
||||
/// Fake outs for linker
|
||||
|
||||
@@ -90,9 +97,6 @@ private:
|
||||
DECL_TRACE_METHOD_B( unsigned short )
|
||||
DECL_TRACE_METHOD_B( unsigned int )
|
||||
DECL_TRACE_METHOD_B( unsigned long )
|
||||
#ifdef SYSTEMC_64BIT_PATCHES
|
||||
DECL_TRACE_METHOD_B( unsigned long long)
|
||||
#endif
|
||||
DECL_TRACE_METHOD_B( char )
|
||||
DECL_TRACE_METHOD_B( short )
|
||||
DECL_TRACE_METHOD_B( int )
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
+8
-957
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2010-2021 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2010-2022 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -12,969 +12,20 @@
|
||||
//*************************************************************************
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilated string and data-type header
|
||||
/// \brief Verilated old string and data-type header
|
||||
///
|
||||
/// This file is included automatically by Verilator at the top of
|
||||
/// all C++ files it generates. It is used when strings or other
|
||||
/// heavyweight types are required; these contents are not part of
|
||||
/// verilated.h to save compile time when such types aren't used.
|
||||
/// This file is deprecated, and provided for backwards compatibility.
|
||||
/// Include verilated.h instead.
|
||||
///
|
||||
//*************************************************************************
|
||||
|
||||
#ifndef VERILATOR_VERILATED_HEAVY_H_
|
||||
#define VERILATOR_VERILATED_HEAVY_H_
|
||||
|
||||
#ifdef VL_NO_LEGACY
|
||||
#error "Include <verilated.h> instead of <verilated_heavy.h>"
|
||||
#endif
|
||||
|
||||
#include "verilated.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
//===================================================================
|
||||
// String formatters (required by below containers)
|
||||
|
||||
extern std::string VL_TO_STRING(CData lhs);
|
||||
extern std::string VL_TO_STRING(SData lhs);
|
||||
extern std::string VL_TO_STRING(IData lhs);
|
||||
extern std::string VL_TO_STRING(QData lhs);
|
||||
inline std::string VL_TO_STRING(const std::string& obj) { return "\"" + obj + "\""; }
|
||||
extern std::string VL_TO_STRING_W(int words, const WDataInP obj);
|
||||
|
||||
//===================================================================
|
||||
// Shuffle RNG
|
||||
|
||||
class VlURNG final {
|
||||
public:
|
||||
using result_type = size_t;
|
||||
static constexpr size_t min() { return 0; }
|
||||
static constexpr size_t max() { return 1ULL << 31; }
|
||||
size_t operator()() { return VL_MASK_I(31) & VL_RANDOM_I(32); }
|
||||
};
|
||||
|
||||
//===================================================================
|
||||
// Readmem/Writemem operation classes
|
||||
|
||||
class VlReadMem final {
|
||||
bool m_hex; // Hex format
|
||||
int m_bits; // Bit width of values
|
||||
const std::string& m_filename; // Filename
|
||||
QData m_end; // End address (as specified by user)
|
||||
FILE* m_fp; // File handle for filename
|
||||
QData m_addr; // Next address to read
|
||||
int m_linenum; // Line number last read from file
|
||||
public:
|
||||
VlReadMem(bool hex, int bits, const std::string& filename, QData start, QData end);
|
||||
~VlReadMem();
|
||||
bool isOpen() const { return m_fp != nullptr; }
|
||||
int linenum() const { return m_linenum; }
|
||||
bool get(QData& addrr, std::string& valuer);
|
||||
void setData(void* valuep, const std::string& rhs);
|
||||
};
|
||||
|
||||
class VlWriteMem final {
|
||||
bool m_hex; // Hex format
|
||||
int m_bits; // Bit width of values
|
||||
FILE* m_fp; // File handle for filename
|
||||
QData m_addr; // Next address to write
|
||||
public:
|
||||
VlWriteMem(bool hex, int bits, const std::string& filename, QData start, QData end);
|
||||
~VlWriteMem();
|
||||
bool isOpen() const { return m_fp != nullptr; }
|
||||
void print(QData addr, bool addrstamp, const void* valuep);
|
||||
};
|
||||
|
||||
//===================================================================
|
||||
/// Verilog wide packed bit container.
|
||||
/// Similar to std::array<WData, N>, but lighter weight, only methods needed
|
||||
/// by Verilator, to help compile time.
|
||||
///
|
||||
/// A 'struct' as we want this to be an aggregate type that allows
|
||||
/// static aggregate initialization. Consider data members private.
|
||||
///
|
||||
/// For example a Verilog "bit [94:0]" will become a VlWide<3> because 3*32
|
||||
/// bits are needed to hold the 95 bits. The MSB (bit 96) must always be
|
||||
/// zero in memory, but during intermediate operations in the Verilated
|
||||
/// internals is unpredictable.
|
||||
|
||||
template <std::size_t T_Words> struct VlWide final {
|
||||
// MEMBERS
|
||||
// This should be the only data member, otherwise generated static initializers need updating
|
||||
EData m_storage[T_Words]; // Contents of the packed array
|
||||
|
||||
// CONSTRUCTORS
|
||||
// cppcheck-suppress uninitVar
|
||||
VlWide() = default;
|
||||
~VlWide() = default;
|
||||
VlWide(const VlWide&) = default;
|
||||
VlWide(VlWide&&) = default;
|
||||
|
||||
// OPERATOR METHODS
|
||||
VlWide& operator=(const VlWide&) = default;
|
||||
VlWide& operator=(VlWide&&) = default;
|
||||
operator WDataOutP() { return &m_storage[0]; } // This also allows []
|
||||
operator WDataInP() const { return &m_storage[0]; } // This also allows []
|
||||
|
||||
// METHODS
|
||||
const EData& at(size_t index) const { return m_storage[index]; }
|
||||
EData& at(size_t index) { return m_storage[index]; }
|
||||
WData* data() { return &m_storage[0]; }
|
||||
const WData* data() const { return &m_storage[0]; }
|
||||
bool operator<(const VlWide<T_Words>& rhs) const {
|
||||
return VL_LT_W(T_Words, data(), rhs.data());
|
||||
}
|
||||
};
|
||||
|
||||
// Convert a C array to std::array reference by pointer magic, without copy.
|
||||
// Data type (second argument) is so the function template can automatically generate.
|
||||
template <std::size_t T_Words>
|
||||
VlWide<T_Words>& VL_CVT_W_A(const WDataInP inp, const VlWide<T_Words>&) {
|
||||
return *((VlWide<T_Words>*)inp);
|
||||
}
|
||||
|
||||
template <std::size_t T_Words> std::string VL_TO_STRING(const VlWide<T_Words>& obj) {
|
||||
return VL_TO_STRING_W(T_Words, obj.data());
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
// Verilog queue and dynamic array container
|
||||
// There are no multithreaded locks on this; the base variable must
|
||||
// be protected by other means
|
||||
//
|
||||
// Bound here is the maximum size() allowed, e.g. 1 + SystemVerilog bound
|
||||
// For dynamic arrays it is always zero
|
||||
template <class T_Value, size_t T_MaxSize = 0> class VlQueue final {
|
||||
private:
|
||||
// TYPES
|
||||
using Deque = std::deque<T_Value>;
|
||||
|
||||
public:
|
||||
using const_iterator = typename Deque::const_iterator;
|
||||
|
||||
private:
|
||||
// MEMBERS
|
||||
Deque m_deque; // State of the assoc array
|
||||
T_Value m_defaultValue; // Default value
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
// m_defaultValue isn't defaulted. Caller's constructor must do it.
|
||||
VlQueue() = default;
|
||||
~VlQueue() = default;
|
||||
VlQueue(const VlQueue&) = default;
|
||||
VlQueue(VlQueue&&) = default;
|
||||
VlQueue& operator=(const VlQueue&) = default;
|
||||
VlQueue& operator=(VlQueue&&) = default;
|
||||
|
||||
// Standard copy constructor works. Verilog: assoca = assocb
|
||||
// Also must allow conversion from a different T_MaxSize queue
|
||||
template <size_t U_MaxSize = 0> VlQueue operator=(const VlQueue<T_Value, U_MaxSize>& rhs) {
|
||||
m_deque = rhs.privateDeque();
|
||||
if (VL_UNLIKELY(T_MaxSize && T_MaxSize < m_deque.size())) m_deque.resize(T_MaxSize - 1);
|
||||
return *this;
|
||||
}
|
||||
|
||||
static VlQueue cons(const T_Value& lhs) {
|
||||
VlQueue out;
|
||||
out.push_back(lhs);
|
||||
return out;
|
||||
}
|
||||
static VlQueue cons(const T_Value& lhs, const T_Value& rhs) {
|
||||
VlQueue out;
|
||||
out.push_back(rhs);
|
||||
out.push_back(lhs);
|
||||
return out;
|
||||
}
|
||||
static VlQueue cons(const VlQueue& lhs, const T_Value& rhs) {
|
||||
VlQueue out = lhs;
|
||||
out.push_front(rhs);
|
||||
return out;
|
||||
}
|
||||
static VlQueue cons(const T_Value& lhs, const VlQueue& rhs) {
|
||||
VlQueue out = rhs;
|
||||
out.push_back(lhs);
|
||||
return out;
|
||||
}
|
||||
static VlQueue cons(const VlQueue& lhs, const VlQueue& rhs) {
|
||||
VlQueue out = rhs;
|
||||
for (const auto& i : lhs.m_deque) out.push_back(i);
|
||||
return out;
|
||||
}
|
||||
|
||||
// METHODS
|
||||
T_Value& atDefault() { return m_defaultValue; }
|
||||
const T_Value& atDefault() const { return m_defaultValue; }
|
||||
const Deque& privateDeque() const { return m_deque; }
|
||||
|
||||
// Size. Verilog: function int size(), or int num()
|
||||
int size() const { return m_deque.size(); }
|
||||
// Clear array. Verilog: function void delete([input index])
|
||||
void clear() { m_deque.clear(); }
|
||||
void erase(vlsint32_t index) {
|
||||
if (VL_LIKELY(index >= 0 && index < m_deque.size()))
|
||||
m_deque.erase(m_deque.begin() + index);
|
||||
}
|
||||
|
||||
// Dynamic array new[] becomes a renew()
|
||||
void renew(size_t size) {
|
||||
clear();
|
||||
m_deque.resize(size, atDefault());
|
||||
}
|
||||
// Dynamic array new[]() becomes a renew_copy()
|
||||
void renew_copy(size_t size, const VlQueue<T_Value, T_MaxSize>& rhs) {
|
||||
if (size == 0) {
|
||||
clear();
|
||||
} else {
|
||||
*this = rhs;
|
||||
m_deque.resize(size, atDefault());
|
||||
}
|
||||
}
|
||||
|
||||
// function void q.push_front(value)
|
||||
void push_front(const T_Value& value) {
|
||||
m_deque.push_front(value);
|
||||
if (VL_UNLIKELY(T_MaxSize != 0 && m_deque.size() > T_MaxSize)) m_deque.pop_back();
|
||||
}
|
||||
// function void q.push_back(value)
|
||||
void push_back(const T_Value& value) {
|
||||
if (VL_LIKELY(T_MaxSize == 0 || m_deque.size() < T_MaxSize)) m_deque.push_back(value);
|
||||
}
|
||||
// function value_t q.pop_front();
|
||||
T_Value pop_front() {
|
||||
if (m_deque.empty()) return m_defaultValue;
|
||||
T_Value v = m_deque.front();
|
||||
m_deque.pop_front();
|
||||
return v;
|
||||
}
|
||||
// function value_t q.pop_back();
|
||||
T_Value pop_back() {
|
||||
if (m_deque.empty()) return m_defaultValue;
|
||||
T_Value v = m_deque.back();
|
||||
m_deque.pop_back();
|
||||
return v;
|
||||
}
|
||||
|
||||
// Setting. Verilog: assoc[index] = v
|
||||
// Can't just overload operator[] or provide a "at" reference to set,
|
||||
// because we need to be able to insert only when the value is set
|
||||
T_Value& at(vlsint32_t index) {
|
||||
static T_Value s_throwAway;
|
||||
// Needs to work for dynamic arrays, so does not use T_MaxSize
|
||||
if (VL_UNLIKELY(index < 0 || index >= m_deque.size())) {
|
||||
s_throwAway = atDefault();
|
||||
return s_throwAway;
|
||||
} else {
|
||||
return m_deque[index];
|
||||
}
|
||||
}
|
||||
// Accessing. Verilog: v = assoc[index]
|
||||
const T_Value& at(vlsint32_t index) const {
|
||||
static T_Value s_throwAway;
|
||||
// Needs to work for dynamic arrays, so does not use T_MaxSize
|
||||
if (VL_UNLIKELY(index < 0 || index >= m_deque.size())) {
|
||||
return atDefault();
|
||||
} else {
|
||||
return m_deque[index];
|
||||
}
|
||||
}
|
||||
// function void q.insert(index, value);
|
||||
void insert(vlsint32_t index, const T_Value& value) {
|
||||
if (VL_UNLIKELY(index < 0 || index >= m_deque.size())) return;
|
||||
m_deque.insert(m_deque.begin() + index, value);
|
||||
}
|
||||
|
||||
// Return slice q[lsb:msb]
|
||||
VlQueue slice(vlsint32_t lsb, vlsint32_t msb) const {
|
||||
VlQueue out;
|
||||
if (VL_UNLIKELY(lsb < 0)) lsb = 0;
|
||||
if (VL_UNLIKELY(lsb >= m_deque.size())) lsb = m_deque.size() - 1;
|
||||
if (VL_UNLIKELY(msb >= m_deque.size())) msb = m_deque.size() - 1;
|
||||
for (vlsint32_t i = lsb; i <= msb; ++i) out.push_back(m_deque[i]);
|
||||
return out;
|
||||
}
|
||||
|
||||
// For save/restore
|
||||
const_iterator begin() const { return m_deque.begin(); }
|
||||
const_iterator end() const { return m_deque.end(); }
|
||||
|
||||
// Methods
|
||||
void sort() { std::sort(m_deque.begin(), m_deque.end()); }
|
||||
template <typename Func> void sort(Func with_func) {
|
||||
// with_func returns arbitrary type to use for the sort comparison
|
||||
std::sort(m_deque.begin(), m_deque.end(), [=](const T_Value& a, const T_Value& b) {
|
||||
// index number is meaninless with sort, as it changes
|
||||
return with_func(0, a) < with_func(0, b);
|
||||
});
|
||||
}
|
||||
void rsort() { std::sort(m_deque.rbegin(), m_deque.rend()); }
|
||||
template <typename Func> void rsort(Func with_func) {
|
||||
// with_func returns arbitrary type to use for the sort comparison
|
||||
std::sort(m_deque.rbegin(), m_deque.rend(), [=](const T_Value& a, const T_Value& b) {
|
||||
// index number is meaninless with sort, as it changes
|
||||
return with_func(0, a) < with_func(0, b);
|
||||
});
|
||||
}
|
||||
void reverse() { std::reverse(m_deque.begin(), m_deque.end()); }
|
||||
void shuffle() { std::shuffle(m_deque.begin(), m_deque.end(), VlURNG()); }
|
||||
VlQueue unique() const {
|
||||
VlQueue out;
|
||||
std::unordered_set<T_Value> saw;
|
||||
for (const auto& i : m_deque) {
|
||||
auto it = saw.find(i);
|
||||
if (it == saw.end()) {
|
||||
saw.insert(it, i);
|
||||
out.push_back(i);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
VlQueue<IData> unique_index() const {
|
||||
VlQueue<IData> out;
|
||||
IData index = 0;
|
||||
std::unordered_set<T_Value> saw;
|
||||
for (const auto& i : m_deque) {
|
||||
auto it = saw.find(i);
|
||||
if (it == saw.end()) {
|
||||
saw.insert(it, i);
|
||||
out.push_back(index);
|
||||
}
|
||||
++index;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
template <typename Func> VlQueue find(Func with_func) const {
|
||||
VlQueue out;
|
||||
IData index = 0;
|
||||
for (const auto& i : m_deque) {
|
||||
if (with_func(index, i)) out.push_back(i);
|
||||
++index;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
template <typename Func> VlQueue<IData> find_index(Func with_func) const {
|
||||
VlQueue<IData> out;
|
||||
IData index = 0;
|
||||
for (const auto& i : m_deque) {
|
||||
if (with_func(index, i)) out.push_back(index);
|
||||
++index;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
template <typename Func> VlQueue find_first(Func with_func) const {
|
||||
// Can't use std::find_if as need index number
|
||||
IData index = 0;
|
||||
for (const auto& i : m_deque) {
|
||||
if (with_func(index, i)) return VlQueue::cons(i);
|
||||
++index;
|
||||
}
|
||||
return VlQueue{};
|
||||
}
|
||||
template <typename Func> VlQueue<IData> find_first_index(Func with_func) const {
|
||||
IData index = 0;
|
||||
for (const auto& i : m_deque) {
|
||||
if (with_func(index, i)) return VlQueue<IData>::cons(index);
|
||||
++index;
|
||||
}
|
||||
return VlQueue<IData>{};
|
||||
}
|
||||
template <typename Func> VlQueue find_last(Func with_func) const {
|
||||
IData index = m_deque.size() - 1;
|
||||
for (auto it = m_deque.rbegin(); it != m_deque.rend(); ++it) {
|
||||
if (with_func(index, *it)) return VlQueue::cons(*it);
|
||||
--index;
|
||||
}
|
||||
return VlQueue{};
|
||||
}
|
||||
template <typename Func> VlQueue<IData> find_last_index(Func with_func) const {
|
||||
IData index = m_deque.size() - 1;
|
||||
for (auto it = m_deque.rbegin(); it != m_deque.rend(); ++it) {
|
||||
if (with_func(index, *it)) return VlQueue<IData>::cons(index);
|
||||
--index;
|
||||
}
|
||||
return VlQueue<IData>{};
|
||||
}
|
||||
|
||||
// Reduction operators
|
||||
VlQueue min() const {
|
||||
if (m_deque.empty()) return VlQueue();
|
||||
const auto it = std::min_element(m_deque.begin(), m_deque.end());
|
||||
return VlQueue::cons(*it);
|
||||
}
|
||||
VlQueue max() const {
|
||||
if (m_deque.empty()) return VlQueue();
|
||||
const auto it = std::max_element(m_deque.begin(), m_deque.end());
|
||||
return VlQueue::cons(*it);
|
||||
}
|
||||
|
||||
T_Value r_sum() const {
|
||||
T_Value out(0); // Type must have assignment operator
|
||||
for (const auto& i : m_deque) out += i;
|
||||
return out;
|
||||
}
|
||||
template <typename Func> T_Value r_sum(Func with_func) const {
|
||||
T_Value out(0); // Type must have assignment operator
|
||||
IData index = 0;
|
||||
for (const auto& i : m_deque) out += with_func(index++, i);
|
||||
return out;
|
||||
}
|
||||
T_Value r_product() const {
|
||||
if (m_deque.empty()) return T_Value(0);
|
||||
auto it = m_deque.begin();
|
||||
T_Value out{*it};
|
||||
++it;
|
||||
for (; it != m_deque.end(); ++it) out *= *it;
|
||||
return out;
|
||||
}
|
||||
template <typename Func> T_Value r_product(Func with_func) const {
|
||||
if (m_deque.empty()) return T_Value(0);
|
||||
auto it = m_deque.begin();
|
||||
IData index = 0;
|
||||
T_Value out{with_func(index, *it)};
|
||||
++it;
|
||||
++index;
|
||||
for (; it != m_deque.end(); ++it) out *= with_func(index++, *it);
|
||||
return out;
|
||||
}
|
||||
T_Value r_and() const {
|
||||
if (m_deque.empty()) return T_Value(0);
|
||||
auto it = m_deque.begin();
|
||||
T_Value out{*it};
|
||||
++it;
|
||||
for (; it != m_deque.end(); ++it) out &= *it;
|
||||
return out;
|
||||
}
|
||||
template <typename Func> T_Value r_and(Func with_func) const {
|
||||
if (m_deque.empty()) return T_Value(0);
|
||||
auto it = m_deque.begin();
|
||||
IData index = 0;
|
||||
T_Value out{with_func(index, *it)};
|
||||
++it;
|
||||
++index;
|
||||
for (; it != m_deque.end(); ++it) out &= with_func(index, *it);
|
||||
return out;
|
||||
}
|
||||
T_Value r_or() const {
|
||||
T_Value out(0); // Type must have assignment operator
|
||||
for (const auto& i : m_deque) out |= i;
|
||||
return out;
|
||||
}
|
||||
template <typename Func> T_Value r_or(Func with_func) const {
|
||||
T_Value out(0); // Type must have assignment operator
|
||||
IData index = 0;
|
||||
for (const auto& i : m_deque) out |= with_func(index++, i);
|
||||
return out;
|
||||
}
|
||||
T_Value r_xor() const {
|
||||
T_Value out(0); // Type must have assignment operator
|
||||
for (const auto& i : m_deque) out ^= i;
|
||||
return out;
|
||||
}
|
||||
template <typename Func> T_Value r_xor(Func with_func) const {
|
||||
T_Value out(0); // Type must have assignment operator
|
||||
IData index = 0;
|
||||
for (const auto& i : m_deque) out ^= with_func(index++, i);
|
||||
return out;
|
||||
}
|
||||
|
||||
// Dumping. Verilog: str = $sformatf("%p", assoc)
|
||||
std::string to_string() const {
|
||||
if (m_deque.empty()) return "'{}"; // No trailing space
|
||||
std::string out = "'{";
|
||||
std::string comma;
|
||||
for (const auto& i : m_deque) {
|
||||
out += comma + VL_TO_STRING(i);
|
||||
comma = ", ";
|
||||
}
|
||||
return out + "} ";
|
||||
}
|
||||
};
|
||||
|
||||
template <class T_Value> std::string VL_TO_STRING(const VlQueue<T_Value>& obj) {
|
||||
return obj.to_string();
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
// Verilog associative array container
|
||||
// There are no multithreaded locks on this; the base variable must
|
||||
// be protected by other means
|
||||
//
|
||||
template <class T_Key, class T_Value> class VlAssocArray final {
|
||||
private:
|
||||
// TYPES
|
||||
using Map = std::map<T_Key, T_Value>;
|
||||
|
||||
public:
|
||||
using const_iterator = typename Map::const_iterator;
|
||||
|
||||
private:
|
||||
// MEMBERS
|
||||
Map m_map; // State of the assoc array
|
||||
T_Value m_defaultValue; // Default value
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
// m_defaultValue isn't defaulted. Caller's constructor must do it.
|
||||
VlAssocArray() = default;
|
||||
~VlAssocArray() = default;
|
||||
VlAssocArray(const VlAssocArray&) = default;
|
||||
VlAssocArray(VlAssocArray&&) = default;
|
||||
VlAssocArray& operator=(const VlAssocArray&) = default;
|
||||
VlAssocArray& operator=(VlAssocArray&&) = default;
|
||||
|
||||
// METHODS
|
||||
T_Value& atDefault() { return m_defaultValue; }
|
||||
const T_Value& atDefault() const { return m_defaultValue; }
|
||||
|
||||
// Size of array. Verilog: function int size(), or int num()
|
||||
int size() const { return m_map.size(); }
|
||||
// Clear array. Verilog: function void delete([input index])
|
||||
void clear() { m_map.clear(); }
|
||||
void erase(const T_Key& index) { m_map.erase(index); }
|
||||
// Return 0/1 if element exists. Verilog: function int exists(input index)
|
||||
int exists(const T_Key& index) const { return m_map.find(index) != m_map.end(); }
|
||||
// Return first element. Verilog: function int first(ref index);
|
||||
int first(T_Key& indexr) const {
|
||||
const auto it = m_map.cbegin();
|
||||
if (it == m_map.end()) return 0;
|
||||
indexr = it->first;
|
||||
return 1;
|
||||
}
|
||||
// Return last element. Verilog: function int last(ref index)
|
||||
int last(T_Key& indexr) const {
|
||||
const auto it = m_map.crbegin();
|
||||
if (it == m_map.rend()) return 0;
|
||||
indexr = it->first;
|
||||
return 1;
|
||||
}
|
||||
// Return next element. Verilog: function int next(ref index)
|
||||
int next(T_Key& indexr) const {
|
||||
auto it = m_map.find(indexr);
|
||||
if (VL_UNLIKELY(it == m_map.end())) return 0;
|
||||
++it;
|
||||
if (VL_UNLIKELY(it == m_map.end())) return 0;
|
||||
indexr = it->first;
|
||||
return 1;
|
||||
}
|
||||
// Return prev element. Verilog: function int prev(ref index)
|
||||
int prev(T_Key& indexr) const {
|
||||
auto it = m_map.find(indexr);
|
||||
if (VL_UNLIKELY(it == m_map.end())) return 0;
|
||||
if (VL_UNLIKELY(it == m_map.begin())) return 0;
|
||||
--it;
|
||||
indexr = it->first;
|
||||
return 1;
|
||||
}
|
||||
// Setting. Verilog: assoc[index] = v
|
||||
// Can't just overload operator[] or provide a "at" reference to set,
|
||||
// because we need to be able to insert only when the value is set
|
||||
T_Value& at(const T_Key& index) {
|
||||
const auto it = m_map.find(index);
|
||||
if (it == m_map.end()) {
|
||||
std::pair<typename Map::iterator, bool> pit = m_map.emplace(index, m_defaultValue);
|
||||
return pit.first->second;
|
||||
}
|
||||
return it->second;
|
||||
}
|
||||
// Accessing. Verilog: v = assoc[index]
|
||||
const T_Value& at(const T_Key& index) const {
|
||||
const auto it = m_map.find(index);
|
||||
if (it == m_map.end()) {
|
||||
return m_defaultValue;
|
||||
} else {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
// Setting as a chained operation
|
||||
VlAssocArray& set(const T_Key& index, const T_Value& value) {
|
||||
at(index) = value;
|
||||
return *this;
|
||||
}
|
||||
VlAssocArray& setDefault(const T_Value& value) {
|
||||
atDefault() = value;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// For save/restore
|
||||
const_iterator begin() const { return m_map.begin(); }
|
||||
const_iterator end() const { return m_map.end(); }
|
||||
|
||||
// Methods
|
||||
VlQueue<T_Value> unique() const {
|
||||
VlQueue<T_Value> out;
|
||||
std::set<T_Value> saw;
|
||||
for (const auto& i : m_map) {
|
||||
auto it = saw.find(i.second);
|
||||
if (it == saw.end()) {
|
||||
saw.insert(it, i.second);
|
||||
out.push_back(i.second);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
VlQueue<T_Key> unique_index() const {
|
||||
VlQueue<T_Key> out;
|
||||
std::set<T_Key> saw;
|
||||
for (const auto& i : m_map) {
|
||||
auto it = saw.find(i.second);
|
||||
if (it == saw.end()) {
|
||||
saw.insert(it, i.second);
|
||||
out.push_back(i.first);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
template <typename Func> VlQueue<T_Value> find(Func with_func) const {
|
||||
VlQueue<T_Value> out;
|
||||
for (const auto& i : m_map)
|
||||
if (with_func(i.first, i.second)) out.push_back(i.second);
|
||||
return out;
|
||||
}
|
||||
template <typename Func> VlQueue<T_Key> find_index(Func with_func) const {
|
||||
VlQueue<T_Key> out;
|
||||
for (const auto& i : m_map)
|
||||
if (with_func(i.first, i.second)) out.push_back(i.first);
|
||||
return out;
|
||||
}
|
||||
template <typename Func> VlQueue<T_Value> find_first(Func with_func) const {
|
||||
const auto it
|
||||
= std::find_if(m_map.begin(), m_map.end(), [=](const std::pair<T_Key, T_Value>& i) {
|
||||
return with_func(i.first, i.second);
|
||||
});
|
||||
if (it == m_map.end()) return VlQueue<T_Value>{};
|
||||
return VlQueue<T_Value>::cons(it->second);
|
||||
}
|
||||
template <typename Func> VlQueue<T_Key> find_first_index(Func with_func) const {
|
||||
const auto it
|
||||
= std::find_if(m_map.begin(), m_map.end(), [=](const std::pair<T_Key, T_Value>& i) {
|
||||
return with_func(i.first, i.second);
|
||||
});
|
||||
if (it == m_map.end()) return VlQueue<T_Value>{};
|
||||
return VlQueue<T_Key>::cons(it->first);
|
||||
}
|
||||
template <typename Func> VlQueue<T_Value> find_last(Func with_func) const {
|
||||
const auto it
|
||||
= std::find_if(m_map.rbegin(), m_map.rend(), [=](const std::pair<T_Key, T_Value>& i) {
|
||||
return with_func(i.first, i.second);
|
||||
});
|
||||
if (it == m_map.rend()) return VlQueue<T_Value>{};
|
||||
return VlQueue<T_Value>::cons(it->second);
|
||||
}
|
||||
template <typename Func> VlQueue<T_Key> find_last_index(Func with_func) const {
|
||||
const auto it
|
||||
= std::find_if(m_map.rbegin(), m_map.rend(), [=](const std::pair<T_Key, T_Value>& i) {
|
||||
return with_func(i.first, i.second);
|
||||
});
|
||||
if (it == m_map.rend()) return VlQueue<T_Value>{};
|
||||
return VlQueue<T_Key>::cons(it->first);
|
||||
}
|
||||
|
||||
// Reduction operators
|
||||
VlQueue<T_Value> min() const {
|
||||
if (m_map.empty()) return VlQueue<T_Value>();
|
||||
const auto it = std::min_element(
|
||||
m_map.begin(), m_map.end(),
|
||||
[](const std::pair<T_Key, T_Value>& a, const std::pair<T_Key, T_Value>& b) {
|
||||
return a.second < b.second;
|
||||
});
|
||||
return VlQueue<T_Value>::cons(it->second);
|
||||
}
|
||||
VlQueue<T_Value> max() const {
|
||||
if (m_map.empty()) return VlQueue<T_Value>();
|
||||
const auto it = std::max_element(
|
||||
m_map.begin(), m_map.end(),
|
||||
[](const std::pair<T_Key, T_Value>& a, const std::pair<T_Key, T_Value>& b) {
|
||||
return a.second < b.second;
|
||||
});
|
||||
return VlQueue<T_Value>::cons(it->second);
|
||||
}
|
||||
|
||||
T_Value r_sum() const {
|
||||
T_Value out(0); // Type must have assignment operator
|
||||
for (const auto& i : m_map) out += i.second;
|
||||
return out;
|
||||
}
|
||||
template <typename Func> T_Value r_sum(Func with_func) const {
|
||||
T_Value out(0); // Type must have assignment operator
|
||||
for (const auto& i : m_map) out += with_func(i.first, i.second);
|
||||
return out;
|
||||
}
|
||||
T_Value r_product() const {
|
||||
if (m_map.empty()) return T_Value(0);
|
||||
auto it = m_map.begin();
|
||||
T_Value out{it->second};
|
||||
++it;
|
||||
for (; it != m_map.end(); ++it) out *= it->second;
|
||||
return out;
|
||||
}
|
||||
template <typename Func> T_Value r_product(Func with_func) const {
|
||||
if (m_map.empty()) return T_Value(0);
|
||||
auto it = m_map.begin();
|
||||
T_Value out{with_func(it->first, it->second)};
|
||||
++it;
|
||||
for (; it != m_map.end(); ++it) out *= with_func(it->first, it->second);
|
||||
return out;
|
||||
}
|
||||
T_Value r_and() const {
|
||||
if (m_map.empty()) return T_Value(0);
|
||||
auto it = m_map.begin();
|
||||
T_Value out{it->second};
|
||||
++it;
|
||||
for (; it != m_map.end(); ++it) out &= it->second;
|
||||
return out;
|
||||
}
|
||||
template <typename Func> T_Value r_and(Func with_func) const {
|
||||
if (m_map.empty()) return T_Value(0);
|
||||
auto it = m_map.begin();
|
||||
T_Value out{with_func(it->first, it->second)};
|
||||
++it;
|
||||
for (; it != m_map.end(); ++it) out &= with_func(it->first, it->second);
|
||||
return out;
|
||||
}
|
||||
T_Value r_or() const {
|
||||
T_Value out(0); // Type must have assignment operator
|
||||
for (const auto& i : m_map) out |= i.second;
|
||||
return out;
|
||||
}
|
||||
template <typename Func> T_Value r_or(Func with_func) const {
|
||||
T_Value out(0); // Type must have assignment operator
|
||||
for (const auto& i : m_map) out |= with_func(i.first, i.second);
|
||||
return out;
|
||||
}
|
||||
T_Value r_xor() const {
|
||||
T_Value out(0); // Type must have assignment operator
|
||||
for (const auto& i : m_map) out ^= i.second;
|
||||
return out;
|
||||
}
|
||||
template <typename Func> T_Value r_xor(Func with_func) const {
|
||||
T_Value out(0); // Type must have assignment operator
|
||||
for (const auto& i : m_map) out ^= with_func(i.first, i.second);
|
||||
return out;
|
||||
}
|
||||
|
||||
// Dumping. Verilog: str = $sformatf("%p", assoc)
|
||||
std::string to_string() const {
|
||||
if (m_map.empty()) return "'{}"; // No trailing space
|
||||
std::string out = "'{";
|
||||
std::string comma;
|
||||
for (const auto& i : m_map) {
|
||||
out += comma + VL_TO_STRING(i.first) + ":" + VL_TO_STRING(i.second);
|
||||
comma = ", ";
|
||||
}
|
||||
// Default not printed - maybe random init data
|
||||
return out + "} ";
|
||||
}
|
||||
};
|
||||
|
||||
template <class T_Key, class T_Value>
|
||||
std::string VL_TO_STRING(const VlAssocArray<T_Key, T_Value>& obj) {
|
||||
return obj.to_string();
|
||||
}
|
||||
|
||||
template <class T_Key, class T_Value>
|
||||
void VL_READMEM_N(bool hex, int bits, const std::string& filename,
|
||||
VlAssocArray<T_Key, T_Value>& obj, QData start, QData end) VL_MT_SAFE {
|
||||
VlReadMem rmem(hex, bits, filename, start, end);
|
||||
if (VL_UNLIKELY(!rmem.isOpen())) return;
|
||||
while (true) {
|
||||
QData addr;
|
||||
std::string data;
|
||||
if (rmem.get(addr /*ref*/, data /*ref*/)) {
|
||||
rmem.setData(&(obj.at(addr)), data);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class T_Key, class T_Value>
|
||||
void VL_WRITEMEM_N(bool hex, int bits, const std::string& filename,
|
||||
const VlAssocArray<T_Key, T_Value>& obj, QData start, QData end) VL_MT_SAFE {
|
||||
VlWriteMem wmem(hex, bits, filename, start, end);
|
||||
if (VL_UNLIKELY(!wmem.isOpen())) return;
|
||||
for (const auto& i : obj) {
|
||||
const QData addr = i.first;
|
||||
if (addr >= start && addr <= end) wmem.print(addr, true, &(i.second));
|
||||
}
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
/// Verilog unpacked array container
|
||||
/// For when a standard C++[] array is not sufficient, e.g. an
|
||||
/// array under a queue, or methods operating on the array.
|
||||
///
|
||||
/// A 'struct' as we want this to be an aggregate type that allows
|
||||
/// static aggregate initialization. Consider data members private.
|
||||
///
|
||||
/// This class may get exposed to a Verilated Model's top I/O, if the top
|
||||
/// IO has an unpacked array.
|
||||
|
||||
template <class T_Value, std::size_t T_Depth> struct VlUnpacked final {
|
||||
// MEMBERS
|
||||
// This should be the only data member, otherwise generated static initializers need updating
|
||||
T_Value m_storage[T_Depth]; // Contents of the unpacked array
|
||||
|
||||
// CONSTRUCTORS
|
||||
VlUnpacked() = default;
|
||||
~VlUnpacked() = default;
|
||||
VlUnpacked(const VlUnpacked&) = default;
|
||||
VlUnpacked(VlUnpacked&&) = default;
|
||||
VlUnpacked& operator=(const VlUnpacked&) = default;
|
||||
VlUnpacked& operator=(VlUnpacked&&) = default;
|
||||
|
||||
// METHODS
|
||||
// Raw access
|
||||
WData* data() { return &m_storage[0]; }
|
||||
const WData* data() const { return &m_storage[0]; }
|
||||
|
||||
T_Value& operator[](size_t index) { return m_storage[index]; };
|
||||
const T_Value& operator[](size_t index) const { return m_storage[index]; };
|
||||
|
||||
// Dumping. Verilog: str = $sformatf("%p", assoc)
|
||||
std::string to_string() const {
|
||||
std::string out = "'{";
|
||||
std::string comma;
|
||||
for (int i = 0; i < T_Depth; ++i) {
|
||||
out += comma + VL_TO_STRING(m_storage[i]);
|
||||
comma = ", ";
|
||||
}
|
||||
return out + "} ";
|
||||
}
|
||||
};
|
||||
|
||||
template <class T_Value, std::size_t T_Depth>
|
||||
std::string VL_TO_STRING(const VlUnpacked<T_Value, T_Depth>& obj) {
|
||||
return obj.to_string();
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
// Verilog class reference container
|
||||
// There are no multithreaded locks on this; the base variable must
|
||||
// be protected by other means
|
||||
|
||||
#define VlClassRef std::shared_ptr
|
||||
|
||||
template <class T> // T typically of type VlClassRef<x>
|
||||
inline T VL_NULL_CHECK(T t, const char* filename, int linenum) {
|
||||
if (VL_UNLIKELY(!t)) Verilated::nullPointerError(filename, linenum);
|
||||
return t;
|
||||
}
|
||||
|
||||
template <typename T, typename U>
|
||||
static inline bool VL_CAST_DYNAMIC(VlClassRef<T> in, VlClassRef<U>& outr) {
|
||||
VlClassRef<U> casted = std::dynamic_pointer_cast<U>(in);
|
||||
if (VL_LIKELY(casted)) {
|
||||
outr = casted;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Conversion functions
|
||||
|
||||
extern std::string VL_CVT_PACK_STR_NW(int lwords, const WDataInP lwp) VL_MT_SAFE;
|
||||
inline std::string VL_CVT_PACK_STR_NQ(QData lhs) VL_PURE {
|
||||
VlWide<VL_WQ_WORDS_E> lw;
|
||||
VL_SET_WQ(lw, lhs);
|
||||
return VL_CVT_PACK_STR_NW(VL_WQ_WORDS_E, lw);
|
||||
}
|
||||
inline std::string VL_CVT_PACK_STR_NN(const std::string& lhs) VL_PURE { return lhs; }
|
||||
inline std::string& VL_CVT_PACK_STR_NN(std::string& lhs) VL_PURE { return lhs; }
|
||||
inline std::string VL_CVT_PACK_STR_NI(IData lhs) VL_PURE {
|
||||
VlWide<VL_WQ_WORDS_E> lw;
|
||||
VL_SET_WI(lw, lhs);
|
||||
return VL_CVT_PACK_STR_NW(1, lw);
|
||||
}
|
||||
inline std::string VL_CONCATN_NNN(const std::string& lhs, const std::string& rhs) VL_PURE {
|
||||
return lhs + rhs;
|
||||
}
|
||||
inline std::string VL_REPLICATEN_NNQ(int, int, int, const std::string& lhs, IData rep) VL_PURE {
|
||||
std::string out;
|
||||
out.reserve(lhs.length() * rep);
|
||||
for (unsigned times = 0; times < rep; ++times) out += lhs;
|
||||
return out;
|
||||
}
|
||||
inline std::string VL_REPLICATEN_NNI(int obits, int lbits, int rbits, const std::string& lhs,
|
||||
IData rep) VL_PURE {
|
||||
return VL_REPLICATEN_NNQ(obits, lbits, rbits, lhs, rep);
|
||||
}
|
||||
|
||||
inline IData VL_LEN_IN(const std::string& ld) { return ld.length(); }
|
||||
extern std::string VL_TOLOWER_NN(const std::string& ld);
|
||||
extern std::string VL_TOUPPER_NN(const std::string& ld);
|
||||
|
||||
extern IData VL_FERROR_IN(IData fpi, std::string& outputr) VL_MT_SAFE;
|
||||
extern IData VL_FOPEN_NN(const std::string& filename, const std::string& mode) VL_MT_SAFE;
|
||||
extern IData VL_FOPEN_MCD_N(const std::string& filename) VL_MT_SAFE;
|
||||
extern void VL_READMEM_N(bool hex, int bits, QData depth, int array_lsb,
|
||||
const std::string& filename, void* memp, QData start,
|
||||
QData end) VL_MT_SAFE;
|
||||
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 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;
|
||||
inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, CData& rdr) VL_MT_SAFE {
|
||||
VlWide<2> rwp; // WData must always be at least 2
|
||||
IData got = VL_VALUEPLUSARGS_INW(rbits, ld, rwp);
|
||||
if (got) rdr = rwp[0];
|
||||
return got;
|
||||
}
|
||||
inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, SData& rdr) VL_MT_SAFE {
|
||||
VlWide<2> rwp; // WData must always be at least 2
|
||||
IData got = VL_VALUEPLUSARGS_INW(rbits, ld, rwp);
|
||||
if (got) rdr = rwp[0];
|
||||
return got;
|
||||
}
|
||||
inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, IData& rdr) VL_MT_SAFE {
|
||||
VlWide<2> rwp;
|
||||
IData got = VL_VALUEPLUSARGS_INW(rbits, ld, rwp);
|
||||
if (got) rdr = rwp[0];
|
||||
return got;
|
||||
}
|
||||
inline IData VL_VALUEPLUSARGS_INQ(int rbits, const std::string& ld, QData& rdr) VL_MT_SAFE {
|
||||
VlWide<2> rwp;
|
||||
IData got = VL_VALUEPLUSARGS_INW(rbits, ld, rwp);
|
||||
if (got) rdr = VL_SET_QW(rwp);
|
||||
return got;
|
||||
}
|
||||
inline IData VL_VALUEPLUSARGS_INQ(int rbits, const std::string& ld, double& rdr) VL_MT_SAFE {
|
||||
VlWide<2> rwp;
|
||||
IData got = VL_VALUEPLUSARGS_INW(rbits, ld, rwp);
|
||||
if (got) rdr = VL_CVT_D_Q(VL_SET_QW(rwp));
|
||||
return got;
|
||||
}
|
||||
extern IData VL_VALUEPLUSARGS_INN(int, const std::string& ld, std::string& rdr) VL_MT_SAFE;
|
||||
|
||||
//======================================================================
|
||||
// Strings
|
||||
|
||||
extern std::string VL_PUTC_N(const std::string& lhs, IData rhs, CData ths) VL_PURE;
|
||||
extern CData VL_GETC_N(const std::string& lhs, IData rhs) VL_PURE;
|
||||
extern std::string VL_SUBSTR_N(const std::string& lhs, IData rhs, IData ths) VL_PURE;
|
||||
|
||||
inline IData VL_CMP_NN(const std::string& lhs, const std::string& rhs, bool ignoreCase) VL_PURE {
|
||||
// SystemVerilog does not allow a string variable to contain '\0'.
|
||||
// So C functions such as strcmp() can correctly compare strings.
|
||||
if (ignoreCase) {
|
||||
return VL_STRCASECMP(lhs.c_str(), rhs.c_str());
|
||||
} else {
|
||||
return std::strcmp(lhs.c_str(), rhs.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
extern IData VL_ATOI_N(const std::string& str, int base) VL_PURE;
|
||||
|
||||
extern IData VL_FGETS_NI(std::string& dest, IData fpi);
|
||||
|
||||
#endif // Guard
|
||||
|
||||
+67
-64
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2009-2021 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2009-2022 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -30,13 +30,17 @@
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h"
|
||||
#include "verilated_heavy.h"
|
||||
#include "verilated_syms.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <deque>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <numeric>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
#ifdef VL_THREADED
|
||||
# include <functional>
|
||||
# include <queue>
|
||||
@@ -61,7 +65,7 @@ public:
|
||||
|
||||
private:
|
||||
// MEMBERS
|
||||
vluint32_t m_mtaskId; // MTask that did enqueue
|
||||
uint32_t m_mtaskId; // MTask that did enqueue
|
||||
std::function<void()> m_cb; // Lambda to execute when message received
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
@@ -74,7 +78,7 @@ public:
|
||||
VerilatedMsg& operator=(const VerilatedMsg&) = default;
|
||||
VerilatedMsg& operator=(VerilatedMsg&&) = default;
|
||||
// METHODS
|
||||
vluint32_t mtaskId() const { return m_mtaskId; }
|
||||
uint32_t mtaskId() const { return m_mtaskId; }
|
||||
// Execute the lambda function
|
||||
void run() const { m_cb(); }
|
||||
};
|
||||
@@ -85,9 +89,9 @@ public:
|
||||
class VerilatedEvalMsgQueue final {
|
||||
using VerilatedThreadQueue = std::multiset<VerilatedMsg, VerilatedMsg::Cmp>;
|
||||
|
||||
std::atomic<vluint64_t> m_depth; // Current depth of queue (see comments below)
|
||||
std::atomic<uint64_t> m_depth; // Current depth of queue (see comments below)
|
||||
|
||||
VerilatedMutex m_mutex; // Mutex protecting queue
|
||||
mutable VerilatedMutex m_mutex; // Mutex protecting queue
|
||||
VerilatedThreadQueue m_queue VL_GUARDED_BY(m_mutex); // Message queue
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
@@ -104,7 +108,7 @@ public:
|
||||
// METHODS
|
||||
// Add message to queue (called by producer)
|
||||
void post(const VerilatedMsg& msg) VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
const VerilatedLockGuard lock(m_mutex);
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
m_queue.insert(msg); // Pass by value to copy the message into queue
|
||||
++m_depth;
|
||||
}
|
||||
@@ -124,7 +128,7 @@ public:
|
||||
const VerilatedMsg msg = *(it);
|
||||
m_queue.erase(it);
|
||||
m_mutex.unlock();
|
||||
m_depth--; // Ok if outside critical section as only this code checks the value
|
||||
--m_depth; // Ok if outside critical section as only this code checks the value
|
||||
{
|
||||
VL_DEBUG_IF(VL_DBG_MSGF("Executing callback from mtaskId=%d\n", msg.mtaskId()););
|
||||
msg.run();
|
||||
@@ -139,11 +143,10 @@ class VerilatedThreadMsgQueue final {
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
VerilatedThreadMsgQueue() {}
|
||||
~VerilatedThreadMsgQueue() {
|
||||
// The only call of this with a non-empty queue is a fatal error.
|
||||
// So this does not flush the queue, as the destination queue is not known to this class.
|
||||
}
|
||||
VerilatedThreadMsgQueue() = default;
|
||||
~VerilatedThreadMsgQueue() = default;
|
||||
// The only call of destructor with a non-empty queue is a fatal error.
|
||||
// So this does not flush the queue, as the destination queue is not known to this class.
|
||||
|
||||
private:
|
||||
VL_UNCOPYABLE(VerilatedThreadMsgQueue);
|
||||
@@ -179,16 +182,16 @@ public:
|
||||
|
||||
// FILE* list constructed from a file-descriptor
|
||||
class VerilatedFpList final {
|
||||
FILE* m_fp[31];
|
||||
FILE* m_fp[31] = {};
|
||||
std::size_t m_sz = 0;
|
||||
|
||||
public:
|
||||
using const_iterator = FILE* const*;
|
||||
explicit VerilatedFpList() {}
|
||||
explicit VerilatedFpList() = default;
|
||||
const_iterator begin() const { return m_fp; }
|
||||
const_iterator end() const { return m_fp + m_sz; }
|
||||
std::size_t size() const { return m_sz; }
|
||||
std::size_t capacity() const { return 31; }
|
||||
static std::size_t capacity() { return 31; }
|
||||
void push_back(FILE* fd) {
|
||||
if (VL_LIKELY(size() < capacity())) m_fp[m_sz++] = fd;
|
||||
}
|
||||
@@ -232,17 +235,16 @@ class VerilatedContextImp final : VerilatedContext {
|
||||
return s_s;
|
||||
}
|
||||
|
||||
private:
|
||||
public: // But only for verilated*.cpp
|
||||
// CONSTRUCTORS - no data can live here, use only VerilatedContext
|
||||
VerilatedContextImp() = delete;
|
||||
~VerilatedContextImp() = delete;
|
||||
|
||||
public: // But only for verilated*.cpp
|
||||
// METHODS - extending into VerilatedContext, call via impp()->
|
||||
|
||||
// Random seed handling
|
||||
vluint64_t randSeedDefault64() const VL_MT_SAFE;
|
||||
static vluint32_t randSeedEpoch() VL_MT_SAFE { return s().s_randSeedEpoch; }
|
||||
uint64_t randSeedDefault64() const VL_MT_SAFE;
|
||||
static uint32_t randSeedEpoch() VL_MT_SAFE { return s().s_randSeedEpoch; }
|
||||
|
||||
// METHODS - timeformat
|
||||
int timeFormatUnits() const VL_MT_SAFE {
|
||||
@@ -256,11 +258,11 @@ public: // But only for verilated*.cpp
|
||||
int timeFormatWidth() const VL_MT_SAFE { return m_s.m_timeFormatWidth; }
|
||||
void timeFormatWidth(int value) VL_MT_SAFE { m_s.m_timeFormatWidth = value; }
|
||||
std::string timeFormatSuffix() const VL_MT_SAFE_EXCLUDES(m_timeDumpMutex) {
|
||||
const VerilatedLockGuard lock(m_timeDumpMutex);
|
||||
const VerilatedLockGuard lock{m_timeDumpMutex};
|
||||
return m_timeFormatSuffix;
|
||||
}
|
||||
void timeFormatSuffix(const std::string& value) VL_MT_SAFE_EXCLUDES(m_timeDumpMutex) {
|
||||
const VerilatedLockGuard lock(m_timeDumpMutex);
|
||||
const VerilatedLockGuard lock{m_timeDumpMutex};
|
||||
m_timeFormatSuffix = value;
|
||||
}
|
||||
|
||||
@@ -268,63 +270,62 @@ public: // But only for verilated*.cpp
|
||||
std::string argPlusMatch(const char* prefixp) VL_MT_SAFE_EXCLUDES(m_argMutex);
|
||||
std::pair<int, char**> argc_argv() VL_MT_SAFE_EXCLUDES(m_argMutex);
|
||||
|
||||
public: // But only for verilated*.cpp
|
||||
// METHODS - scope name
|
||||
// METHODS - scope name - INTERNAL only for verilated*.cpp
|
||||
void scopeInsert(const VerilatedScope* scopep) VL_MT_SAFE;
|
||||
void scopeErase(const VerilatedScope* scopep) VL_MT_SAFE;
|
||||
|
||||
public: // But only for verilated*.cpp
|
||||
// METHODS - file IO
|
||||
// METHODS - file IO - INTERNAL only for verilated*.cpp
|
||||
|
||||
IData fdNewMcd(const char* filenamep) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
||||
const VerilatedLockGuard lock(m_fdMutex);
|
||||
const VerilatedLockGuard lock{m_fdMutex};
|
||||
if (m_fdFreeMct.empty()) return 0;
|
||||
IData idx = m_fdFreeMct.back();
|
||||
const IData idx = m_fdFreeMct.back();
|
||||
m_fdFreeMct.pop_back();
|
||||
m_fdps[idx] = std::fopen(filenamep, "w");
|
||||
if (VL_UNLIKELY(!m_fdps[idx])) return 0;
|
||||
return (1 << idx);
|
||||
}
|
||||
IData fdNew(const char* filenamep, const char* modep) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
||||
FILE* fp = std::fopen(filenamep, modep);
|
||||
FILE* const fp = std::fopen(filenamep, modep);
|
||||
if (VL_UNLIKELY(!fp)) return 0;
|
||||
// Bit 31 indicates it's a descriptor not a MCD
|
||||
const VerilatedLockGuard lock(m_fdMutex);
|
||||
const VerilatedLockGuard lock{m_fdMutex};
|
||||
if (m_fdFree.empty()) {
|
||||
// Need to create more space in m_fdps and m_fdFree
|
||||
const std::size_t start = std::max<std::size_t>(31UL + 1UL + 3UL, m_fdps.size());
|
||||
const std::size_t excess = 10;
|
||||
m_fdps.resize(start + excess);
|
||||
std::fill(m_fdps.begin() + start, m_fdps.end(), (FILE*)0);
|
||||
std::fill(m_fdps.begin() + start, m_fdps.end(), static_cast<FILE*>(nullptr));
|
||||
m_fdFree.resize(excess);
|
||||
for (std::size_t i = 0, id = start; i < m_fdFree.size(); ++i, ++id) {
|
||||
m_fdFree[i] = id;
|
||||
}
|
||||
}
|
||||
IData idx = m_fdFree.back();
|
||||
const IData idx = m_fdFree.back();
|
||||
m_fdFree.pop_back();
|
||||
m_fdps[idx] = fp;
|
||||
return (idx | (1UL << 31)); // bit 31 indicates not MCD
|
||||
}
|
||||
void fdFlush(IData fdi) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
||||
const VerilatedLockGuard lock(m_fdMutex);
|
||||
const VerilatedLockGuard lock{m_fdMutex};
|
||||
const VerilatedFpList fdlist = fdToFpList(fdi);
|
||||
for (const auto& i : fdlist) std::fflush(i);
|
||||
}
|
||||
IData fdSeek(IData fdi, IData offset, IData origin) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
||||
const VerilatedLockGuard lock(m_fdMutex);
|
||||
const VerilatedLockGuard lock{m_fdMutex};
|
||||
const VerilatedFpList fdlist = fdToFpList(fdi);
|
||||
if (VL_UNLIKELY(fdlist.size() != 1)) return 0;
|
||||
if (VL_UNLIKELY(fdlist.size() != 1)) return ~0U; // -1
|
||||
return static_cast<IData>(
|
||||
std::fseek(*fdlist.begin(), static_cast<long>(offset), static_cast<int>(origin)));
|
||||
}
|
||||
IData fdTell(IData fdi) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
||||
const VerilatedLockGuard lock(m_fdMutex);
|
||||
const VerilatedLockGuard lock{m_fdMutex};
|
||||
const VerilatedFpList fdlist = fdToFpList(fdi);
|
||||
if (VL_UNLIKELY(fdlist.size() != 1)) return 0;
|
||||
if (VL_UNLIKELY(fdlist.size() != 1)) return ~0U; // -1
|
||||
return static_cast<IData>(std::ftell(*fdlist.begin()));
|
||||
}
|
||||
void fdWrite(IData fdi, const std::string& output) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
||||
const VerilatedLockGuard lock(m_fdMutex);
|
||||
const VerilatedLockGuard lock{m_fdMutex};
|
||||
const VerilatedFpList fdlist = fdToFpList(fdi);
|
||||
for (const auto& i : fdlist) {
|
||||
if (VL_UNLIKELY(!i)) continue;
|
||||
@@ -332,15 +333,15 @@ public: // But only for verilated*.cpp
|
||||
}
|
||||
}
|
||||
void fdClose(IData fdi) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
||||
const VerilatedLockGuard lock(m_fdMutex);
|
||||
const VerilatedLockGuard lock{m_fdMutex};
|
||||
if (VL_BITISSET_I(fdi, 31)) {
|
||||
// Non-MCD case
|
||||
IData idx = VL_MASK_I(31) & fdi;
|
||||
const IData idx = VL_MASK_I(31) & fdi;
|
||||
if (VL_UNLIKELY(idx >= m_fdps.size())) return;
|
||||
if (VL_UNLIKELY(idx <= 2)) return; // stdout/stdin/stderr
|
||||
if (VL_UNLIKELY(!m_fdps[idx])) return; // Already free
|
||||
std::fclose(m_fdps[idx]);
|
||||
m_fdps[idx] = (FILE*)0;
|
||||
m_fdps[idx] = nullptr;
|
||||
m_fdFree.push_back(idx);
|
||||
} else {
|
||||
// MCD case
|
||||
@@ -356,7 +357,7 @@ public: // But only for verilated*.cpp
|
||||
}
|
||||
}
|
||||
inline FILE* fdToFp(IData fdi) VL_MT_SAFE_EXCLUDES(m_fdMutex) {
|
||||
const VerilatedLockGuard lock(m_fdMutex);
|
||||
const VerilatedLockGuard lock{m_fdMutex};
|
||||
const VerilatedFpList fdlist = fdToFpList(fdi);
|
||||
if (VL_UNLIKELY(fdlist.size() != 1)) return nullptr;
|
||||
return *fdlist.begin();
|
||||
@@ -391,7 +392,11 @@ protected:
|
||||
// METHODS - protected
|
||||
void commandArgsAddGuts(int argc, const char** argv);
|
||||
void commandArgVl(const std::string& arg);
|
||||
bool commandArgVlValue(const std::string& arg, const std::string& prefix, std::string& valuer);
|
||||
bool commandArgVlString(const std::string& arg, const std::string& prefix,
|
||||
std::string& valuer);
|
||||
bool commandArgVlUint64(const std::string& arg, const std::string& prefix, uint64_t& valuer,
|
||||
uint64_t min = std::numeric_limits<uint64_t>::min(),
|
||||
uint64_t max = std::numeric_limits<uint64_t>::max());
|
||||
void commandArgDump() const VL_MT_SAFE_EXCLUDES(m_argMutex);
|
||||
};
|
||||
|
||||
@@ -456,14 +461,13 @@ public:
|
||||
// METHODS - debug
|
||||
static void versionDump() VL_MT_SAFE;
|
||||
|
||||
public:
|
||||
// METHODS - user scope tracking
|
||||
// We implement this as a single large map instead of one map per scope.
|
||||
// There's often many more scopes than userdata's and thus having a ~48byte
|
||||
// per map overhead * N scopes would take much more space and cache thrashing.
|
||||
// As scopep's are pointers, this implicitly handles multiple Context's
|
||||
static inline void userInsert(const void* scopep, void* userKey, void* userData) VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock(s().m_userMapMutex);
|
||||
const VerilatedLockGuard lock{s().m_userMapMutex};
|
||||
const auto it = s().m_userMap.find(std::make_pair(scopep, userKey));
|
||||
if (it != s().m_userMap.end()) {
|
||||
it->second = userData;
|
||||
@@ -472,17 +476,18 @@ public:
|
||||
}
|
||||
}
|
||||
static inline void* userFind(const void* scopep, void* userKey) VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock(s().m_userMapMutex);
|
||||
const VerilatedLockGuard lock{s().m_userMapMutex};
|
||||
const auto& it = vlstd::as_const(s().m_userMap).find(std::make_pair(scopep, userKey));
|
||||
if (VL_UNLIKELY(it == s().m_userMap.end())) return nullptr;
|
||||
return it->second;
|
||||
}
|
||||
|
||||
public: // But only for verilated.cpp
|
||||
// METHODS - But only for verilated.cpp
|
||||
|
||||
// Symbol table destruction cleans up the entries for each scope.
|
||||
static void userEraseScope(const VerilatedScope* scopep) VL_MT_SAFE {
|
||||
// Slow ok - called once/scope on destruction, so we simply iterate.
|
||||
const VerilatedLockGuard lock(s().m_userMapMutex);
|
||||
// Slow ok - called once/scope on destruction, so we only iterate.
|
||||
const VerilatedLockGuard lock{s().m_userMapMutex};
|
||||
for (auto it = s().m_userMap.begin(); it != s().m_userMap.end();) {
|
||||
if (it->first.first == scopep) {
|
||||
s().m_userMap.erase(it++);
|
||||
@@ -492,7 +497,7 @@ public: // But only for verilated.cpp
|
||||
}
|
||||
}
|
||||
static void userDump() VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock(s().m_userMapMutex); // Avoid it changing in middle of dump
|
||||
const VerilatedLockGuard lock{s().m_userMapMutex}; // Avoid it changing in middle of dump
|
||||
bool first = true;
|
||||
for (const auto& i : s().m_userMap) {
|
||||
if (first) {
|
||||
@@ -504,17 +509,16 @@ public: // But only for verilated.cpp
|
||||
}
|
||||
}
|
||||
|
||||
public: // But only for verilated*.cpp
|
||||
// METHODS - hierarchy
|
||||
// METHODS - hierarchy - only for verilated*.cpp
|
||||
static void hierarchyAdd(const VerilatedScope* fromp, const VerilatedScope* top) VL_MT_SAFE {
|
||||
// Slow ok - called at construction for VPI accessible elements
|
||||
const VerilatedLockGuard lock(s().m_hierMapMutex);
|
||||
const VerilatedLockGuard lock{s().m_hierMapMutex};
|
||||
s().m_hierMap[fromp].push_back(top);
|
||||
}
|
||||
static void hierarchyRemove(const VerilatedScope* fromp,
|
||||
const VerilatedScope* top) VL_MT_SAFE {
|
||||
// Slow ok - called at destruction for VPI accessible elements
|
||||
const VerilatedLockGuard lock(s().m_hierMapMutex);
|
||||
const VerilatedLockGuard lock{s().m_hierMapMutex};
|
||||
VerilatedHierarchyMap& map = s().m_hierMap;
|
||||
if (map.find(fromp) == map.end()) return;
|
||||
auto& scopes = map[fromp];
|
||||
@@ -526,8 +530,7 @@ public: // But only for verilated*.cpp
|
||||
return &s().m_hierMap;
|
||||
}
|
||||
|
||||
public: // But only for verilated*.cpp
|
||||
// METHODS - export names
|
||||
// METHODS - export names - only for verilated*.cpp
|
||||
|
||||
// Each function prototype is converted to a function number which we
|
||||
// then use to index a 2D table also indexed by scope number, because we
|
||||
@@ -537,7 +540,7 @@ public: // But only for verilated*.cpp
|
||||
// miss at the cost of a multiply, and all lookups move to slowpath.
|
||||
static int exportInsert(const char* namep) VL_MT_SAFE {
|
||||
// Slow ok - called once/function at creation
|
||||
const VerilatedLockGuard lock(s().m_exportMutex);
|
||||
const VerilatedLockGuard lock{s().m_exportMutex};
|
||||
const auto it = s().m_exportMap.find(namep);
|
||||
if (it == s().m_exportMap.end()) {
|
||||
s().m_exportMap.emplace(namep, s().m_exportNext++);
|
||||
@@ -547,24 +550,24 @@ public: // But only for verilated*.cpp
|
||||
}
|
||||
}
|
||||
static int exportFind(const char* namep) VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock(s().m_exportMutex);
|
||||
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;
|
||||
std::string msg = (std::string("%Error: Testbench C called ") + namep
|
||||
+ " but no such DPI export function name exists in ANY model");
|
||||
const std::string msg = (std::string{"%Error: Testbench C called "} + namep
|
||||
+ " but no such DPI export function name exists in ANY model");
|
||||
VL_FATAL_MT("unknown", 0, "", msg.c_str());
|
||||
return -1;
|
||||
}
|
||||
static const char* exportName(int funcnum) VL_MT_SAFE {
|
||||
// Slowpath; find name for given export; errors only so no map to reverse-map it
|
||||
const VerilatedLockGuard lock(s().m_exportMutex);
|
||||
const VerilatedLockGuard lock{s().m_exportMutex};
|
||||
for (const auto& i : s().m_exportMap) {
|
||||
if (i.second == funcnum) return i.first;
|
||||
}
|
||||
return "*UNKNOWN*";
|
||||
}
|
||||
static void exportsDump() VL_MT_SAFE {
|
||||
const VerilatedLockGuard lock(s().m_exportMutex);
|
||||
const VerilatedLockGuard lock{s().m_exportMutex};
|
||||
bool first = true;
|
||||
for (const auto& i : s().m_exportMap) {
|
||||
if (first) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2003-2021 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2022 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
@@ -0,0 +1,225 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2012-2022 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilated run-time profiling implementation code
|
||||
///
|
||||
//=============================================================================
|
||||
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include "verilated_profiler.h"
|
||||
|
||||
#if VL_THREADED
|
||||
#include "verilated_threads.h"
|
||||
#endif
|
||||
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
//=============================================================================
|
||||
// Globals
|
||||
|
||||
// Internal note: Globals may multi-construct, see verilated.cpp top.
|
||||
|
||||
VL_THREAD_LOCAL VlExecutionProfiler::ExecutionTrace VlExecutionProfiler::t_trace;
|
||||
|
||||
constexpr const char* const VlExecutionRecord::s_ascii[];
|
||||
|
||||
//=============================================================================
|
||||
// VlPgoProfiler implementation
|
||||
|
||||
uint16_t VlExecutionRecord::getcpu() {
|
||||
#if defined(__linux)
|
||||
return sched_getcpu(); // TODO: this is a system call. Not exactly cheap.
|
||||
#elif defined(__APPLE__) && !defined(__arm64__)
|
||||
uint32_t info[4];
|
||||
__cpuid_count(1, 0, info[0], info[1], info[2], info[3]);
|
||||
// info[1] is EBX, bits 24-31 are APIC ID
|
||||
if ((info[3] & (1 << 9)) == 0) {
|
||||
return -1; // no APIC on chip
|
||||
} else {
|
||||
return (unsigned)info[1] >> 24;
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
return GetCurrentProcessorNumber();
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// VlExecutionProfiler implementation
|
||||
|
||||
template <size_t N>
|
||||
static size_t roundUptoMultipleOf(size_t value) {
|
||||
static_assert((N & (N - 1)) == 0, "'N' must be a power of 2");
|
||||
size_t mask = N - 1;
|
||||
return (value + mask) & ~mask;
|
||||
}
|
||||
|
||||
VlExecutionProfiler::VlExecutionProfiler(VerilatedContext& context)
|
||||
: m_context{context} {
|
||||
// Setup profiling on main thread
|
||||
setupThread(0);
|
||||
}
|
||||
|
||||
void VlExecutionProfiler::configure() {
|
||||
|
||||
if (VL_UNLIKELY(m_enabled)) {
|
||||
--m_windowCount;
|
||||
if (VL_UNLIKELY(m_windowCount == m_context.profExecWindow())) {
|
||||
VL_DEBUG_IF(VL_DBG_MSGF("+ profile start collection\n"););
|
||||
clear(); // Clear the profile after the cache warm-up cycles.
|
||||
m_tickBegin = VL_CPU_TICK();
|
||||
} else if (VL_UNLIKELY(m_windowCount == 0)) {
|
||||
const uint64_t tickEnd = VL_CPU_TICK();
|
||||
VL_DEBUG_IF(VL_DBG_MSGF("+ profile end\n"););
|
||||
const std::string& fileName = m_context.profExecFilename();
|
||||
dump(fileName.c_str(), tickEnd);
|
||||
m_enabled = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const uint64_t startReq = m_context.profExecStart() + 1; // + 1, so we can start at time 0
|
||||
|
||||
if (VL_UNLIKELY(m_lastStartReq < startReq && VL_TIME_Q() >= m_context.profExecStart())) {
|
||||
VL_DEBUG_IF(VL_DBG_MSGF("+ profile start warmup\n"););
|
||||
VL_DEBUG_IF(assert(m_windowCount == 0););
|
||||
m_enabled = true;
|
||||
m_windowCount = m_context.profExecWindow() * 2;
|
||||
m_lastStartReq = startReq;
|
||||
}
|
||||
}
|
||||
|
||||
VerilatedVirtualBase* VlExecutionProfiler::construct(VerilatedContext& context) {
|
||||
VlExecutionProfiler* const selfp = new VlExecutionProfiler{context};
|
||||
#if VL_THREADED
|
||||
if (VlThreadPool* const threadPoolp = static_cast<VlThreadPool*>(context.threadPoolp())) {
|
||||
for (int i = 0; i < threadPoolp->numThreads(); ++i) {
|
||||
// Data to pass to worker thread initialization
|
||||
struct Data {
|
||||
VlExecutionProfiler* const selfp;
|
||||
const uint32_t threadId;
|
||||
} data{selfp, static_cast<uint32_t>(i + 1)};
|
||||
|
||||
// Initialize worker thread
|
||||
threadPoolp->workerp(i)->addTask(
|
||||
[](void* userp, bool) {
|
||||
Data* const datap = static_cast<Data*>(userp);
|
||||
datap->selfp->setupThread(datap->threadId);
|
||||
},
|
||||
&data);
|
||||
|
||||
// Wait until initializationis complete
|
||||
threadPoolp->workerp(i)->wait();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return selfp;
|
||||
}
|
||||
|
||||
void VlExecutionProfiler::setupThread(uint32_t threadId) {
|
||||
// Reserve some space in the thread-local profiling buffer, in order to try to avoid malloc
|
||||
// while profiling.
|
||||
t_trace.reserve(RESERVED_TRACE_CAPACITY);
|
||||
// Register thread-local buffer in list of all buffers
|
||||
bool exists;
|
||||
{
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
exists = !m_traceps.emplace(threadId, &t_trace).second;
|
||||
}
|
||||
if (VL_UNLIKELY(exists)) {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "", "multiple initialization of profiler on some thread");
|
||||
}
|
||||
}
|
||||
|
||||
void VlExecutionProfiler::clear() VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
for (const auto& pair : m_traceps) {
|
||||
ExecutionTrace* const tracep = pair.second;
|
||||
const size_t reserve = roundUptoMultipleOf<RESERVED_TRACE_CAPACITY>(tracep->size());
|
||||
tracep->clear();
|
||||
tracep->reserve(reserve);
|
||||
}
|
||||
}
|
||||
|
||||
void VlExecutionProfiler::dump(const char* filenamep, uint64_t tickEnd)
|
||||
VL_MT_SAFE_EXCLUDES(m_mutex) {
|
||||
const VerilatedLockGuard lock{m_mutex};
|
||||
VL_DEBUG_IF(VL_DBG_MSGF("+prof+exec writing to '%s'\n", filenamep););
|
||||
|
||||
FILE* const fp = std::fopen(filenamep, "w");
|
||||
if (VL_UNLIKELY(!fp)) { VL_FATAL_MT(filenamep, 0, "", "+prof+exec+file file not writable"); }
|
||||
|
||||
// TODO Perhaps merge with verilated_coverage output format, so can
|
||||
// have a common merging and reporting tool, etc.
|
||||
fprintf(fp, "VLPROFVERSION 2.0 # Verilator execution profile version 2.0\n");
|
||||
fprintf(fp, "VLPROF arg +verilator+prof+exec+start+%" PRIu64 "\n",
|
||||
Verilated::threadContextp()->profExecStart());
|
||||
fprintf(fp, "VLPROF arg +verilator+prof+exec+window+%u\n",
|
||||
Verilated::threadContextp()->profExecWindow());
|
||||
const unsigned threads = static_cast<unsigned>(m_traceps.size());
|
||||
fprintf(fp, "VLPROF stat threads %u\n", threads);
|
||||
#ifdef VL_THREADED
|
||||
fprintf(fp, "VLPROF stat yields %" PRIu64 "\n", VlMTaskVertex::yields());
|
||||
#endif
|
||||
|
||||
// Copy /proc/cpuinfo into this output so verilator_gantt can be run on
|
||||
// a different machine
|
||||
{
|
||||
const std::unique_ptr<std::ifstream> ifp{new std::ifstream("/proc/cpuinfo")};
|
||||
if (!ifp->fail()) {
|
||||
std::string line;
|
||||
while (std::getline(*ifp, line)) { fprintf(fp, "VLPROFPROC %s\n", line.c_str()); }
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& pair : m_traceps) {
|
||||
const uint32_t threadId = pair.first;
|
||||
ExecutionTrace* const tracep = pair.second;
|
||||
fprintf(fp, "VLPROFTHREAD %" PRIu32 "\n", threadId);
|
||||
|
||||
for (const VlExecutionRecord& er : *tracep) {
|
||||
const char* const name = VlExecutionRecord::s_ascii[static_cast<uint8_t>(er.m_type)];
|
||||
const uint64_t time = er.m_tick - m_tickBegin;
|
||||
fprintf(fp, "VLPROFEXEC %s %" PRIu64, name, time);
|
||||
|
||||
switch (er.m_type) {
|
||||
case VlExecutionRecord::Type::EVAL_BEGIN:
|
||||
case VlExecutionRecord::Type::EVAL_END:
|
||||
case VlExecutionRecord::Type::EVAL_LOOP_BEGIN:
|
||||
case VlExecutionRecord::Type::EVAL_LOOP_END:
|
||||
// No payload
|
||||
fprintf(fp, "\n");
|
||||
break;
|
||||
case VlExecutionRecord::Type::MTASK_BEGIN: {
|
||||
const auto& payload = er.m_payload.mtaskBegin;
|
||||
fprintf(fp, " id %u predictStart %u cpu %u\n", payload.m_id,
|
||||
payload.m_predictStart, payload.m_cpu);
|
||||
break;
|
||||
}
|
||||
case VlExecutionRecord::Type::MTASK_END: {
|
||||
const auto& payload = er.m_payload.mtaskEnd;
|
||||
fprintf(fp, " id %u predictCost %u\n", payload.m_id, payload.m_predictCost);
|
||||
break;
|
||||
}
|
||||
default: abort(); // LCOV_EXCL_LINE
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(fp, "VLPROF stat ticks %" PRIu64 "\n", tickEnd - m_tickBegin);
|
||||
|
||||
std::fclose(fp);
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2012-2022 by Wilson Snyder. This program is free software; you
|
||||
// can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilated run-time profiling header
|
||||
///
|
||||
/// This file is not part of the Verilated public-facing API.
|
||||
/// It is only for internal use by Verilated library routines.
|
||||
///
|
||||
//=============================================================================
|
||||
|
||||
#ifndef VERILATOR_VERILATED_PROFILER_H_
|
||||
#define VERILATOR_VERILATED_PROFILER_H_
|
||||
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include "verilated.h"
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
class VlExecutionProfiler;
|
||||
class VlThreadPool;
|
||||
|
||||
//=============================================================================
|
||||
// Macros to simplify generated code
|
||||
|
||||
#define VL_EXEC_TRACE_ADD_RECORD(vlSymsp) \
|
||||
if (VL_UNLIKELY((vlSymsp)->__Vm_executionProfilerp->enabled())) \
|
||||
(vlSymsp)->__Vm_executionProfilerp->addRecord()
|
||||
|
||||
//=============================================================================
|
||||
// Return high-precision counter for profiling, or 0x0 if not available
|
||||
VL_ATTR_ALWINLINE
|
||||
inline QData VL_CPU_TICK() {
|
||||
uint64_t val;
|
||||
VL_GET_CPU_TICK(val);
|
||||
return val;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Private class used by VlExecutionProfiler
|
||||
|
||||
#define _VL_FOREACH_APPLY(macro, arg) macro(arg, #arg)
|
||||
|
||||
// clang-format off
|
||||
#define FOREACH_VlExecutionRecord_TYPE(macro) \
|
||||
_VL_FOREACH_APPLY(macro, EVAL_BEGIN) \
|
||||
_VL_FOREACH_APPLY(macro, EVAL_END) \
|
||||
_VL_FOREACH_APPLY(macro, EVAL_LOOP_BEGIN) \
|
||||
_VL_FOREACH_APPLY(macro, EVAL_LOOP_END) \
|
||||
_VL_FOREACH_APPLY(macro, MTASK_BEGIN) \
|
||||
_VL_FOREACH_APPLY(macro, MTASK_END)
|
||||
// clang-format on
|
||||
|
||||
class VlExecutionRecord final {
|
||||
friend class VlExecutionProfiler;
|
||||
|
||||
// TYPES
|
||||
enum class Type : uint8_t {
|
||||
#define VL_FOREACH_MACRO(id, name) id,
|
||||
FOREACH_VlExecutionRecord_TYPE(VL_FOREACH_MACRO)
|
||||
#undef VL_FOREACH_MACRO
|
||||
};
|
||||
|
||||
static constexpr const char* const s_ascii[] = {
|
||||
#define VL_FOREACH_MACRO(id, name) name,
|
||||
FOREACH_VlExecutionRecord_TYPE(VL_FOREACH_MACRO)
|
||||
#undef VL_FOREACH_MACRO
|
||||
};
|
||||
|
||||
union Payload {
|
||||
struct {
|
||||
uint32_t m_id; // MTask id
|
||||
uint32_t m_predictStart; // Time scheduler predicted would start
|
||||
uint32_t m_cpu; // Executing CPU id
|
||||
} mtaskBegin;
|
||||
struct {
|
||||
uint32_t m_id; // MTask id
|
||||
uint32_t m_predictCost; // How long scheduler predicted would take
|
||||
} mtaskEnd;
|
||||
};
|
||||
|
||||
// STATE
|
||||
// Layout below allows efficient packing.
|
||||
const uint64_t m_tick = VL_CPU_TICK(); // Tick at construction
|
||||
Payload m_payload; // The record payload
|
||||
Type m_type; // The record type
|
||||
static_assert(alignof(uint64_t) >= alignof(Payload), "Padding not allowed");
|
||||
static_assert(alignof(Payload) >= alignof(Type), "Padding not allowed");
|
||||
|
||||
static uint16_t getcpu(); // Return currently executing CPU id
|
||||
|
||||
public:
|
||||
// CONSTRUCTOR
|
||||
VlExecutionRecord() = default;
|
||||
|
||||
// METHODS
|
||||
void evalBegin() { m_type = Type::EVAL_BEGIN; }
|
||||
void evalEnd() { m_type = Type::EVAL_END; }
|
||||
void evalLoopBegin() { m_type = Type::EVAL_LOOP_BEGIN; }
|
||||
void evalLoopEnd() { m_type = Type::EVAL_LOOP_END; }
|
||||
void mtaskBegin(uint32_t id, uint32_t predictStart) {
|
||||
m_payload.mtaskBegin.m_id = id;
|
||||
m_payload.mtaskBegin.m_predictStart = predictStart;
|
||||
m_payload.mtaskBegin.m_cpu = getcpu();
|
||||
m_type = Type::MTASK_BEGIN;
|
||||
}
|
||||
void mtaskEnd(uint32_t id, uint32_t predictCost) {
|
||||
m_payload.mtaskEnd.m_id = id;
|
||||
m_payload.mtaskEnd.m_predictCost = predictCost;
|
||||
m_type = Type::MTASK_END;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(std::is_trivially_destructible<VlExecutionRecord>::value,
|
||||
"VlExecutionRecord should be trivially destructible for fast buffer clearing");
|
||||
|
||||
//=============================================================================
|
||||
// VlExecutionProfiler is for collecting profiling data about model execution
|
||||
|
||||
class VlExecutionProfiler final : public VerilatedVirtualBase {
|
||||
// CONSTANTS
|
||||
|
||||
// In order to try to avoid dynamic memory allocations during the actual profiling phase,
|
||||
// trace buffers are pre-allocated to be able to hold [a multiple] of this many records.
|
||||
static constexpr size_t RESERVED_TRACE_CAPACITY = 4096;
|
||||
|
||||
// TYPES
|
||||
|
||||
// Execution traces are recorded into thread local vectors. We can append records of profiling
|
||||
// events to this vector with very low overhead, and then dump them out later. This prevents
|
||||
// the overhead of printf/malloc/IO from corrupting the profiling data. It's super cheap to
|
||||
// append a VlProfileRec struct on the end of a pre-allocated vector; this is the only cost we
|
||||
// pay in real-time during a profiling cycle. Internal note: Globals may multi-construct, see
|
||||
// verilated.cpp top.
|
||||
using ExecutionTrace = std::vector<VlExecutionRecord>;
|
||||
|
||||
// STATE
|
||||
VerilatedContext& m_context; // The context this profiler is under
|
||||
static VL_THREAD_LOCAL ExecutionTrace t_trace; // thread-local trace buffers
|
||||
mutable VerilatedMutex m_mutex;
|
||||
// Map from thread id to &t_trace of given thread
|
||||
std::map<uint32_t, ExecutionTrace*> m_traceps VL_GUARDED_BY(m_mutex);
|
||||
|
||||
bool m_enabled = false; // Is profiling currently enabled
|
||||
|
||||
uint64_t m_tickBegin = 0; // Sample time (rdtsc() on x86) at beginning of collection
|
||||
uint64_t m_lastStartReq = 0; // Last requested profiling start (in simulation time)
|
||||
uint32_t m_windowCount = 0; // Track our position in the cache warmup and profile window
|
||||
|
||||
public:
|
||||
// CONSTRUCTOR
|
||||
explicit VlExecutionProfiler(VerilatedContext& context);
|
||||
~VlExecutionProfiler() override = default;
|
||||
|
||||
// METHODS
|
||||
|
||||
// Is profiling enabled
|
||||
inline bool enabled() const { return m_enabled; }
|
||||
// Append a trace record to the trace buffer of the current thread
|
||||
static inline VlExecutionRecord& addRecord() {
|
||||
t_trace.emplace_back();
|
||||
return t_trace.back();
|
||||
}
|
||||
// Configure profiler (called in beginning of 'eval')
|
||||
void configure();
|
||||
// Setup profiling on a particular thread;
|
||||
void setupThread(uint32_t threadId);
|
||||
// Clear all profiling data
|
||||
void clear() VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||
// Write profiling data into file
|
||||
void dump(const char* filenamep, uint64_t tickEnd) VL_MT_SAFE_EXCLUDES(m_mutex);
|
||||
|
||||
// Passed to VerilatedContext to create the VlExecutionProfiler profiler instance
|
||||
static VerilatedVirtualBase* construct(VerilatedContext& context);
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VlPgoProfiler is for collecting profiling data for PGO
|
||||
|
||||
template <std::size_t T_Entries>
|
||||
class VlPgoProfiler final {
|
||||
// TYPES
|
||||
struct Record final {
|
||||
const std::string m_name; // Hashed name of mtask/etc
|
||||
const size_t m_counterNumber = 0; // Which counter has data
|
||||
};
|
||||
|
||||
// Counters are stored packed, all together to reduce cache effects
|
||||
std::array<uint64_t, T_Entries> m_counters; // Time spent on this record
|
||||
std::vector<Record> m_records; // Record information
|
||||
|
||||
public:
|
||||
// METHODS
|
||||
VlPgoProfiler() = default;
|
||||
~VlPgoProfiler() = default;
|
||||
void write(const char* modelp, const std::string& filename) VL_MT_SAFE;
|
||||
void addCounter(size_t counter, const std::string& name) {
|
||||
VL_DEBUG_IF(assert(counter < T_Entries););
|
||||
m_records.emplace_back(Record{name, counter});
|
||||
}
|
||||
void startCounter(size_t counter) {
|
||||
// -= so when we add end time in stopCounter, the net effect is adding the difference,
|
||||
// without needing to hold onto a temporary
|
||||
m_counters[counter] -= VL_CPU_TICK();
|
||||
}
|
||||
void stopCounter(size_t counter) { m_counters[counter] += VL_CPU_TICK(); }
|
||||
};
|
||||
|
||||
template <std::size_t T_Entries>
|
||||
void VlPgoProfiler<T_Entries>::write(const char* modelp, const std::string& filename) VL_MT_SAFE {
|
||||
static VerilatedMutex s_mutex;
|
||||
const VerilatedLockGuard lock{s_mutex};
|
||||
|
||||
// On the first call we create the file. On later calls we append.
|
||||
// So when we have multiple models in an executable, possibly even
|
||||
// running on different threads, each will have a different symtab so
|
||||
// each will collect is own data correctly. However when each is
|
||||
// destroyed we need to get all the data, not keep overwriting and only
|
||||
// get the last model's data.
|
||||
static bool s_firstCall = true;
|
||||
|
||||
VL_DEBUG_IF(VL_DBG_MSGF("+prof+vlt+file writing to '%s'\n", filename.c_str()););
|
||||
|
||||
FILE* const fp = std::fopen(filename.c_str(), s_firstCall ? "w" : "a");
|
||||
if (VL_UNLIKELY(!fp)) {
|
||||
VL_FATAL_MT(filename.c_str(), 0, "", "+prof+vlt+file file not writable");
|
||||
}
|
||||
s_firstCall = false;
|
||||
|
||||
// TODO Perhaps merge with verilated_coverage output format, so can
|
||||
// have a common merging and reporting tool, etc.
|
||||
fprintf(fp, "// Verilated model profile-guided optimization data dump file\n");
|
||||
fprintf(fp, "`verilator_config\n");
|
||||
|
||||
for (const Record& rec : m_records) {
|
||||
fprintf(fp, "profile_data -model \"%s\" -mtask \"%s\" -cost 64'd%" PRIu64 "\n", modelp,
|
||||
rec.m_name.c_str(), m_counters[rec.m_counterNumber]);
|
||||
}
|
||||
|
||||
std::fclose(fp);
|
||||
}
|
||||
|
||||
#endif
|
||||
+17
-15
@@ -3,7 +3,7 @@
|
||||
//
|
||||
// Code available from: https://verilator.org
|
||||
//
|
||||
// Copyright 2001-2021 by Wilson Snyder. This program is free software; you
|
||||
// Copyright 2001-2022 by Wilson Snyder. This program is free software; you
|
||||
// can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
@@ -24,8 +24,10 @@
|
||||
#define VERILATOR_VERILATED_SAVE_CPP_
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h"
|
||||
|
||||
#include "verilated_save.h"
|
||||
|
||||
#include "verilated.h"
|
||||
#include "verilated_imp.h"
|
||||
|
||||
#include <cerrno>
|
||||
@@ -38,13 +40,13 @@
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef O_LARGEFILE // For example on WIN32
|
||||
#ifndef O_LARGEFILE // WIN32 headers omit this
|
||||
# define O_LARGEFILE 0
|
||||
#endif
|
||||
#ifndef O_NONBLOCK
|
||||
#ifndef O_NONBLOCK // WIN32 headers omit this
|
||||
# define O_NONBLOCK 0
|
||||
#endif
|
||||
#ifndef O_CLOEXEC
|
||||
#ifndef O_CLOEXEC // WIN32 headers omit this
|
||||
# define O_CLOEXEC 0
|
||||
#endif
|
||||
// clang-format on
|
||||
@@ -63,8 +65,8 @@ static const char* const VLTSAVE_TRAILER_STR = "vltsaved";
|
||||
bool VerilatedDeserialize::readDiffers(const void* __restrict datap,
|
||||
size_t size) VL_MT_UNSAFE_ONE {
|
||||
bufferCheck();
|
||||
const vluint8_t* __restrict dp = static_cast<const vluint8_t* __restrict>(datap);
|
||||
vluint8_t miss = 0;
|
||||
const uint8_t* __restrict dp = static_cast<const uint8_t* __restrict>(datap);
|
||||
uint8_t miss = 0;
|
||||
while (size--) miss |= (*dp++ ^ *m_cp++);
|
||||
return (miss != 0);
|
||||
}
|
||||
@@ -93,8 +95,8 @@ 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: ")
|
||||
= std::
|
||||
string{"Can't deserialize; file has wrong header signature, or file not found: "}
|
||||
+ filename();
|
||||
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
||||
// Die before we close() as close would infinite loop
|
||||
@@ -112,7 +114,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: ")
|
||||
= std::string{"Can't deserialize; file has wrong end-of-file signature: "}
|
||||
+ filename();
|
||||
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
||||
// Die before we close() as close would infinite loop
|
||||
@@ -192,7 +194,7 @@ void VerilatedRestore::close() VL_MT_UNSAFE_ONE {
|
||||
void VerilatedSave::flush() VL_MT_UNSAFE_ONE {
|
||||
m_assertOne.check();
|
||||
if (VL_UNLIKELY(!isOpen())) return;
|
||||
vluint8_t* wp = m_bufp;
|
||||
const uint8_t* wp = m_bufp;
|
||||
while (true) {
|
||||
const ssize_t remaining = (m_cp - wp);
|
||||
if (remaining == 0) break;
|
||||
@@ -204,7 +206,7 @@ void VerilatedSave::flush() VL_MT_UNSAFE_ONE {
|
||||
if (VL_UNCOVERABLE(errno != EAGAIN && errno != EINTR)) {
|
||||
// LCOV_EXCL_START
|
||||
// write failed, presume error (perhaps out of disk space)
|
||||
std::string msg = std::string(__FUNCTION__) + ": " + std::strerror(errno);
|
||||
const std::string msg = std::string{__FUNCTION__} + ": " + std::strerror(errno);
|
||||
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||
close();
|
||||
break;
|
||||
@@ -219,8 +221,8 @@ void VerilatedRestore::fill() VL_MT_UNSAFE_ONE {
|
||||
m_assertOne.check();
|
||||
if (VL_UNLIKELY(!isOpen())) return;
|
||||
// Move remaining characters down to start of buffer. (No memcpy, overlaps allowed)
|
||||
vluint8_t* rp = m_bufp;
|
||||
for (vluint8_t* sp = m_cp; sp < m_endp; *rp++ = *sp++) {} // Overlaps
|
||||
uint8_t* rp = m_bufp;
|
||||
for (uint8_t* sp = m_cp; sp < m_endp; *rp++ = *sp++) {} // Overlaps
|
||||
m_endp = m_bufp + (m_endp - m_cp);
|
||||
m_cp = m_bufp; // Reset buffer
|
||||
// Read into buffer starting at m_endp
|
||||
@@ -235,7 +237,7 @@ void VerilatedRestore::fill() VL_MT_UNSAFE_ONE {
|
||||
if (VL_UNCOVERABLE(errno != EAGAIN && errno != EINTR)) {
|
||||
// LCOV_EXCL_START
|
||||
// write failed, presume error (perhaps out of disk space)
|
||||
const std::string msg = std::string(__FUNCTION__) + ": " + std::strerror(errno);
|
||||
const std::string msg = std::string{__FUNCTION__} + ": " + std::strerror(errno);
|
||||
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||
close();
|
||||
break;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user