mirror of
https://github.com/verilator/verilator.git
synced 2026-10-02 16:13:34 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc1d380864 | ||
|
|
f96942a526 | ||
|
|
b23fc06388 | ||
|
|
f818ddc71c | ||
|
|
37c8cc82b2 | ||
|
|
03ebd5554f | ||
|
|
a2a7021914 | ||
|
|
c6650f88e1 | ||
|
|
55a25674a2 | ||
|
|
05c3d520a6 | ||
|
|
6b3304320b | ||
|
|
8d15276625 | ||
|
|
354f107fed | ||
|
|
1ff55c20e0 | ||
|
|
9583f0d3cc | ||
|
|
3acb85a005 | ||
|
|
08d041cb93 | ||
|
|
274b2002c2 | ||
|
|
681e91f9d8 | ||
|
|
6e333bd9ab | ||
|
|
6a331e37fc | ||
|
|
d8a020905a | ||
|
|
efa6f4cd95 | ||
|
|
ca537dc3ed | ||
|
|
3b64f54cea | ||
|
|
32c1e38b84 | ||
|
|
a7aa8820e1 | ||
|
|
2582a83376 | ||
|
|
0094cd7a81 | ||
|
|
d9b33d74a4 | ||
|
|
539a773ea7 | ||
|
|
b1831d7e33 | ||
|
|
b8ccb7a4c1 | ||
|
|
0eb75a41bb | ||
|
|
4cc47e3297 | ||
|
|
7bf3366041 | ||
|
|
c4b9f4bccf | ||
|
|
455c552132 | ||
|
|
f26fb51509 | ||
|
|
ab3c6576ed | ||
|
|
d1bd994113 | ||
|
|
d1548b1161 | ||
|
|
8a43f41ed6 | ||
|
|
42759e4011 | ||
|
|
27fa19eb94 | ||
|
|
426ed8589b | ||
|
|
44e53129a0 | ||
|
|
cf2e8f7a9c | ||
|
|
46be6d32c9 | ||
|
|
93d1fd6bb5 | ||
|
|
f700a73b3e | ||
|
|
abd69167ef | ||
|
|
60f2f176a2 | ||
|
|
3a51e84ebc | ||
|
|
a2a09253a2 | ||
|
|
ef884143d1 | ||
|
|
62a7d713a7 | ||
|
|
aaf5b7c2c0 | ||
|
|
30aa180211 | ||
|
|
0d4270c979 | ||
|
|
3505486ec8 | ||
|
|
9b0f2cce86 | ||
|
|
0e1f8db0d1 | ||
|
|
8a4aeddbb0 | ||
|
|
e8636f987f | ||
|
|
0198a2e9f3 | ||
|
|
db92ab47ba | ||
|
|
47107a5a36 | ||
|
|
e01c9df35e | ||
|
|
8f16557499 | ||
|
|
89fb57e54f | ||
|
|
8a3e9748b3 | ||
|
|
66b23be746 | ||
|
|
f0cdae129e | ||
|
|
ede7236945 | ||
|
|
a226111829 | ||
|
|
49edcbc2ac | ||
|
|
6050ab311e | ||
|
|
83b5c981d0 | ||
|
|
2685037ca2 | ||
|
|
940dc98c66 | ||
|
|
49353784fd | ||
|
|
2e5919549c | ||
|
|
8170391573 | ||
|
|
61e4b0a472 | ||
|
|
15af706286 | ||
|
|
2a43410fa6 | ||
|
|
5cc11839b5 | ||
|
|
d1bfeae026 | ||
|
|
e0b2c46664 | ||
|
|
ea61559ab5 | ||
|
|
6a5a2a56d7 | ||
|
|
5cbf80918f | ||
|
|
196e3a9712 | ||
|
|
3798b80091 | ||
|
|
689e4cf1d3 | ||
|
|
64f11251b6 | ||
|
|
6cd2bd2972 | ||
|
|
d396c55e34 | ||
|
|
45c9939a5e | ||
|
|
ad2929dff0 | ||
|
|
d3e1dfd3f5 | ||
|
|
14b48140bd | ||
|
|
7be1678fb0 | ||
|
|
d464ce1477 | ||
|
|
0a04f79576 | ||
|
|
b8098098d8 | ||
|
|
dc26815b1c | ||
|
|
f2028b60af | ||
|
|
06c7d8ce3b | ||
|
|
160505c5a4 | ||
|
|
3df9b4230b | ||
|
|
13163aef24 | ||
|
|
5c2b5bd782 | ||
|
|
da1ebcb4e4 | ||
|
|
8dbfc940ba | ||
|
|
e0654dc218 | ||
|
|
74a92e739f | ||
|
|
304a24d03a | ||
|
|
5ae1ce90ad | ||
|
|
d87b9d25ca | ||
|
|
9bc8d77f39 | ||
|
|
b7e4083e70 | ||
|
|
595419b370 | ||
|
|
442e4f35f0 | ||
|
|
e8b8b33ff6 | ||
|
|
e4d638c73d | ||
|
|
bccb9f794c | ||
|
|
fe0dae74c1 | ||
|
|
b59c23d346 | ||
|
|
6047049fc7 | ||
|
|
08e650a2b4 | ||
|
|
11d4d6562f | ||
|
|
5c9da65606 | ||
|
|
97d89cce35 | ||
|
|
cc45a3dd72 | ||
|
|
870918a788 | ||
|
|
41be66af95 | ||
|
|
9ad252be34 | ||
|
|
1f344ac99e | ||
|
|
8b738c0022 | ||
|
|
57fbf38fb2 | ||
|
|
4cd01bc99a | ||
|
|
fc0cf00b1d | ||
|
|
4333c201f1 | ||
|
|
1f5913a83c | ||
|
|
159c653b4b | ||
|
|
47a2e2aeb9 | ||
|
|
98b0d19363 | ||
|
|
24a0873f6d | ||
|
|
c5fee7c456 | ||
|
|
d11592cadd | ||
|
|
8ef9ac7dba | ||
|
|
a5aa0e2b0a | ||
|
|
f8ae08c0c2 | ||
|
|
72f5d39ace | ||
|
|
5c9801d42c | ||
|
|
c9ee425ed5 | ||
|
|
1871e2b541 | ||
|
|
3e39c55a97 | ||
|
|
e4d6fa0e3b | ||
|
|
9f8dbc91f2 | ||
|
|
0e37747d2c | ||
|
|
a8519a7a53 | ||
|
|
d4159811d2 | ||
|
|
b2ca4995ab | ||
|
|
7876fe94ad | ||
|
|
cc9f7d1ac3 | ||
|
|
94c295f26a | ||
|
|
8c51b5a980 | ||
|
|
4f98f84da9 | ||
|
|
63a429dd64 | ||
|
|
9c3331927b | ||
|
|
3a6edae59d | ||
|
|
75794e2eaa | ||
|
|
24efa6c19a | ||
|
|
7a8c5ecfe1 | ||
|
|
4684f1d4cc | ||
|
|
ef5c31b4c9 | ||
|
|
9d21c5441b | ||
|
|
24fe724e0b | ||
|
|
acf4a3fa99 | ||
|
|
3ed8d968ff | ||
|
|
45c09f3fae | ||
|
|
c93d28050e | ||
|
|
15abb4d590 | ||
|
|
ae98e87222 | ||
|
|
77f6b8cf5f | ||
|
|
573e79a329 | ||
|
|
aaac5d4685 | ||
|
|
b02e353ad1 | ||
|
|
80a269f49a | ||
|
|
75f28fd446 | ||
|
|
ec538c02d8 | ||
|
|
f7b93c8718 | ||
|
|
18ae08e14a | ||
|
|
bffe658026 | ||
|
|
789917cd06 | ||
|
|
8f838433df | ||
|
|
0b84222500 | ||
|
|
aad5c3ae75 | ||
|
|
b586e071fb | ||
|
|
c8e437c45c | ||
|
|
4d034d774d | ||
|
|
4627716aa4 | ||
|
|
847dbbbaf0 | ||
|
|
c011842edf | ||
|
|
aabb7394c3 | ||
|
|
d90064eaee | ||
|
|
ec8dbbffed | ||
|
|
0070520edb | ||
|
|
8e646bc55f | ||
|
|
e97dbf9537 | ||
|
|
0ef3baa87d | ||
|
|
3a777c2a37 | ||
|
|
237f4806bf | ||
|
|
8ec8c0ea76 | ||
|
|
dfe66a2b77 | ||
|
|
a18d6c8159 | ||
|
|
a0b09b6450 | ||
|
|
ca24357611 | ||
|
|
78c16081a4 | ||
|
|
e37dce9d85 | ||
|
|
43694ec87c | ||
|
|
22939d7473 | ||
|
|
9e3a88c41d | ||
|
|
cf4bf9b7a5 | ||
|
|
d065662afc | ||
|
|
70e2538436 | ||
|
|
338ebcd6f0 | ||
|
|
ea8b416e91 | ||
|
|
de81593e98 | ||
|
|
84562f98de | ||
|
|
5520759d9e | ||
|
|
9156a0e400 | ||
|
|
736bf75a50 | ||
|
|
81ef9b5dd2 | ||
|
|
2f18a52118 | ||
|
|
f3ed36840e | ||
|
|
129610821f | ||
|
|
4cd0310516 | ||
|
|
8b245138ee | ||
|
|
4f962bddd8 | ||
|
|
02738ec4ea | ||
|
|
e8a23cf8bc | ||
|
|
39ecfd9900 | ||
|
|
d6a7073a2b | ||
|
|
45eddfb335 | ||
|
|
d4b9b5aba6 | ||
|
|
b1bf742544 | ||
|
|
ebab30d864 | ||
|
|
cdd70ff8fc | ||
|
|
ad4c8ee955 | ||
|
|
2edfe7b8a8 | ||
|
|
3444dad9ce | ||
|
|
b8842f7e55 | ||
|
|
86d85412e1 | ||
|
|
2b56acb39a | ||
|
|
35a40b4930 | ||
|
|
c1f2b2cf93 | ||
|
|
011e9f3b0a | ||
|
|
dddc51b75c | ||
|
|
5187096bf9 | ||
|
|
ae33a1ceb1 | ||
|
|
d225e46e4a | ||
|
|
dcf946b437 | ||
|
|
2a5123f318 | ||
|
|
43d07235c9 | ||
|
|
1fad055286 | ||
|
|
e89cb1b9f7 | ||
|
|
4c7a397dc4 | ||
|
|
047a08c999 | ||
|
|
1d74657bbb | ||
|
|
7085fdbc27 | ||
|
|
4c9c39bd08 | ||
|
|
ec82243ee6 | ||
|
|
65bb93a6c5 | ||
|
|
6e7f28785e | ||
|
|
35654b5355 | ||
|
|
efb2801eeb | ||
|
|
9f5a4c9b22 | ||
|
|
7fc565a1bd | ||
|
|
0eb1d0a84e | ||
|
|
5d26bca55c | ||
|
|
ba69297c33 | ||
|
|
8b5dc0b678 | ||
|
|
5988bba9fb | ||
|
|
a15e6f68dd | ||
|
|
77e7e2bf1c | ||
|
|
1c5c9e2435 | ||
|
|
adfb903469 | ||
|
|
3e739db7fa | ||
|
|
c124fe6d0c | ||
|
|
f0ed4346b2 | ||
|
|
94c8064798 | ||
|
|
95da5f90c7 | ||
|
|
e4a79d643d | ||
|
|
27c7d0c95b | ||
|
|
cf0464c263 | ||
|
|
05a8a9ee28 | ||
|
|
6268db643c | ||
|
|
fd98d231e4 | ||
|
|
b1ab48b9fc | ||
|
|
e4e3294363 | ||
|
|
92649ba494 | ||
|
|
9afa1f7fb9 | ||
|
|
c253b7769e | ||
|
|
0efe343494 | ||
|
|
f3c9b4fb03 | ||
|
|
26c31db75e | ||
|
|
84335b9580 | ||
|
|
e8b2c57610 | ||
|
|
3d49136e27 | ||
|
|
5e22ca77ec | ||
|
|
b6e8133a4d | ||
|
|
02a22c12ea | ||
|
|
cd4e6b35b3 | ||
|
|
4abf5be9ce | ||
|
|
9ba6fc9279 | ||
|
|
fe917ba7f4 | ||
|
|
2c568603f6 | ||
|
|
05db8ce6c8 | ||
|
|
51422e3ee8 | ||
|
|
489f58011b | ||
|
|
0ef3c10931 | ||
|
|
1759b0826e | ||
|
|
35be80f789 | ||
|
|
5f3c9cca11 | ||
|
|
c29e7619eb | ||
|
|
a265417727 | ||
|
|
b69af164f7 | ||
|
|
ff61bb509c | ||
|
|
f02b99c709 | ||
|
|
c8ba51581f | ||
|
|
29f1a9208e | ||
|
|
542cf9b6e1 | ||
|
|
8b954dc381 | ||
|
|
2f7002c5ec | ||
|
|
767ac2547d | ||
|
|
a46aa2d62b | ||
|
|
9219ddaece | ||
|
|
c7c99d8553 | ||
|
|
422c915c1d | ||
|
|
1f04d17e77 | ||
|
|
e3354a0191 | ||
|
|
df3d1a4da9 | ||
|
|
3963fe4384 | ||
|
|
38261ac649 | ||
|
|
e49539fb4c | ||
|
|
3cd96cf558 | ||
|
|
02f18fc21b | ||
|
|
1bcaaa0f0d | ||
|
|
7922a1de28 | ||
|
|
e897c862f2 | ||
|
|
f55040a38b | ||
|
|
2d580e6939 | ||
|
|
fc48008c1c | ||
|
|
4cf2e4024f | ||
|
|
57c7d77af3 | ||
|
|
5652867316 | ||
|
|
c8cf2afb15 | ||
|
|
d08a91b71e | ||
|
|
2c30aecc5b | ||
|
|
770045676f | ||
|
|
68cca0e114 | ||
|
|
0a1b775ed6 | ||
|
|
54a101acbe | ||
|
|
db1af07d72 | ||
|
|
ff82f75023 | ||
|
|
9ae54786e4 | ||
|
|
22ff760f0b | ||
|
|
86fe6ac3a8 | ||
|
|
3dccd89c18 | ||
|
|
9f52e23158 | ||
|
|
aed3307214 | ||
|
|
ef3c7bb6a2 | ||
|
|
0a887c29f1 | ||
|
|
e1410775fb | ||
|
|
f0ba17a19b | ||
|
|
a7a790416e | ||
|
|
fe5c4df079 | ||
|
|
1376e5de92 | ||
|
|
7f5b1a402c | ||
|
|
22573d238b | ||
|
|
32859d9fc2 | ||
|
|
597d28b505 | ||
|
|
94e8cf1de9 | ||
|
|
33d6205e20 | ||
|
|
1b12800b8f | ||
|
|
13d11b037a | ||
|
|
0ca0854cac | ||
|
|
1726c71649 | ||
|
|
fd8c29f981 | ||
|
|
e07ee559a0 | ||
|
|
097107bd0b | ||
|
|
b40b152b87 | ||
|
|
3c7fef68c0 | ||
|
|
b2322ae873 | ||
|
|
e3f137875b | ||
|
|
71fcf45d73 | ||
|
|
652b68a5a0 | ||
|
|
3e0401de1c | ||
|
|
c164024f38 | ||
|
|
bd1f1e8699 | ||
|
|
7ee6efab74 | ||
|
|
3788e90644 | ||
|
|
8e65d93d6d | ||
|
|
4901668f13 | ||
|
|
f98940e40a | ||
|
|
49fe4d081c | ||
|
|
3054b36a8d | ||
|
|
b888158907 | ||
|
|
173f71dca6 | ||
|
|
37a931feb4 | ||
|
|
79f5c7fbda | ||
|
|
bf3f111ca4 | ||
|
|
9a2a5d3155 | ||
|
|
2a7c61cd6d | ||
|
|
51787d68b9 | ||
|
|
33eb0db6f8 | ||
|
|
a0b2727c59 | ||
|
|
d1b8f53711 | ||
|
|
27b5bfe9b1 | ||
|
|
ea91b10086 | ||
|
|
08da777b33 | ||
|
|
345657ab32 | ||
|
|
1b605ade94 | ||
|
|
b11fa372b1 | ||
|
|
662ebece71 | ||
|
|
6b6e8dc83e | ||
|
|
d215149c7c | ||
|
|
895fc0911a | ||
|
|
754527edfd | ||
|
|
f0217edef1 | ||
|
|
8f1798cc6f | ||
|
|
631bda395d | ||
|
|
791d02a753 | ||
|
|
54b3f92951 | ||
|
|
45de0599d7 | ||
|
|
331ecdc2e7 | ||
|
|
339a7640a8 | ||
|
|
0478dbdd1f | ||
|
|
38b0e8a777 | ||
|
|
fe9f1add6f | ||
|
|
ae9179f412 | ||
|
|
4c35a76cdb | ||
|
|
8ca3428fb6 | ||
|
|
7369500bb7 | ||
|
|
45702e319b | ||
|
|
813468bfe6 | ||
|
|
78192308e1 | ||
|
|
cb72390b57 | ||
|
|
71b2eeef67 | ||
|
|
57c8590b21 | ||
|
|
f8ad0a0923 | ||
|
|
7c443ab108 | ||
|
|
0d645757e7 | ||
|
|
dd37c2ea86 | ||
|
|
d3032bfc21 | ||
|
|
bd6ecdfa6f | ||
|
|
3558e70722 | ||
|
|
a579e9273b | ||
|
|
21369bec95 | ||
|
|
d119d10569 | ||
|
|
38988c005c | ||
|
|
8cc4b588b2 | ||
|
|
12607abb33 | ||
|
|
562f17ea4b | ||
|
|
0aea9b7709 | ||
|
|
c0afe96b80 | ||
|
|
5c919cd0de | ||
|
|
f555c93c11 | ||
|
|
cbb7cd16d0 | ||
|
|
4d074b5414 | ||
|
|
dfd22b2b07 | ||
|
|
6edaef9598 | ||
|
|
f63e946f04 | ||
|
|
add5cc8b56 | ||
|
|
2a4e830bee | ||
|
|
eb87232472 | ||
|
|
52c3031a82 | ||
|
|
df471e87eb | ||
|
|
ec6fae5d1a | ||
|
|
cb422a9a02 | ||
|
|
f91bac7b31 | ||
|
|
d542921ff7 | ||
|
|
ad693d67b2 | ||
|
|
350932e9c0 | ||
|
|
4e98d96755 | ||
|
|
c17a9eb5f1 | ||
|
|
252ed4c1ae | ||
|
|
f9fd634fae | ||
|
|
c17c81254e | ||
|
|
5ead61dc7b | ||
|
|
e403db5877 | ||
|
|
32874fa848 | ||
|
|
b90f383cfe | ||
|
|
eb65984368 | ||
|
|
10e0d34140 | ||
|
|
f4b00d3c64 | ||
|
|
cc0b780412 | ||
|
|
fbbbe4ec87 | ||
|
|
1372d62186 | ||
|
|
a69936de74 | ||
|
|
f5dfa1e9c3 | ||
|
|
5fb21c2159 | ||
|
|
132f61e900 | ||
|
|
0e9be8eea0 | ||
|
|
96f5f66c26 | ||
|
|
bbed4d50ab | ||
|
|
4b7ee8267b | ||
|
|
f6a745a4c2 | ||
|
|
a23a5505c4 | ||
|
|
21030f0a4f | ||
|
|
d21824cbae | ||
|
|
124786ad1b | ||
|
|
f81daac9c0 | ||
|
|
db8e8392fa | ||
|
|
5bc2f87d3e | ||
|
|
de35c90847 | ||
|
|
bc813fddcc | ||
|
|
13c91f5fce | ||
|
|
ac4690d74b | ||
|
|
a1a8f17617 | ||
|
|
12be852a43 | ||
|
|
440fbef79b | ||
|
|
e1c221a4d5 | ||
|
|
e1f1c82d4e | ||
|
|
3c1b82255e | ||
|
|
6bd47b54df | ||
|
|
3261a45ec1 | ||
|
|
0ac116bb4e | ||
|
|
221e4ff6fe | ||
|
|
fe80499f9c | ||
|
|
d3d1f3ab60 | ||
|
|
264b888ef2 | ||
|
|
ba270e09a4 | ||
|
|
8281ee1520 | ||
|
|
75aab4e9d2 | ||
|
|
b532a47e4a | ||
|
|
77a3d683e3 | ||
|
|
c132d0e1fe | ||
|
|
1a6348f113 | ||
|
|
89ac6ab594 | ||
|
|
3d1012b73b | ||
|
|
c98ad79e68 | ||
|
|
82460b0da3 | ||
|
|
0bdc57a14a | ||
|
|
33780a09df | ||
|
|
a9c9d5ca4b | ||
|
|
ab07dbdb9d | ||
|
|
6dd6750985 | ||
|
|
59aa0f43d5 | ||
|
|
04ca6a4307 | ||
|
|
c7cbe11ba4 | ||
|
|
4794093aba | ||
|
|
46e300b2c5 | ||
|
|
c693e52f6c | ||
|
|
4e2ec09f9a | ||
|
|
cdbae456d5 | ||
|
|
379177d2f4 | ||
|
|
fb193d6172 | ||
|
|
16234bb713 | ||
|
|
3f14e649b5 | ||
|
|
c2e8062f84 | ||
|
|
5d3fef21b0 | ||
|
|
b64e1b4a49 | ||
|
|
89f414b185 | ||
|
|
47e13cfdf4 | ||
|
|
48d3ce46d8 | ||
|
|
89c8449ec0 | ||
|
|
331fcb633e | ||
|
|
bffc2233a0 | ||
|
|
393b5d48b2 | ||
|
|
6006cdff2c | ||
|
|
d6b10465f3 | ||
|
|
b3cf5c4f5f | ||
|
|
3862f2f022 | ||
|
|
38ab22bf1d | ||
|
|
ce16f7689d | ||
|
|
b06a329466 | ||
|
|
c5b24f3850 | ||
|
|
103b956581 | ||
|
|
63361fc56e | ||
|
|
1e9e334929 | ||
|
|
f30d71b0c5 | ||
|
|
fee4aba9ec | ||
|
|
f1960273a0 | ||
|
|
778564e63b | ||
|
|
cf6a69da27 | ||
|
|
960b2ed023 | ||
|
|
74420550e6 | ||
|
|
cb5887b376 | ||
|
|
41b40157d8 | ||
|
|
b11b693c08 | ||
|
|
256eb4bba0 | ||
|
|
77804b4d38 | ||
|
|
8c9ca7a1b3 | ||
|
|
9d055f8c13 | ||
|
|
3dacd87dfb | ||
|
|
691fbb0c42 | ||
|
|
c28a6eef3b | ||
|
|
17fed3fedd | ||
|
|
1448cc56fc | ||
|
|
074689b5de | ||
|
|
8dd612a0a0 | ||
|
|
22fdbba0b5 | ||
|
|
39b787670b | ||
|
|
a221278c05 | ||
|
|
5f26b9ec66 | ||
|
|
48778d0a77 | ||
|
|
42d2cbad41 | ||
|
|
cb82c42e35 | ||
|
|
f13fb330ed | ||
|
|
d4bae48ca2 | ||
|
|
590ad964b1 | ||
|
|
d4595df8a4 | ||
|
|
7b642bcbb4 | ||
|
|
ca26596695 | ||
|
|
88cf5e5d98 | ||
|
|
13f790360d | ||
|
|
70daadf987 | ||
|
|
9d5004db1c | ||
|
|
ea82bfcced | ||
|
|
00a502942e | ||
|
|
2031bc7fc4 | ||
|
|
3adb22e971 | ||
|
|
331ea5116f | ||
|
|
1da5a33f88 | ||
|
|
6c87724af8 | ||
|
|
c7a5ff5e82 | ||
|
|
abf2fcf820 | ||
|
|
644c22b08f | ||
|
|
c54024a5e6 | ||
|
|
97093fdf81 | ||
|
|
50c4f60c68 | ||
|
|
f0fb3b78d1 | ||
|
|
9b06178f35 | ||
|
|
a01c96140b | ||
|
|
02530172e7 | ||
|
|
447d803800 | ||
|
|
6b04901c4d | ||
|
|
7fb29621c3 | ||
|
|
b032fce962 | ||
|
|
ce879122bb | ||
|
|
2fa16708b7 | ||
|
|
54bc8608e3 | ||
|
|
706a7802cc | ||
|
|
9dc01cf540 | ||
|
|
8943ad5966 | ||
|
|
deb7a1c9c0 | ||
|
|
96a5445d44 | ||
|
|
d693065afb | ||
|
|
bdeee35669 | ||
|
|
62b3deb90d | ||
|
|
9df9ff59e0 | ||
|
|
23a3271c06 | ||
|
|
f4a5aa2e94 | ||
|
|
bdd54eed1c | ||
|
|
c6a20a72f2 | ||
|
|
d7a54b3632 | ||
|
|
be6a3d0f10 | ||
|
|
e9125a3a22 | ||
|
|
c27a60658f | ||
|
|
8f2bc6e028 | ||
|
|
a6b78cbbee | ||
|
|
182a7076fd | ||
|
|
17a9b22dce | ||
|
|
f190d12802 | ||
|
|
b12dd526f9 | ||
|
|
473d555dc1 | ||
|
|
fa9208ccdd | ||
|
|
4aa088eb2f | ||
|
|
8f8147d646 | ||
|
|
e637dd2390 | ||
|
|
c90960fc88 | ||
|
|
da86a1c9f2 | ||
|
|
0adb789238 | ||
|
|
15082a178b | ||
|
|
4a0db26c36 | ||
|
|
ad3ea636d5 | ||
|
|
6a238b0514 | ||
|
|
e6d7e7e329 | ||
|
|
f942aba855 | ||
|
|
2f34132275 | ||
|
|
663b2be065 | ||
|
|
a1e4d676c3 | ||
|
|
6f28d21207 | ||
|
|
9f115e056e | ||
|
|
8352ba4af4 | ||
|
|
9b06310cbe | ||
|
|
77fe33e57f | ||
|
|
df58eb9bc7 | ||
|
|
2d0084308d | ||
|
|
7efa40966a | ||
|
|
6d644dc764 | ||
|
|
b0de0b1176 | ||
|
|
c72d473e96 | ||
|
|
c8a91bd46f | ||
|
|
498f19a6a1 | ||
|
|
c7a2138ece | ||
|
|
4078902543 | ||
|
|
9e38ed9a39 | ||
|
|
183cabc77d | ||
|
|
b582e481c6 | ||
|
|
ad39931e87 | ||
|
|
1ae22e1365 | ||
|
|
b748ddfe06 | ||
|
|
e52f5f1b63 | ||
|
|
bda4b326ab | ||
|
|
70ddf32719 | ||
|
|
3edba7b662 | ||
|
|
f74ef650ac | ||
|
|
f093c3d78b | ||
|
|
d933f33bdb | ||
|
|
813d62005d | ||
|
|
411de9bddf | ||
|
|
bd28945374 | ||
|
|
1e4c3751e1 | ||
|
|
5b6f47cd0f | ||
|
|
bec8c5bf4c | ||
|
|
15495bb200 | ||
|
|
999f278971 | ||
|
|
7ca1d35a4e | ||
|
|
2117fe414e | ||
|
|
7d8c51181d | ||
|
|
c30211cb27 | ||
|
|
901da118e5 | ||
|
|
f11757e43a | ||
|
|
3f143317a6 | ||
|
|
45d7312dfc | ||
|
|
26774eb045 | ||
|
|
6789d247e2 | ||
|
|
462bc3d707 | ||
|
|
e1755ea6a8 | ||
|
|
b4a7e4697e | ||
|
|
cd61b1d045 | ||
|
|
24dc36ba4c | ||
|
|
e8e4f1777d | ||
|
|
ae38a26af3 | ||
|
|
8ee94dd7aa | ||
|
|
e741a29d36 | ||
|
|
be1d275151 | ||
|
|
31c9e26e2e | ||
|
|
20ed1ada03 | ||
|
|
891214fa72 | ||
|
|
e819e285e2 | ||
|
|
171c175e54 | ||
|
|
675cbce8cb | ||
|
|
4f1398f773 | ||
|
|
ae89e399a3 | ||
|
|
2c9716c64c | ||
|
|
bc58245abf | ||
|
|
8c4aa8517e | ||
|
|
c0b7a54bb9 | ||
|
|
6b32bb635d | ||
|
|
691de22ae3 | ||
|
|
e64b2d3372 | ||
|
|
e190af9d87 | ||
|
|
8d14463b18 | ||
|
|
04977ef721 | ||
|
|
d84e6875c5 | ||
|
|
80678ae7bc | ||
|
|
482bdab0e0 | ||
|
|
b2623b9841 | ||
|
|
9ae40d64f0 | ||
|
|
cef097b7b7 | ||
|
|
b840334ad2 | ||
|
|
acff683e8e | ||
|
|
c5332de86d | ||
|
|
90ecf14a0a | ||
|
|
4945282369 | ||
|
|
ca532d23f0 | ||
|
|
a509b6a21c | ||
|
|
46229473cb | ||
|
|
65be2448dc | ||
|
|
be74806044 | ||
|
|
b488666c1e | ||
|
|
d1acaea611 | ||
|
|
db6e5ce7cf | ||
|
|
d56179df17 | ||
|
|
850100c9c2 | ||
|
|
0725999f0a | ||
|
|
cb2d8259f2 | ||
|
|
61a1f3d817 | ||
|
|
63f111b7f3 | ||
|
|
e061eb3003 | ||
|
|
29daa58222 | ||
|
|
340cc02171 | ||
|
|
b738d1960a | ||
|
|
38f5b780d7 | ||
|
|
fa9dac29e8 | ||
|
|
afc432042f | ||
|
|
21cb29baf0 | ||
|
|
e8b5001cfe | ||
|
|
849c1e46a2 | ||
|
|
ebad6cde36 | ||
|
|
f920b3945e | ||
|
|
178028a70a | ||
|
|
5e54d3e41a | ||
|
|
f0af8726e3 | ||
|
|
57f2fe77ea | ||
|
|
d56ca25089 | ||
|
|
d39ce17dea | ||
|
|
373a68ec8b | ||
|
|
5613758ee3 | ||
|
|
2102f86909 | ||
|
|
d5ea785de7 | ||
|
|
9edd28d2ed | ||
|
|
7698af5178 | ||
|
|
52ae451f5c | ||
|
|
9254443cd4 | ||
|
|
4e4bc7b90f | ||
|
|
c7e0f2e196 | ||
|
|
acabaab6ac | ||
|
|
b0a249f338 | ||
|
|
0cb5d5cc5a | ||
|
|
9208c87f91 | ||
|
|
0081ce4a75 | ||
|
|
7850f49963 | ||
|
|
c72ee41142 | ||
|
|
bf5dee955d | ||
|
|
3df23a148a | ||
|
|
0a1b55c296 | ||
|
|
14b8efe4bb | ||
|
|
64162efebd | ||
|
|
faf5e1de51 | ||
|
|
0d7b1a7dc7 | ||
|
|
fa63bc6b78 | ||
|
|
379bfd062f | ||
|
|
49108c23f0 | ||
|
|
4475060268 | ||
|
|
4f269e336d | ||
|
|
4464b13163 | ||
|
|
215d5f68b0 | ||
|
|
281f4e04ee | ||
|
|
17a3f9691d | ||
|
|
4fde6ee7af | ||
|
|
040b1b06d5 | ||
|
|
b16ea8b719 | ||
|
|
cc22847bc3 | ||
|
|
3702e17b2e | ||
|
|
7abc220fb3 | ||
|
|
4fc9a906f6 | ||
|
|
5de83c9805 | ||
|
|
f71d904a9b | ||
|
|
318ded4198 | ||
|
|
f1874b211f | ||
|
|
c60ffd7fd9 | ||
|
|
dc57282168 | ||
|
|
3c336e179f | ||
|
|
6bda57da5d | ||
|
|
9a16001e51 | ||
|
|
34870e899f | ||
|
|
d0653f72e2 | ||
|
|
64748b7b1d | ||
|
|
7163c8d048 | ||
|
|
d0ec991bb2 | ||
|
|
d458af4454 | ||
|
|
9e9e7c33ae | ||
|
|
ce7de5ed30 | ||
|
|
776d8edf52 | ||
|
|
5f21385e41 | ||
|
|
94fed93f54 | ||
|
|
a950e4816d | ||
|
|
c87c66efb1 | ||
|
|
5a5a0006fe | ||
|
|
60b48a6830 | ||
|
|
5e41350588 | ||
|
|
ff9f5b62ac | ||
|
|
882913f0ca | ||
|
|
2062f7e97b | ||
|
|
445c83a60d | ||
|
|
1891cfd79a | ||
|
|
06d5a7b2bf | ||
|
|
5af8a8aa4c | ||
|
|
dc6b085d8b | ||
|
|
00759f777e | ||
|
|
95ac0e61b2 | ||
|
|
6c5884853f | ||
|
|
7578ef889f | ||
|
|
da254af8d5 | ||
|
|
98123dc422 | ||
|
|
466909b3d9 | ||
|
|
0d4305192a | ||
|
|
9e61b9f696 | ||
|
|
491539ff32 | ||
|
|
4c29a13a6e | ||
|
|
b66e1bdb9e | ||
|
|
7312de6bc2 | ||
|
|
1d6bcda014 | ||
|
|
5a747bad7d | ||
|
|
9542783a7e | ||
|
|
a59639413d | ||
|
|
d5eb92a071 | ||
|
|
994cde57af | ||
|
|
238a5809bf | ||
|
|
49fa65c0dd | ||
|
|
49123f169c | ||
|
|
4dc64c387f | ||
|
|
98a63711dd | ||
|
|
cb95cf4745 | ||
|
|
acd48fa61d | ||
|
|
cb7abcbaea | ||
|
|
793c974480 | ||
|
|
78a321925f | ||
|
|
643572595e | ||
|
|
fb4d462325 | ||
|
|
c0df07c86f | ||
|
|
e918d945f2 | ||
|
|
0ee5743853 | ||
|
|
486d69da5f | ||
|
|
005b4b7609 | ||
|
|
a0fd065dcf | ||
|
|
751384cb5c | ||
|
|
6ac672b4a3 | ||
|
|
a89502be9f | ||
|
|
04e7b3bd4d | ||
|
|
9ebb37b6a5 | ||
|
|
052a7e3deb | ||
|
|
108c0f6bb8 | ||
|
|
6ed89b6ca5 | ||
|
|
27ccaffb37 | ||
|
|
a001babad2 | ||
|
|
32a76c5255 | ||
|
|
099f797975 | ||
|
|
b7df3e24b4 | ||
|
|
8323092a0c | ||
|
|
e5af46d3fb | ||
|
|
a6743588b6 | ||
|
|
90cbcd2dfd | ||
|
|
a36b7afba5 | ||
|
|
4c91ade61d | ||
|
|
f2a17b9b70 | ||
|
|
b71b9ccb57 | ||
|
|
8b0af19351 | ||
|
|
9f7c473376 | ||
|
|
0206767478 | ||
|
|
1a3378e0f5 | ||
|
|
5c3eee34a1 | ||
|
|
2b5017e610 | ||
|
|
e755c7fdcc | ||
|
|
8d463b33cd | ||
|
|
7d9b21a874 | ||
|
|
a118921b21 | ||
|
|
a1aefd2330 | ||
|
|
8b511379ac | ||
|
|
c1593f856d | ||
|
|
93f1d7643d | ||
|
|
ce4dfb4296 | ||
|
|
2e5f5010f7 | ||
|
|
7c588c2e30 | ||
|
|
43be4cf2b5 | ||
|
|
8b457b9b66 | ||
|
|
25efee2e62 | ||
|
|
546c91a940 | ||
|
|
85ebc5f7bd | ||
|
|
e002b0e25f | ||
|
|
4944383769 | ||
|
|
68c6f0ff07 | ||
|
|
5078152292 | ||
|
|
9837b40330 | ||
|
|
cb645c9a74 | ||
|
|
87573a9fef | ||
|
|
7c486e27ba | ||
|
|
4a3bdc340d | ||
|
|
903ee0622d | ||
|
|
d33ad7600b | ||
|
|
9ec35a2348 | ||
|
|
6da13c6486 | ||
|
|
87a47a5ca0 | ||
|
|
c682f1c16a | ||
|
|
591075a8ed | ||
|
|
41701673a0 | ||
|
|
55f0d4ddd8 | ||
|
|
6d66fcaa57 | ||
|
|
26e79ca889 | ||
|
|
62eb247c1e | ||
|
|
c5fd583b2c | ||
|
|
117db3e11c | ||
|
|
3f82fd2f37 | ||
|
|
e9c46afcf7 | ||
|
|
3234fa15ef | ||
|
|
7ef84df852 | ||
|
|
4e2884b509 | ||
|
|
03100020ab | ||
|
|
8bfb5cc5e9 | ||
|
|
cf6d07aafa | ||
|
|
85c3179dbd | ||
|
|
bfbca34eb0 | ||
|
|
b73edc0564 | ||
|
|
6ba90e3a50 | ||
|
|
e8edbad18c | ||
|
|
c86fec5307 | ||
|
|
6e476255ca | ||
|
|
27af9b6b06 | ||
|
|
f8208fa961 | ||
|
|
87b9cb49ad | ||
|
|
b2da0772e6 | ||
|
|
4f73e0850e | ||
|
|
b6a39db627 | ||
|
|
3a83b06572 | ||
|
|
fe5bf01b25 | ||
|
|
5559ec903b | ||
|
|
18750028b2 | ||
|
|
6b88648c67 | ||
|
|
58ee803cb4 | ||
|
|
894ff73c7d | ||
|
|
8031f0ed7f | ||
|
|
3a56b5da47 | ||
|
|
fedcb6d26a | ||
|
|
eed3c5e543 | ||
|
|
e26ab67e25 | ||
|
|
e77b7427b4 | ||
|
|
475e4207cc | ||
|
|
71b2eed32c | ||
|
|
6cf50e6579 | ||
|
|
69468708e2 | ||
|
|
5da5678e64 | ||
|
|
a428e7f618 | ||
|
|
0eb5a0a539 | ||
|
|
a1c1ff9981 | ||
|
|
2029ade18c | ||
|
|
5f8f474c0c | ||
|
|
f705f9b275 | ||
|
|
91e706ec1f | ||
|
|
dcf351f847 | ||
|
|
06744b664a | ||
|
|
d3049d9c89 | ||
|
|
1f2abb9c0f | ||
|
|
9f0d7e50a5 | ||
|
|
5f262a8f11 | ||
|
|
f62bc6a2e5 | ||
|
|
d7e4bc1379 | ||
|
|
cd2d6575c6 | ||
|
|
b46f656d17 | ||
|
|
58fd602bbd | ||
|
|
9cc95704cd | ||
|
|
5f5a3dbb0a | ||
|
|
f8f53df4ec | ||
|
|
56b85cc63c | ||
|
|
90aca97e66 | ||
|
|
6ce2a52c5f | ||
|
|
1f56312132 | ||
|
|
3aa290cddb | ||
|
|
1d1eb4fedb | ||
|
|
266ff41386 | ||
|
|
02331e5536 | ||
|
|
621c51589a | ||
|
|
4a58e859a4 | ||
|
|
48d393d8f5 | ||
|
|
321552d998 | ||
|
|
a985a1f9f5 | ||
|
|
d532a36739 | ||
|
|
b631b5927b | ||
|
|
adb39ceb98 | ||
|
|
84b91b19ca | ||
|
|
aaea68d3d6 | ||
|
|
2accba2e71 | ||
|
|
8f4f4eb5ae | ||
|
|
c5aabb3c6e | ||
|
|
60c2d136e1 | ||
|
|
cae6ec16ba | ||
|
|
30601c77d4 | ||
|
|
b0f4cf3c9c | ||
|
|
c41dfcf6ad | ||
|
|
2e10555f03 | ||
|
|
6b2ee0fcf3 | ||
|
|
0dbdbffba7 | ||
|
|
9c5dd8d767 | ||
|
|
fff0ebb5f3 | ||
|
|
d34275150c | ||
|
|
d04eb977c2 | ||
|
|
fb4928b2f5 | ||
|
|
5c39420d91 | ||
|
|
14fcfd8a40 | ||
|
|
ff19dd94f9 | ||
|
|
b6913ff9b3 | ||
|
|
4573fd3069 | ||
|
|
6cf6d9f7e1 | ||
|
|
28e35a64ea | ||
|
|
091818483a | ||
|
|
3b43556c41 | ||
|
|
ed39c66715 | ||
|
|
446b0e4e5e | ||
|
|
6e3e8318d0 | ||
|
|
17b8b660f0 | ||
|
|
40bceea68a | ||
|
|
b655c17c09 | ||
|
|
a3813f94fc | ||
|
|
c70540a825 | ||
|
|
9caffe330b | ||
|
|
8d8c5da812 | ||
|
|
55bb766c15 | ||
|
|
c18df68ead | ||
|
|
3996e94c39 | ||
|
|
1bdf017f9e | ||
|
|
93790c1dc6 | ||
|
|
ba8c11b25d | ||
|
|
ca57edfa0b | ||
|
|
ccb6545c32 | ||
|
|
d146dbc9d7 | ||
|
|
b4eaaccc88 | ||
|
|
c9ed9e74f2 | ||
|
|
587c7c70f5 | ||
|
|
749ff021b6 | ||
|
|
85c5765c00 | ||
|
|
9e76078939 | ||
|
|
334e0e1ca6 | ||
|
|
dce4519995 | ||
|
|
45bbae80e7 | ||
|
|
d37709a922 | ||
|
|
2560ae9bc1 | ||
|
|
2bdd3ca353 | ||
|
|
8a8aab1aae | ||
|
|
85d790ff79 | ||
|
|
68afc96a9f | ||
|
|
94efaa7675 | ||
|
|
180af74a50 | ||
|
|
88af0d3509 | ||
|
|
97633f7bed | ||
|
|
053e016388 | ||
|
|
2d61e0270e | ||
|
|
3a23afb0bc | ||
|
|
470f12ff46 | ||
|
|
4422de0c6c | ||
|
|
8a708f52f7 | ||
|
|
bcefc17631 | ||
|
|
daf19e241e | ||
|
|
b5f5b1fdf9 | ||
|
|
801b718953 | ||
|
|
f571658aa4 | ||
|
|
5d233b8c09 | ||
|
|
00724597f4 | ||
|
|
c659940ea8 | ||
|
|
23539eb55c | ||
|
|
e69bf418de | ||
|
|
0e1fcd38bb | ||
|
|
e74186565d | ||
|
|
7e54281e26 | ||
|
|
15f512bdee | ||
|
|
ecfe0283e2 | ||
|
|
3b874f759c | ||
|
|
9c9b4ed4e0 | ||
|
|
4f6d80c602 | ||
|
|
b50542531d | ||
|
|
8ab28d1d12 | ||
|
|
9567da22f8 | ||
|
|
36814b7681 | ||
|
|
82235e6c6f | ||
|
|
a8310f35f2 | ||
|
|
85989af031 | ||
|
|
cf9ffd16dd | ||
|
|
0602537cce | ||
|
|
24e32420b7 | ||
|
|
39c494260b | ||
|
|
761b9c9290 | ||
|
|
27686d8c2f | ||
|
|
d2b007005d | ||
|
|
f1ef30a5bb | ||
|
|
f1d9437c55 | ||
|
|
bcba5075e8 | ||
|
|
d6e8b0263c | ||
|
|
9aba617bad | ||
|
|
c24f7b1391 | ||
|
|
d4e27b635f | ||
|
|
c996d2870c | ||
|
|
bbd59f8a22 | ||
|
|
d3d359e757 | ||
|
|
ae763ea93d | ||
|
|
236b9e9761 | ||
|
|
e42c9dfd84 | ||
|
|
bebf5b291b | ||
|
|
1e3dcd203d | ||
|
|
cc7da63dec | ||
|
|
1baa2a2558 | ||
|
|
e63ff77b15 | ||
|
|
6cf9468477 | ||
|
|
b277bc8750 | ||
|
|
ba9da64207 | ||
|
|
9cb9f9c80b | ||
|
|
7a65df7636 | ||
|
|
eab46d547d | ||
|
|
3dd552c4a2 | ||
|
|
23bb045a72 | ||
|
|
7c834ad118 | ||
|
|
8e2617ab8d | ||
|
|
24fcae4f49 | ||
|
|
ce18674d88 | ||
|
|
6b8d9b5c36 | ||
|
|
81bf95763c | ||
|
|
2d64077fd0 | ||
|
|
38faebcf20 | ||
|
|
48d177a9d0 | ||
|
|
3b3a7f7354 | ||
|
|
99cd2818a1 | ||
|
|
5765e099a6 | ||
|
|
175d59ecba | ||
|
|
3bd3d01968 | ||
|
|
85e2a6bb45 | ||
|
|
84efd239a5 | ||
|
|
6a69813326 | ||
|
|
2c9dcc3913 | ||
|
|
20ea1ca018 | ||
|
|
0abde90933 | ||
|
|
e01b69198a | ||
|
|
53cd9d2403 | ||
|
|
3d0f5fc078 | ||
|
|
54eedcc739 | ||
|
|
ae6f5844da | ||
|
|
1bea845ceb | ||
|
|
d581582339 | ||
|
|
4eabc1992e | ||
|
|
316eb24bbb | ||
|
|
f0a8824efc | ||
|
|
345a5d5646 | ||
|
|
464679c78b | ||
|
|
28eeec1cf4 | ||
|
|
7d0dce3267 | ||
|
|
9e29625207 | ||
|
|
a767da4f3f | ||
|
|
7bd96c2876 | ||
|
|
70fd64dcd6 | ||
|
|
bb2822f4b5 | ||
|
|
ad21108b63 | ||
|
|
e6808a787c | ||
|
|
1fb2762725 | ||
|
|
cce55941d3 | ||
|
|
6c8d95e0e2 | ||
|
|
216a178b28 | ||
|
|
6594a54a95 | ||
|
|
a9a4cf061a | ||
|
|
b7f0e204cb | ||
|
|
e6a15f233b | ||
|
|
e0edb596ea | ||
|
|
f2fb77c15a | ||
|
|
772a3a97eb | ||
|
|
6c310836a1 | ||
|
|
75416a3016 | ||
|
|
ebef78a13e | ||
|
|
e71baca39b | ||
|
|
18eb210313 | ||
|
|
7d38a5e1f9 | ||
|
|
4386077e2d | ||
|
|
49dbfd2131 | ||
|
|
a80fce5ac1 | ||
|
|
891b981cab | ||
|
|
2dd87b8384 | ||
|
|
062eb85075 | ||
|
|
e1f6802f5f | ||
|
|
6cfcd50f12 | ||
|
|
bcadb0b3b3 | ||
|
|
0df561f873 | ||
|
|
238fc24684 | ||
|
|
936855c81c | ||
|
|
61ad9d4651 | ||
|
|
f07f6a26a8 | ||
|
|
4a5a56f8ef | ||
|
|
7d44bba95c | ||
|
|
6e6f1045b8 | ||
|
|
5dd3221759 | ||
|
|
09edb467f6 | ||
|
|
ffb187ae15 | ||
|
|
b4a8be07f3 | ||
|
|
4968a2abc5 | ||
|
|
91159da30d | ||
|
|
c9ad61b4fb | ||
|
|
3f0dcd8c0e | ||
|
|
e1eb41fe77 | ||
|
|
498ab23355 | ||
|
|
5d6a053f98 | ||
|
|
929aeebf12 | ||
|
|
00bd947385 | ||
|
|
d4ef86afc0 | ||
|
|
1856cad816 | ||
|
|
91e2d1d2a0 | ||
|
|
f29f30dce0 | ||
|
|
e7ba6ef492 | ||
|
|
de4016dcff | ||
|
|
bbeb382cbb | ||
|
|
385c166830 | ||
|
|
410e6ff203 | ||
|
|
8b47c4e307 | ||
|
|
6d1b42bedb | ||
|
|
f0a4bd28b6 | ||
|
|
2879684f21 | ||
|
|
0437d0abea | ||
|
|
0286f588bf | ||
|
|
042fb76837 | ||
|
|
795e66eac9 | ||
|
|
aae0615ffd | ||
|
|
8127a79cb1 | ||
|
|
057ca497dd | ||
|
|
66b1611649 | ||
|
|
7f5220a6ca | ||
|
|
e41e26717b | ||
|
|
7a8184d206 | ||
|
|
13bf2f19ac | ||
|
|
1d5ebfd0b1 | ||
|
|
dfc11da2ce | ||
|
|
191af2e87b | ||
|
|
0985b82760 | ||
|
|
26f4b5a69a | ||
|
|
5c7a6e278f | ||
|
|
ae1ab8aaaa | ||
|
|
18c25d1b6f | ||
|
|
5888a2c399 | ||
|
|
c00603704e | ||
|
|
786bc4b04f | ||
|
|
5eca20f849 | ||
|
|
0a3a582949 | ||
|
|
08fec0534d | ||
|
|
5bf92c9d3a | ||
|
|
a8bbf7231b | ||
|
|
83c171012d | ||
|
|
229d854607 | ||
|
|
562460606f | ||
|
|
46f70b1cbb | ||
|
|
a547133efe | ||
|
|
cf445898ce | ||
|
|
98f68e46d6 | ||
|
|
27660b271d | ||
|
|
895e374860 | ||
|
|
4c7f051247 | ||
|
|
e68afa53a8 | ||
|
|
cc47ba2404 | ||
|
|
2238fa46ed | ||
|
|
de8b040e31 | ||
|
|
4ffc48d194 | ||
|
|
2433848408 | ||
|
|
e602f7febc | ||
|
|
f607b32938 | ||
|
|
c7a088faa5 | ||
|
|
30f6c0e105 | ||
|
|
38b9fa7b93 | ||
|
|
39a31fc17f | ||
|
|
899a7df14a | ||
|
|
7a8c425103 | ||
|
|
0e8ce59022 | ||
|
|
77ac76a158 | ||
|
|
8108b97050 | ||
|
|
a1c3491dea | ||
|
|
8bba96a84e | ||
|
|
6cd9b25a53 | ||
|
|
0431b1909c | ||
|
|
907665e2e8 | ||
|
|
61e8836fbd | ||
|
|
0e921b5dff | ||
|
|
7ef37d6e17 | ||
|
|
dce227684a | ||
|
|
158e112752 | ||
|
|
ec992c7f5e | ||
|
|
e7d63c7644 | ||
|
|
6464e8fee6 | ||
|
|
047d66a657 | ||
|
|
55c23360d9 | ||
|
|
c378d32c85 | ||
|
|
3d9540c58c | ||
|
|
39724eb916 | ||
|
|
48dddd4ae7 | ||
|
|
9c00fd10de | ||
|
|
9309d0b00f | ||
|
|
038b5d32a3 | ||
|
|
706920ba19 | ||
|
|
39492a0726 | ||
|
|
df1170fea9 | ||
|
|
f0e1d204fa | ||
|
|
8ece0a8a5f | ||
|
|
1373b81e7c | ||
|
|
d3601dd561 | ||
|
|
f685cf1d0c | ||
|
|
d5fcf0c153 | ||
|
|
5f9810070d | ||
|
|
923efa004b | ||
|
|
869e8eab3c | ||
|
|
b51d197117 | ||
|
|
e4f0a8952c | ||
|
|
072ee425f4 | ||
|
|
a4c2819be2 | ||
|
|
2a274f9c19 | ||
|
|
b4d5a20670 | ||
|
|
6339159b04 | ||
|
|
aec019991c | ||
|
|
33e6a17747 | ||
|
|
ecf508ec23 | ||
|
|
a5bcfc0509 | ||
|
|
1899096ff4 | ||
|
|
6e219f5831 | ||
|
|
de1bb5aeb6 | ||
|
|
b52d94273c | ||
|
|
e655c85489 | ||
|
|
dee7210231 | ||
|
|
cbd073ed08 | ||
|
|
09ebc0c163 | ||
|
|
d2ede75c71 | ||
|
|
3e03fef3e3 | ||
|
|
0f583f4b33 | ||
|
|
f175db74a5 | ||
|
|
8d5e37a413 | ||
|
|
8b9b7178a2 | ||
|
|
a2f49063e2 | ||
|
|
f3f34baa73 | ||
|
|
abe9ecd225 | ||
|
|
67409af38d | ||
|
|
b7d1c34aa6 | ||
|
|
92809b95c9 | ||
|
|
b18690cbe2 | ||
|
|
96155365b2 | ||
|
|
3e5067feb1 | ||
|
|
3ec687a0cf | ||
|
|
365034d7dd | ||
|
|
09aa9f87d8 | ||
|
|
97963fb8c9 | ||
|
|
ee1643ce39 | ||
|
|
a82cdcfe48 | ||
|
|
1b439703ff | ||
|
|
4cc5943f90 | ||
|
|
5fad666678 | ||
|
|
e12bf35996 | ||
|
|
d34fccec22 | ||
|
|
429437f1b9 | ||
|
|
c6e7d87960 | ||
|
|
716320f3ca | ||
|
|
1d12b47cb8 | ||
|
|
1bc1ee9e08 | ||
|
|
53f50463bc | ||
|
|
7ab91e660f | ||
|
|
2f0e230522 | ||
|
|
280f674ce9 | ||
|
|
a92c66d512 | ||
|
|
c45eedcb02 | ||
|
|
a9a49345ba | ||
|
|
8d960a2eb9 | ||
|
|
3e623b8959 | ||
|
|
1b1991d53d | ||
|
|
6d0f39d841 | ||
|
|
3087501b6c | ||
|
|
b429319bc0 | ||
|
|
247e855dbf | ||
|
|
1aec645510 | ||
|
|
3ea2038d3d | ||
|
|
942cb5e87e | ||
|
|
37a3a7cdce | ||
|
|
435a27b66a | ||
|
|
b31a7cdcbf | ||
|
|
ac61548e6a | ||
|
|
f5ace0f72a | ||
|
|
e498b73933 | ||
|
|
ff69bdbc6f | ||
|
|
0c1e184cb7 | ||
|
|
e97541dcbc | ||
|
|
7b3eb22865 | ||
|
|
d55f065ce2 | ||
|
|
86af244636 | ||
|
|
2c9e2b2e3c | ||
|
|
33c8bf886e | ||
|
|
ef71a089a6 | ||
|
|
5fc98cce0d | ||
|
|
b9101c3d6a | ||
|
|
6aab0f627c | ||
|
|
6b97673d0a | ||
|
|
5d8c1ce84e | ||
|
|
33c9591a4b | ||
|
|
87e8736823 | ||
|
|
c0da16bfcd | ||
|
|
a4ddc5b3ac | ||
|
|
91e4010039 | ||
|
|
486b6580d8 | ||
|
|
9c4ef27d49 | ||
|
|
33577eaa68 | ||
|
|
d5e19661bd | ||
|
|
799afac05b | ||
|
|
3ba36dc30c | ||
|
|
641024c235 | ||
|
|
d9598db117 | ||
|
|
2e4da07a15 | ||
|
|
40f4411b69 | ||
|
|
c75de0f37c | ||
|
|
74c4c1bf44 | ||
|
|
60a637921c | ||
|
|
22312b3c9c | ||
|
|
2e26e44538 | ||
|
|
24e79ecc68 | ||
|
|
5b532a1812 | ||
|
|
f3867d7f80 | ||
|
|
fb90e47e70 | ||
|
|
68046244dd | ||
|
|
b1507060ad | ||
|
|
ffbd595d88 | ||
|
|
ed5bc1e69c | ||
|
|
9734931f67 | ||
|
|
0048b04540 | ||
|
|
c361932fe2 | ||
|
|
2d8feabe54 | ||
|
|
1b511dd130 | ||
|
|
52024f4d80 | ||
|
|
735fa6287f | ||
|
|
7eb407fe2b | ||
|
|
897d5c58b3 | ||
|
|
dc9086512b | ||
|
|
0029d068c7 | ||
|
|
de388b3dc8 | ||
|
|
fb904d53cd | ||
|
|
600cc02de3 | ||
|
|
946d0cd219 | ||
|
|
4d0b964e36 | ||
|
|
2b12ab4d5a | ||
|
|
8114957e6d | ||
|
|
50edef4ab2 | ||
|
|
e5a991988f | ||
|
|
e85eb6d0f4 | ||
|
|
6949f35f22 | ||
|
|
e0391b93c4 | ||
|
|
4a5e775a2b | ||
|
|
323f019350 | ||
|
|
98053c2d4c | ||
|
|
aab338760c | ||
|
|
ab9a2b1728 | ||
|
|
6a38d3bcf3 | ||
|
|
76f3cbdf4c | ||
|
|
d45d58b6bf | ||
|
|
f32a422330 | ||
|
|
74d4be28dd | ||
|
|
b4a31bd292 | ||
|
|
cc1adf9b38 | ||
|
|
1601b3b6b0 | ||
|
|
61cbdd1a19 | ||
|
|
a3ee6131a3 | ||
|
|
6dfddaa453 | ||
|
|
de696b7092 | ||
|
|
9165233657 | ||
|
|
aa3a417e97 | ||
|
|
996f48fcf0 | ||
|
|
81d83f629f | ||
|
|
5e3b0bf348 | ||
|
|
4a31463299 | ||
|
|
8a5471e175 | ||
|
|
605fd9f8e1 | ||
|
|
2bda43875d | ||
|
|
11edc9e7a7 | ||
|
|
3b9b823511 | ||
|
|
da0ecf59c6 | ||
|
|
e5b1fdf668 | ||
|
|
204fb82975 | ||
|
|
37839e2709 | ||
|
|
dbaedb5995 | ||
|
|
0a832e90bd | ||
|
|
b4e908d04d | ||
|
|
4619d29b78 | ||
|
|
c63b697636 | ||
|
|
06d29d6fda | ||
|
|
c0f7bc4b5e | ||
|
|
7139c9ae59 | ||
|
|
0ae00fc921 | ||
|
|
fe456cb83d | ||
|
|
a8432ed4a4 | ||
|
|
04f910b747 | ||
|
|
1c3de70155 | ||
|
|
b73642f8a8 | ||
|
|
479b497528 | ||
|
|
31b55d3844 | ||
|
|
dbf4e08d09 | ||
|
|
274359e6ee | ||
|
|
8687dcbce1 | ||
|
|
03dfbdb7b1 | ||
|
|
3c8519f245 | ||
|
|
4d2cc3ebdd | ||
|
|
6e2758ae26 | ||
|
|
4637e06ad2 | ||
|
|
764399256c | ||
|
|
f4ca4edc64 | ||
|
|
872a1216a7 | ||
|
|
8c75674591 | ||
|
|
e6244ca204 | ||
|
|
f540362e36 | ||
|
|
2be6699a6a | ||
|
|
09c10492ab | ||
|
|
c8e4b1fc84 | ||
|
|
0de7cece5b | ||
|
|
a3413a6749 | ||
|
|
b104ab9491 | ||
|
|
269c5dce60 | ||
|
|
a39c81c63f | ||
|
|
d699247269 | ||
|
|
7caafb4014 | ||
|
|
f1546abf09 | ||
|
|
3083562f6f | ||
|
|
da2ee70462 | ||
|
|
7e9dda3c5e | ||
|
|
0b96f88875 | ||
|
|
f13ffe2098 | ||
|
|
bca5d26583 | ||
|
|
660bc757f1 | ||
|
|
ca927fe587 | ||
|
|
9df8966f4a | ||
|
|
3429f41489 | ||
|
|
0c7c4924ee | ||
|
|
8f40d6617e | ||
|
|
af9e85bda1 | ||
|
|
717f45d117 | ||
|
|
35c53865fb | ||
|
|
a1d1d6d3d4 | ||
|
|
d17f812827 | ||
|
|
3916758529 | ||
|
|
2396181bc5 | ||
|
|
6e8640bf1b | ||
|
|
c2c7c7bd9a | ||
|
|
071a1c4adb | ||
|
|
d5b2dda2e8 | ||
|
|
2ac281eb3e | ||
|
|
5e81543448 | ||
|
|
b32f925468 | ||
|
|
fdeb6bcae0 | ||
|
|
76232cd9e7 | ||
|
|
4da9b5e491 | ||
|
|
c4504a9221 | ||
|
|
65de8359e7 | ||
|
|
f6fab74436 | ||
|
|
350ba264e8 | ||
|
|
29e24818a1 | ||
|
|
71cd6f7b90 | ||
|
|
84ba253791 | ||
|
|
fce158b8ad | ||
|
|
da13ba6c67 | ||
|
|
7618133298 | ||
|
|
0d1698f81d | ||
|
|
362d642c87 | ||
|
|
e4c96d5be5 | ||
|
|
f488701adc | ||
|
|
8ff2bf51c5 | ||
|
|
a2490a55a9 | ||
|
|
20189f5191 | ||
|
|
06b796c6bd | ||
|
|
ad4edf6c68 | ||
|
|
4100f20a69 | ||
|
|
bedf946fb2 | ||
|
|
b9e67157c6 | ||
|
|
b30b2a183b | ||
|
|
9ab3bcdde3 | ||
|
|
5df3bbe188 | ||
|
|
8cf12416c0 | ||
|
|
b7c2c83c88 | ||
|
|
3b6da93331 | ||
|
|
b4642d3fd4 | ||
|
|
88a2b0b911 | ||
|
|
954e127f1d | ||
|
|
7654add5e5 | ||
|
|
85a37ea53f | ||
|
|
b337acebcc | ||
|
|
fb9ca54c95 | ||
|
|
1a15d41523 | ||
|
|
e378cc5791 | ||
|
|
748c189c79 | ||
|
|
b89be6c4b9 | ||
|
|
df207807b6 | ||
|
|
1f2b40cff1 | ||
|
|
734400fd37 | ||
|
|
f19979d928 | ||
|
|
19be7a53da | ||
|
|
e56af34fb0 | ||
|
|
7737aa20e8 | ||
|
|
ead046201c | ||
|
|
0aa7c3f659 | ||
|
|
4aa7222022 | ||
|
|
86e3c78776 | ||
|
|
40076287ea | ||
|
|
ca81db8edf | ||
|
|
ae68a80e98 | ||
|
|
beb7c58375 | ||
|
|
e080b9d565 | ||
|
|
ca2db37039 | ||
|
|
194825f78e | ||
|
|
55bd765ea0 | ||
|
|
b03d61e2cf | ||
|
|
6fc0e5167b | ||
|
|
0065be011f | ||
|
|
3f7cbce58c | ||
|
|
246b62e322 | ||
|
|
7c2fdd1ee9 | ||
|
|
f77aa2623c | ||
|
|
20847a3ff5 | ||
|
|
eb6d42acf9 | ||
|
|
094d676a8b | ||
|
|
71306ceb1d | ||
|
|
8bbfc7fc22 | ||
|
|
19baba12b1 | ||
|
|
15b8819136 | ||
|
|
3fae8ade05 | ||
|
|
f9bbf31d65 | ||
|
|
df1da3dda9 | ||
|
|
c83f2a4abd | ||
|
|
ad53833040 | ||
|
|
bc8c85668a | ||
|
|
d12a3dde45 | ||
|
|
301c878c0f | ||
|
|
bd55bfa071 | ||
|
|
6d2f09b579 | ||
|
|
4bfea7f54d | ||
|
|
55906486d8 | ||
|
|
d5478e6e08 | ||
|
|
d88d85c172 | ||
|
|
59c3c536c7 | ||
|
|
a007458cb8 | ||
|
|
d051912f21 | ||
|
|
a547158a50 | ||
|
|
95f2351aa0 | ||
|
|
698aaffb0b | ||
|
|
73eccecbf8 | ||
|
|
ae4a261463 | ||
|
|
c9f0d0cec2 | ||
|
|
4fa1e45d45 | ||
|
|
1b3d252bfe | ||
|
|
a9ba4a9fcd | ||
|
|
7f49619875 | ||
|
|
696660639a | ||
|
|
da4323062d | ||
|
|
a901e171b2 | ||
|
|
6e41d532fe | ||
|
|
4fc78ffb58 | ||
|
|
8137f41fc3 | ||
|
|
2e9471797d | ||
|
|
344248cea0 | ||
|
|
2789e3dba5 | ||
|
|
cca759a41e | ||
|
|
4f7b3d8882 | ||
|
|
2b330b78b7 | ||
|
|
d47ca1912b | ||
|
|
3fd2108b10 | ||
|
|
96e2a407f4 | ||
|
|
cdf18c96f4 | ||
|
|
53acaa05b8 | ||
|
|
fb85679068 | ||
|
|
9558e14479 | ||
|
|
4af0af93bf | ||
|
|
df4bc950fe | ||
|
|
250394f72b | ||
|
|
ca83fd6dc1 | ||
|
|
d5e9e7cd2b | ||
|
|
9a96f621ef | ||
|
|
5d7ce096c6 | ||
|
|
c9f8109c06 | ||
|
|
a20b4f2864 | ||
|
|
44a19d2a0a | ||
|
|
02f3beb8db | ||
|
|
3269cc3d90 | ||
|
|
fb70a1f4ab | ||
|
|
df0aa483ce | ||
|
|
c83f12a55c | ||
|
|
9704f59566 | ||
|
|
2923893d34 | ||
|
|
890dab0742 | ||
|
|
607e26b041 | ||
|
|
ea75290f65 | ||
|
|
a176054118 | ||
|
|
9a697dc5f5 | ||
|
|
cfdb852843 | ||
|
|
2e67a91982 | ||
|
|
074ca9330d | ||
|
|
f0d7cdcb20 | ||
|
|
40d961e059 | ||
|
|
e5de759236 | ||
|
|
e26a75c59d | ||
|
|
8701145b40 | ||
|
|
a2558886c8 | ||
|
|
f818ee86ae | ||
|
|
ad0dbdaa9c | ||
|
|
a9f14b294f | ||
|
|
a435ae98f9 | ||
|
|
481b261458 | ||
|
|
48df52d743 | ||
|
|
0af0d3b171 | ||
|
|
8287cf35e7 | ||
|
|
fab7924cc2 | ||
|
|
0ab739e8b1 | ||
|
|
2dcd4d171b | ||
|
|
e7f4d18c3d | ||
|
|
1611362c22 | ||
|
|
2327698160 | ||
|
|
71c1f00ec2 | ||
|
|
6574a126ef | ||
|
|
1e68086355 | ||
|
|
326cc8fd67 | ||
|
|
4afcb421bd | ||
|
|
8d21917035 | ||
|
|
4ca7f8834c | ||
|
|
b43299c8da | ||
|
|
b763809f5e | ||
|
|
2cb97f7475 | ||
|
|
6283df7491 | ||
|
|
acc4490370 | ||
|
|
f85c1a995a | ||
|
|
809e5fda8a | ||
|
|
dce245da5a | ||
|
|
d261c4cd27 | ||
|
|
c33299d542 | ||
|
|
ebdf8a5f3c | ||
|
|
c8852d183f | ||
|
|
9f161b20ef | ||
|
|
40f9d64973 | ||
|
|
4a2e68a0fd | ||
|
|
bcd90d3401 | ||
|
|
114af7d33f | ||
|
|
7b83d2de49 | ||
|
|
850de5913d | ||
|
|
bb9ee46f40 | ||
|
|
e94fc1305b | ||
|
|
3e4e8feb29 | ||
|
|
fedf347b1a | ||
|
|
285277a50b | ||
|
|
323c96f42f | ||
|
|
7dee344ea9 | ||
|
|
65bce588e4 | ||
|
|
233ff1b744 | ||
|
|
0837e39787 | ||
|
|
86db565a21 | ||
|
|
d6ac5e5001 | ||
|
|
e6443f1981 | ||
|
|
d13e6c73db | ||
|
|
79ca7f3cb5 | ||
|
|
cfd07ccd34 | ||
|
|
48047d523a | ||
|
|
eeb8fc2626 | ||
|
|
3d1baf3f2f | ||
|
|
4e382d6765 | ||
|
|
582963375d | ||
|
|
56c7c1bcc8 | ||
|
|
f88e57ddb8 | ||
|
|
9d98e012e4 | ||
|
|
d305a774f0 | ||
|
|
16b0c8d353 | ||
|
|
55da4fdbf6 | ||
|
|
ed2fbd8f25 | ||
|
|
42199bc8e5 | ||
|
|
7c5318768c | ||
|
|
aba25aab19 | ||
|
|
f99bd33f91 | ||
|
|
a6a6ce83f0 | ||
|
|
f4908a9758 | ||
|
|
5e4ca4b76a | ||
|
|
1e938d0e90 | ||
|
|
f3704f4c05 | ||
|
|
8800efe953 | ||
|
|
a320c4584e | ||
|
|
3841850168 | ||
|
|
beb3885840 | ||
|
|
06967c0c46 | ||
|
|
9a382c572c | ||
|
|
44b6c371db | ||
|
|
00970be996 | ||
|
|
aca4ab015f | ||
|
|
68b63d5783 | ||
|
|
4b499f2bb1 | ||
|
|
ed17581f92 | ||
|
|
a46c4ec912 | ||
|
|
930cbeec17 | ||
|
|
10689ffaba | ||
|
|
29b0ea0af9 | ||
|
|
57d00946be | ||
|
|
ef51de72c9 | ||
|
|
c807bf1e0e | ||
|
|
2525b3fb05 | ||
|
|
9163ce0f6e | ||
|
|
d776638f53 | ||
|
|
83fff41312 | ||
|
|
dd7d9bc95b | ||
|
|
f8eabbc100 | ||
|
|
7ed18ac62d | ||
|
|
3ac707c645 | ||
|
|
8e9a1e0bf3 | ||
|
|
bc31b5d27a | ||
|
|
936738b750 | ||
|
|
7c3048ab9c | ||
|
|
64719f3ace | ||
|
|
a11a5f04d5 | ||
|
|
eb5c035dde | ||
|
|
c3887efbf3 | ||
|
|
495585830d | ||
|
|
6715cb9880 | ||
|
|
41b167d23c | ||
|
|
7ea8b54210 | ||
|
|
bcea39a858 | ||
|
|
fb560abac4 | ||
|
|
ba93a08b40 | ||
|
|
2be6b3481c | ||
|
|
6ef44a6fbb | ||
|
|
2afe40a0b5 | ||
|
|
e57d004718 | ||
|
|
d780d0aabb | ||
|
|
0f9e3f0767 | ||
|
|
381972c923 | ||
|
|
845d7ad718 | ||
|
|
f1b6c0c559 | ||
|
|
e39eddf3fe | ||
|
|
72218fb475 | ||
|
|
9a3e497c22 | ||
|
|
85d510cd48 | ||
|
|
786c65ea5f | ||
|
|
10e6f61125 | ||
|
|
cdd06e7236 | ||
|
|
48603c0ee2 | ||
|
|
63f30492be | ||
|
|
0e8772290d | ||
|
|
6cfc5798b0 | ||
|
|
6be275f5d4 | ||
|
|
716f237c4c | ||
|
|
2a192be4f5 | ||
|
|
2679185a09 | ||
|
|
b85e7ab0b1 | ||
|
|
29c9804843 | ||
|
|
56d8ddbaaf | ||
|
|
8b324249b1 | ||
|
|
59cc61529b | ||
|
|
3912e5ef0b | ||
|
|
e40fbf1470 | ||
|
|
56a03e1a10 | ||
|
|
5d5952d354 | ||
|
|
53fda88d4c | ||
|
|
c4f306c145 | ||
|
|
e01d7fcefc | ||
|
|
aec04b07e0 | ||
|
|
b1872a8e21 | ||
|
|
634816d378 | ||
|
|
2fd5a6d47f | ||
|
|
8dca56521b | ||
|
|
a41aefe77d | ||
|
|
46dbc7157d | ||
|
|
59261113d8 | ||
|
|
fc2834cf04 | ||
|
|
a15633053b | ||
|
|
60a06eef19 | ||
|
|
7fd6ddc25b | ||
|
|
c49e0ac5c8 | ||
|
|
a51e95d052 | ||
|
|
4df9d70e4a | ||
|
|
78d490d5e4 | ||
|
|
2f6002b197 | ||
|
|
abcb95b8a1 | ||
|
|
bf435cae7c | ||
|
|
4b38acd540 | ||
|
|
f71749c3c4 | ||
|
|
cbc90e7ffb | ||
|
|
62866dc8be | ||
|
|
11e702c430 | ||
|
|
3e6e6ec0a5 | ||
|
|
898c08c8e0 | ||
|
|
88fba101a3 | ||
|
|
b0f431e1a2 | ||
|
|
42a7aca504 | ||
|
|
c017f2e7c4 | ||
|
|
d17bcd8afe | ||
|
|
874673f64f | ||
|
|
e052d73321 | ||
|
|
58efab5cdf | ||
|
|
4360fe492e | ||
|
|
295faf726b | ||
|
|
2da9d46ca6 | ||
|
|
e4f1e5f4c3 | ||
|
|
c695af31b8 | ||
|
|
24753c8c6a | ||
|
|
6196cf09ff | ||
|
|
28eb5b9bc4 | ||
|
|
bb20331f9e | ||
|
|
d2bce042a5 | ||
|
|
5d57263a15 | ||
|
|
bded8755a1 | ||
|
|
2e9ade61b2 | ||
|
|
89e03a86b7 | ||
|
|
48e88e4e74 | ||
|
|
d182ecb2d3 | ||
|
|
27e4503dc6 | ||
|
|
72b596efb3 | ||
|
|
0d1de96dbc | ||
|
|
788f69a8c9 | ||
|
|
08b63b4f01 | ||
|
|
ba07dc1804 | ||
|
|
d46074e0ad | ||
|
|
d651063749 | ||
|
|
f60f8396bb | ||
|
|
919fdd70b8 | ||
|
|
ab2702070b | ||
|
|
057e1a1aff | ||
|
|
a2af4e1284 | ||
|
|
97adede70b | ||
|
|
b6447a9032 | ||
|
|
e40b5819bd | ||
|
|
16926edf18 | ||
|
|
8203c79f76 | ||
|
|
43e1b27d16 | ||
|
|
d1cb3b0d15 | ||
|
|
266b3b8678 | ||
|
|
a2629c4929 | ||
|
|
c1fc629c54 | ||
|
|
0d12fe43a0 | ||
|
|
6aec0ce702 | ||
|
|
32c30c34e9 | ||
|
|
6b7b2612a9 | ||
|
|
0b9c6ed178 | ||
|
|
d903855aa3 | ||
|
|
89234bcd42 | ||
|
|
85ba590fa9 | ||
|
|
2950f77dbc | ||
|
|
a94f5ba200 | ||
|
|
0c4e40102f | ||
|
|
27e8126b18 | ||
|
|
bf860b21d7 | ||
|
|
a03a540156 | ||
|
|
eb63c8dcb8 | ||
|
|
cdcb94751e | ||
|
|
cd5d8cceb8 | ||
|
|
8fbc87be46 | ||
|
|
06fba42858 | ||
|
|
0f8a1e3901 | ||
|
|
729dfdfed7 | ||
|
|
1b8051dfe5 | ||
|
|
be6454193b | ||
|
|
f3347be629 | ||
|
|
dbce06500d | ||
|
|
7a81dd3378 | ||
|
|
57dd9c9e01 | ||
|
|
ef4e52a60e | ||
|
|
e7cbefa316 | ||
|
|
b4f805b4e9 | ||
|
|
9b0d26aedd | ||
|
|
f6758c397d | ||
|
|
ef3ed6e338 | ||
|
|
45aa8742d8 | ||
|
|
ebe8f554c6 | ||
|
|
45b0e63be2 | ||
|
|
934dc842e0 | ||
|
|
deda877355 | ||
|
|
2dba8404eb | ||
|
|
f581b4e92c | ||
|
|
02c74b5bee | ||
|
|
df69439b9c | ||
|
|
eb4a686b14 | ||
|
|
3386466e7a | ||
|
|
6a2aa7e4f0 | ||
|
|
735871d501 | ||
|
|
097f3590ae | ||
|
|
17bf13fcb6 | ||
|
|
2dc7b7ad78 | ||
|
|
a3c1724d17 | ||
|
|
5a9309de78 | ||
|
|
a40fae04ce | ||
|
|
f8cb6979d7 | ||
|
|
fc70ae180e | ||
|
|
66b5fa821c | ||
|
|
2f2f416bea | ||
|
|
1da07a3b86 | ||
|
|
ad0fcb745e | ||
|
|
5a502d451d | ||
|
|
955824e634 | ||
|
|
3b62f3c9c0 | ||
|
|
d2a27a84cf | ||
|
|
c7d8eb126f | ||
|
|
d608fd77b9 | ||
|
|
af5aa38bc3 | ||
|
|
2f2f367c0b | ||
|
|
d7a2362a76 | ||
|
|
e479c8a553 | ||
|
|
62f707f501 | ||
|
|
19d62b7a68 | ||
|
|
103bda04d9 | ||
|
|
8e6846d9da | ||
|
|
fd38216eda | ||
|
|
ae27b8944e | ||
|
|
bb6b825836 | ||
|
|
3fc55bba8e | ||
|
|
92819f5082 | ||
|
|
736b9074c8 | ||
|
|
376147911f | ||
|
|
4281690021 | ||
|
|
65714165f9 | ||
|
|
82d917c2c5 | ||
|
|
8487d67f00 | ||
|
|
67d1dad77c | ||
|
|
3b39c3391d | ||
|
|
8a55c6fd9f | ||
|
|
68567e763c | ||
|
|
bc2d3a13f4 | ||
|
|
e0bca07e06 | ||
|
|
377f194837 | ||
|
|
de9989d5a2 | ||
|
|
50db34457c | ||
|
|
b1ce6bd5cc | ||
|
|
81915540de | ||
|
|
0d65f08b1d | ||
|
|
ffbd1fd474 | ||
|
|
700c1f836d | ||
|
|
db2c6820ee | ||
|
|
3236607be4 | ||
|
|
3edbeb8902 | ||
|
|
f59467b897 | ||
|
|
6bc81d3d26 | ||
|
|
4c26792c9b | ||
|
|
9a133ced2d | ||
|
|
18bebaf5c3 | ||
|
|
f7efae93d5 | ||
|
|
7b4d2118ea | ||
|
|
26eb7c9375 | ||
|
|
e4d5367ead | ||
|
|
47b5157f01 | ||
|
|
39444d83c5 | ||
|
|
350028553b | ||
|
|
7392add8e0 | ||
|
|
e14695c96e | ||
|
|
b4d3806f10 | ||
|
|
996afe7d95 | ||
|
|
905cadc00e | ||
|
|
6634751303 | ||
|
|
64b57fa907 | ||
|
|
dd4059beb8 | ||
|
|
fe3b54bc2e | ||
|
|
1b5e1943f5 | ||
|
|
b1e6fe7139 | ||
|
|
92718a819c | ||
|
|
ceb2f6894f | ||
|
|
c42612abac | ||
|
|
7069d7d802 | ||
|
|
9aaa6d5df1 | ||
|
|
3eb155cf2a | ||
|
|
7c8d914711 | ||
|
|
4d1f8bd057 | ||
|
|
b883ce95b2 | ||
|
|
546e7c0c1f | ||
|
|
4f2dc0ecff | ||
|
|
03c5d06107 | ||
|
|
9499047f8e | ||
|
|
db5674cb08 | ||
|
|
66d000f4ba | ||
|
|
2c3c990019 | ||
|
|
807aecdb11 | ||
|
|
ea1b705c1c | ||
|
|
cb8b0d3597 | ||
|
|
7a86514505 | ||
|
|
3a0babb47d | ||
|
|
b085b34a69 | ||
|
|
abc738b6f1 | ||
|
|
d37cc5a160 | ||
|
|
1a0de753e9 | ||
|
|
b798f4fe71 | ||
|
|
0c0a588b55 | ||
|
|
faa5ef193b | ||
|
|
4c7b5005a6 | ||
|
|
9cf61cef9d | ||
|
|
28c61b548b | ||
|
|
0b24e62d43 | ||
|
|
b19dd49fc9 | ||
|
|
91b1e66933 | ||
|
|
eea2712eac | ||
|
|
b19a4b6956 | ||
|
|
a01c995a53 | ||
|
|
59b491e3a8 | ||
|
|
c44febe85e | ||
|
|
15b3c9797b | ||
|
|
584cfa4d4a | ||
|
|
b92f57eacb | ||
|
|
aeeaaa53d4 | ||
|
|
a532fce0e4 | ||
|
|
510fe8e634 | ||
|
|
556d90a1b4 | ||
|
|
4dde1ede0e | ||
|
|
1c833f8a9a | ||
|
|
6a36bd8514 | ||
|
|
12cb819adc | ||
|
|
0607edd191 | ||
|
|
96c7abdb39 | ||
|
|
6835aecdce | ||
|
|
8174c1ad02 | ||
|
|
6129452681 | ||
|
|
be1a3f427e | ||
|
|
18dc947fa9 | ||
|
|
348c43de63 | ||
|
|
cd9b15b2a6 | ||
|
|
8b20d777b0 | ||
|
|
ec0947ef7e | ||
|
|
02e6005fa9 | ||
|
|
a32caac3c1 | ||
|
|
2aa618ce98 | ||
|
|
96b23f6edd | ||
|
|
02d162858f | ||
|
|
82844a5591 | ||
|
|
46fb5a852f | ||
|
|
10a3aa18bc | ||
|
|
3c395c26be | ||
|
|
ea78520220 | ||
|
|
92fbec2294 | ||
|
|
b9be4ae4e8 | ||
|
|
e9a7f60fa7 | ||
|
|
0a02d1f336 | ||
|
|
663f3592ba | ||
|
|
f9484a894f | ||
|
|
4e522ab7f5 | ||
|
|
96d150e92d | ||
|
|
592b2e76a8 | ||
|
|
a3e463030d | ||
|
|
4569278c53 | ||
|
|
851b022c7a | ||
|
|
0985f675e3 | ||
|
|
7df730cedd | ||
|
|
314ffd9353 | ||
|
|
2c953dc37f | ||
|
|
9b9e4e5a3f | ||
|
|
50f835c701 | ||
|
|
cbb3351d97 | ||
|
|
fb81721e7e | ||
|
|
2cedef1333 | ||
|
|
4a1697a1b5 | ||
|
|
86f08a341c | ||
|
|
3d85cbe6b5 | ||
|
|
6d3dd98e77 | ||
|
|
9b2004d6b7 | ||
|
|
eb072da81c | ||
|
|
38669d0a10 | ||
|
|
202a8bc3bb | ||
|
|
45e8ed6b49 | ||
|
|
96692e8a5b | ||
|
|
ecb08b0cf3 | ||
|
|
71bdfd9710 | ||
|
|
193dcf38f4 | ||
|
|
09091781cf | ||
|
|
023519c8f6 | ||
|
|
d60d0a60c7 | ||
|
|
8fe0c3dd84 | ||
|
|
85419f01a9 | ||
|
|
a199f4a849 | ||
|
|
290795a76b | ||
|
|
c2cf2bc0ba | ||
|
|
2224918730 | ||
|
|
c4e69daecd | ||
|
|
9162e68d82 | ||
|
|
08f736ae33 | ||
|
|
81092edab4 | ||
|
|
21b5a4e9e4 | ||
|
|
057928b079 | ||
|
|
4beaa45199 | ||
|
|
8f88fa45f1 | ||
|
|
13e8176884 | ||
|
|
aac0130613 | ||
|
|
0877f44cb5 | ||
|
|
59159b4811 | ||
|
|
12bd12e112 | ||
|
|
0e4f9170fa | ||
|
|
6f81a9cb1e | ||
|
|
41555e5aa3 | ||
|
|
3d06720628 | ||
|
|
c1d2b98386 | ||
|
|
1a60723d77 | ||
|
|
cc31ab84d7 | ||
|
|
a07a234761 | ||
|
|
0bb4ccd7cd | ||
|
|
74cf205bcf | ||
|
|
77405ddded | ||
|
|
6b46da0240 | ||
|
|
0815812546 | ||
|
|
0fed1d34d1 | ||
|
|
a1e091cff7 | ||
|
|
adebc99e49 | ||
|
|
d3d1291d5a | ||
|
|
de61015e08 | ||
|
|
9d856ec1bf | ||
|
|
ad19d32a66 | ||
|
|
5bdb8674ed | ||
|
|
5563c9666c | ||
|
|
30ad20be52 | ||
|
|
314c9de845 | ||
|
|
41dbfc9e1c | ||
|
|
b07dd622fa | ||
|
|
6ad21b3b3b | ||
|
|
a242c1019d | ||
|
|
c595d67311 | ||
|
|
8b77379e2c | ||
|
|
7ad29c6329 | ||
|
|
14756fa131 | ||
|
|
ddbfc176b6 | ||
|
|
ab668b066f | ||
|
|
a4bcb3de4a | ||
|
|
211894cb3e | ||
|
|
7565b1f4f2 | ||
|
|
b75ff3652c | ||
|
|
13f6c5a934 | ||
|
|
2e0f6e2b13 | ||
|
|
c5d41ee2d9 | ||
|
|
5f70c1aa68 | ||
|
|
d2105ba390 | ||
|
|
e46e7bbf99 | ||
|
|
4eeeb72dd5 | ||
|
|
adefa45fb4 | ||
|
|
cfc06ab2a7 | ||
|
|
f3a4752799 | ||
|
|
3d788b4b93 | ||
|
|
5d2675e38a | ||
|
|
288d7bd9dc | ||
|
|
3e8cf26c1a | ||
|
|
ce212722ad | ||
|
|
5c127daeb4 | ||
|
|
e49fc945df | ||
|
|
384807ebbd | ||
|
|
ac619ef3d8 | ||
|
|
a348bd3458 | ||
|
|
bcc7045fc9 | ||
|
|
3b1929259a | ||
|
|
cdd6ea8e60 | ||
|
|
4b8927af75 | ||
|
|
0fba25c1b3 | ||
|
|
f19ba9d54d | ||
|
|
8e9a0121ac | ||
|
|
bd6e8d808c | ||
|
|
11b9a631d4 | ||
|
|
f197dd29cb | ||
|
|
daf7f42138 | ||
|
|
dd487d4184 | ||
|
|
d90071637d | ||
|
|
d8efae2aba | ||
|
|
22543f3e19 | ||
|
|
6aaef67e73 | ||
|
|
82a934d6fb | ||
|
|
eca6f2ca05 | ||
|
|
ef69f36403 | ||
|
|
99cf981c2f | ||
|
|
fc7a449f6d | ||
|
|
b7fafdafaa | ||
|
|
8e180cfcde | ||
|
|
4770fd39d2 | ||
|
|
df107628c6 | ||
|
|
3463080a71 | ||
|
|
500dc2170f | ||
|
|
a76ae67a81 | ||
|
|
1d091e49e1 | ||
|
|
2b63219cc6 | ||
|
|
f1b7762bef | ||
|
|
043ad86482 | ||
|
|
74ca9578ed | ||
|
|
d499161446 | ||
|
|
34e8de56bc | ||
|
|
8a7864ebaa | ||
|
|
9e5fb5467f | ||
|
|
fb34bf7222 | ||
|
|
4591f35b7c | ||
|
|
f0a06182ca | ||
|
|
d9e47a6293 | ||
|
|
a555f87705 | ||
|
|
826b997166 | ||
|
|
d34bc6f304 | ||
|
|
5771ea48ef | ||
|
|
a4f3199427 | ||
|
|
e6a43fc127 | ||
|
|
701bd38d01 | ||
|
|
1a8c8bec0d | ||
|
|
20aa21d4b6 | ||
|
|
8c6adeb85a | ||
|
|
09b7ba1317 | ||
|
|
0703843ac1 | ||
|
|
d962dfe48c | ||
|
|
d6884db439 | ||
|
|
fdcbedef8f | ||
|
|
8afd19648f | ||
|
|
3017f12238 | ||
|
|
23ee0342c6 | ||
|
|
499f98a51c | ||
|
|
3073db4e81 | ||
|
|
5703377a5f | ||
|
|
b85aa872cc | ||
|
|
5a1a5a7d97 | ||
|
|
52912c6329 | ||
|
|
056f72f27f | ||
|
|
bb038e86a2 | ||
|
|
cc6c71eb37 | ||
|
|
de4358f8d8 | ||
|
|
d6e9c72424 | ||
|
|
96608fb18d | ||
|
|
280b826d6d | ||
|
|
538d3d46f4 | ||
|
|
66b8ec8935 | ||
|
|
4f30025aa0 | ||
|
|
faad36a3ef | ||
|
|
0b461599d1 | ||
|
|
0cbab84143 | ||
|
|
a4e2a770f6 | ||
|
|
36e84973ec | ||
|
|
f6c8888ee2 | ||
|
|
f2bf6a037b | ||
|
|
9dade8fbd9 | ||
|
|
d2d38edf06 | ||
|
|
e0abd238e3 | ||
|
|
7edcc08886 | ||
|
|
0c73b547f1 | ||
|
|
73c3d4bb50 | ||
|
|
77f063367a | ||
|
|
8e812058cb | ||
|
|
506c36beed | ||
|
|
0110f0193e | ||
|
|
7b870f4b2a | ||
|
|
aa2630f837 | ||
|
|
e137e93f94 | ||
|
|
215bdfccc2 | ||
|
|
956a0a9c99 | ||
|
|
ab83717b7d | ||
|
|
61e876e4bf | ||
|
|
9ca3dbc140 | ||
|
|
a02e2e25bb | ||
|
|
a9281f2c37 | ||
|
|
95395a8b87 | ||
|
|
ecdbd72fa1 | ||
|
|
3a2f8224e4 | ||
|
|
15841fe5f6 | ||
|
|
7e5a7b65a0 | ||
|
|
549bf876e4 | ||
|
|
bd60cf12f8 | ||
|
|
61fbab1910 | ||
|
|
957f495314 | ||
|
|
280eb48ba4 | ||
|
|
ebe5711b40 | ||
|
|
a16477d84f | ||
|
|
f6fb2362c6 | ||
|
|
170427bba1 | ||
|
|
93531e520a | ||
|
|
aa2db8fdde | ||
|
|
7c3c2af90b | ||
|
|
6dca9b4ba4 | ||
|
|
ede37bb9d8 | ||
|
|
4a1729eaab | ||
|
|
b1565f5b89 | ||
|
|
4fb8dcfd4e | ||
|
|
16d1f2b835 | ||
|
|
73594e5aa5 | ||
|
|
c0a365bd34 | ||
|
|
45940ff820 | ||
|
|
d545ae242c | ||
|
|
e862aaf2e1 | ||
|
|
30c3540086 | ||
|
|
663a084ca4 | ||
|
|
b4d9ccd9af | ||
|
|
98fff6a4ce | ||
|
|
4977a5e1d9 | ||
|
|
e4297486ef | ||
|
|
ad591767c9 | ||
|
|
8bc1e75d9f | ||
|
|
a1c7adcffc | ||
|
|
8867169957 | ||
|
|
79eac1e6b0 | ||
|
|
87533b13e1 | ||
|
|
a2ffe86a36 | ||
|
|
22bde7d461 | ||
|
|
f23203dc96 | ||
|
|
a94f1c779b | ||
|
|
6412aff82d | ||
|
|
99bc1f92c9 | ||
|
|
891edad53a | ||
|
|
98e35b02ad | ||
|
|
8075372675 | ||
|
|
10e34ca48e | ||
|
|
329808afff | ||
|
|
7fc3e6c168 | ||
|
|
199b32709c | ||
|
|
1775da5f43 | ||
|
|
45c202f78f | ||
|
|
a77b58dba9 | ||
|
|
c300ab6dd9 | ||
|
|
9ac0f1accb | ||
|
|
7990e5d4b1 | ||
|
|
fb2cb3c49d | ||
|
|
c4b1bc2506 | ||
|
|
551393d443 | ||
|
|
79d305f3e8 | ||
|
|
822956e769 | ||
|
|
a681a6a6d5 | ||
|
|
5f6d69affd | ||
|
|
4a9bea6980 | ||
|
|
bfddd80f43 | ||
|
|
84a778719a | ||
|
|
829d80d5b5 | ||
|
|
d6a5c97f3a | ||
|
|
4ba00bd256 | ||
|
|
c18f9da400 | ||
|
|
5b620a8dc5 | ||
|
|
9c968c590c | ||
|
|
dff5d5c4e4 | ||
|
|
1265e8cce8 | ||
|
|
2b5d7eeb50 | ||
|
|
bb9ae89049 | ||
|
|
72832a2810 | ||
|
|
18cb210eac | ||
|
|
2c5a183368 | ||
|
|
386f0a75df | ||
|
|
ea26482154 | ||
|
|
3aee7f918a | ||
|
|
b3dd18b215 | ||
|
|
a77e331e89 | ||
|
|
6f414ee9e2 | ||
|
|
8d56b498d1 | ||
|
|
871c1853bf | ||
|
|
f8cd3a785c | ||
|
|
6a6995187e | ||
|
|
a216c1e7e4 | ||
|
|
ea8445d187 | ||
|
|
77261cce5b | ||
|
|
78db712438 | ||
|
|
749302acb8 | ||
|
|
cbf52bb5d0 | ||
|
|
d2ce499b59 | ||
|
|
01e9bc4855 | ||
|
|
28d5e425a9 | ||
|
|
eae1f380cd | ||
|
|
e7280d7237 | ||
|
|
78997ee13c | ||
|
|
79ab50d84f | ||
|
|
98282114c9 | ||
|
|
d6cb175f96 | ||
|
|
b4d9eb6ec4 | ||
|
|
fabbfbc46e | ||
|
|
c7d80f8cf8 | ||
|
|
c70add7d0f | ||
|
|
44fe8741f3 | ||
|
|
f8680cf5c2 | ||
|
|
24c3424e51 | ||
|
|
bd264006ef | ||
|
|
bec3daa79f | ||
|
|
ead01ba0b9 | ||
|
|
8e7267f0e2 | ||
|
|
5dbae27f01 | ||
|
|
ecb938f20e | ||
|
|
f1a2ee3273 | ||
|
|
eb2eb14297 | ||
|
|
da07cc6ed1 | ||
|
|
3ff10b40d6 | ||
|
|
7f515e6033 | ||
|
|
a583592cd4 |
@@ -0,0 +1,9 @@
|
||||
Checks: 'clang-diagnostic-*,clang-analyzer-*,*,-modernize*,-hicpp*,-android-cloexec-fopen,-cert-dcl50-cpp,-cert-env33-c,-cert-err34-c,-cert-err58-cpp,-clang-analyzer-core.UndefinedBinaryOperatorResult,-clang-analyzer-security*,-cppcoreguidelines-no-malloc,-cppcoreguidelines-owning-memory,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-const-cast,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-static-cast-downcast,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-special-member-functions,-fuchsia-default-arguments,-fuchsia-overloaded-operator,-google-default-arguments,-google-readability-todo,-google-runtime-references,-llvm-header-guard,-llvm-include-order,-misc-string-integer-assignment,-misc-string-literal-with-embedded-nul,-readability-braces-around-statements,-readability-container-size-empty,-readability-delete-null-pointer,-readability-else-after-return,-readability-implicit-bool-conversion,-readability-named-parameter,-readability-static-accessed-through-instance'
|
||||
WarningsAsErrors: ''
|
||||
HeaderFilterRegex: ''
|
||||
FormatStyle: none
|
||||
CheckOptions:
|
||||
- key: google-readability-braces-around-statements.ShortStatementLines
|
||||
value: '2'
|
||||
- key: google-readability-namespace-comments.SpacesBeforeComments
|
||||
value: '2'
|
||||
+16
-3
@@ -1,3 +1,7 @@
|
||||
\#*
|
||||
.#*
|
||||
*~
|
||||
*.tidy
|
||||
*.old
|
||||
*.gz
|
||||
*.gz.uu
|
||||
@@ -5,16 +9,25 @@
|
||||
*.info
|
||||
*.log
|
||||
*.1
|
||||
.*.swp
|
||||
*.tmp
|
||||
*.tex
|
||||
Makefile
|
||||
*.pdf
|
||||
/Makefile
|
||||
README
|
||||
TAGS
|
||||
autom4te.cache
|
||||
config.cache
|
||||
config.status
|
||||
configure
|
||||
dddrun*
|
||||
doxygen-doc
|
||||
gdbrun*
|
||||
gmon.out
|
||||
ncverilog.history
|
||||
internals.txt
|
||||
verilator.txt
|
||||
verilator.pdf
|
||||
verilator_bin*
|
||||
autom4te.cache
|
||||
verilator_coverage_bin*
|
||||
verilator.pc
|
||||
**/obj_dir/*
|
||||
@@ -0,0 +1,197 @@
|
||||
Artistic License 2.0
|
||||
|
||||
Copyright (c) 2000-2006, The Perl Foundation.
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies of this
|
||||
license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
********
|
||||
|
||||
This license establishes the terms under which a given free software
|
||||
Package may be copied, modified, distributed, and/or redistributed. The
|
||||
intent is that the Copyright Holder maintains some artistic control over
|
||||
the development of that Package while still keeping the Package
|
||||
available as open source and free software.
|
||||
|
||||
You are always permitted to make arrangements wholly outside of this
|
||||
license directly with the Copyright Holder of a given Package. If the
|
||||
terms of this license do not permit the full use that you propose to
|
||||
make of the Package, you should contact the Copyright Holder and seek a
|
||||
different licensing arrangement.
|
||||
|
||||
Definitions
|
||||
***********
|
||||
|
||||
"Copyright Holder" means the individual(s) or organization(s) named in
|
||||
the copyright notice for the entire Package.
|
||||
|
||||
"Contributor" means any party that has contributed code or other
|
||||
material to the Package, in accordance with the Copyright Holder's
|
||||
procedures.
|
||||
|
||||
"You" and "your" means any person who would like to copy, distribute, or
|
||||
modify the Package.
|
||||
|
||||
"Package" means the collection of files distributed by the Copyright
|
||||
Holder, and derivatives of that collection and/or of those files. A
|
||||
given Package may consist of either the Standard Version, or a Modified
|
||||
Version.
|
||||
|
||||
"Distribute" means providing a copy of the Package or making it
|
||||
accessible to anyone else, or in the case of a company or organization,
|
||||
to others outside of your company or organization.
|
||||
|
||||
"Distributor Fee" means any fee that you charge for Distributing this
|
||||
Package or providing support for this Package to another party. It does
|
||||
not mean licensing fees.
|
||||
|
||||
"Standard Version" refers to the Package if it has not been modified, or
|
||||
has been modified only in ways explicitly requested by the Copyright
|
||||
Holder.
|
||||
|
||||
"Modified Version" means the Package, if it has been changed, and such
|
||||
changes were not explicitly requested by the Copyright Holder.
|
||||
|
||||
"Original License" means this Artistic License as Distributed with the
|
||||
Standard Version of the Package, in its current version or as it may be
|
||||
modified by The Perl Foundation in the future.
|
||||
|
||||
"Source" form means the source code, documentation source, and
|
||||
configuration files for the Package.
|
||||
|
||||
"Compiled" form means the compiled bytecode, object code, binary, or any
|
||||
other form resulting from mechanical transformation or translation of
|
||||
the Source form.
|
||||
|
||||
Permission for Use and Modification Without Distribution
|
||||
********************************************************
|
||||
|
||||
(1) You are permitted to use the Standard Version and create and use
|
||||
Modified Versions for any purpose without restriction, provided that you
|
||||
do not Distribute the Modified Version.
|
||||
|
||||
Permissions for Redistribution of the Standard Version
|
||||
******************************************************
|
||||
|
||||
(2) You may Distribute verbatim copies of the Source form of the
|
||||
Standard Version of this Package in any medium without restriction,
|
||||
either gratis or for a Distributor Fee, provided that you duplicate all
|
||||
of the original copyright notices and associated disclaimers. At your
|
||||
discretion, such verbatim copies may or may not include a Compiled form
|
||||
of the Package.
|
||||
|
||||
(3) You may apply any bug fixes, portability changes, and other
|
||||
modifications made available from the Copyright Holder. The resulting
|
||||
Package will still be considered the Standard Version, and as such will
|
||||
be subject to the Original License.
|
||||
|
||||
Distribution of Modified Versions of the Package as Source
|
||||
**********************************************************
|
||||
|
||||
(4) You may Distribute your Modified Version as Source (either gratis or
|
||||
for a Distributor Fee, and with or without a Compiled form of the
|
||||
Modified Version) provided that you clearly document how it differs from
|
||||
the Standard Version, including, but not limited to, documenting any
|
||||
non-standard features, executables, or modules, and provided that you do
|
||||
at least ONE of the following:
|
||||
|
||||
(a) make the Modified Version available to the Copyright Holder of the
|
||||
Standard Version, under the Original License, so that the Copyright
|
||||
Holder may include your modifications in the Standard Version.
|
||||
|
||||
(b) ensure that installation of your Modified Version does not prevent
|
||||
the user installing or running the Standard Version. In addition, the
|
||||
Modified Version must bear a name that is different from the name of the
|
||||
Standard Version.
|
||||
|
||||
(c) allow anyone who receives a copy of the Modified Version to make the
|
||||
Source form of the Modified Version available to others under
|
||||
|
||||
(i) the Original License or
|
||||
|
||||
(ii) a license that permits the licensee to freely copy, modify and
|
||||
redistribute the Modified Version using the same licensing terms that
|
||||
apply to the copy that the licensee received, and requires that the
|
||||
Source form of the Modified Version, and of any works derived from it,
|
||||
be made freely available in that license fees are prohibited but
|
||||
Distributor Fees are allowed.
|
||||
|
||||
Distribution of Compiled Forms of the Standard Version or Modified
|
||||
******************************************************************
|
||||
Versions without the Source
|
||||
***************************
|
||||
|
||||
(5) You may Distribute Compiled forms of the Standard Version without
|
||||
the Source, provided that you include complete instructions on how to
|
||||
get the Source of the Standard Version. Such instructions must be valid
|
||||
at the time of your distribution. If these instructions, at any time
|
||||
while you are carrying out such distribution, become invalid, you must
|
||||
provide new instructions on demand or cease further distribution. If
|
||||
you provide valid instructions or cease distribution within thirty days
|
||||
after you become aware that the instructions are invalid, then you do
|
||||
not forfeit any of your rights under this license.
|
||||
|
||||
(6) You may Distribute a Modified Version in Compiled form without the
|
||||
Source, provided that you comply with Section 4 with respect to the
|
||||
Source of the Modified Version.
|
||||
|
||||
Aggregating or Linking the Package
|
||||
**********************************
|
||||
|
||||
(7) You may aggregate the Package (either the Standard Version or
|
||||
Modified Version) with other packages and Distribute the resulting
|
||||
aggregation provided that you do not charge a licensing fee for the
|
||||
Package. Distributor Fees are permitted, and licensing fees for other
|
||||
components in the aggregation are permitted. The terms of this license
|
||||
apply to the use and Distribution of the Standard or Modified Versions
|
||||
as included in the aggregation.
|
||||
|
||||
(8) You are permitted to link Modified and Standard Versions with other
|
||||
works, to embed the Package in a larger work of your own, or to build
|
||||
stand-alone binary or bytecode versions of applications that include the
|
||||
Package, and Distribute the result without restriction, provided the
|
||||
result does not expose a direct interface to the Package.
|
||||
|
||||
Items That are Not Considered Part of a Modified Version
|
||||
********************************************************
|
||||
|
||||
(9) Works (including, but not limited to, modules and scripts) that
|
||||
merely extend or make use of the Package, do not, by themselves, cause
|
||||
the Package to be a Modified Version. In addition, such works are not
|
||||
considered parts of the Package itself, and are not subject to the terms
|
||||
of this license.
|
||||
|
||||
General Provisions
|
||||
******************
|
||||
|
||||
(10) Any use, modification, and distribution of the Standard or Modified
|
||||
Versions is governed by this Artistic License. By using, modifying or
|
||||
distributing the Package, you accept this license. Do not use, modify,
|
||||
or distribute the Package, if you do not accept this license.
|
||||
|
||||
(11) If your Modified Version has been derived from a Modified Version
|
||||
made by someone other than you, you are nevertheless required to ensure
|
||||
that your Modified Version complies with the requirements of this
|
||||
license.
|
||||
|
||||
(12) This license does not grant you the right to use any trademark,
|
||||
service mark, tradename, or logo of the Copyright Holder.
|
||||
|
||||
(13) This license includes the non-exclusive, worldwide, free-of-charge
|
||||
patent license to make, have made, use, offer to sell, sell, import and
|
||||
otherwise transfer the Package with respect to any patent claims
|
||||
licensable by the Copyright Holder that are necessarily infringed by the
|
||||
Package. If you institute patent litigation (including a cross-claim or
|
||||
counterclaim) against any party alleging that the Package constitutes
|
||||
direct or contributory patent infringement, then this Artistic License
|
||||
to you shall terminate on the date that such litigation is filed.
|
||||
|
||||
(14) Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT
|
||||
HOLDER AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
WARRANTIES. THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||
PARTICULAR PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT
|
||||
PERMITTED BY YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT
|
||||
HOLDER OR CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THE PACKAGE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
@@ -1,285 +1,626 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
0. Definitions.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
1. Source Code.
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
14. Revised Versions of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
NO WARRANTY
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
@@ -287,15 +628,15 @@ free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
@@ -304,36 +645,30 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||
|
||||
+165
@@ -0,0 +1,165 @@
|
||||
GNU LESSER GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
0) Convey the Minimal Corresponding Source under the terms of this
|
||||
License, and the Corresponding Application Code in a form
|
||||
suitable for, and under terms that permit, the user to
|
||||
recombine or relink the Application with a modified version of
|
||||
the Linked Version to produce a modified Combined Work, in the
|
||||
manner specified by section 6 of the GNU GPL for conveying
|
||||
Corresponding Source.
|
||||
|
||||
1) Use a suitable shared library mechanism for linking with the
|
||||
Library. A suitable mechanism is one that (a) uses at run time
|
||||
a copy of the Library already present on the user's computer
|
||||
system, and (b) will operate properly with a modified version
|
||||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
@@ -0,0 +1,53 @@
|
||||
\.clang-tidy
|
||||
\.git/
|
||||
\.git$
|
||||
\.svn/
|
||||
\.(bak|old)/
|
||||
\.(bak|old)$
|
||||
\.tar\.
|
||||
.*\.tgz
|
||||
.*\.log
|
||||
\..*\.swp
|
||||
.*\.tmp
|
||||
.*\.tidy
|
||||
.*\.tex
|
||||
.*\.key
|
||||
.*\.vcd
|
||||
.*\.1
|
||||
/obj_dir/
|
||||
/obj_dbg/
|
||||
/obj_nc/
|
||||
/obj_opt/
|
||||
/obj_vcs/
|
||||
/obj_vlt/
|
||||
/obj_vltmt/
|
||||
/obj_dist/
|
||||
/INCA_libs/
|
||||
/cov_work/
|
||||
/logs/
|
||||
^Makefile$
|
||||
bin/verilator_bin.*
|
||||
bin/verilator_coverage_bin.*
|
||||
src/Makefile$
|
||||
src/Makefile_obj$
|
||||
include/verilated.mk$
|
||||
test_regress/.gdbinit$
|
||||
config.cache$
|
||||
config.status$
|
||||
verilator\.log
|
||||
verilator\.tex
|
||||
verilator.pc$
|
||||
verilator_bin.*
|
||||
verilator_coverage_bin.*
|
||||
.vcsmx_rebuild$
|
||||
ncverilog.history
|
||||
autom4te\.cache/
|
||||
nodist/
|
||||
/simv$
|
||||
/simv.daidir/
|
||||
/vc_hdrs.h$
|
||||
/csrc/
|
||||
doxygen-doc/.*
|
||||
obj_dir/.*
|
||||
TAGS
|
||||
.*~
|
||||
+372
-144
@@ -1,24 +1,22 @@
|
||||
# $Id$
|
||||
#*****************************************************************************
|
||||
# DESCRIPTION: Verilator top level: Makefile pre-configure version
|
||||
#
|
||||
# This file is part of Verilator.
|
||||
#
|
||||
# Author: Wilson Snyder <[email protected]> or <[email protected]>
|
||||
#
|
||||
# Code available from: http://www.veripool.com/verilator
|
||||
#
|
||||
#
|
||||
# This file is part of Verilator.
|
||||
#
|
||||
# Code available from: http://www.veripool.org/verilator
|
||||
#
|
||||
#*****************************************************************************
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
#
|
||||
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
#
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
#
|
||||
# Verilator is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
#
|
||||
#****************************************************************************/
|
||||
#
|
||||
# make all to compile and build Verilator.
|
||||
@@ -38,15 +36,12 @@
|
||||
# source and built the program without creating any other files,
|
||||
# `make distclean' should leave only the files that were in the
|
||||
# distribution.
|
||||
#
|
||||
#
|
||||
# make maintainer-clean
|
||||
# Delete everything from the current directory that can be
|
||||
# reconstructed with this Makefile. This typically includes
|
||||
# everything deleted by distclean, plus more: C source files
|
||||
# produced by Bison, tags tables, info files, and so on.
|
||||
#
|
||||
# make extraclean
|
||||
# Still more severe - delete backup and autosave files, too.
|
||||
|
||||
#### Start of system configuration section. ####
|
||||
|
||||
@@ -54,13 +49,19 @@ srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
HOST = @HOST@
|
||||
|
||||
DOXYGEN = doxygen
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
MAKEINFO = makeinfo
|
||||
TEXI2DVI = texi2dvi
|
||||
POD2TEXT = pod2text
|
||||
POD2LATEXFIX = $(srcdir)/src/pod2latexfix
|
||||
MKINSTALLDIRS = $(SHELL) $(srcdir)/src/mkinstalldirs
|
||||
PERL = @PERL@
|
||||
|
||||
# Destination prefix for RPMs
|
||||
DESTDIR =
|
||||
|
||||
#### Don't edit: You're much better using configure switches to set these
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -68,7 +69,7 @@ exec_prefix = @exec_prefix@
|
||||
# Directory in which to install scripts.
|
||||
bindir = @bindir@
|
||||
|
||||
# Directory in which to install scripts.
|
||||
# Directory in which to install manpages.
|
||||
mandir = @mandir@
|
||||
|
||||
# Directory in which to install library files.
|
||||
@@ -78,164 +79,314 @@ datadir = @datadir@
|
||||
infodir = @infodir@
|
||||
|
||||
# Directory in which to install package specific files
|
||||
# Generally ${prefix}/share/verilator
|
||||
pkgdatadir = @pkgdatadir@
|
||||
|
||||
# Directory in which to install pkgconfig file
|
||||
# Generall ${prefix}/share/pkgconfig
|
||||
pkgconfigdir = @pkgconfigdir@
|
||||
|
||||
# Directory in which to install data across multiple architectures
|
||||
datarootdir = @datarootdir@
|
||||
|
||||
# Compile options
|
||||
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
|
||||
CFG_WITH_DEFENV = @CFG_WITH_DEFENV@
|
||||
CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
|
||||
CFG_WITH_THREADED = @CFG_WITH_THREADED@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
|
||||
#### End of system configuration section. ####
|
||||
######################################################################
|
||||
|
||||
.SUFFIXES:
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
SUBDIRS = src test_verilated test_c test_sc test_sp test_regress test_vcs
|
||||
SUBDIRS = src test_regress \
|
||||
examples/hello_world_c examples/hello_world_sc \
|
||||
examples/tracing_c examples/tracing_sc \
|
||||
|
||||
INFOS = README verilator.txt verilator.html verilator.1 verilator.pdf
|
||||
INFOS = README README.html README.pdf internals.txt internals.html \
|
||||
internals.pdf verilator.txt verilator.html verilator.pdf \
|
||||
$(VL_INST_MAN_FILES)
|
||||
|
||||
# Files that can be generated, but should be up to date for a distribution.
|
||||
DISTDEP = info Makefile
|
||||
# Files to distribute.
|
||||
DISTBIN = $(wildcard bin/verilator-*)
|
||||
|
||||
DISTFILES_INC = $(INFOS) .cvsignore COPYING *.in *.ac \
|
||||
Changes README TODO \
|
||||
bin/* \
|
||||
install-sh configure mkinstalldirs *.texi \
|
||||
include/verilated.[chv]* \
|
||||
include/verilatedos.[chv]* \
|
||||
DISTFILES_INC = $(INFOS) .gitignore Artistic COPYING COPYING.LESSER \
|
||||
*.in *.ac \
|
||||
Changes TODO \
|
||||
MANIFEST.SKIP \
|
||||
bin/verilator \
|
||||
bin/verilator_coverage \
|
||||
bin/verilator_difftree \
|
||||
bin/verilator_gantt \
|
||||
bin/verilator_includer \
|
||||
bin/verilator_profcfunc \
|
||||
doxygen-mainpage doxygen.config verilator_logo.png \
|
||||
install-sh configure *.pod \
|
||||
include/*.[chv]* \
|
||||
include/*.in \
|
||||
src/.cvsignore src/*.in src/*.cpp src/*.[chly] src/astgen src/flexfix \
|
||||
src/*.pl \
|
||||
test_*/.cvsignore test_*/Makefile* test_*/*.cpp \
|
||||
test_*/*.pl test_*/*.v test_*/*.vc test_*/vlint \
|
||||
test_verilated/vgen*.pl \
|
||||
test_regress/t/*.v* \
|
||||
test_regress/t/*.pl \
|
||||
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/vlcovgen src/mkinstalldirs \
|
||||
src/.gdbinit \
|
||||
src/*.pl src/*.pod \
|
||||
examples/*/.*ignore examples/*/Makefile* \
|
||||
examples/*/*.[chv]* examples/*/*.pl \
|
||||
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
|
||||
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \
|
||||
test_regress/t/t*/*.sv* \
|
||||
test_regress/t/t*/*.v* \
|
||||
test_regress/t/t*/*/*.sv* \
|
||||
test_regress/t/t*/*/*.v* \
|
||||
test_regress/t/*.cpp \
|
||||
test_regress/t/*.h \
|
||||
test_regress/t/*.dat \
|
||||
test_regress/t/*.mem \
|
||||
test_regress/t/*.out \
|
||||
verilator.* \
|
||||
test_regress/t/*.pl \
|
||||
test_regress/t/*.pf \
|
||||
test_regress/t/*.v* \
|
||||
|
||||
INST_PROJ_FILES = \
|
||||
bin/verilator \
|
||||
bin/verilator_coverage \
|
||||
bin/verilator_gantt \
|
||||
bin/verilator_includer \
|
||||
include/verilated.[chv]* \
|
||||
bin/verilator_profcfunc \
|
||||
include/verilated.mk \
|
||||
include/verilatedos.[chv]* \
|
||||
include/*.[chv]* \
|
||||
include/gtkwave/*.[chv]* \
|
||||
include/vltstd/*.[chv]* \
|
||||
|
||||
INST_PROJ_BIN_FILES = \
|
||||
verilator_bin \
|
||||
verilator_bin_dbg \
|
||||
bin/verilator_bin \
|
||||
bin/verilator_bin_dbg \
|
||||
bin/verilator_coverage_bin_dbg \
|
||||
|
||||
DISTFILES := $(DISTFILES_INC)
|
||||
|
||||
ifeq ($(OBJCACHE_JOBS),)
|
||||
ifneq ($(OBJCACHE_HOSTS),)
|
||||
export OBJCACHE_JOBS := -j $(shell objcache --jobs "$(OBJCACHE_HOSTS)")
|
||||
endif
|
||||
endif
|
||||
|
||||
default: all
|
||||
all: all_nomsg msg_test
|
||||
all_nomsg: verilator_exe
|
||||
all_nomsg: verilator_exe $(VL_INST_MAN_FILES)
|
||||
|
||||
.PHONY:verilator_exe
|
||||
verilator_exe verilator_bin verilator_bin_dbg:
|
||||
.PHONY:verilator_bin
|
||||
.PHONY:verilator_bin_dbg
|
||||
.PHONY:verilator_coverage_bin_dbg
|
||||
verilator_exe verilator_bin verilator_bin_dbg verilator_coverage_bin_dbg:
|
||||
@echo ------------------------------------------------------------
|
||||
@echo "making verilator in src" ; \
|
||||
(cd src && $(MAKE) )
|
||||
@echo "making verilator in src"
|
||||
$(MAKE) -C src $(OBJCACHE_JOBS)
|
||||
|
||||
.PHONY:msg_test
|
||||
msg_test:
|
||||
msg_test: all_nomsg
|
||||
@echo "Build complete!"
|
||||
@echo
|
||||
@echo "Type 'make test' to test."
|
||||
@echo "Now type 'make test' to test."
|
||||
@echo
|
||||
|
||||
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
|
||||
test: test_vcs test_c test_sc test_sp test_verilated test_regress
|
||||
.PHONY: test
|
||||
ifeq ($(CFG_WITH_LONGTESTS),yes) # Local... Else don't burden users
|
||||
test: smoke-test examples test_regress
|
||||
else
|
||||
test: test_c test_sc test_sp
|
||||
test: smoke-test examples
|
||||
endif
|
||||
@echo "Tests passed!"
|
||||
@echo
|
||||
@echo "Type 'make install' to install documentation."
|
||||
@echo "Now type 'make install' to install."
|
||||
@echo "Or type 'make' inside an examples subdirectory."
|
||||
@echo
|
||||
|
||||
test_vcs: all_nomsg
|
||||
@(cd test_vcs && $(MAKE))
|
||||
test_c: all_nomsg
|
||||
@(cd test_c && $(MAKE))
|
||||
test_c_debug: all_nomsg
|
||||
@(cd test_c && $(MAKE) test_debug)
|
||||
test_sc: all_nomsg
|
||||
@(cd test_sc && $(MAKE))
|
||||
test_sc_debug: all_nomsg
|
||||
@(cd test_sc && $(MAKE) test_debug)
|
||||
test_sp: all_nomsg
|
||||
@(cd test_sp && $(MAKE))
|
||||
test_sp_debug: all_nomsg
|
||||
@(cd test_sp && $(MAKE) test_debug)
|
||||
test_verilated: all_nomsg
|
||||
@(cd test_verilated && $(MAKE))
|
||||
smoke-test: all_nomsg
|
||||
test_regress/t/t_a_first_cc.pl
|
||||
test_regress/t/t_a_first_sc.pl
|
||||
|
||||
test_regress: all_nomsg
|
||||
@(cd test_regress && $(MAKE))
|
||||
$(MAKE) -C test_regress
|
||||
|
||||
examples: all_nomsg
|
||||
for p in examples/* ; do \
|
||||
$(MAKE) -C $$p VERILATOR_ROOT=`pwd` || exit 10; \
|
||||
done
|
||||
|
||||
info: $(INFOS)
|
||||
|
||||
# Use --no-split to avoid creating filenames > 14 chars.
|
||||
verilator.1: bin/verilator
|
||||
%.1: ${srcdir}/bin/%
|
||||
pod2man $< $@
|
||||
|
||||
verilator.txt: bin/verilator
|
||||
pod2text $< $@
|
||||
verilator.txt: ${srcdir}/bin/verilator
|
||||
$(POD2TEXT) $< $@
|
||||
|
||||
verilator.html: bin/verilator
|
||||
verilator.html: ${srcdir}/bin/verilator
|
||||
pod2html $< >$@
|
||||
|
||||
verilator.pdf: bin/verilator $(DISTCONFIG)
|
||||
pod2latex --full --out verilator.tex bin/verilator
|
||||
cat < verilator.tex \
|
||||
| sed 's/\\begin{document}/\\usepackage{fancyhdr} \\pagestyle{fancy}\n\\begin{document}/' \
|
||||
| sed 's/\\begin{document}/\\setlength{\\parindent}{0pt} \\setlength{\\parskip}{\\baselineskip}\n\\begin{document}/' \
|
||||
| sed 's/\\begin{document}/\\title{$(DISTTITLE)} \\date{${DISTDATE}} \\author{Wilson Snyder\\\\ http:\/\/www.veripool.com}\n\\begin{document}/' \
|
||||
| sed 's/\\begin{document}/\\lhead[$(DISTTITLE)]{$(DISTTITLE)}\n\\begin{document}/' \
|
||||
| sed 's/\\tableofcontents/\\begin{titlepage} \\maketitle \\end{titlepage}\n\\tableofcontents/' \
|
||||
> verilator2.tex
|
||||
# PDF needs DIST variables; but having configure.ac as dependency isn't detected
|
||||
verilator.pdf: ${srcdir}/bin/verilator Makefile $(POD2LATEXFIX)
|
||||
pod2latex --full --out verilator.tex $<
|
||||
$(PERL) $(POD2LATEXFIX) "$(DISTTITLE)" "${DISTDATE}" < verilator.tex > verilator2.tex
|
||||
mv verilator2.tex verilator.tex
|
||||
pdflatex verilator.tex
|
||||
pdflatex verilator.tex
|
||||
-rm -f verilator.toc verilator.aux verilator.idx
|
||||
-rm -f verilator.toc verilator.aux verilator.idx verilator.out
|
||||
|
||||
INSTALL: install.texi
|
||||
$(MAKEINFO) -I$(srcdir) $(srcdir)/install.texi --output=$@ \
|
||||
--no-headers --no-validate
|
||||
README: README.pod
|
||||
-rm -f $@
|
||||
$(POD2TEXT) --loose $< > $@
|
||||
|
||||
README: readme.texi
|
||||
$(MAKEINFO) -I$(srcdir) $(srcdir)/readme.texi --output=$@ \
|
||||
--no-headers --no-validate
|
||||
README.html: README.pod
|
||||
pod2html $< >$@
|
||||
|
||||
installdirs:
|
||||
$(SHELL) ${srcdir}/mkinstalldirs $(bindir) $(infodir)
|
||||
# PDF needs DIST variables; but having configure.ac as dependency isn't detected
|
||||
README.pdf: README.pod Makefile $(POD2LATEXFIX)
|
||||
pod2latex --full --out README.tex $<
|
||||
$(PERL) $(POD2LATEXFIX) "$(DISTTITLE) README File" "${DISTDATE}" < README.tex > README2.tex
|
||||
mv README2.tex README.tex
|
||||
pdflatex README.tex
|
||||
pdflatex README.tex
|
||||
-rm -f README.toc README.aux README.idx README.out
|
||||
|
||||
internals.txt: internals.pod
|
||||
-rm -f $@
|
||||
$(POD2TEXT) --loose $< > $@
|
||||
|
||||
internals.html: internals.pod
|
||||
pod2html $< >$@
|
||||
|
||||
# PDF needs DIST variables; but having configure.ac as dependency isn't detected
|
||||
internals.pdf: internals.pod Makefile $(POD2LATEXFIX)
|
||||
pod2latex --full --out internals.tex $<
|
||||
$(PERL) $(POD2LATEXFIX) "$(DISTTITLE) Internals Manual" "${DISTDATE}" < internals.tex > internals2.tex
|
||||
mv internals2.tex internals.tex
|
||||
pdflatex internals.tex
|
||||
pdflatex internals.tex
|
||||
-rm -f internals.toc internals.aux internals.idx internals.out
|
||||
|
||||
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
|
||||
VL_INST_BIN_FILES = verilator verilator_bin verilator_bin_dbg verilator_coverage_bin_dbg \
|
||||
verilator_coverage verilator_gantt verilator_includer verilator_profcfunc
|
||||
# Some scripts go into both the search path and pkgdatadir,
|
||||
# so they can be found by the user, and under $VERILATOR_ROOT.
|
||||
|
||||
# See uninstall also - don't put wildcards in this variable, it might uninstall other stuff
|
||||
VL_INST_MAN_FILES = verilator.1 verilator_coverage.1 verilator_gantt.1 verilator_profcfunc.1
|
||||
|
||||
VL_INST_INC_BLDDIR_FILES = \
|
||||
include/verilated_config.h \
|
||||
include/verilated.mk \
|
||||
|
||||
# Files under srcdir, instead of build time
|
||||
VL_INST_INC_SRCDIR_FILES = \
|
||||
include/*.[chv]* \
|
||||
include/gtkwave/*.[chv]* \
|
||||
include/vltstd/*.[chv]* \
|
||||
|
||||
VL_INST_DATA_SRCDIR_FILES = \
|
||||
examples/*/*.[chv]* examples/*/Makefile* \
|
||||
|
||||
# See uninstall also
|
||||
VL_INST_BIN_FILES = verilator
|
||||
installbin:
|
||||
( cd bin ; $(INSTALL_PROGRAM) verilator $(bindir)/verilator )
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(bindir)
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator $(DESTDIR)$(bindir)/verilator )
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_coverage $(DESTDIR)$(bindir)/verilator_coverage )
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_gantt $(DESTDIR)$(bindir)/verilator_gantt )
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_profcfunc $(DESTDIR)$(bindir)/verilator_profcfunc )
|
||||
( cd bin ; $(INSTALL_PROGRAM) verilator_bin $(DESTDIR)$(bindir)/verilator_bin )
|
||||
( cd bin ; $(INSTALL_PROGRAM) verilator_bin_dbg $(DESTDIR)$(bindir)/verilator_bin_dbg )
|
||||
( cd bin ; $(INSTALL_PROGRAM) verilator_coverage_bin_dbg $(DESTDIR)$(bindir)/verilator_coverage_bin_dbg )
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/bin
|
||||
( cd ${srcdir}/bin ; $(INSTALL_PROGRAM) verilator_includer $(DESTDIR)$(pkgdatadir)/bin/verilator_includer )
|
||||
|
||||
VL_INST_MAN_FILES = verilator.1
|
||||
installman:
|
||||
for p in $(VL_INST_MAN_FILES) ; do \
|
||||
$(INSTALL_PROGRAM) $$p $(mandir)/man1/$$p; \
|
||||
# Man files can either be part of the original kit, or built in current directory
|
||||
# So important we use $^ so VPATH is searched
|
||||
installman: $(VL_INST_MAN_FILES)
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(mandir)/man1
|
||||
for p in $^ ; do \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(mandir)/man1/$$p; \
|
||||
done
|
||||
|
||||
install: all_nomsg installdirs installbin installman install-msg
|
||||
installdata:
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/include/gtkwave
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/include/vltstd
|
||||
for p in $(VL_INST_INC_BLDDIR_FILES) ; do \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
|
||||
done
|
||||
cd $(srcdir) \
|
||||
; for p in $(VL_INST_INC_SRCDIR_FILES) ; do \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
|
||||
done
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/hello_world_c
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/hello_world_sc
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/tracing_c
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/tracing_sc
|
||||
cd $(srcdir) \
|
||||
; for p in $(VL_INST_DATA_SRCDIR_FILES) ; do \
|
||||
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
|
||||
done
|
||||
$(MKINSTALLDIRS) $(DESTDIR)$(pkgconfigdir)
|
||||
$(INSTALL_DATA) verilator.pc $(DESTDIR)$(pkgconfigdir)
|
||||
|
||||
# We don't trust rm -rf, so rmdir instead as it will fail if user put in other files
|
||||
uninstall:
|
||||
-cd $(DESTDIR)$(bindir) && rm -f $(VL_INST_BIN_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir)/bin && rm -f $(VL_INST_BIN_FILES)
|
||||
-cd $(DESTDIR)$(mandir)/man1 && rm -f $(VL_INST_MAN_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_BLDDIR_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_SRCDIR_FILES)
|
||||
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_DATA_SRCDIR_FILES)
|
||||
-rm $(DESTDIR)$(pkgconfigdir)/verilator.pc
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/bin
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/include/gtkwave
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/include/vltstd
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/include
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/hello_world_c
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/hello_world_sc
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/tracing_c
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples/tracing_sc
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)/examples
|
||||
-rmdir $(DESTDIR)$(pkgdatadir)
|
||||
-rmdir $(DESTDIR)$(pkgconfigdir)
|
||||
|
||||
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)
|
||||
|
||||
DIRPROJECT := $(shell project_dir --project)
|
||||
VERILATOR_CAD_DIR = $(CAD_DIR)/verilator/$(DISTNAMEREV)/$(DIRPROJECT_ARCH)
|
||||
INST_PROJ_CVS = cp_if_cvs_diff
|
||||
|
||||
install-project: dist
|
||||
@echo "Install-project to $(DIRPROJECT)"
|
||||
strip verilator_bin*
|
||||
strip bin/verilator_bin*
|
||||
strip bin/verilator_coverage_bin*
|
||||
$(MAKE) install-project-quick
|
||||
for p in verilator.1 ; do \
|
||||
$(INSTALL_PROGRAM) -m 0666 $$p $(DIRPROJECT_PREFIX)/man/man1/$$p; \
|
||||
for p in $(VL_INST_MAN_FILES) ; do \
|
||||
$(INSTALL_DATA) $$p $(DIRPROJECT_PREFIX)/man/man1/$$p; \
|
||||
done
|
||||
$(INST_PROJ_CVS) $(DISTNAME).tar.gz $(DIRPROJECT)/hw/utils/verilator/verilator.tgz
|
||||
rm $(DISTNAME).tar.gz
|
||||
$(INST_PROJ_CVS) $(DISTNAME).tgz $(DIRPROJECT)/hw/utils/verilator/verilator.tgz
|
||||
rm $(DISTNAME).tgz
|
||||
|
||||
install-project-quick:
|
||||
ifeq ($(CFG_WITH_DEFENV),yes)
|
||||
@echo "%Error: Reconfigure with './configure --disable-defenv' to avoid hardcoded paths."
|
||||
false
|
||||
endif
|
||||
@echo "Install-project-quick (no strip) to $(DIRPROJECT)"
|
||||
for p in $(INST_PROJ_FILES) ; do \
|
||||
$(INST_PROJ_CVS) $$p $(DIRPROJECT)/hw/utils/verilator/$$p; \
|
||||
@@ -243,87 +394,164 @@ install-project-quick:
|
||||
for p in $(INST_PROJ_BIN_FILES) ; do \
|
||||
$(INST_PROJ_CVS) $$p $(DIRPROJECT)/hw/utils/verilator/$$p-$(DIRPROJECT_ARCH); \
|
||||
done
|
||||
|
||||
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
|
||||
|
||||
# Use --xml flag to see the cppcheck code to use for suppression
|
||||
CPPCHECK_CPP = $(wildcard \
|
||||
$(srcdir)/include/*.cpp \
|
||||
$(srcdir)/src/*.cpp )
|
||||
CPPCHECK_H = $(wildcard \
|
||||
$(srcdir)/include/*.h \
|
||||
$(srcdir)/src/*.h )
|
||||
CPPCHECK = src/cppcheck_filtered
|
||||
CPPCHECK_FLAGS = --enable=all --inline-suppr \
|
||||
--suppress=unusedScopedObject --suppress=cstyleCast --suppress=useInitializationList
|
||||
CPPCHECK_FLAGS += --xml
|
||||
CPPCHECK_DEP = $(subst .cpp,.cppcheck,$(CPPCHECK_CPP))
|
||||
CPPCHECK_INC = -I$(srcdir)/include -I$(srcdir)/src/obj_dbg -I$(srcdir)/src
|
||||
|
||||
cppcheck: $(CPPCHECK_DEP)
|
||||
%.cppcheck: %.cpp
|
||||
$(CPPCHECK) $(CPPCHECK_FLAGS) -DVL_DEBUG=1 -DVL_CPPCHECK=1 $(CPPCHECK_INC) $<
|
||||
|
||||
CLANGTIDY = clang-tidy
|
||||
CLANGTIDY_FLAGS = -config=''
|
||||
CLANGTIDY_DEP = $(subst .h,.h.tidy,$(CPPCHECK_H)) \
|
||||
$(subst .cpp,.cpp.tidy,$(CPPCHECK_CPP))
|
||||
|
||||
clangtidy: $(CLANGTIDY_DEP)
|
||||
%.cpp.tidy: %.cpp
|
||||
$(CLANGTIDY) $(CLANGTIDY_FLAGS) $< -- -DVL_DEBUG=1 -DVL_CPPCHECK=1 $(CPPCHECK_INC) | 2>&1 tee $@
|
||||
%.h.tidy: %.h
|
||||
$(CLANGTIDY) $(CLANGTIDY_FLAGS) $< -- -DVL_DEBUG=1 -DVL_CPPCHECK=1 $(CPPCHECK_INC) | 2>&1 tee $@
|
||||
|
||||
analyzer-src:
|
||||
-rm -rf src/obj_dbg
|
||||
scan-build $(MAKE) -k verilator_coverage_bin_dbg verilator_bin_dbg
|
||||
|
||||
analyzer-include:
|
||||
-rm -rf examples/*/obj*
|
||||
scan-build $(MAKE) -k examples
|
||||
|
||||
ftp: info
|
||||
echo "http://www.veripool.com/verilator3.html"
|
||||
cp verilator.html verilator_man.html
|
||||
ftp_tree --password $(VERIPOOL_PW) --user $(VERIPOOL_USER) verilator_man.html webftp.veripool.com:/web
|
||||
|
||||
install-msg:
|
||||
@echo "Installed!"
|
||||
@echo
|
||||
@echo "Add to your startup file (for bash or csh, as appropriate):"
|
||||
@echo " export VERILATOR_ROOT="`pwd`
|
||||
@echo " setenv VERILATOR_ROOT "`pwd` " ; export VERILATOR_ROOT "
|
||||
@echo "Installed binaries to $(DESTDIR)$(bindir)/verilator"
|
||||
@echo "Installed man to $(DESTDIR)$(mandir)/man1"
|
||||
@echo "Installed examples to $(DESTDIR)$(pkgdatadir)/examples"
|
||||
@echo
|
||||
@echo "See 'verilator.txt' for documentation."
|
||||
@echo "For documentation see 'man verilator' or 'verilator --help'"
|
||||
@echo "For forums and to report bugs see http://www.veripool.org/verilator"
|
||||
@echo
|
||||
|
||||
uninstall:
|
||||
-cd $(mandir)/man1 && rm -f $(VL_INST_MAN_FILES)
|
||||
-cd $(bindir) && rm -f $(VL_INST_BIN_FILES)
|
||||
IN_WILD := ${srcdir}/*.in ${srcdir}/*/*.in
|
||||
|
||||
# autoheader might not change config_build.h.in, so touch a stamp file.
|
||||
IN_WILD := ${srcdir}/*.in ${srcdir}/*/*.in ${srcdir}/*/*/*.in \
|
||||
*.in */*.in */*.in
|
||||
|
||||
${srcdir}/config_build.h.in: stamp-h.in
|
||||
${srcdir}/stamp-h.in: configure.ac $(wildcard $(IN_WILD))
|
||||
# autoheader might not change config_build.h.in, so touch it
|
||||
${srcdir}/config_build.h: ${srcdir}/config_build.h.in configure
|
||||
cd ${srcdir} && autoheader
|
||||
echo timestamp > ${srcdir}/stamp-h.in
|
||||
config_build.h: stamp-h
|
||||
stamp-h: config_build.h.in config.status
|
||||
./config.status
|
||||
Makefile: Makefile.in config.status
|
||||
./config.status
|
||||
src/Makefile: src/Makefile.in config.status
|
||||
touch $@
|
||||
Makefile: Makefile.in config.status $(IN_WILD)
|
||||
./config.status
|
||||
src/Makefile: src/Makefile.in Makefile
|
||||
config.status: configure
|
||||
./config.status --recheck
|
||||
|
||||
configure: configure.ac
|
||||
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||
autoconf --warnings=all
|
||||
else
|
||||
autoconf
|
||||
endif
|
||||
|
||||
maintainer-clean::
|
||||
@echo "This command is intended for maintainers to use;"
|
||||
@echo "rebuilding the deleted files requires makeinfo."
|
||||
rm -f *.info* $(INFOS) faq.html verilator.html configure bin/*
|
||||
@echo "rebuilding the deleted files requires autoconf."
|
||||
rm -f configure
|
||||
|
||||
clean mostlyclean distclean maintainer-clean maintainer-copy::
|
||||
for dir in $(SUBDIRS); do \
|
||||
echo making $@ in $$dir ; \
|
||||
(cd $$dir && $(MAKE) $@) ; \
|
||||
$(MAKE) -C $$dir $@ ; \
|
||||
done
|
||||
|
||||
clean mostlyclean distclean maintainer-clean::
|
||||
rm -f $(SCRIPTS) *.tmp
|
||||
rm -f $(SCRIPTS) *.tmp
|
||||
rm -f *.aux *.cp *.cps *.dvi *.fn *.fns *.ky *.kys *.log
|
||||
rm -f *.pg *.pgs *.toc *.tp *.tps *.vr *.vrs *.idx
|
||||
rm -f *.ev *.evs *.ov *.ovs *.cv *.cvs *.ma *.mas
|
||||
rm -f *.tex
|
||||
rm -rf test_*/obj_dir
|
||||
rm -rf examples/*/obj_dir examples/*/logs
|
||||
|
||||
distclean maintainer-clean::
|
||||
rm -f Makefile config.status config.cache config.log verilator_bin* TAGS
|
||||
rm -f include/verilated.mk
|
||||
rm -f *.info* *.1 $(INFOS)
|
||||
rm -f Makefile config.status config.cache config.log TAGS
|
||||
rm -f verilator_bin* verilator_coverage_bin*
|
||||
rm -f bin/verilator_bin* bin/verilator_coverage_bin*
|
||||
rm -f include/verilated.mk include/verilated_config.h
|
||||
|
||||
TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/[a-z]*.in \
|
||||
${srcdir}/[a-z]*.in ${srcdir}/*.texi
|
||||
TAGFILES=${srcdir}/*/*.cpp ${srcdir}/*/*.h ${srcdir}/*/*.in \
|
||||
${srcdir}/*.in ${srcdir}/*.pod
|
||||
|
||||
TAGS: $(TAGFILES)
|
||||
etags $(TAGFILES)
|
||||
|
||||
.PHONY: doxygen
|
||||
|
||||
doxygen:
|
||||
$(DOXYGEN) doxygen.config
|
||||
|
||||
######################################################################
|
||||
# Test targets
|
||||
|
||||
dist-file-list:
|
||||
@echo "begin-dist-file-list:"; # Scripts look for this
|
||||
@echo $(wildcard $(DISTFILES))
|
||||
@echo "end-dist-file-list:"; # Scripts look for this
|
||||
|
||||
print-cfg-with-threaded:
|
||||
@echo $(CFG_WITH_THREADED)
|
||||
|
||||
######################################################################
|
||||
# Distributions
|
||||
|
||||
DISTCONFIG = src/config_build.h.in
|
||||
|
||||
DISTTITLE := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e 's/v/V/' -e q $(DISTCONFIG))
|
||||
DISTNAME := $(shell sed -e '/DTVERSION/!d' -e 's/[^0-9]*\([0-9.a-z]*\).*/verilator-\1/' -e q $(DISTCONFIG))
|
||||
DISTDATEPRE := $(shell sed -e '/DTVERSION/!d' -e 's/.*\([0-3]\?[0-9].[0-3]\?[0-9].[1-2][0-9][0-9][0-9]\).*/\1/' -e q $(DISTCONFIG))
|
||||
DISTTITLE := Verilator $(word 1,$(PACKAGE_VERSION))
|
||||
DISTNAME := verilator-$(word 1,$(PACKAGE_VERSION))
|
||||
DISTDATEPRE := $(word 2,$(PACKAGE_VERSION))
|
||||
DISTDATE := $(subst /,-,$(DISTDATEPRE))
|
||||
|
||||
DISTTAGNAME := $(subst .,_,$(subst -,_,$(DISTNAME)))
|
||||
DISTDATE := $(subst /,-,$(DISTDATEPRE))
|
||||
|
||||
tag:
|
||||
svnorcvs tag $(DISTTAGNAME)
|
||||
@@ -339,14 +567,14 @@ dist: $(DISTDEP) maintainer-copy
|
||||
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:
|
||||
test ! -r ~/src/kits/$(DISTNAME).tar.gz
|
||||
svnorcvs nexists $(DISTTAGNAME)
|
||||
|
||||
maintainer-dist: preexist dist tag
|
||||
cp *.gz ~/backpack
|
||||
cp *.gz ~/src/kits
|
||||
svnorcvs release $(DISTNAME).tgz
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
1 Verilator
|
||||
***********
|
||||
|
||||
This is the Verilator Package.
|
||||
|
||||
1.1 Copyright
|
||||
=============
|
||||
|
||||
This package is Copyright 2003-2007 by Wilson Snyder
|
||||
<[email protected]>.
|
||||
|
||||
You may distribute under the terms of either the GNU General Public
|
||||
License or the Artistic License, as specified in the Perl README file.
|
||||
|
||||
This code is provided with no warranty of any kind, and is used
|
||||
entirely at your own risk.
|
||||
|
||||
1.2 Description
|
||||
===============
|
||||
|
||||
Verilator converts synthesizable (not behavioral) Verilog code into C++
|
||||
or SystemC code. It is not a complete simulator, just a translator.
|
||||
|
||||
Verilator is invoked with parameters similar to GCC or Synopsys's
|
||||
VCS. It reads the specified Verilog code, lints it, and optionally
|
||||
adds coverage code. For C++ format, it outputs .cpp and .h files. For
|
||||
SystemC format, it outputs .sp files for the SystemPerl preprocessor
|
||||
available at http://veripool.com.
|
||||
|
||||
The resulting files are then compiled with C++. The user writes a
|
||||
little C++ wrapper file, which instantiates the top level module. This
|
||||
is compiled in C++, and linked with the Verilated files.
|
||||
|
||||
The resulting executable will perform the actual simulation.
|
||||
|
||||
1.3 Obtaining Distribution
|
||||
==========================
|
||||
|
||||
The latest version is available at `http://veripool.com/verilator.htm'
|
||||
|
||||
Download the latest package from that site, and decompress. `gunzip
|
||||
verilator_version.tar.gz ; tar xvf verilator_version.tar'
|
||||
|
||||
1.4 Directory Structure
|
||||
=======================
|
||||
|
||||
The directories after de-taring are as follows:
|
||||
|
||||
* bin/verilator => Compiler Wrapper invoked on user Verilog code
|
||||
|
||||
* include/ => Files that should be in your -I compiler
|
||||
path
|
||||
|
||||
* include/verilated.cpp => Global routines to link into your
|
||||
simulator
|
||||
|
||||
* include/verilated.h => Global headers
|
||||
|
||||
* include/verilated.v => Stub defines for linting
|
||||
|
||||
* include/verilated.mk => Common makefile
|
||||
|
||||
* src/ => Translator source code
|
||||
|
||||
* test_v => Example Verilog code for other test dirs
|
||||
|
||||
* test_c => Example Verilog->C++ conversion
|
||||
|
||||
* test_sc => Example Verilog->SystemC conversion
|
||||
|
||||
* test_sp => Example Verilog->SystemPerl conversion
|
||||
|
||||
* test_vcs => Example Verilog->VCS conversion (test the
|
||||
test)
|
||||
|
||||
* test_verilated => Internal tests
|
||||
|
||||
* test_regress => Internal tests
|
||||
|
||||
1.5 Supported Systems
|
||||
=====================
|
||||
|
||||
This version of verilator has been built and tested on:
|
||||
|
||||
* SuSE AMD64 i686-linux-2.6.5
|
||||
|
||||
Other users report success with Redhat Linux 2.4, Windows under
|
||||
Cygwin, HPUX and Solaris. It should run with minor porting on any Unix
|
||||
system.
|
||||
|
||||
1.6 Installation
|
||||
================
|
||||
|
||||
1. If you will be using SystemC (vs straight C++ output), download
|
||||
SystemC 2.0.1 from `http://www.systemc.org'. Follow their
|
||||
installation instructions. As described in the System-Perl README,
|
||||
you will need to set SYSTEMC and/or SYSTEMC_KIT to point to this
|
||||
download. Also, set SYSTEMC_ARCH to the architecture name you used
|
||||
with SystemC, generally 'linux' or 'cygwin'.
|
||||
|
||||
2. If you will be using SystemC, download and install Verilog-Perl,
|
||||
`http://search.cpan.org/search?module=Verilog::Language'.
|
||||
|
||||
3. If you will be using SystemC, download and install System-Perl,
|
||||
`http://search.cpan.org/search?module=SystemC::Netlist'. Note
|
||||
you'll need to set a `SYSTEMPERL' environment variable to point to
|
||||
the downloaded kit (not the installed files.) Also, make sure to
|
||||
do a `make sc_patch'.
|
||||
|
||||
4. `cd' to the Verilator directory containing this README.
|
||||
|
||||
5. Type `./configure' to configure Verilator for your system.
|
||||
|
||||
6. Type `make' to compile Verilator.
|
||||
|
||||
On Cygwin (Windows) you may get a error about libperl.a not being
|
||||
found. You need to copy your perl libraries as follows.
|
||||
|
||||
1. Type `perl -MExtUtils::Embed -e ldopts'
|
||||
|
||||
2. It will show a directory name ending in /CORE. cd to that
|
||||
directory.
|
||||
|
||||
3. `cp libperl5_6_1.a libperl.a'
|
||||
|
||||
4. `cp libperl5_6_1.dll libperl.dll'
|
||||
|
||||
5. `cp libperl5_6_1.def libperl.def'
|
||||
|
||||
7. Type `make test' to check the compilation.
|
||||
|
||||
You may get a error about the Bit::Vector perl package. You will
|
||||
need to install it if you want the tests to pass. (Try `make
|
||||
test_c' for a smaller test that doesn't require it.)
|
||||
|
||||
You may get a error about a typedef conflict for uint32_t. Edit
|
||||
verilated.h to change the typedef to work, probably to `typedef
|
||||
unsigned long uint32_t;'.
|
||||
|
||||
If you get warnings, you might want to edit `include/verilated.mk'
|
||||
to delete the lines that define VK_CPPFLAGS_WALL.
|
||||
|
||||
8. There is no installation at present; this package runs from the
|
||||
distribution directory. Programs should set the environment
|
||||
variable VERILATOR_ROOT to point to this distribution, then execute
|
||||
$VERILATOR_ROOT/bin/verilator, which will find the path to all
|
||||
needed files.
|
||||
|
||||
Verilator assumes you did a make in the SystemC kit directory. If
|
||||
not, you will need to populate `$SYSTEMC/include' and
|
||||
`$SYSTEMC/lib-linux' appropriately.
|
||||
|
||||
If you will be modifying Verilator, you will probably want a second
|
||||
stable copy of this kit for others to use while you experiment.
|
||||
|
||||
9. Detailed documentation and the man page can be seen by running:
|
||||
|
||||
bin/verilator -help
|
||||
|
||||
or reading verilator.txt in the same directory as this README.
|
||||
|
||||
|
||||
1.7 Limitations
|
||||
===============
|
||||
|
||||
See verilator.txt (or execute `bin/verilator --help') for limitations.
|
||||
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
# DESCRIPTION: DOCUMENT source run through perl to produce README file
|
||||
# Use 'make README' to produce the output file
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
This is the Verilator package README file.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
http://www.veripool.org/verilator
|
||||
|
||||
This package is Copyright 2003-2019 by Wilson Snyder. (Report bugs to
|
||||
L<http://www.veripool.org/>.)
|
||||
|
||||
Verilator is free software; you can redistribute it and/or modify it under
|
||||
the terms of either the GNU Lesser General Public License Version 3 or the
|
||||
Perl Artistic License Version 2.0. (See the documentation for more
|
||||
details.)
|
||||
|
||||
This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
more details.
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Verilator converts synthesizable (generally not behavioral) Verilog code
|
||||
into C++ or SystemC code. It is not a complete simulator, just a
|
||||
translator.
|
||||
|
||||
Verilator is invoked with parameters similar to GCC or Synopsys's VCS. It
|
||||
reads the specified Verilog code, lints it, and optionally adds coverage
|
||||
code. For C++ format, it outputs .cpp and .h files. For SystemC format,
|
||||
it outputs .cpp and .h files using the standard SystemC headers.
|
||||
|
||||
The resulting files are then compiled with C++. The user writes a little
|
||||
C++ wrapper file, which instantiates the top level module. This is
|
||||
compiled in C++, and linked with the Verilated files.
|
||||
|
||||
The resulting executable will perform the actual simulation.
|
||||
|
||||
=head1 SUPPORTED SYSTEMS
|
||||
|
||||
Verilator is developed and has primary testing on Ubuntu. Versions have
|
||||
also built on Redhat Linux, Macs OS-X, HPUX and Solaris. It should run
|
||||
with minor porting on any Linix-ish platform. Verilator also works on
|
||||
Windows under Cygwin, and Windows under MinGW (gcc -mno-cygwin). Verilated
|
||||
output (not Verilator itself) compiles under MSVC++ 2008 and newer.
|
||||
|
||||
=head1 INSTALLATION
|
||||
|
||||
For more details see
|
||||
L<http://www.veripool.org/projects/verilator/wiki/Installing>.
|
||||
|
||||
If you will be modifying Verilator, you should use the "git" method as it
|
||||
will let you track changes.
|
||||
|
||||
=over 4
|
||||
|
||||
=item
|
||||
|
||||
The latest version is available at L<http://www.veripool.org/verilator>.
|
||||
|
||||
Download the latest package from that site, and decompress.
|
||||
|
||||
tar xvzf verilator_version.tgz
|
||||
|
||||
=item
|
||||
|
||||
If you will be using SystemC (vs straight C++ output), download SystemC
|
||||
from L<http://www.systemc.org>. Follow their installation instructions.
|
||||
You will need to set SYSTEMC_INCLUDE to point to the include directory with
|
||||
systemc.h in it, and SYSTEMC_LIBDIR to points to the directory with
|
||||
libsystemc.a in it. (Older installations may set SYSTEMC and SYSTEMC_ARCH
|
||||
instead.)
|
||||
|
||||
=item
|
||||
|
||||
To use Verilator you will need the C<perl>, C<make> (or C<gmake>), and
|
||||
C<g++> (or C<clang>) packages.
|
||||
|
||||
To use Verilator FST tracing you will need the C<gtkwave> and C<libgz> (on
|
||||
Ubuntu C<zlibc> C<zlib1g> C<zlib1g-dev>) packages installed.
|
||||
|
||||
To compile Verilator in addition to the above you need the C<flex>,
|
||||
C<bison> and C<texi2html> packages installed.
|
||||
|
||||
=item
|
||||
|
||||
C<cd> to the Verilator directory containing this README.
|
||||
|
||||
=item
|
||||
|
||||
You now have to decide how you're going to eventually install the kit.
|
||||
|
||||
Note Verilator builds the current value of VERILATOR_ROOT, SYSTEMC_INCLUDE,
|
||||
and SYSTEMC_LIBDIR as defaults into the executable, so try to have them
|
||||
correct before configuring.
|
||||
|
||||
=over 4
|
||||
|
||||
=item 1.
|
||||
|
||||
Our personal favorite is to always run Verilator from the kit directory.
|
||||
This allows the easiest experimentation and upgrading. It's also how most
|
||||
EDA tools operate; to run you point to the tarball, no install is needed.
|
||||
|
||||
export VERILATOR_ROOT=`pwd` # if your shell is bash
|
||||
setenv VERILATOR_ROOT `pwd` # if your shell is csh
|
||||
./configure
|
||||
|
||||
=item 2.
|
||||
|
||||
To install globally onto a "cad" disk with multiple versions of every tool,
|
||||
and add it to path using Modules/modulecmd:
|
||||
|
||||
unset VERILATOR_ROOT # if your shell is bash
|
||||
unsetenv VERILATOR_ROOT # if your shell is csh
|
||||
# For the tarball, use the version number instead of git describe
|
||||
./configure --prefix /CAD_DISK/verilator/`git describe | sed "s/verilator_//"`
|
||||
|
||||
After installing you'll want a module file like the following:
|
||||
|
||||
set install_root /CAD_DISK/verilator/{version-number-used-above}
|
||||
unsetenv VERILATOR_ROOT
|
||||
prepend-path PATH $install_root/bin
|
||||
prepend-path MANPATH $install_root/man
|
||||
prepend-path PKG_CONFIG_PATH $install_root/share/pkgconfig
|
||||
|
||||
=item 3.
|
||||
|
||||
The next option is to install it globally, using the normal system paths:
|
||||
|
||||
unset VERILATOR_ROOT # if your shell is bash
|
||||
unsetenv VERILATOR_ROOT # if your shell is csh
|
||||
./configure
|
||||
|
||||
=item 4.
|
||||
|
||||
Alternatively you can configure a prefix that install will populate, as
|
||||
most GNU tools support:
|
||||
|
||||
unset VERILATOR_ROOT # if your shell is bash
|
||||
unsetenv VERILATOR_ROOT # if your shell is csh
|
||||
./configure --prefix /opt/verilator-VERSION
|
||||
|
||||
Then after installing you will need to add /opt/verilator-VERSION/bin to
|
||||
PATH.
|
||||
|
||||
=back
|
||||
|
||||
=item
|
||||
|
||||
Type C<make> to compile Verilator.
|
||||
|
||||
Type C<make test> to check the compilation.
|
||||
|
||||
Configure with C<--enable-longtests> for more complete developer tests.
|
||||
Additional packages may be required for these tests.
|
||||
|
||||
You may get a error about a typedef conflict for uint32_t. Edit
|
||||
verilated.h to change the typedef to work, probably to @samp{typedef
|
||||
unsigned long uint32_t;}.
|
||||
|
||||
=item
|
||||
|
||||
If you used the VERILATOR_ROOT scheme you're done. Programs should set the
|
||||
environment variable VERILATOR_ROOT to point to this distribution, then
|
||||
execute $VERILATOR_ROOT/bin/verilator, which will find the path to all
|
||||
needed files.
|
||||
|
||||
If you used the prefix scheme, now do a C<make install>. To run verilator,
|
||||
have the verilator binary directory in your PATH (this should already be
|
||||
true if using the default configure), and make sure VERILATOR_ROOT is not
|
||||
set.
|
||||
|
||||
You may now wish to consult the examples directory. Type C<make> inside any
|
||||
example directory to run the example.
|
||||
|
||||
=back
|
||||
|
||||
=head1 USAGE DOCUMENTATION
|
||||
|
||||
Detailed documentation and the man page can be seen by running:
|
||||
|
||||
bin/verilator --help
|
||||
|
||||
or reading verilator.txt in the same directory as this README.
|
||||
|
||||
=head1 DIRECTORY STRUCTURE
|
||||
|
||||
The directories in the kit after de-taring are as follows:
|
||||
|
||||
bin/verilator => Compiler Wrapper invoked to Verilate code
|
||||
include/ => Files that should be in your -I compiler path
|
||||
include/verilated*.cpp => Global routines to link into your simulator
|
||||
include/verilated*.h => Global headers
|
||||
include/verilated.v => Stub defines for linting
|
||||
include/verilated.mk => Common makefile
|
||||
src/ => Translator source code
|
||||
examples/hello_world_c => Example simple Verilog->C++ conversion
|
||||
examples/hello_world_sc => Example simple Verilog->SystemC conversion
|
||||
examples/tracing_c => Example Verilog->C++ with tracing
|
||||
examples/tracing_sc => Example Verilog->SystemC with tracing
|
||||
test_regress => Internal tests
|
||||
|
||||
=head1 LIMITATIONS
|
||||
|
||||
See verilator.txt (or execute C<bin/verilator --help>) for limitations.
|
||||
@@ -1,138 +1,119 @@
|
||||
// $Id$
|
||||
// DESCRIPTION: Verilator: List of To Do issues.
|
||||
//
|
||||
// Copyright 2004-2007 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2004-2019 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// General Public License or the Perl Artistic License.
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
|
||||
* Language support:
|
||||
** Fix ordering of each bit separately in a signal (mips)
|
||||
assign b[3:0] = b[7:4]; assign b[7:4] = in;
|
||||
** Support UDP gate primitives/ cell libraries
|
||||
(have code for combos - problem is sequential udps)
|
||||
** Function to eval combo logic after /*verilator public*/ functions [gwaters]
|
||||
** Support generated clocks (correctness)
|
||||
** Recursive functions
|
||||
** Verilog configuration files
|
||||
** Expression coverage (see notes)
|
||||
** Better tristate support
|
||||
** UVM
|
||||
|
||||
Features:
|
||||
Finish 3.400 new ordering fixes
|
||||
Latch optimizations {Need here}
|
||||
Task I/Os connecting to non-simple variables.
|
||||
Fix nested casez statements expanding into to huge C++. [JeanPaul Vanitegem]
|
||||
Fix FileLine memory inefficiency
|
||||
Fix ordering of each bit separately in a signal (mips)
|
||||
assign b[3:0] = b[7:4]; assign b[7:4] = in;
|
||||
Support gate primitives/ cell libraries from xilinx, etc
|
||||
Assign dont_care value to an 1'bzzz assignment
|
||||
Function to eval combo logic after /*verilator public*/ functions [gwaters]
|
||||
Support generated clocks (correctness)
|
||||
?gcov coverage
|
||||
Selectable SystemC types based on widths (see notes below)
|
||||
Compile time
|
||||
Inline first level trace routines
|
||||
Coverage
|
||||
Points should be per-scope like everything else rather then per-module
|
||||
Expression coverage (see notes)
|
||||
More Verilog 2001 Support
|
||||
C-style function and task arguments. [Wim Michiels]
|
||||
(* *) Attributes (just ignore -- preprocessor?)
|
||||
Real numbers (NEVER)
|
||||
Recursive functions (NEVER)
|
||||
Verilog configuration files (NEVER)
|
||||
* Long-term Features
|
||||
** Assertions
|
||||
** Tristate support
|
||||
|
||||
Long-term Features
|
||||
Assertions
|
||||
VHDL parser [Philips]
|
||||
Tristate support
|
||||
SystemPerl integration
|
||||
Multithreaded execution
|
||||
Front end parser integration into Verilog-Perl like Netlist
|
||||
* Configure/Make/Install
|
||||
** Distribute with flex/bison already expanded?
|
||||
Flex library not needed. Probably too difficult to be worth it.
|
||||
|
||||
Testing:
|
||||
Capture all inputs into global "rerun it" file
|
||||
Code to make wrapper that sets signals, so can do comparison checks
|
||||
New random program generator
|
||||
Better graph viewer with search and zoom
|
||||
Port and test against opencores.org code
|
||||
* Testing:
|
||||
** Capture all inputs into global "rerun it" file
|
||||
** Code to make wrapper that sets signals, so can do comparison checks
|
||||
** New random program generator
|
||||
** Better graph viewer with search and zoom
|
||||
** Port and test against opencores.org code
|
||||
** // verilator debug in code so can see only tree affecting those nodes
|
||||
|
||||
Performance:
|
||||
Constant propagation
|
||||
Extra cleaning AND: 1 & ((VARREF >> 1) | ((&VARREF >> 1) & VARREF))
|
||||
Extra shift (perhaps due to clean): if (1 & CAST (VARREF >> #))
|
||||
Gated clock and latch conversion to flops. [JeanPaul Vanitegem]
|
||||
Could propagate the AND into pos/negedges and let domaining optimize.
|
||||
Negedge reset
|
||||
Switch to remove negedges that don't matter
|
||||
Can't remove async resets from control flops (like in syncronizers)
|
||||
If all references to array have a constant index, blow up into separate signals-per-index
|
||||
Multithreaded execution
|
||||
Bit-multiply for faster bit swapping and a=b[1,3,2] random bit reorderings.
|
||||
Move _last sets and all other combo logic inside master
|
||||
if() that triggers on all possible sense items
|
||||
Rewrite and combine V3Life, V3Subst
|
||||
If block temp only ever set in one place to constant, propagate it
|
||||
Used in t_mem for array delayed assignments
|
||||
Replace variables if set later in same cfunc branch
|
||||
See for example duplicate sets of _narrow in cycle 90/91 of t_select_plusloop
|
||||
Same assignment on both if branches
|
||||
"if (a) { ... b=2; } else { ... b=2;}" -> "b=2; if ..."
|
||||
Careful though, as b could appear in the statement or multiple times in statement
|
||||
(Could just require exatly two 'b's in statement)
|
||||
Simplify XOR/XNOR/AND/OR bit selection trees
|
||||
Foo = A[1] ^ A[2] ^ A[3] etc are better as ^ ( A & 32'b...1110 )
|
||||
Combine variables into wider elements
|
||||
Parallel statements on different bits should become single signal
|
||||
Variables that are always consumed in "parallel" can be joined
|
||||
Duplicate assignments in gate optimization
|
||||
Common to have many separate posedge blocks, each with identical
|
||||
reset_r <= rst_in
|
||||
*If signal is used only once (not counting trace), always gate substitute
|
||||
Don't merge if any combining would form circ logic (out goes back to in)
|
||||
Multiple assignments each bit can become single assign with concat
|
||||
Make sure a SEL of a CONCAT can get the single bit back.
|
||||
Usually blocks/values
|
||||
Enable only after certain time, so VL_TIME_I(32) > 0x1e gets eliminated out
|
||||
Better ordering of a<=b, b<=c, put all refs to 'b' next to each other to optimize caching
|
||||
Allow Split of case statements without a $display/$stop
|
||||
I-cache packing improvements (what/how?)
|
||||
Data cache organization (order of vars in class)
|
||||
First have clocks,
|
||||
then bools instead of uint32_t's
|
||||
then based on what sense list they come from, all outputs, then all inputs
|
||||
finally have any signals part of a "usually" block, or constant.
|
||||
Rather then tracking widths, have a MSB...LSB of this expression
|
||||
(or better, a bitmask of bits relevant in this expression)
|
||||
Track recirculation and convert into clock-enables
|
||||
Clock enables should become new clocking domains for speed
|
||||
If floped(a) & flopped(b) and no other a&b, then instead flop(a&b).
|
||||
Sort by output bitselects so can combine more assignments (see DDP example dx_dm signal)
|
||||
* Usability:
|
||||
** Detect and pre-remove most UNOPTFLATs
|
||||
** Better reporting of unopt problems, including what lines of code
|
||||
** Report more errors (all of them?) before exiting [Eugene Weber]
|
||||
** Auto-create scons config files
|
||||
** Print version/etc message at runtime. (4.000?)
|
||||
Include number of lines of code, percent comments, code complexity measurement
|
||||
<-80chars------------------------------------------------------------------->
|
||||
Verilator 3.600 - The fast free open-sourced simulator. Copyright 2001-2013.
|
||||
Verilated #### modules, #### instances, ##### sigs,
|
||||
#### non-comment lines, ##### ops, ### KB model size
|
||||
|
||||
//**********************************************************************
|
||||
//* Detailed notes on 'todo' features
|
||||
* Lint:
|
||||
** CDCRSTLOGIC should allow filtering with paths
|
||||
"waive CDCRSTLOGIC --from a.b.sig --to a.c.sig --via OR"
|
||||
|
||||
Selectable SystemC types based on widths (see notes below)
|
||||
Statements:
|
||||
verilator sc_type uint32_t {override specific I/O signals}
|
||||
verilator sc_typedef width 1 bool
|
||||
verilator sc_typedef width 2-32 uint32_t
|
||||
verilator sc_typedef width 33-64 uint64_t
|
||||
verilator sc_typedef width 65+ sc_bv<width> //<< programmable width
|
||||
Replace `systemc_clock, --pins64
|
||||
Have accessor function with type overloading to get or set the pin value.
|
||||
(Get rid of getdatap mess?)
|
||||
* Internal Code:
|
||||
** A Visitor class that understands how to traverse data types
|
||||
** V3Graph should be templated container type, taking in Vertex + Edge types
|
||||
** Instead of string, have an VEncodedString/VIdString which contains __DOT__ish
|
||||
things, to reduce bugs. Also add _20 trailing space to \ encoded names.
|
||||
|
||||
//**********************************************************************
|
||||
//* Eventual tristate bus Stuff allowed (old verilator)
|
||||
|
||||
1) Tristate assignments must be continuous assignments
|
||||
The RHS of a tristate assignment can be the following
|
||||
a) a node (tristate or non-tristate)
|
||||
b) a constant (must be all or no z's)
|
||||
x'b0, x'bz, x{x'bz}, x{x'b0} -> are allowed
|
||||
c) a conditional whose possible values are (a) or (b)
|
||||
|
||||
2) One can lose that fact that a node is a tristate node. This happens
|
||||
if a tristate node is assigned to a 'standard' node, or is used on
|
||||
RHS of a conditional. The following infer tristate signals:
|
||||
a) inout <SIGNAL>
|
||||
b) tri <SIGNAL>
|
||||
c) assigning to 'Z' (maybe through a conditional)
|
||||
Note: tristate-ness of an output port determined only by
|
||||
statements in the module (not the instances it calls)
|
||||
|
||||
4) Tristate variables can't be multidimensional arrays
|
||||
5) Only check tristate contention between modules (not within!)
|
||||
6) Only simple compares with 'Z' are allowed (===)
|
||||
* Runtime:
|
||||
** New evalulation loop ~/src/verilator/notes/event_loop.txt (4.000?)
|
||||
** Remove all private internal functions from top level wrapper header, move
|
||||
to new level
|
||||
** Completely standalone simulation
|
||||
main() records arguments for $test$plusvars
|
||||
instantiates top,
|
||||
does tracing (support $dump?)
|
||||
calls top->simulateForever()
|
||||
exits
|
||||
|
||||
* Performance:
|
||||
** Latch optimizations
|
||||
** Constant propagation
|
||||
Extra cleaning AND: 1 & ((VARREF >> 1) | ((&VARREF >> 1) & VARREF))
|
||||
Extra shift (perhaps due to clean): if (1 & CAST (VARREF >> #))
|
||||
** Gated clock and latch conversion to flops. [JeanPaul Vanitegem]
|
||||
Could propagate the AND into pos/negedges and let domaining optimize.
|
||||
** Negedge reset
|
||||
Switch to remove negedges that don't matter
|
||||
Can't remove async resets from control flops (like in syncronizers)
|
||||
** If all references to array have a constant index, blow up into separate signals-per-index
|
||||
** Bit-multiply for faster bit swapping and a=b[1,3,2] random bit reorderings.
|
||||
** Move _last sets and all other combo logic inside master
|
||||
if() that triggers on all possible sense items
|
||||
** Rewrite and combine V3Life, V3Subst
|
||||
If block temp only ever set in one place to constant, propagate it
|
||||
Used in t_mem for array delayed assignments
|
||||
Replace variables if set later in same cfunc branch
|
||||
See for example duplicate sets of _narrow in cycle 90/91 of t_select_plusloop
|
||||
** Same assignment on both if branches
|
||||
"if (a) { ... b=2; } else { ... b=2;}" -> "b=2; if ..."
|
||||
Careful though, as b could appear in the statement or multiple times in statement
|
||||
(Could just require exatly two 'b's in statement)
|
||||
** Simplify XOR/XNOR/AND/OR bit selection trees
|
||||
Foo = A[1] ^ A[2] ^ A[3] etc are better as ^ ( A & 32'b...1110 )
|
||||
** Combine variables into wider elements
|
||||
Parallel statements on different bits should become single signal
|
||||
Variables that are always consumed in "parallel" can be joined
|
||||
** Duplicate assignments in gate optimization
|
||||
Common to have many separate posedge blocks, each with identical
|
||||
reset_r <= rst_in
|
||||
** If signal is used only once (not counting trace), always gate substitute
|
||||
Don't merge if any combining would form circ logic (out goes back to in)
|
||||
** Multiple assignments each bit can become single assign with concat
|
||||
Make sure a SEL of a CONCAT can get the single bit back.
|
||||
** Usually blocks/values
|
||||
Enable only after certain time, so VL_TIME_I(32) > 0x1e gets eliminated out
|
||||
** Better ordering of a<=b, b<=c, put all refs to 'b' next to each other to optimize caching
|
||||
** I-cache packing improvements (what/how?)
|
||||
** Data cache organization (order of vars in class)
|
||||
First have clocks,
|
||||
then bools instead of uint32_t's
|
||||
then based on what sense list they come from, all outputs, then all inputs
|
||||
finally have any signals part of a "usually" block, or constant.
|
||||
** Rather then tracking widths, have a MSB...LSB of this expression
|
||||
(or better, a bitmask of bits relevant in this expression)
|
||||
** Track recirculation and convert into clock-enables
|
||||
** Clock enables should become new clocking domains for speed
|
||||
** If floped(a) & flopped(b) and no other a&b, then instead flop(a&b).
|
||||
** Sort by output bitselects so can combine more assignments (see DDP example dx_dm signal)
|
||||
|
||||
+3369
-621
File diff suppressed because it is too large
Load Diff
Executable
+293
@@ -0,0 +1,293 @@
|
||||
: # -*-Mode: perl;-*- use perl, wherever it is
|
||||
eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
######################################################################
|
||||
|
||||
require 5.006_001;
|
||||
use warnings;
|
||||
BEGIN {
|
||||
if ($ENV{DIRPROJECT} && $ENV{DIRPROJECT_PERL_BOOT}) {
|
||||
# Magic to allow author testing of perl packages in local directory
|
||||
require $ENV{DIRPROJECT}."/".$ENV{DIRPROJECT_PERL_BOOT};
|
||||
}
|
||||
}
|
||||
|
||||
use Getopt::Long;
|
||||
use FindBin qw($RealBin $RealScript);
|
||||
use IO::File;
|
||||
use Pod::Usage;
|
||||
use Cwd qw(abs_path getcwd);
|
||||
|
||||
use strict;
|
||||
use vars qw($Debug @Opt_Verilator_Sw);
|
||||
|
||||
#######################################################################
|
||||
#######################################################################
|
||||
# main
|
||||
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
|
||||
$Debug = 0;
|
||||
|
||||
# No arguments can't do anything useful. Give help
|
||||
if ($#ARGV < 0) {
|
||||
pod2usage(-exitstatus=>2, -verbose=>0);
|
||||
}
|
||||
|
||||
# We sneak a look at the flags so we can do some pre-environment checks
|
||||
# All flags will hit verilator...
|
||||
foreach my $sw (@ARGV) {
|
||||
$sw = "'$sw'" if $sw =~ m![^---a-zA-Z0-9_/\\:.+]!;
|
||||
push @Opt_Verilator_Sw, $sw;
|
||||
}
|
||||
|
||||
Getopt::Long::config("no_auto_abbrev","pass_through");
|
||||
if (! GetOptions (
|
||||
# Major operating modes
|
||||
"help" => \&usage,
|
||||
"debug:s" => \&debug,
|
||||
# "version!" => \&version, # Also passthru'ed
|
||||
# Additional parameters
|
||||
"<>" => sub {}, # Ignored
|
||||
)) {
|
||||
pod2usage(-exitstatus=>2, -verbose=>0);
|
||||
}
|
||||
|
||||
# Normal, non gdb
|
||||
run(verilator_coverage_bin()
|
||||
." ".join(' ',@Opt_Verilator_Sw));
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
||||
}
|
||||
|
||||
sub debug {
|
||||
shift;
|
||||
my $level = shift;
|
||||
$Debug = $level||3;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#######################################################################
|
||||
# Builds
|
||||
|
||||
sub verilator_coverage_bin {
|
||||
my $bin = "";
|
||||
# Use VERILATOR_ROOT if defined, else assume verilator_bin is in the search path
|
||||
my $basename = ($ENV{VERILATOR_COVERAGE_BIN}
|
||||
|| "verilator_coverage_bin_dbg");
|
||||
if (defined($ENV{VERILATOR_ROOT})) {
|
||||
my $dir = $ENV{VERILATOR_ROOT};
|
||||
if (-x "$dir/bin/$basename"
|
||||
|| -x "$dir/bin/$basename.exe") { # From a "make install" into VERILATOR_ROOT
|
||||
$bin = "$dir/bin/$basename";
|
||||
} else {
|
||||
$bin = "$dir/$basename"; # From pointing to kit directory
|
||||
}
|
||||
} else {
|
||||
if (-x "$RealBin/$basename"
|
||||
|| -x "$RealBin/$basename.exe") {
|
||||
$bin = "$RealBin/$basename"; # From path/to/verilator with verilator_bin installed
|
||||
} else {
|
||||
$bin = $basename; # Find in PATH
|
||||
}
|
||||
# Note we don't look under bin/$basename which would be right if running
|
||||
# in the kit dir. Running that would likely break, since
|
||||
# VERILATOR_ROOT wouldn't be set and Verilator won't find internal files.
|
||||
}
|
||||
return $bin;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#######################################################################
|
||||
# Utilities
|
||||
|
||||
sub run {
|
||||
# Run command, check errors
|
||||
my $command = shift;
|
||||
$! = undef; # Cleanup -x
|
||||
print "\t$command\n" if $Debug>=3;
|
||||
system($command);
|
||||
my $status = $?;
|
||||
if ($status) {
|
||||
if ($! =~ /no such file or directory/i) {
|
||||
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: $command\n";
|
||||
}
|
||||
if ($status & 127) {
|
||||
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;
|
||||
} else {
|
||||
warn "%Error: Verilator_coverage threw signal $status.\n" if !$Debug;
|
||||
}
|
||||
}
|
||||
die "%Error: Command Failed $command\n";
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
#######################################################################
|
||||
package main;
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
verilator_coverage - Verilator coverage analyzer
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
verilator_coverage --help
|
||||
verilator_coverage --version
|
||||
|
||||
verilator_coverage --annotate <obj>
|
||||
|
||||
verilator_coverage -write merged.dat -read <datafiles>...
|
||||
|
||||
Verilator_coverage processes Verilator coverage reports.
|
||||
|
||||
With --anotate, it reads the specified data file and generates annotated
|
||||
source code with coverage metrics annotated. If multiple coverage points
|
||||
exist on the same line, additional lines will be inserted to report the
|
||||
additional points.
|
||||
|
||||
Additional Verilog-standard arguments specify the search paths necessary to
|
||||
find the source code that the coverage analysis was performed on.
|
||||
|
||||
To get correct coverage percentages, you may wish to read logs/coverage.dat
|
||||
into Emacs and do a M-x keep-lines to include only those statistics of
|
||||
interest.
|
||||
|
||||
For Verilog conditions that should never occur, you should add a $stop
|
||||
statement. This will remove the coverage during the next build.
|
||||
|
||||
=head1 ARGUMENTS
|
||||
|
||||
=over 4
|
||||
|
||||
=item I<filename>
|
||||
|
||||
Specify input data file, may be repeated to read multiple inputs. If no
|
||||
data file is specified, by default coverage.dat is read.
|
||||
|
||||
=item --annotate I<output_directory>
|
||||
|
||||
Sprcifies the directory name that source files with annotated coverage data
|
||||
should be written to.
|
||||
|
||||
=item --annotate-all
|
||||
|
||||
Specifies all files should be shown. By default, only those source files
|
||||
which have low coverage are written to the output directory.
|
||||
|
||||
=item --annotate-min I<count>
|
||||
|
||||
Specifies the minimum occurrence count that should be flagged if the
|
||||
coverage point does not include a specified threshold. Defaults to 10.
|
||||
|
||||
=item --help
|
||||
|
||||
Displays this message and program version and exits.
|
||||
|
||||
=item --rank
|
||||
|
||||
Print an experimental report listing the relative importance of each test
|
||||
in covering all of the coverage points. The report shows "Covered" which
|
||||
indicates the number of points that test covers; a test is considered to
|
||||
cover a point if it has a bucket count of at least 1. The "rank" column has
|
||||
a higher number t indicate the test is more important, and rank 0 means the
|
||||
test does not need to be run to cover the points. "RankPts" indicates the
|
||||
number of coverage points this test will contribute to overall coverage if
|
||||
all tests are run in the order of highest to lowest rank.
|
||||
|
||||
=item --unlink
|
||||
|
||||
When using --write to combine coverage data, unlink all input files after
|
||||
the output has been created.
|
||||
|
||||
=item --version
|
||||
|
||||
Displays program version and exits.
|
||||
|
||||
=item --write I<filename>
|
||||
|
||||
Specifies the aggregate coverage results, summed across all the files,
|
||||
should be written to the given filename. This is useful in scripts to
|
||||
combine many sequential runs into one master coverage file.
|
||||
|
||||
=back
|
||||
|
||||
=head1 VERILOG ARGUMENTS
|
||||
|
||||
The following arguments are compatible with GCC, VCS and most Verilog
|
||||
programs.
|
||||
|
||||
=over 4
|
||||
|
||||
=item +libext+I<ext>+I<ext>...
|
||||
|
||||
Defines the extensions for Verilog files.
|
||||
|
||||
=item +define+I<var>+I<value>
|
||||
=item -DI<var>=I<value>
|
||||
|
||||
Defines the given variable.
|
||||
|
||||
=item +incdir+I<dir>
|
||||
=item -II<dir>
|
||||
|
||||
Specifies a directory for finding include files.
|
||||
|
||||
=item -f I<file>
|
||||
|
||||
Specifies a file containing additional command line arguments.
|
||||
|
||||
=item -y I<dir>
|
||||
|
||||
Specifies a module search directory.
|
||||
|
||||
=back
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2003-2019 by Wilson Snyder. Verilator 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.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Wilson Snyder <[email protected]>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
C<verilator>
|
||||
|
||||
L<verilator_coverage --help> which is the source for this document.
|
||||
|
||||
=cut
|
||||
|
||||
######################################################################
|
||||
+110
-53
@@ -1,19 +1,7 @@
|
||||
: # -*-Mode: perl;-*- use perl, wherever it is
|
||||
eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
# $Id$
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2005-2007 by Wilson Snyder <[email protected]>. This
|
||||
# program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of either the GNU Lesser General Public License or the Perl
|
||||
# Artistic License.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
require 5.006_001;
|
||||
@@ -22,10 +10,23 @@ use Getopt::Long;
|
||||
use IO::File;
|
||||
use Pod::Usage;
|
||||
use strict;
|
||||
use vars qw ($Debug);
|
||||
use vars qw($Debug);
|
||||
|
||||
#======================================================================
|
||||
|
||||
# Old version 1 dump nodes with no dtypep's
|
||||
our %Ver1_Non_Dtyped = map {$_ => 1} qw(
|
||||
ACTIVE ALWAYS ALWAYSPOST ALWAYSPUBLIC ATTROF BEGIN BREAK CASE CASEITEM
|
||||
CCALL CELL CELLINLINE CFILE CFUNC CHANGEDET CLOCKING COMMENT CONTINUE
|
||||
COVERDECL COVERINC COVERTOGGLE CRETURN CSTMT DEFPARAM DISABLE DISPLAY DOT
|
||||
DPIEXPORT FCLOSE FFLUSH FINAL FINISH FOPEN GENCASE GENERATE GENFOR GENIF
|
||||
IF IMPLICIT INITARRAY INITIAL JUMPGO JUMPLABEL MODULE NETLIST
|
||||
NOTFOUNDMODULE PACKAGE PACKAGEIMPORT PARSEREF PIN PORT PRAGMA PRIMITIVE
|
||||
PSLASSERT PSLCOVER PSLDEFCLOCK PULL RANGE READMEM REPEAT RETURN SCCTOR
|
||||
SCDTOR SCHDR SCIMP SCIMPHDR SCINT SCOPE SELBIT SELEXTRACT SELMINUS
|
||||
SELPLUS SENGATE SENITEM SENTREE SFORMAT SFORMATF STOP SYSIGNORE SYSTEMT
|
||||
TASK TASKREF TEXT TOPSCOPE TYPEDEFFWD TYPETABLE UCSTMT UDPTABLE
|
||||
UDPTABLELINE UNTILSTABLE VASSERT WHILE );
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
@@ -33,14 +34,17 @@ use vars qw ($Debug);
|
||||
$Debug = 0;
|
||||
my $Opt_A;
|
||||
my $Opt_B;
|
||||
my $Opt_Lineno = 1;
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
if (! GetOptions (
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
usage();
|
||||
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";
|
||||
}
|
||||
|
||||
defined $Opt_A or die "%Error: No old diff filename\n";
|
||||
@@ -50,9 +54,9 @@ defined $Opt_B or die "%Error: No new diff filename\n";
|
||||
-e $Opt_B or die "%Error: No new diff filename found: $Opt_B\n";
|
||||
|
||||
if (-d $Opt_A && -d $Opt_B) {
|
||||
diff_dir ($Opt_A, $Opt_B);
|
||||
diff_dir($Opt_A, $Opt_B);
|
||||
} elsif (-f $Opt_A && -f $Opt_B) {
|
||||
diff_file ($Opt_A, $Opt_B);
|
||||
diff_file($Opt_A, $Opt_B);
|
||||
} else {
|
||||
die "%Error: Mix of files and dirs\n";
|
||||
}
|
||||
@@ -64,48 +68,98 @@ sub diff_dir {
|
||||
my %files;
|
||||
|
||||
foreach my $fn (glob("$a/*.tree")) {
|
||||
(my $base = $fn) =~ s!.*/!!;
|
||||
$files{$base}{a} = $fn;
|
||||
(my $base = $fn) =~ s!.*/!!;
|
||||
$files{$base}{a} = $fn;
|
||||
}
|
||||
foreach my $fn (glob("$b/*.tree")) {
|
||||
(my $base = $fn) =~ s!.*/!!;
|
||||
$files{$base}{b} = $fn;
|
||||
(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);
|
||||
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");
|
||||
}
|
||||
|
||||
sub diff_file {
|
||||
my $a = shift;
|
||||
my $b = shift;
|
||||
# Compare the two tree files
|
||||
my $tmp_a = "/tmp/$$.a";
|
||||
my $tmp_b = "/tmp/$$.b";
|
||||
(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";
|
||||
|
||||
filter ($a, $tmp_a);
|
||||
filter ($b, $tmp_b);
|
||||
system("diff $tmp_a $tmp_b");
|
||||
my $vera = version_from($a);
|
||||
my $verb = version_from($b);
|
||||
my $verCvt = (($vera < 0x3900 && $verb >= 0x3900)
|
||||
|| ($vera >= 0x3900 && $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;
|
||||
}
|
||||
|
||||
sub version_from {
|
||||
my $fn = shift;
|
||||
# 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;
|
||||
}
|
||||
|
||||
sub filter {
|
||||
my $fn1 = shift;
|
||||
my $fn2 = shift;
|
||||
my $verCvt = shift;
|
||||
# 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())) {
|
||||
next if $line =~ / This=/;
|
||||
$line =~ s/0x[a-f0-9]+/0x/g;
|
||||
$line =~ s/<e[0-9]+\#?>/<e>/g;
|
||||
print $f2 $line;
|
||||
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/;
|
||||
$line =~ s!\@dt=0x\(G?/?([^)]+)\)!$1!g; # NEW: @dt -> OLD: non @dt format
|
||||
# # Below Ver1_Non_Dtyped may replace above further
|
||||
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;
|
||||
}
|
||||
if ($Ver1_Non_Dtyped{$type}) {
|
||||
$line =~ s! w[0-9]+!!g;
|
||||
}
|
||||
}
|
||||
$line =~ s!\@dt=0$!NoW!g; # NEW: dt=null -> common format
|
||||
$line =~ s!\@dt=0 !NoW !g; # NEW: dt=null -> common format
|
||||
$line =~ s! s?w0$! NoW!g; # OLD: no width -> common format
|
||||
$line =~ s! s?w0 ! NoW !g; # OLD: no width -> common format
|
||||
}
|
||||
print $f2 $line;
|
||||
}
|
||||
$f1->close;
|
||||
$f2->close;
|
||||
@@ -114,9 +168,8 @@ sub filter {
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
print '$Id$ ', "\n";
|
||||
pod2usage(-verbose=>2, -exitval => 2);
|
||||
exit (1);
|
||||
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sub debug {
|
||||
@@ -126,11 +179,11 @@ sub debug {
|
||||
sub parameter {
|
||||
my $param = shift;
|
||||
if (!defined $Opt_A) {
|
||||
$Opt_A = $param;
|
||||
$Opt_A = $param;
|
||||
} elsif (!defined $Opt_B) {
|
||||
$Opt_B = $param;
|
||||
} else {
|
||||
die "%Error: Unknown parameter: $param\n";
|
||||
$Opt_B = $param;
|
||||
} else {
|
||||
die "%Error: Unknown parameter: $param\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,15 +226,19 @@ directories, ignoring irrelevant pointer differences.
|
||||
|
||||
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<http://www.veripool.com/>.
|
||||
The latest version is available from L<http://www.veripool.org/verilator>.
|
||||
|
||||
Copyright 2005-2007 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 or the Perl Artistic License.
|
||||
Copyright 2005-2019 by Wilson Snyder. This package is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
@@ -195,5 +252,5 @@ C<verilator>
|
||||
|
||||
######################################################################
|
||||
### Local Variables:
|
||||
### compile-command: "$V4/bin/verilator_difftree $V4/test_c/obj_dir/V*_03_*.tree $V4N/test_c/obj_dir/V*_03_*.tree"
|
||||
### compile-command: "$V4/bin/verilator_difftree {$V4D,$V4}/test_regress/obj_dir/t_EXAMPLE/V*_03_*.tree"
|
||||
### End:
|
||||
|
||||
Executable
+560
@@ -0,0 +1,560 @@
|
||||
: # -*-Mode: perl;-*- use perl, wherever it is
|
||||
eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long;
|
||||
use IO::File;
|
||||
use Pod::Usage;
|
||||
use vars qw($Debug);
|
||||
|
||||
$Debug = 0;
|
||||
my $Opt_File;
|
||||
my $Opt_Time_Per_Char = 0; # rdtsc ticks per char in gantt chart, 0=auto
|
||||
my $opt_vcd = "profile_threads.vcd";
|
||||
|
||||
our %Threads;
|
||||
our %Mtasks;
|
||||
our %Global;
|
||||
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
Getopt::Long::config("no_auto_abbrev");
|
||||
if (! GetOptions(
|
||||
"help" => \&usage,
|
||||
"scale=i" => \$Opt_Time_Per_Char,
|
||||
"debug" => sub { $Debug = 1; },
|
||||
"vcd=s" => \$opt_vcd,
|
||||
"no-vcd!" => sub { $opt_vcd = undef; },
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
die "%Error: Bad usage, try 'verilator_gantt --help'\n";
|
||||
}
|
||||
|
||||
$Opt_File = "profile_threads.dat" if !defined $Opt_File;
|
||||
|
||||
process($Opt_File);
|
||||
write_vcd($opt_vcd) if defined $opt_vcd;
|
||||
exit(0);
|
||||
|
||||
#######################################################################
|
||||
|
||||
sub usage {
|
||||
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sub parameter {
|
||||
my $param = shift;
|
||||
if (!defined $Opt_File) {
|
||||
$Opt_File = $param;
|
||||
} else {
|
||||
die "%Error: Unknown parameter: $param\n";
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
|
||||
sub process {
|
||||
my $filename = shift;
|
||||
|
||||
read_data($filename);
|
||||
report();
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
|
||||
sub read_data {
|
||||
my $filename = shift;
|
||||
|
||||
%Global = (rdtsc_cycle_time => 0);
|
||||
|
||||
my $fh = IO::File->new ($filename) or die "%Error: $! $filename,";
|
||||
while (my $line = $fh->getline) {
|
||||
if ($line =~ m/VLPROF mtask\s(\d+)\sstart\s(\d+)\send\s(\d+)\selapsed\s(\d+)\spredict_time\s(\d+)\scpu\s(\d+)\son thread (\d+)/) {
|
||||
my $mtask = $1;
|
||||
my $start = $2;
|
||||
my $end = $3;
|
||||
my $elapsed_time = $4;
|
||||
my $predict_time = $5;
|
||||
my $cpu = $6;
|
||||
my $thread = $7;
|
||||
$Threads{$thread}{$start}{mtask} = $mtask;
|
||||
$Threads{$thread}{$start}{end} = $end;
|
||||
$Threads{$thread}{$start}{cpu} = $cpu;
|
||||
|
||||
if (!exists $Mtasks{$mtask}{elapsed}) {
|
||||
$Mtasks{$mtask}{elapsed} = 0;
|
||||
}
|
||||
$Mtasks{$mtask}{elapsed} += $elapsed_time;
|
||||
$Mtasks{$mtask}{predict} = $predict_time;
|
||||
$Mtasks{$mtask}{end} = max($Mtasks{$mtask}{end}, $end);
|
||||
}
|
||||
elsif ($line =~ /^VLPROFTHREAD/) {}
|
||||
elsif ($line =~ m/VLPROF arg\s+(\S+)\+([0-9.])\s*$/
|
||||
|| $line =~ m/VLPROF arg\s+(\S+)\s+([0-9.])\s*$/) {
|
||||
$Global{args}{$1} = $2;
|
||||
}
|
||||
elsif ($line =~ m/VLPROF stat\s+(\S+)\s+([0-9.]+)/) {
|
||||
$Global{stats}{$1} = $2;
|
||||
}
|
||||
elsif ($line =~ /^#/) {}
|
||||
elsif ($Debug) {
|
||||
chomp $line;
|
||||
print "Unk: $line\n";
|
||||
}
|
||||
# TODO -- this is parsing text printed by a client.
|
||||
# Really, verilator proper should generate this
|
||||
# if it's useful...
|
||||
if ($line =~ m/rdtsc time = (\d+) ticks/) {
|
||||
$Global{rdtsc_cycle_time} = $1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub report {
|
||||
print "Verilator Gantt report\n";
|
||||
|
||||
print "\nArgument settings:\n";
|
||||
foreach my $arg (sort keys %{$Global{args}}) {
|
||||
my $plus = ($arg =~ /^\+/) ? "+" : " ";
|
||||
printf " %s%s%d\n", $arg, $plus, $Global{args}{$arg};
|
||||
}
|
||||
|
||||
my $nthreads = scalar keys %Threads;
|
||||
$Global{cpus}{cpu_time} = {};
|
||||
foreach my $thread (keys %Threads) {
|
||||
# Make potentially multiple characters per column
|
||||
foreach my $start (keys %{$Threads{$thread}}) {
|
||||
my $cpu = $Threads{$thread}{$start}{cpu};
|
||||
my $elapsed = $Threads{$thread}{$start}{end} - $start;
|
||||
$Global{cpus}{cpu_time}{$cpu} += $elapsed;
|
||||
}
|
||||
}
|
||||
|
||||
my $mt_mtask_time = 0;
|
||||
my $long_mtask_time = 0;
|
||||
my $last_end = 0;
|
||||
foreach my $mtask (keys %Mtasks) {
|
||||
$mt_mtask_time += $Mtasks{$mtask}{elapsed};
|
||||
$last_end = max($last_end, $Mtasks{$mtask}{end});
|
||||
$long_mtask_time = max($long_mtask_time, $Mtasks{$mtask}{elapsed});
|
||||
}
|
||||
$Global{last_end} = $last_end;
|
||||
|
||||
report_graph();
|
||||
|
||||
# If we know cycle time in the same (rdtsc) units,
|
||||
# this will give us an actual utilization number,
|
||||
# (how effectively we keep the cores busy.)
|
||||
#
|
||||
# It also gives us a number we can compare against
|
||||
# serial mode, to estimate the overhead of data sharing,
|
||||
# which will show up in the total elapsed time. (Overhead
|
||||
# of synchronization and scheduling should not.)
|
||||
print "\nAnalysis:\n";
|
||||
printf " Total threads = %d\n", $nthreads;
|
||||
printf " Total mtasks = %d\n", scalar(keys %Mtasks);
|
||||
printf " Total cpus used = %d\n", scalar(keys %{$Global{cpus}});
|
||||
printf " Total yields = %d\n", $Global{stats}{yields};
|
||||
printf " Total eval time = %d rdtsc ticks\n", $Global{last_end};
|
||||
printf " Longest mtask time = %d rdtsc ticks\n", $long_mtask_time;
|
||||
printf " All-thread mtask time = %d rdtsc ticks\n", $mt_mtask_time;
|
||||
my $long_efficiency = $long_mtask_time/($Global{last_end});
|
||||
printf " Longest-thread efficiency = %0.1f%%\n", $long_efficiency*100;
|
||||
my $mt_efficiency = $mt_mtask_time/($Global{last_end}*$nthreads);
|
||||
printf " All-thread efficiency = %0.1f%%\n", $mt_efficiency*100;
|
||||
printf " All-thread speedup = %0.1f\n", $mt_efficiency*$nthreads;
|
||||
if ($Global{rdtsc_cycle_time} > 0) {
|
||||
my $ut = $mt_mtask_time / $Global{rdtsc_cycle_time};
|
||||
print "tot_mtask_cpu=$mt_mtask_time cyc=$Global{rdtsc_cycle_time} ut=$ut\n";
|
||||
}
|
||||
|
||||
my @p2e_ratios;
|
||||
my $min_p2e = 1000000;
|
||||
my $min_mtask;
|
||||
my $max_p2e = -1000000;
|
||||
my $max_mtask;
|
||||
foreach my $mtask (sort keys %Mtasks) {
|
||||
if ($Mtasks{$mtask}{elapsed} > 0) {
|
||||
if ($Mtasks{$mtask}{predict} == 0) {
|
||||
$Mtasks{$mtask}{predict} = 1; # don't log(0) below
|
||||
}
|
||||
my $p2e_ratio = log( $Mtasks{$mtask}{predict} / $Mtasks{$mtask}{elapsed} );
|
||||
#print "log(p2e $mtask) = $p2e_ratio (predict $Mtasks{$mtask}{predict}, elapsed $Mtasks{$mtask}{elapsed})\n";
|
||||
push @p2e_ratios, $p2e_ratio;
|
||||
|
||||
if ($p2e_ratio > $max_p2e) {
|
||||
$max_p2e = $p2e_ratio;
|
||||
$max_mtask = $mtask;
|
||||
}
|
||||
if ($p2e_ratio < $min_p2e) {
|
||||
$min_p2e = $p2e_ratio;
|
||||
$min_mtask = $mtask;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print "\nStatistics:\n";
|
||||
print " min log(p2e) = $min_p2e from mtask $min_mtask (predict $Mtasks{$min_mtask}{predict}, elapsed $Mtasks{$min_mtask}{elapsed})\n";
|
||||
print " max log(p2e) = $max_p2e from mtask $max_mtask (predict $Mtasks{$max_mtask}{predict}, elapsed $Mtasks{$max_mtask}{elapsed})\n";
|
||||
|
||||
my $stddev = stddev(\@p2e_ratios);
|
||||
my $mean = mean(\@p2e_ratios);
|
||||
print " mean = " . ($mean) . "\n";
|
||||
print " stddev = " . ($stddev) . "\n";
|
||||
print " e ^ stddev = " . exp($stddev). "\n";
|
||||
print "\n";
|
||||
}
|
||||
|
||||
sub report_graph {
|
||||
my $time_per = $Opt_Time_Per_Char;
|
||||
if ($time_per == 0) {
|
||||
$time_per = ($Global{last_end} / 40); # Start with 40 columns
|
||||
while ($time_per > 10) {
|
||||
my ($graph, $conflicts) = _make_graph($time_per);
|
||||
last if !$conflicts;
|
||||
$time_per = int($time_per/2);
|
||||
}
|
||||
# One more step so we can fit more labels
|
||||
$time_per = int($time_per/2);
|
||||
}
|
||||
|
||||
my ($graph, $conflicts) = _make_graph($time_per);
|
||||
|
||||
print "\nThread gantt graph:\n";
|
||||
print " Legend: One character width = $time_per rdtsc ticks\n";
|
||||
print " Legend: '&' = multiple mtasks in this period (character width)\n";
|
||||
|
||||
my $scale = " <-".$Global{last_end}." rdtsc total";
|
||||
for (my $col = length($scale); # -2 for '->' below
|
||||
$col < ($Global{last_end}/$time_per); ++$col) {
|
||||
$scale .= "-";
|
||||
}
|
||||
print " $scale->\n";
|
||||
|
||||
foreach my $thread (sort keys %{$graph}) {
|
||||
print " t: ";
|
||||
_print_graph_line($graph->{$thread}, '');
|
||||
}
|
||||
}
|
||||
|
||||
sub _make_graph {
|
||||
my $time_per = shift;
|
||||
|
||||
my $graph = {}; # {thread}{column}{char=>'x' or chars=>#}
|
||||
my $conflicts = 0;
|
||||
foreach my $thread (keys %Threads) {
|
||||
# Make potentially multiple characters per column
|
||||
foreach my $start (sort {$a <=> $b} keys %{$Threads{$thread}}) {
|
||||
my $end = $Threads{$thread}{$start}{end};
|
||||
my $mtask = $Threads{$thread}{$start}{mtask};
|
||||
my $cpu = $Threads{$thread}{$start}{cpu};
|
||||
|
||||
my $startcol = _time_col($time_per, $start);
|
||||
my $endcol = _time_col($time_per, $end);
|
||||
|
||||
my $label = "[";
|
||||
$label .= "$cpu"; # Maybe make optional in future
|
||||
my $width = $endcol - $startcol + 1;
|
||||
while (length($label) < ($width-1)) { # -1 for ']'
|
||||
$label .= "-";
|
||||
}
|
||||
$label .= "]";
|
||||
$graph->{$thread}[$startcol]{char} .= $label;
|
||||
}
|
||||
if ($Debug) {
|
||||
print "# Multicol: "; _print_graph_line($graph->{$thread}, '|');
|
||||
}
|
||||
# Expand line to one char per column
|
||||
for (my $col = 0; $col <= $#{$graph->{$thread}}; ++$col) {
|
||||
if (my $chars = $graph->{$thread}[$col]{char}) {
|
||||
my $ok = 1;
|
||||
for (my $coladd = 1; $coladd<length($chars); ++$coladd) {
|
||||
if ($graph->{$thread}[$col + $coladd]{char}) {
|
||||
$ok = 0; last;
|
||||
}
|
||||
}
|
||||
if (!$ok) {
|
||||
if ($chars =~ /\[.*\[/) { # Two begins or more
|
||||
$conflicts++;
|
||||
$graph->{$thread}[$col]{char} = "&";
|
||||
} else {
|
||||
$graph->{$thread}[$col]{char} = "[";
|
||||
}
|
||||
for (my $coladd = 1; $coladd<length($chars); ++$coladd) {
|
||||
if ($graph->{$thread}[$col + $coladd]{char}) {
|
||||
last;
|
||||
} else {
|
||||
$graph->{$thread}[$col + $coladd]{char} = 'x';
|
||||
}
|
||||
}
|
||||
} else {
|
||||
my $coladd = 0;
|
||||
foreach my $char (split //, $chars) {
|
||||
$graph->{$thread}[$col+$coladd]{char} = $char;
|
||||
++$coladd;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($Debug) {
|
||||
print "# Singlcol: "; _print_graph_line($graph->{$thread}, '|');
|
||||
}
|
||||
}
|
||||
print "# Conflicts $conflicts\n" if $Debug;
|
||||
return ($graph, $conflicts);
|
||||
}
|
||||
|
||||
sub _print_graph_line {
|
||||
my $graph_thread = shift;
|
||||
my $sep = shift;
|
||||
for (my $col = 0; $col <= $#{$graph_thread}; ++$col) {
|
||||
my $c = $graph_thread->[$col]{char}; $c=' ' if !defined $c;
|
||||
print $c, $sep;
|
||||
}
|
||||
print "\n";
|
||||
}
|
||||
|
||||
sub _time_col {
|
||||
my $time_per = shift;
|
||||
my $time = shift;
|
||||
return int($time/$time_per);
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
|
||||
sub write_vcd {
|
||||
my $filename = shift;
|
||||
print "Writing $filename\n";
|
||||
my $fh = IO::File->new(">$filename") or die "%Error: $! $filename,";
|
||||
my $vcd = {values => {}, # {<time>}{<code>} = value
|
||||
sigs => {}, # {<module>}{<sig}} = code
|
||||
code => 0,
|
||||
};
|
||||
|
||||
my %parallelism;
|
||||
foreach my $thread (keys %Threads) {
|
||||
my $mcode = ($vcd->{sigs}{threads}{"thread${thread}_mtask"} ||= $vcd->{code}++);
|
||||
foreach my $start (sort {$a <=> $b} keys %{$Threads{$thread}}) {
|
||||
my $end = $Threads{$thread}{$start}{end};
|
||||
my $mtask = $Threads{$thread}{$start}{mtask};
|
||||
my $cpu = $Threads{$thread}{$start}{cpu};
|
||||
$vcd->{values}{$start}{$mcode} = $mtask;
|
||||
$vcd->{values}{$end}{$mcode} = undef;
|
||||
$parallelism{$start}++;
|
||||
$parallelism{$end}--;
|
||||
|
||||
my $ccode = $vcd->{sigs}{cpus}{"cpu${cpu}_thread"} ||= $vcd->{code}++;
|
||||
$vcd->{values}{$start}{$ccode} = $thread;
|
||||
$vcd->{values}{$end}{$ccode} = undef;
|
||||
|
||||
my $mcode = $vcd->{sigs}{mtasks}{"mtask${mtask}_cpu"} ||= $vcd->{code}++;
|
||||
$vcd->{values}{$start}{$mcode} = $cpu;
|
||||
$vcd->{values}{$end}{$mcode} = undef;
|
||||
}
|
||||
}
|
||||
{
|
||||
my $pcode = ($vcd->{sigs}{Stats}{"parallelism"} ||= $vcd->{code}++);
|
||||
my $value = 0;
|
||||
foreach my $time (sort {$a<=>$b} keys %parallelism) {
|
||||
$value += $parallelism{$time};
|
||||
$vcd->{values}{$time}{$pcode} = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$fh->print('$version Generated by verilator_gantt $end'."\n");
|
||||
$fh->print('$timescale 1ns $end'."\n");
|
||||
$fh->print("\n");
|
||||
|
||||
my %all_codes;
|
||||
$fh->print(' $scope module gantt $end'."\n");
|
||||
foreach my $module (sort keys %{$vcd->{sigs}}) {
|
||||
$fh->printf(' $scope module %s $end'."\n", $module);
|
||||
foreach my $sig (sort keys %{$vcd->{sigs}{$module}}) {
|
||||
my $code = $vcd->{sigs}{$module}{$sig};
|
||||
$fh->printf(' $var wire 32 v%x %s [31:0] $end'."\n",
|
||||
$code, $sig);
|
||||
$all_codes{$code} = 1;
|
||||
}
|
||||
$fh->print(' $upscope $end'."\n");
|
||||
}
|
||||
$fh->print(' $upscope $end'."\n");
|
||||
$fh->print('$enddefinitions $end'."\n");
|
||||
$fh->print("\n");
|
||||
|
||||
my $first = 1;
|
||||
foreach my $time (sort {$a <=> $b} keys %{$vcd->{values}}) {
|
||||
if ($first) {
|
||||
$first = 0;
|
||||
# Start with Z for any signals without time zero data
|
||||
foreach my $code (keys %all_codes) {
|
||||
if (!defined $vcd->{values}{$time}{$code}) {
|
||||
$vcd->{values}{$time}{$code} = undef;
|
||||
}
|
||||
}
|
||||
}
|
||||
$fh->printf("#%d\n", $time);
|
||||
foreach my $code (sort keys %{$vcd->{values}{$time}}) {
|
||||
my $value = $vcd->{values}{$time}{$code};
|
||||
if (defined $value) {
|
||||
$fh->printf("b%b v%x\n", $value, $code);
|
||||
} else {
|
||||
$fh->printf("bz v%x\n", $code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# Similar to Statistics::Basic functions, but avoid a package dependency
|
||||
|
||||
sub max {
|
||||
my $n = $_[0]; shift;
|
||||
while (defined $_[0]) {
|
||||
$n = $_[0] if !defined $n || $_[0] > $n;
|
||||
shift;
|
||||
}
|
||||
return $n;
|
||||
}
|
||||
|
||||
sub mean {
|
||||
my $arrayref = shift;
|
||||
my $n = 0;
|
||||
my $sum = 0;
|
||||
foreach my $v (@$arrayref) {
|
||||
$sum += $v;
|
||||
$n++;
|
||||
}
|
||||
return undef if !$n;
|
||||
return $sum/$n;
|
||||
}
|
||||
|
||||
sub stddev {
|
||||
my $arrayref = shift;
|
||||
my $n = 0;
|
||||
my $sum = 0;
|
||||
my $sumsq = 0;
|
||||
foreach my $v (@$arrayref) {
|
||||
$sum += $v;
|
||||
$sumsq += $v**2;
|
||||
$n++;
|
||||
}
|
||||
return undef if !$n;
|
||||
return sqrt(($sumsq/$n) - ($sum/$n)**2);
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
verilator_gantt - Create Gantt chart of multi-threaded execution
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
Creates a visual representation to help analyze Verilator multithreaded
|
||||
simulation performance, by showing when each macro-task starts and ends,
|
||||
and showing when each thread is busy or idle.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
Also creates a value change dump (VCD) format dump file which may be viewed
|
||||
in a waveform viewer (e.g. C<GTKWave>). See below.
|
||||
|
||||
=head1 USAGE
|
||||
|
||||
Build with --prof-threads.
|
||||
|
||||
Run a sim with +verilator+prof+threads+window 2.
|
||||
|
||||
This will create profile_threads.dat.
|
||||
|
||||
Then run:
|
||||
|
||||
verilator_gantt profile_threads.dat
|
||||
|
||||
The report will be printed on standard output, this also generates
|
||||
profile_threads.vcd
|
||||
|
||||
View profile_threads.vcd in a waveform viewer.
|
||||
|
||||
=head1 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.
|
||||
|
||||
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 view this signal.
|
||||
|
||||
cpu#_thread: For the given CPU number, the thread number executing.
|
||||
|
||||
mtask#_cpu; For the given mtask id, the CPU it is executing on.
|
||||
|
||||
thread#_mtask: For the given thread number, the mtask id executing.
|
||||
|
||||
=head1 ARGUMENTS
|
||||
|
||||
=over 4
|
||||
|
||||
=item I<filename>
|
||||
|
||||
The filename to read data from, defaults to "profile_threads.dat".
|
||||
|
||||
=item --help
|
||||
|
||||
Displays this message and program version and exits.
|
||||
|
||||
=item --scale I<n>
|
||||
|
||||
On the X-axis of the generated Gantt chart, each character represents this
|
||||
many time units. (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.
|
||||
|
||||
=item --no-vcd
|
||||
|
||||
=item --vcd I<filename>
|
||||
|
||||
Set output filename for vcd dump, or disable. Default is
|
||||
verilator_gantt.vcd.
|
||||
|
||||
=back
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2018-2019 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Wilson Snyder <[email protected]>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
C<verilator>
|
||||
|
||||
=cut
|
||||
|
||||
######################################################################
|
||||
### Local Variables:
|
||||
### compile-command: "$V4/bin/verilator_gantt $V4/test_regress/obj_vltmt/t_gantt/vlt_sim.log"
|
||||
### End:
|
||||
@@ -1,16 +1,20 @@
|
||||
: # -*-Mode: perl;-*- use perl, wherever it is
|
||||
eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
# $Id$
|
||||
# DESCRIPTION: Print include statements for each ARGV
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
# Copyright 2003-2019 by Wilson Snyder. This package is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
######################################################################
|
||||
|
||||
require 5.005;
|
||||
use warnings;
|
||||
print "// DESCR"."IPTION: Generated by verilator_includer via makefile\n";
|
||||
foreach my $param (@ARGV) {
|
||||
print "#include \"$param\"\n"
|
||||
if ($param =~ /^-D([^=]+)=(.*)/) {
|
||||
print "#define $1 $2\n"
|
||||
} else {
|
||||
print "#include \"$param\"\n"
|
||||
}
|
||||
}
|
||||
|
||||
Executable
+250
@@ -0,0 +1,250 @@
|
||||
: # -*-Mode: perl;-*- use perl, wherever it is
|
||||
eval 'exec perl -wS $0 ${1+"$@"}'
|
||||
if 0;
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
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);
|
||||
|
||||
#======================================================================
|
||||
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
$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";
|
||||
}
|
||||
|
||||
defined $Opt_File or die "%Error: No filename given\n";
|
||||
|
||||
profcfunc($Opt_File);
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
# 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);
|
||||
|
||||
# Resort by Verilog name
|
||||
my %vfuncs;
|
||||
my %groups;
|
||||
foreach my $func (keys %funcs) {
|
||||
my $pct = $funcs{$func}{pct};
|
||||
my $vfunc = $func;
|
||||
my $design;
|
||||
|
||||
if ($func =~ /\(([a-zA-Z_0-9]+__Syms)/) {
|
||||
$design = $pointer_mods{$1};
|
||||
}
|
||||
|
||||
foreach my $vde (keys %verilated_mods) {
|
||||
last if $design;
|
||||
if ($func =~ /$verilated_mods{$vde}/) {
|
||||
$design=$vde;
|
||||
last;
|
||||
}
|
||||
}
|
||||
|
||||
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};
|
||||
}
|
||||
|
||||
|
||||
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 --ggdb -pg ....
|
||||
{run executable}
|
||||
gprof
|
||||
verilator_profcfuncs gprof.out
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
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.
|
||||
|
||||
=head1 ARGUMENTS
|
||||
|
||||
=over 4
|
||||
|
||||
=item --help
|
||||
|
||||
Displays this message and program version and exits.
|
||||
|
||||
=back
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
The latest version is available from L<http://www.veripool.org/>.
|
||||
|
||||
Copyright 2007-2019 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Wilson Snyder <[email protected]>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
C<verilator>
|
||||
|
||||
=cut
|
||||
|
||||
######################################################################
|
||||
### 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:
|
||||
+322
-27
@@ -1,51 +1,346 @@
|
||||
dnl $Id$
|
||||
dnl DESCRIPTION: Process this file with autoconf to produce a configure script.
|
||||
dnl Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
dnl redistribute it and/or modify it under the terms of either the GNU
|
||||
dnl General Public License or the Perl Artistic License.
|
||||
# DESCRIPTION: Process this file with autoconf to produce a configure script.
|
||||
#
|
||||
# Copyright 2003-2019 by Wilson Snyder. Verilator is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
#AC_INIT([Verilator],[#.### YYYY-MM-DD])
|
||||
#AC_INIT([Verilator],[#.### devel])
|
||||
AC_INIT([Verilator],[4.014 2019-05-08],
|
||||
[https://www.veripool.org/verilator],
|
||||
[verilator],[https://www.veripool.org/verilator])
|
||||
# When releasing, also update header of Changes file
|
||||
# and commit using "devel release" or "Version bump" message
|
||||
|
||||
AC_REVISION($Revision$)dnl
|
||||
AC_INIT(src/Verilator.cpp)
|
||||
AC_CONFIG_HEADER(src/config_build.h)
|
||||
AC_CONFIG_FILES(Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc)
|
||||
|
||||
dnl Special Substitutions
|
||||
AC_MSG_RESULT([configuring for $PACKAGE_STRING])
|
||||
|
||||
dnl Checks for programs.
|
||||
CXX=g++
|
||||
# Ignore automake flags passed by Ubuntu builds
|
||||
AC_ARG_ENABLE([dependency-tracking],
|
||||
[AS_HELP_STRING([--disable-dependency-tracking], [ignored])])
|
||||
AC_ARG_ENABLE([maintainer-mode],
|
||||
[AS_HELP_STRING([--enable-maintainer-mode], [ignored])])
|
||||
AC_ARG_ENABLE([silent-rules],
|
||||
[AS_HELP_STRING([--disable-silent-rules], [ignored])])
|
||||
|
||||
# Special Substitutions - CFG_WITH_DEFENV
|
||||
AC_MSG_CHECKING(whether to use hardcoded paths)
|
||||
AC_ARG_ENABLE([defenv],
|
||||
[AS_HELP_STRING([--disable-defenv],
|
||||
[disable using some hardcoded data paths extracted from some default environment variables (the default is to use hardcoded paths)])],
|
||||
[case "${enableval}" in
|
||||
yes) CFG_WITH_DEFENV=yes ;;
|
||||
no) CFG_WITH_DEFENV=no ;;
|
||||
*) AC_MSG_ERROR([bad value ${enableval} for --disable-defenv]) ;;
|
||||
esac],
|
||||
CFG_WITH_DEFENV=yes)
|
||||
AC_SUBST(CFG_WITH_DEFENV)
|
||||
AC_MSG_RESULT($CFG_WITH_DEFENV)
|
||||
|
||||
# Special Substitutions - CFG_WITH_CCWARN
|
||||
AC_MSG_CHECKING(whether to show and stop on compilation warnings)
|
||||
AC_ARG_ENABLE([ccwarn],
|
||||
[AS_HELP_STRING([--enable-ccwarn],
|
||||
[enable showing and stopping on compilation warnings])],
|
||||
[case "${enableval}" in
|
||||
yes) CFG_WITH_CCWARN=yes ;;
|
||||
no) CFG_WITH_CCWARN=no ;;
|
||||
*) AC_MSG_ERROR([bad value ${enableval} for --enable-ccwarn]) ;;
|
||||
esac],
|
||||
[case "x${VERILATOR_AUTHOR_SITE}" in
|
||||
x) CFG_WITH_CCWARN=no ;;
|
||||
*) CFG_WITH_CCWARN=yes ;;
|
||||
esac]
|
||||
)
|
||||
AC_SUBST(CFG_WITH_CCWARN)
|
||||
AC_MSG_RESULT($CFG_WITH_CCWARN)
|
||||
|
||||
# Special Substitutions - CFG_WITH_LONGTESTS
|
||||
AC_MSG_CHECKING(whether to run long tests)
|
||||
AC_ARG_ENABLE([longtests],
|
||||
[AS_HELP_STRING([--enable-longtests],
|
||||
[enable running long developer tests])],
|
||||
[case "${enableval}" in
|
||||
yes) CFG_WITH_LONGTESTS=yes ;;
|
||||
no) CFG_WITH_LONGTESTS=no ;;
|
||||
*) AC_MSG_ERROR([bad value ${enableval} for --enable-longtests]) ;;
|
||||
esac],
|
||||
[case "x${VERILATOR_AUTHOR_SITE}" in
|
||||
x) CFG_WITH_LONGTESTS=no ;;
|
||||
*) CFG_WITH_LONGTESTS=yes ;;
|
||||
esac]
|
||||
)
|
||||
AC_SUBST(CFG_WITH_LONGTESTS)
|
||||
AC_MSG_RESULT($CFG_WITH_LONGTESTS)
|
||||
|
||||
# CFG_WITH_PREC11
|
||||
AC_MSG_CHECKING(whether allow pre-C++11)
|
||||
AC_ARG_ENABLE([prec11],
|
||||
[AS_HELP_STRING([--enable-prec11],
|
||||
[enable pre-C++11 compilers])],
|
||||
[case "${enableval}" in
|
||||
yes) CFG_WITH_PREC11=yes ;;
|
||||
no) CFG_WITH_PREC11=no ;;
|
||||
*) AC_MSG_ERROR([bad value ${enableval} for --enable-prec11]) ;;
|
||||
esac],
|
||||
[CFG_WITH_PREC11=no;]
|
||||
)
|
||||
AC_SUBST(CFG_WITH_PREC11)
|
||||
AC_MSG_RESULT($CFG_WITH_PREC11)
|
||||
|
||||
# Compiler flags
|
||||
CFLAGS=-I${includedir}
|
||||
CPPFLAGS=-I${includedir}
|
||||
CXXFLAGS=-I${includedir}
|
||||
LDFLAGS=-L${libdir}
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_PROG_INSTALL
|
||||
|
||||
AC_LANG_PUSH(C++)
|
||||
cxx_version=$($CXX --version | head -1)
|
||||
AC_MSG_RESULT([compiler is $CXX --version = $cxx_version])
|
||||
AC_MSG_CHECKING([that C++ compiler can compile simple program])
|
||||
AC_RUN_IFELSE(
|
||||
[AC_LANG_SOURCE([int main() { return 0; }])],
|
||||
AC_MSG_RESULT(yes),
|
||||
AC_MSG_RESULT(no);AC_MSG_ERROR([a working C++ compiler is required]),
|
||||
AC_MSG_RESULT(yes))
|
||||
|
||||
AC_PATH_PROG(PERL,perl)
|
||||
AC_PATH_PROG(YACC,bison)
|
||||
if test "x$PERL" = "x" ; then
|
||||
AC_MSG_ERROR([Cannot find "perl" in your PATH, please install it])
|
||||
fi
|
||||
AC_PATH_PROG(LEX,flex)
|
||||
if test "x$LEX" = "x" ; then
|
||||
AC_MSG_ERROR([Cannot find "flex" in your PATH, please install it])
|
||||
fi
|
||||
AC_PATH_PROG(YACC,bison)
|
||||
if test "x$YACC" = "x" ; then
|
||||
AC_MSG_ERROR([Cannot find "bison" in your PATH, please install it])
|
||||
fi
|
||||
|
||||
dnl Checks for libraries.
|
||||
# Checks for libraries.
|
||||
|
||||
dnl Checks for header files.
|
||||
AC_HEADER_STDC
|
||||
AC_HEADER_SYS_WAIT
|
||||
AC_CHECK_HEADERS(fcntl.h unistd.h inttypes.h sys/file.h sys/time.h sys/un.h math.h stdint.h mingw/stdint.h)
|
||||
|
||||
dnl Checks for typedefs, structures
|
||||
# Checks for typedefs, structures
|
||||
AC_CHECK_TYPE(size_t,unsigned int)
|
||||
AC_CHECK_TYPE(uint_t,unsigned int)
|
||||
AC_CHECK_TYPE(ulong_t,unsigned long)
|
||||
AC_TYPE_SIZE_T
|
||||
AC_STRUCT_TM
|
||||
|
||||
dnl Checks for compiler characteristics.
|
||||
# Checks for compiler characteristics.
|
||||
AC_C_INLINE
|
||||
|
||||
dnl Checks for library functions.
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([#include <new>], [[int* a=new int; delete a; ]])],
|
||||
[], [AC_MSG_ERROR([$CXX does not seem to successfully compile a simple C++ program])])
|
||||
|
||||
dnl Checks for system services
|
||||
AC_DEFUN([_MY_CXX_CHECK_FLAG],
|
||||
[# _MY_CXX_CHECK_FLAG(flag) -- Check if compiler supports specific options
|
||||
# Set $_my_result appropriately
|
||||
ACO_SAVE_CXXFLAGS="$CXXFLAGS"
|
||||
# -Werror needed otherwise unknown -Wno-div-by-zero won't report problems
|
||||
# new/delete is needed to find -faligned-new link problem on Darwin
|
||||
CXXFLAGS="$CXXFLAGS $1 -Werror"
|
||||
AC_MSG_CHECKING([whether $CXX accepts $1])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([#include <new>], [[int* a=new int; delete a; ]])],
|
||||
[_my_result=yes
|
||||
if test -s conftest.err; then
|
||||
if grep -e "$1" conftest.err >/dev/null; then
|
||||
_my_result=no
|
||||
fi
|
||||
fi],
|
||||
[_my_result=no])
|
||||
# GCC is annoying, trying to be helpful, it postpones unknown -Wno-
|
||||
# options if there's no error We want to see them regardless, so try
|
||||
# forcing an error and see if we get a gcc warning
|
||||
AC_COMPILE_IFELSE(
|
||||
[AC_LANG_PROGRAM([[an_error "intentional-error-for-test.h"
|
||||
]],[])],
|
||||
[], # Ignore ok exit
|
||||
[if test -s conftest.err; then
|
||||
if grep -e "$1" conftest.err >/dev/null; then
|
||||
_my_result=no
|
||||
fi
|
||||
fi])
|
||||
AC_MSG_RESULT($_my_result)
|
||||
CXXFLAGS="$ACO_SAVE_CXXFLAGS"
|
||||
])
|
||||
|
||||
dnl Other install directories
|
||||
AC_DEFUN([_MY_CXX_CHECK_SET],
|
||||
[# _MY_CXX_CHECK_SET(variable,flag) -- Check if compiler supports specific options
|
||||
# If it does, set variable to flag, only if not previously set
|
||||
if test "$$1" = ""; then
|
||||
_MY_CXX_CHECK_FLAG($2)
|
||||
if test "$_my_result" = "yes" ; then
|
||||
$1="$2"
|
||||
fi
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([_MY_CXX_CHECK_OPT],
|
||||
[# _MY_CXX_CHECK_OPT(flag) -- Check if compiler supports specific options
|
||||
# If it does, append flag to variable
|
||||
_MY_CXX_CHECK_FLAG($2)
|
||||
if test "$_my_result" = "yes" ; then
|
||||
$1="$$1 $2"
|
||||
fi
|
||||
])
|
||||
|
||||
AC_DEFUN([_MY_LDLIBS_CHECK_FLAG],
|
||||
[# _MY_LDLIBS_CHECK_FLAG(flag) -- Check if linker supports specific options
|
||||
# Set $_my_result appropriately
|
||||
ACO_SAVE_LIBS="$LIBS"
|
||||
LIBS="$LIBS $1"
|
||||
AC_MSG_CHECKING([whether $CXX linker accepts $1])
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([[]])],
|
||||
[_my_result=yes
|
||||
if test -s conftest.err; then
|
||||
if grep -e "$1" conftest.err >/dev/null; then
|
||||
_my_result=no
|
||||
fi
|
||||
fi],
|
||||
[_my_result=no])
|
||||
AC_MSG_RESULT($_my_result)
|
||||
LIBS="$ACO_SAVE_LIBS"
|
||||
])
|
||||
|
||||
AC_DEFUN([_MY_LDLIBS_CHECK_OPT],
|
||||
[# _MY_LDLIBS_CHECK_OPT(flag) -- Check if linker supports specific options
|
||||
# If it does, append flag to variable
|
||||
_MY_LDLIBS_CHECK_FLAG($2)
|
||||
if test "$_my_result" = "yes" ; then
|
||||
$1="$$1 $2"
|
||||
fi
|
||||
])
|
||||
|
||||
# Flag to select newest language standard supported
|
||||
# Macros work such that first option that passes is the one we take
|
||||
# gnu++17 code is clean, but SystemC in 2018 doesn't link with it (bug1339)
|
||||
# gnu++14 is the newest that Verilator supports
|
||||
# std++03 is the oldest that Verilator supports
|
||||
#_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++17)
|
||||
_MY_CXX_CHECK_SET(CFG_CXXFLAGS_STD_NEWEST,-std=c++14)
|
||||
_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=std++17)
|
||||
_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)
|
||||
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'
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wextra)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wfloat-conversion)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wlogical-op)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_WEXTRA,-Wthread-safety)
|
||||
AC_SUBST(CFG_CXXFLAGS_WEXTRA)
|
||||
|
||||
# Flags for compiling Verilator internals including parser always
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Qunused-arguments)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-faligned-new)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-unused-parameter)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-undefined-bool-conversion)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_SRC,-Wno-shadow)
|
||||
AC_SUBST(CFG_CXXFLAGS_SRC)
|
||||
|
||||
# Flags for compiling Verilator parser always (in addition to above CFG_CXXFLAGS_SRC)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-char-subscripts)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-null-conversion)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-parentheses-equality)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_PARSER,-Wno-unused)
|
||||
AC_SUBST(CFG_CXXFLAGS_PARSER)
|
||||
|
||||
# Flags for Verilated makefile
|
||||
# For example, -Wno-div-by-zero isn't in 4.1.2
|
||||
# Random code often does / 0. Unfortunately VL_DIV_I(0,0) will warn
|
||||
# without this flag, even though there's a conditional to prevent the divide.
|
||||
# We still don't add no-div-by-zero as it throws message to stdout, though doesn't die.
|
||||
#_MY_CXX_CHECK_OPT(-Wno-div-by-zero)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-faligned-new)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-fbracket-depth=4096)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Qunused-arguments)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-bool-operation)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-parentheses-equality)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-sign-compare)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-uninitialized)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-but-set-variable)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-parameter)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-variable)
|
||||
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-shadow)
|
||||
AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
|
||||
|
||||
# Find multithread linker flags
|
||||
_MY_LDLIBS_CHECK_OPT(CFG_LDLIBS_THREADS,-mt)
|
||||
_MY_LDLIBS_CHECK_OPT(CFG_LDLIBS_THREADS,-pthread)
|
||||
_MY_LDLIBS_CHECK_OPT(CFG_LDLIBS_THREADS,-lpthread)
|
||||
_MY_LDLIBS_CHECK_OPT(CFG_LDLIBS_THREADS,-latomic)
|
||||
AC_SUBST(CFG_LDLIBS_THREADS)
|
||||
|
||||
# Set CFG_WITH_THREADED if can support threading
|
||||
AC_MSG_CHECKING(whether $CXX supports Verilated threads)
|
||||
ACO_SAVE_CXXFLAGS="$CXXFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $CFG_CXXFLAGS_STD_NEWEST $CFG_CXXFLAGS_NO_UNUSED"
|
||||
AC_LINK_IFELSE(
|
||||
[AC_LANG_PROGRAM([#include <thread>], [[ ]])],
|
||||
[_my_result=yes
|
||||
if test -s conftest.err; then
|
||||
if grep -e "$1" conftest.err >/dev/null; then
|
||||
_my_result=no
|
||||
fi
|
||||
fi],
|
||||
[_my_result=no])
|
||||
CFG_WITH_THREADED=$_my_result
|
||||
AC_SUBST(CFG_WITH_THREADED)
|
||||
AC_MSG_RESULT($CFG_WITH_THREADED)
|
||||
|
||||
# Check compiler flag
|
||||
if test "$CFG_WITH_THREADED" = "no" ; then
|
||||
if test "$CFG_WITH_PREC11" = "no" ; then
|
||||
AC_MSG_NOTICE([[]])
|
||||
AC_MSG_ERROR([[the $CXX compiler appears to not support C++11.
|
||||
|
||||
Verilator plans to require a C++11 or newer compiler in a future release,
|
||||
unless sufficient people report problems. Therefore, if you do not have a
|
||||
C++11 compiler, please post a message to
|
||||
https://www.veripool.org/boards/3/topics/2580-Verilator-Requiring-C-11-compiler
|
||||
indicating your OS and when you think C++11 might be ok, and then rerun
|
||||
configure with the --enable-prec11 argument. Thanks.]])
|
||||
|
||||
fi
|
||||
fi
|
||||
|
||||
# Checks for library functions.
|
||||
AC_CHECK_MEMBER([struct stat.st_mtim.tv_nsec],
|
||||
[AC_DEFINE([HAVE_STAT_NSEC],[1],[Defined if struct stat has st_mtim.tv_nsec])],
|
||||
[], [#include <sys/stat.h>])
|
||||
|
||||
# Checks for system services
|
||||
|
||||
# Other install directories
|
||||
pkgdatadir=${datadir}/verilator
|
||||
AC_SUBST(pkgdatadir)
|
||||
pkgconfigdir=${datadir}/pkgconfig
|
||||
AC_SUBST(pkgconfigdir)
|
||||
|
||||
AC_OUTPUT(Makefile src/Makefile src/Makefile_obj include/verilated.mk)
|
||||
AC_OUTPUT
|
||||
|
||||
AC_MSG_RESULT([])
|
||||
AC_MSG_RESULT([Now type 'make'])
|
||||
AC_MSG_RESULT([Now type 'make' (or sometimes 'gmake') to build Verilator.])
|
||||
AC_MSG_RESULT([])
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/*! \mainpage Verilator Doxygen Documentation
|
||||
*
|
||||
* \section intro_sec Introduction
|
||||
*
|
||||
* This is a full doxygen analysis of the Verilator source tree.
|
||||
*/
|
||||
+1765
File diff suppressed because it is too large
Load Diff
@@ -3,4 +3,4 @@
|
||||
*.csrc
|
||||
*.vcd
|
||||
obj_*
|
||||
project
|
||||
logs
|
||||
@@ -0,0 +1,52 @@
|
||||
######################################################################
|
||||
#
|
||||
# DESCRIPTION: Verilator Example: Small Makefile
|
||||
#
|
||||
# This calls the object directory makefile. That allows the objects to
|
||||
# be placed in the "current directory" which simplifies the Makefile.
|
||||
#
|
||||
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
#
|
||||
######################################################################
|
||||
# Check for sanity to avoid later confusion
|
||||
|
||||
ifneq ($(words $(CURDIR)),1)
|
||||
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
|
||||
# This is intended to be a minimal example. Before copying this to start a
|
||||
# real project, it is better to start with a more complete example,
|
||||
# e.g. examples/tracing_c.
|
||||
|
||||
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
|
||||
# package inatall, and verilator is in your path. Otherwise find the
|
||||
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||
ifeq ($(VERILATOR_ROOT),)
|
||||
VERILATOR = verilator
|
||||
else
|
||||
export VERILATOR_ROOT
|
||||
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
|
||||
endif
|
||||
|
||||
default:
|
||||
@echo "-- Verilator hello-world simple example"
|
||||
@echo "-- VERILATE ----------------"
|
||||
$(VERILATOR) -cc --exe top.v sim_main.cpp
|
||||
@echo "-- COMPILE -----------------"
|
||||
$(MAKE) -j 4 -C obj_dir -f Vtop.mk
|
||||
@echo "-- RUN ---------------------"
|
||||
obj_dir/Vtop
|
||||
@echo "-- DONE --------------------"
|
||||
@echo "Note: Once this example is understood, see examples/tracing_c."
|
||||
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
|
||||
|
||||
######################################################################
|
||||
|
||||
maintainer-copy::
|
||||
clean mostlyclean distclean maintainer-clean::
|
||||
-rm -rf obj_dir *.log *.dmp *.vpd core
|
||||
@@ -0,0 +1,41 @@
|
||||
// DESCRIPTION: Verilator: Verilog example module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2017 by Wilson Snyder.
|
||||
//======================================================================
|
||||
|
||||
// Include common routines
|
||||
#include <verilated.h>
|
||||
|
||||
// Include model header, generated from Verilating "top.v"
|
||||
#include "Vtop.h"
|
||||
|
||||
int main(int argc, char** argv, char** env) {
|
||||
// See a similar example walkthrough in the verilator manpage.
|
||||
|
||||
// This is intended to be a minimal example. Before copying this to start a
|
||||
// real project, it is better to start with a more complete example,
|
||||
// e.g. examples/c_tracing.
|
||||
|
||||
// Prevent unused variable warnings
|
||||
if (0 && argc && argv && env) {}
|
||||
|
||||
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
|
||||
Vtop* top = new Vtop;
|
||||
|
||||
// Simulate until $finish
|
||||
while (!Verilated::gotFinish()) {
|
||||
|
||||
// Evaluate model
|
||||
top->eval();
|
||||
}
|
||||
|
||||
// Final model cleanup
|
||||
top->final();
|
||||
|
||||
// Destroy model
|
||||
delete top;
|
||||
|
||||
// Fin
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// DESCRIPTION: Verilator: Verilog example module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2017 by Wilson Snyder.
|
||||
|
||||
// See also the EXAMPLE section in the verilator manpage/document.
|
||||
module top;
|
||||
initial begin
|
||||
$display("Hello World!");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -1,8 +1,6 @@
|
||||
*.old
|
||||
*.dmp
|
||||
*.log
|
||||
*.csrc
|
||||
*.vcd
|
||||
obj_*
|
||||
logs
|
||||
project
|
||||
@@ -0,0 +1,67 @@
|
||||
######################################################################
|
||||
#
|
||||
# DESCRIPTION: Verilator Example: Small Makefile
|
||||
#
|
||||
# This calls the object directory makefile. That allows the objects to
|
||||
# be placed in the "current directory" which simplifies the Makefile.
|
||||
#
|
||||
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
#
|
||||
######################################################################
|
||||
# Check for sanity to avoid later confusion
|
||||
|
||||
ifneq ($(words $(CURDIR)),1)
|
||||
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
|
||||
# This is intended to be a minimal example. Before copying this to start a
|
||||
# real project, it is better to start with a more complete example,
|
||||
# e.g. examples/tracing_sc.
|
||||
|
||||
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
|
||||
# package inatall, and verilator is in your path. Otherwise find the
|
||||
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||
ifeq ($(VERILATOR_ROOT),)
|
||||
VERILATOR = verilator
|
||||
else
|
||||
export VERILATOR_ROOT
|
||||
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
|
||||
endif
|
||||
|
||||
# Check if SC exists via a verilator call (empty if not)
|
||||
SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE)
|
||||
|
||||
ifneq ($(SYSTEMC_EXISTS),)
|
||||
default: run
|
||||
else
|
||||
default: nosc
|
||||
endif
|
||||
|
||||
run:
|
||||
@echo "-- Verilator hello-world simple example"
|
||||
@echo "-- VERILATE ----------------"
|
||||
$(VERILATOR) -sc --exe top.v sc_main.cpp
|
||||
@echo "-- COMPILE -----------------"
|
||||
$(MAKE) -j 4 -C obj_dir -f Vtop.mk
|
||||
@echo "-- RUN ---------------------"
|
||||
obj_dir/Vtop
|
||||
@echo "-- DONE --------------------"
|
||||
@echo "Note: Once this example is understood, see examples/tracing_sc."
|
||||
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
|
||||
|
||||
######################################################################
|
||||
|
||||
nosc:
|
||||
@echo
|
||||
@echo "%Skip: SYSTEMC_INCLUDE not in environment"
|
||||
@echo "(If you have SystemC see the README, and rebuild Verilator)"
|
||||
@echo
|
||||
|
||||
maintainer-copy::
|
||||
clean mostlyclean distclean maintainer-clean::
|
||||
-rm -rf obj_dir *.log *.dmp *.vpd core
|
||||
@@ -0,0 +1,51 @@
|
||||
// -*- SystemC -*-
|
||||
// DESCRIPTION: Verilator Example: Top level main for invoking SystemC model
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2017 by Wilson Snyder.
|
||||
//======================================================================
|
||||
|
||||
// SystemC global header
|
||||
#include <systemc.h>
|
||||
|
||||
// Include common routines
|
||||
#include <verilated.h>
|
||||
|
||||
// Include model header, generated from Verilating "top.v"
|
||||
#include "Vtop.h"
|
||||
|
||||
int sc_main(int argc, char* argv[]) {
|
||||
// See a similar example walkthrough in the verilator manpage.
|
||||
|
||||
// This is intended to be a minimal example. Before copying this to start a
|
||||
// real project, it is better to start with a more complete example,
|
||||
// e.g. examples/c_tracing.
|
||||
|
||||
// Prevent unused variable warnings
|
||||
if (0 && argc && argv) {}
|
||||
|
||||
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
|
||||
Vtop* top = new Vtop("top");
|
||||
|
||||
// Initialize SC model
|
||||
#if (SYSTEMC_VERSION>=20070314)
|
||||
sc_start(1,SC_NS);
|
||||
#else
|
||||
sc_start(1);
|
||||
#endif
|
||||
|
||||
// Simulate until $finish
|
||||
while (!Verilated::gotFinish()) {
|
||||
#if (SYSTEMC_VERSION>=20070314)
|
||||
sc_start(1,SC_NS);
|
||||
#else
|
||||
sc_start(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Final model cleanup
|
||||
top->final();
|
||||
|
||||
// Fin
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// DESCRIPTION: Verilator: Verilog example module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2017 by Wilson Snyder.
|
||||
|
||||
// See also the EXAMPLE section in the verilator manpage/document.
|
||||
module top;
|
||||
initial begin
|
||||
$display("Hello World!");
|
||||
$finish;
|
||||
end
|
||||
endmodule
|
||||
@@ -1,8 +1,6 @@
|
||||
*.old
|
||||
*.dmp
|
||||
*.log
|
||||
*.csrc
|
||||
*.vcd
|
||||
obj_*
|
||||
logs
|
||||
project
|
||||
@@ -0,0 +1,96 @@
|
||||
######################################################################
|
||||
#
|
||||
# DESCRIPTION: Verilator Example: Small Makefile
|
||||
#
|
||||
# This calls the object directory makefile. That allows the objects to
|
||||
# be placed in the "current directory" which simplifies the Makefile.
|
||||
#
|
||||
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
#
|
||||
######################################################################
|
||||
# Check for sanity to avoid later confusion
|
||||
|
||||
ifneq ($(words $(CURDIR)),1)
|
||||
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
# Set up variables
|
||||
|
||||
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
|
||||
# package inatall, and verilator is in your path. Otherwise find the
|
||||
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||
ifeq ($(VERILATOR_ROOT),)
|
||||
VERILATOR = verilator
|
||||
VERILATOR_COVERAGE = verilator_coverage
|
||||
else
|
||||
export VERILATOR_ROOT
|
||||
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
|
||||
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||
endif
|
||||
|
||||
VERILATOR_FLAGS =
|
||||
# Generate C++ in executable form
|
||||
VERILATOR_FLAGS += -cc --exe
|
||||
# Generate makefile dependencies (not shown as complicates the Makefile)
|
||||
#VERILATOR_FLAGS += -MMD
|
||||
# Optimize
|
||||
VERILATOR_FLAGS += -O2 -x-assign 0
|
||||
# Warn abount lint issues; may not want this on less solid designs
|
||||
VERILATOR_FLAGS += -Wall
|
||||
# Make waveforms
|
||||
VERILATOR_FLAGS += --trace
|
||||
# Check SystemVerilog assertions
|
||||
VERILATOR_FLAGS += --assert
|
||||
# Generate coverage analysis
|
||||
VERILATOR_FLAGS += --coverage
|
||||
# Run Verilator in debug mode
|
||||
#VERILATOR_FLAGS += --debug
|
||||
# Add this trace to get a backtrace in gdb
|
||||
#VERILATOR_FLAGS += --gdbbt
|
||||
|
||||
######################################################################
|
||||
default: run
|
||||
|
||||
run:
|
||||
@echo
|
||||
@echo "-- Verilator tracing example"
|
||||
|
||||
@echo
|
||||
@echo "-- VERILATE ----------------"
|
||||
$(VERILATOR) $(VERILATOR_FLAGS) -f input.vc top.v sim_main.cpp
|
||||
|
||||
@echo
|
||||
@echo "-- COMPILE -----------------"
|
||||
# To compile, we can either just do what Verilator asks,
|
||||
# or call a submakefile where we can override the rules ourselves
|
||||
# $(MAKE) -j 4 -C obj_dir -f Vtop.mk
|
||||
$(MAKE) -j 4 -C obj_dir -f ../Makefile_obj
|
||||
|
||||
@echo
|
||||
@echo "-- RUN ---------------------"
|
||||
@mkdir -p logs
|
||||
obj_dir/Vtop +trace
|
||||
|
||||
@echo
|
||||
@echo "-- COVERAGE ----------------"
|
||||
$(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
|
||||
|
||||
@echo
|
||||
@echo "-- DONE --------------------"
|
||||
@echo "To see waveforms, open vlt_dump.vcd in a waveform viewer"
|
||||
@echo
|
||||
|
||||
|
||||
######################################################################
|
||||
# Other targets
|
||||
|
||||
show-config:
|
||||
$(VERILATOR) -V
|
||||
|
||||
maintainer-copy::
|
||||
clean mostlyclean distclean maintainer-clean::
|
||||
-rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core
|
||||
@@ -0,0 +1,58 @@
|
||||
# -*- Makefile -*-
|
||||
#######################################################################
|
||||
#
|
||||
# DESCRIPTION: Verilator Example: Makefile for inside object directory
|
||||
#
|
||||
# This is executed in the object directory, and called by ../Makefile
|
||||
#
|
||||
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
default: Vtop
|
||||
|
||||
# Include the rules made by Verilator
|
||||
include Vtop.mk
|
||||
|
||||
# Use OBJCACHE (ccache) if using gmake and its installed
|
||||
COMPILE.cc = $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
|
||||
|
||||
#######################################################################
|
||||
# Compile flags
|
||||
|
||||
# Override some default compile flags
|
||||
CPPFLAGS += -MMD -MP
|
||||
CPPFLAGS += -DVL_DEBUG=1
|
||||
# Turn on some more flags (when configured appropriately)
|
||||
# For testing inside Verilator, "configure --enable-ccwarn" will do this
|
||||
# automatically; otherwise you may want this unconditionally enabled
|
||||
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||
USER_CPPFLAGS_WALL += -W -Werror -Wall
|
||||
endif
|
||||
|
||||
# See the benchmarking section of bin/verilator.
|
||||
# Support class optimizations. This includes the tracing and symbol table.
|
||||
# SystemC takes minutes to optimize, thus it is off by default.
|
||||
OPT_SLOW =
|
||||
# Fast path optimizations. Most time is spent in these classes.
|
||||
OPT_FAST = -O2 -fstrict-aliasing
|
||||
#OPT_FAST = -O
|
||||
#OPT_FAST =
|
||||
|
||||
#######################################################################
|
||||
# Linking final exe -- presumes have a sim_main.cpp
|
||||
|
||||
# Special compile rule
|
||||
sim_main.o: sim_main.cpp $(VM_PREFIX).h
|
||||
|
||||
######################################################################
|
||||
######################################################################
|
||||
# Automatically understand dependencies
|
||||
|
||||
DEPS := $(wildcard *.d)
|
||||
ifneq ($(DEPS),)
|
||||
include $(DEPS)
|
||||
endif
|
||||
@@ -0,0 +1,2 @@
|
||||
// This file typically lists flags required by a large project, e.g. include directories
|
||||
+librescan +libext+.v+.sv+.vh+.svh -y .
|
||||
@@ -0,0 +1,126 @@
|
||||
// DESCRIPTION: Verilator: Verilog example module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2017 by Wilson Snyder.
|
||||
//======================================================================
|
||||
|
||||
// Include common routines
|
||||
#include <verilated.h>
|
||||
|
||||
// Include model header, generated from Verilating "top.v"
|
||||
#include "Vtop.h"
|
||||
|
||||
// If "verilator --trace" is used, include the tracing class
|
||||
#if VM_TRACE
|
||||
# include <verilated_vcd_c.h>
|
||||
#endif
|
||||
|
||||
// Current simulation time (64-bit unsigned)
|
||||
vluint64_t main_time = 0;
|
||||
// Called by $time in Verilog
|
||||
double sc_time_stamp() {
|
||||
return main_time; // Note does conversion to real, to match SystemC
|
||||
}
|
||||
|
||||
int main(int argc, char** argv, char** env) {
|
||||
// This is a more complicated example, please also see the simpler examples/hello_world_c.
|
||||
|
||||
// Prevent unused variable warnings
|
||||
if (0 && argc && argv && env) {}
|
||||
|
||||
// Set debug level, 0 is off, 9 is highest presently used
|
||||
// May be overridden by commandArgs
|
||||
Verilated::debug(0);
|
||||
|
||||
// Randomization reset policy
|
||||
// May be overridden by commandArgs
|
||||
Verilated::randReset(2);
|
||||
|
||||
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
|
||||
// This needs to be called before you create any model
|
||||
Verilated::commandArgs(argc, argv);
|
||||
|
||||
// Construct the Verilated model, from Vtop.h generated from Verilating "top.v"
|
||||
Vtop* top = new Vtop; // Or use a const unique_ptr, or the VL_UNIQUE_PTR wrapper
|
||||
|
||||
#if VM_TRACE
|
||||
// If verilator was invoked with --trace argument,
|
||||
// and if at run time passed the +trace argument, turn on tracing
|
||||
VerilatedVcdC* tfp = NULL;
|
||||
const char* flag = Verilated::commandArgsPlusMatch("trace");
|
||||
if (flag && 0==strcmp(flag, "+trace")) {
|
||||
Verilated::traceEverOn(true); // Verilator must compute traced signals
|
||||
VL_PRINTF("Enabling waves into logs/vlt_dump.vcd...\n");
|
||||
tfp = new VerilatedVcdC;
|
||||
top->trace(tfp, 99); // Trace 99 levels of hierarchy
|
||||
Verilated::mkdir("logs");
|
||||
tfp->open("logs/vlt_dump.vcd"); // Open the dump file
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set some inputs
|
||||
top->reset_l = !0;
|
||||
top->fastclk = 0;
|
||||
top->clk = 0;
|
||||
top->in_small = 1;
|
||||
top->in_quad = 0x1234;
|
||||
top->in_wide[0] = 0x11111111;
|
||||
top->in_wide[1] = 0x22222222;
|
||||
top->in_wide[2] = 0x3;
|
||||
|
||||
// Simulate until $finish
|
||||
while (!Verilated::gotFinish()) {
|
||||
main_time++; // Time passes...
|
||||
|
||||
// Toggle clocks and such
|
||||
top->fastclk = !top->fastclk;
|
||||
if ((main_time % 10) == 3) {
|
||||
top->clk = 1;
|
||||
}
|
||||
if ((main_time % 10) == 8) {
|
||||
top->clk = 0;
|
||||
}
|
||||
if (main_time > 1 && main_time < 10) {
|
||||
top->reset_l = !1; // Assert reset
|
||||
} else {
|
||||
top->reset_l = !0; // Deassert reset
|
||||
}
|
||||
|
||||
// Assign some other inputs
|
||||
top->in_quad += 0x12;
|
||||
|
||||
// Evaluate model
|
||||
top->eval();
|
||||
|
||||
#if VM_TRACE
|
||||
// Dump trace data for this cycle
|
||||
if (tfp) tfp->dump(main_time);
|
||||
#endif
|
||||
|
||||
// Read outputs
|
||||
VL_PRINTF("[%" VL_PRI64 "d] clk=%x rstl=%x iquad=%" VL_PRI64 "x"
|
||||
" -> oquad=%" VL_PRI64"x owide=%x_%08x_%08x\n",
|
||||
main_time, top->clk, top->reset_l, top->in_quad,
|
||||
top->out_quad, top->out_wide[2], top->out_wide[1], top->out_wide[0]);
|
||||
}
|
||||
|
||||
// Final model cleanup
|
||||
top->final();
|
||||
|
||||
// Close trace if opened
|
||||
#if VM_TRACE
|
||||
if (tfp) { tfp->close(); tfp = NULL; }
|
||||
#endif
|
||||
|
||||
// Coverage analysis (since test passed)
|
||||
#if VM_COVERAGE
|
||||
Verilated::mkdir("logs");
|
||||
VerilatedCov::write("logs/coverage.dat");
|
||||
#endif
|
||||
|
||||
// Destroy model
|
||||
delete top; top = NULL;
|
||||
|
||||
// Fin
|
||||
exit(0);
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
// ======================================================================
|
||||
|
||||
module sub
|
||||
(
|
||||
input clk,
|
||||
input fastclk,
|
||||
input reset_l
|
||||
);
|
||||
|
||||
// Example counter/flop
|
||||
reg [31:0] count_f;
|
||||
always_ff @ (posedge fastclk) begin
|
||||
if (!reset_l) begin
|
||||
/*AUTORESET*/
|
||||
// Beginning of autoreset for uninitialized flops
|
||||
count_f <= 32'h0;
|
||||
// End of automatics
|
||||
end
|
||||
else begin
|
||||
count_f <= count_f + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// Another example flop
|
||||
reg [31:0] count_c;
|
||||
always_ff @ (posedge clk) begin
|
||||
if (!reset_l) begin
|
||||
/*AUTORESET*/
|
||||
// Beginning of autoreset for uninitialized flops
|
||||
count_c <= 32'h0;
|
||||
// End of automatics
|
||||
end
|
||||
else begin
|
||||
count_c <= count_c + 1;
|
||||
if (count_c >= 3) begin
|
||||
$display("[%0t] fastclk is %0d times faster than clk\n",
|
||||
$time, count_f/count_c);
|
||||
// This write is a magic value the Makefile uses to make sure the
|
||||
// test completes successfully.
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// An example assertion
|
||||
always_ff @ (posedge clk) begin
|
||||
AssertionExample: assert (!reset_l || count_c<100);
|
||||
end
|
||||
|
||||
// And example coverage analysis
|
||||
cover property (@(posedge clk) count_c==3);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,42 @@
|
||||
// DESCRIPTION: Verilator: Verilog example module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
// ======================================================================
|
||||
|
||||
// This is intended to be a complex example of several features, please also
|
||||
// see the simpler examples/hello_world_c.
|
||||
|
||||
module top
|
||||
(
|
||||
// Declare some signals so we can see how I/O works
|
||||
input clk,
|
||||
input fastclk,
|
||||
input reset_l,
|
||||
|
||||
output [1:0] out_small,
|
||||
output [39:0] out_quad,
|
||||
output [69:0] out_wide,
|
||||
input [1:0] in_small,
|
||||
input [39:0] in_quad,
|
||||
input [69:0] in_wide
|
||||
);
|
||||
|
||||
// Connect up the outputs, using some trivial logic
|
||||
wire [1:0] out_small = ~reset_l ? '0 : (in_small + 2'b1);
|
||||
wire [39:0] out_quad = ~reset_l ? '0 : (in_quad + 40'b1);
|
||||
wire [69:0] out_wide = ~reset_l ? '0 : (in_wide + 70'b1);
|
||||
|
||||
// And an example sub module. The submodule will print stuff.
|
||||
sub sub (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.fastclk (fastclk),
|
||||
.reset_l (reset_l));
|
||||
|
||||
// Print some stuff as an example
|
||||
initial begin
|
||||
$display("[%0t] Model running...\n", $time);
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,6 @@
|
||||
*.dmp
|
||||
*.log
|
||||
*.csrc
|
||||
*.vcd
|
||||
obj_*
|
||||
logs
|
||||
@@ -0,0 +1,109 @@
|
||||
######################################################################
|
||||
#
|
||||
# DESCRIPTION: Verilator Example: Small Makefile
|
||||
#
|
||||
# This calls the object directory makefile. That allows the objects to
|
||||
# be placed in the "current directory" which simplifies the Makefile.
|
||||
#
|
||||
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
#
|
||||
######################################################################
|
||||
# Check for sanity to avoid later confusion
|
||||
|
||||
ifneq ($(words $(CURDIR)),1)
|
||||
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
# Set up variables
|
||||
|
||||
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
|
||||
# package inatall, and verilator is in your path. Otherwise find the
|
||||
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
|
||||
ifeq ($(VERILATOR_ROOT),)
|
||||
VERILATOR = verilator
|
||||
VERILATOR_COVERAGE = verilator_coverage
|
||||
else
|
||||
export VERILATOR_ROOT
|
||||
VERILATOR = $(VERILATOR_ROOT)/bin/verilator
|
||||
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||
endif
|
||||
|
||||
VERILATOR_FLAGS =
|
||||
# Generate SystemC in executable form
|
||||
VERILATOR_FLAGS += -sc --exe
|
||||
# Generate makefile dependencies (not shown as complicates the Makefile)
|
||||
#VERILATOR_FLAGS += -MMD
|
||||
# Optimize
|
||||
VERILATOR_FLAGS += -O2 -x-assign 0
|
||||
# Warn abount lint issues; may not want this on less solid designs
|
||||
VERILATOR_FLAGS += -Wall
|
||||
# Make waveforms
|
||||
VERILATOR_FLAGS += --trace
|
||||
# Check SystemVerilog assertions
|
||||
VERILATOR_FLAGS += --assert
|
||||
# Generate coverage analysis
|
||||
VERILATOR_FLAGS += --coverage
|
||||
# Run Verilator in debug mode
|
||||
#VERILATOR_FLAGS += --debug
|
||||
# Add this trace to get a backtrace in gdb
|
||||
#VERILATOR_FLAGS += --gdbbt
|
||||
|
||||
# Check if SC exists via a verilator call (empty if not)
|
||||
SYSTEMC_EXISTS := $(shell $(VERILATOR) --getenv SYSTEMC_INCLUDE)
|
||||
|
||||
######################################################################
|
||||
|
||||
ifneq ($(SYSTEMC_EXISTS),)
|
||||
default: run
|
||||
else
|
||||
default: nosc
|
||||
endif
|
||||
|
||||
run:
|
||||
@echo
|
||||
@echo "-- Verilator tracing example"
|
||||
|
||||
@echo
|
||||
@echo "-- VERILATE ----------------"
|
||||
$(VERILATOR) $(VERILATOR_FLAGS) -f input.vc top.v sc_main.cpp
|
||||
|
||||
@echo
|
||||
@echo "-- COMPILE ----------------="
|
||||
# To compile, we can either just do what Verilator asks,
|
||||
# or call a submakefile where we can override the rules ourselves
|
||||
# $(MAKE) -j 4 -C obj_dir -f Vtop.mk
|
||||
$(MAKE) -j 4 -C obj_dir -f ../Makefile_obj
|
||||
|
||||
@echo
|
||||
@echo "-- RUN ---------------------"
|
||||
@mkdir -p logs
|
||||
obj_dir/Vtop +trace
|
||||
|
||||
@echo
|
||||
@echo "-- COVERAGE ----------------"
|
||||
$(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
|
||||
|
||||
@echo
|
||||
@echo "-- DONE --------------------"
|
||||
@echo "To see waveforms, open vlt_dump.vcd in a waveform viewer"
|
||||
@echo
|
||||
|
||||
######################################################################
|
||||
# Other targets
|
||||
|
||||
nosc:
|
||||
@echo
|
||||
@echo "%Skip: SYSTEMC_INCLUDE not in environment"
|
||||
@echo "(If you have SystemC see the README, and rebuild Verilator)"
|
||||
@echo
|
||||
|
||||
show-config:
|
||||
$(VERILATOR) -V
|
||||
|
||||
maintainer-copy::
|
||||
clean mostlyclean distclean maintainer-clean::
|
||||
-rm -rf obj_dir logs *.log *.dmp *.vpd coverage.dat core
|
||||
@@ -0,0 +1,66 @@
|
||||
# -*- Makefile -*-
|
||||
#######################################################################
|
||||
#
|
||||
# DESCRIPTION: Verilator Example: Makefile for inside object directory
|
||||
#
|
||||
# This is executed in the object directory, and called by ../Makefile
|
||||
#
|
||||
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
#
|
||||
#######################################################################
|
||||
|
||||
default: Vtop
|
||||
|
||||
# Include the rules made by Verilator
|
||||
include Vtop.mk
|
||||
|
||||
# Use OBJCACHE (ccache) if using gmake and its installed
|
||||
COMPILE.cc = $(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
|
||||
|
||||
#######################################################################
|
||||
# Compile flags
|
||||
|
||||
# Override some default compile flags
|
||||
CPPFLAGS += -MMD -MP
|
||||
CPPFLAGS += -DVL_DEBUG=1
|
||||
# SystemC isn't too clean
|
||||
CPPFLAGS += -Wno-deprecated
|
||||
# Turn on some more flags (when configured appropriately)
|
||||
# For testing inside Verilator, "configure --enable-ccwarn" will do this
|
||||
# automatically; otherwise you may want this unconditionally enabled
|
||||
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||
USER_CPPFLAGS_WALL += -W -Werror -Wall
|
||||
endif
|
||||
|
||||
# If you build your own rules from scratch, note you need to include
|
||||
# SystemC as follows (Vtop.mk file includes verilated.mk with these
|
||||
# already).
|
||||
# CPPFLAGS += $(SYSTEMC_CXX_FLAGS) -I$(SYSTEMC_INCLUDE)
|
||||
# LDFLAGS += $(SYSTEMC_CXX_FLAGS) -L$(SYSTEMC_LIBDIR)
|
||||
|
||||
# See the benchmarking section of bin/verilator.
|
||||
# Support class optimizations. This includes the tracing and symbol table.
|
||||
# SystemC takes minutes to optimize, thus it is off by default.
|
||||
OPT_SLOW =
|
||||
# Fast path optimizations. Most time is spent in these classes.
|
||||
OPT_FAST = -O2 -fstrict-aliasing
|
||||
#OPT_FAST = -O
|
||||
#OPT_FAST =
|
||||
|
||||
#######################################################################
|
||||
# Linking final exe -- presumes have a sim_main.cpp
|
||||
|
||||
# Special compile rule
|
||||
sim_main.o: sim_main.cpp $(VM_PREFIX).h
|
||||
|
||||
######################################################################
|
||||
######################################################################
|
||||
# Automatically understand dependencies
|
||||
|
||||
DEPS := $(wildcard *.d)
|
||||
ifneq ($(DEPS),)
|
||||
include $(DEPS)
|
||||
endif
|
||||
@@ -0,0 +1,2 @@
|
||||
// This file typically lists flags required by a large project, e.g. include directories
|
||||
+librescan +libext+.v+.sv+.vh+.svh -y .
|
||||
@@ -0,0 +1,150 @@
|
||||
// -*- SystemC -*-
|
||||
// DESCRIPTION: Verilator Example: Top level main for invoking SystemC model
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2017 by Wilson Snyder.
|
||||
//======================================================================
|
||||
|
||||
// SystemC global header
|
||||
#include <systemc.h>
|
||||
|
||||
// Include common routines
|
||||
#include <verilated.h>
|
||||
#if VM_TRACE
|
||||
#include <verilated_vcd_sc.h>
|
||||
#endif
|
||||
|
||||
#include <sys/stat.h> // mkdir
|
||||
|
||||
// Include model header, generated from Verilating "top.v"
|
||||
#include "Vtop.h"
|
||||
|
||||
int sc_main(int argc, char* argv[]) {
|
||||
// This is a more complicated example, please also see the simpler examples/hello_world_c.
|
||||
|
||||
// Prevent unused variable warnings
|
||||
if (0 && argc && argv) {}
|
||||
|
||||
// Set debug level, 0 is off, 9 is highest presently used
|
||||
// May be overridden by commandArgs
|
||||
Verilated::debug(0);
|
||||
|
||||
// Randomization reset policy
|
||||
// May be overridden by commandArgs
|
||||
Verilated::randReset(2);
|
||||
|
||||
// Pass arguments so Verilated code can see them, e.g. $value$plusargs
|
||||
// This needs to be called before you create any model
|
||||
Verilated::commandArgs(argc, argv);
|
||||
|
||||
// General logfile
|
||||
ios::sync_with_stdio();
|
||||
|
||||
// Defaults time
|
||||
#if (SYSTEMC_VERSION>20011000)
|
||||
#else
|
||||
sc_time dut(1.0, sc_ns);
|
||||
sc_set_default_time_unit(dut);
|
||||
#endif
|
||||
|
||||
// Define clocks
|
||||
#if (SYSTEMC_VERSION>=20070314)
|
||||
sc_clock clk ("clk", 10,SC_NS, 0.5, 3,SC_NS, true);
|
||||
sc_clock fastclk ("fastclk", 2,SC_NS, 0.5, 2,SC_NS, true);
|
||||
#else
|
||||
sc_clock clk ("clk", 10, 0.5, 3, true);
|
||||
sc_clock fastclk ("fastclk", 2, 0.5, 2, true);
|
||||
#endif
|
||||
|
||||
// Define interconnect
|
||||
sc_signal<bool> reset_l;
|
||||
sc_signal<vluint32_t> in_small;
|
||||
sc_signal<vluint64_t> in_quad;
|
||||
sc_signal<sc_bv<70> > in_wide;
|
||||
sc_signal<vluint32_t> out_small;
|
||||
sc_signal<vluint64_t> out_quad;
|
||||
sc_signal<sc_bv<70> > out_wide;
|
||||
|
||||
// Construct the Verilated model, from inside Vtop.h
|
||||
Vtop* top = new Vtop("top");
|
||||
// Attach signals to the model
|
||||
top->clk (clk);
|
||||
top->fastclk (fastclk);
|
||||
top->reset_l (reset_l);
|
||||
top->in_small (in_small);
|
||||
top->in_quad (in_quad);
|
||||
top->in_wide (in_wide);
|
||||
top->out_small (out_small);
|
||||
top->out_quad (out_quad);
|
||||
top->out_wide (out_wide);
|
||||
|
||||
#if VM_TRACE
|
||||
// Before any evaluation, need to know to calculate those signals only used for tracing
|
||||
Verilated::traceEverOn(true);
|
||||
#endif
|
||||
|
||||
// You must do one evaluation before enabling waves, in order to allow
|
||||
// SystemC to interconnect everything for testing.
|
||||
#if (SYSTEMC_VERSION>=20070314)
|
||||
sc_start(1,SC_NS);
|
||||
#else
|
||||
sc_start(1);
|
||||
#endif
|
||||
|
||||
#if VM_TRACE
|
||||
// If verilator was invoked with --trace argument,
|
||||
// and if at run time passed the +trace argument, turn on tracing
|
||||
VerilatedVcdSc* tfp = NULL;
|
||||
const char* flag = Verilated::commandArgsPlusMatch("trace");
|
||||
if (flag && 0==strcmp(flag, "+trace")) {
|
||||
cout << "Enabling waves into logs/vlt_dump.vcd...\n";
|
||||
tfp = new VerilatedVcdSc;
|
||||
top->trace(tfp, 99); // Trace 99 levels of hierarchy
|
||||
Verilated::mkdir("logs");
|
||||
tfp->open("logs/vlt_dump.vcd");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Simulate until $finish
|
||||
while (!Verilated::gotFinish()) {
|
||||
#if VM_TRACE
|
||||
// Flush the wave files each cycle so we can immediately see the output
|
||||
// Don't do this in "real" programs, do it in an abort() handler instead
|
||||
if (tfp) tfp->flush();
|
||||
#endif
|
||||
|
||||
// Apply inputs
|
||||
if (VL_TIME_Q() > 1 && VL_TIME_Q() < 10) {
|
||||
reset_l = !1; // Assert reset
|
||||
} else if (VL_TIME_Q() > 1) {
|
||||
reset_l = !0; // Deassert reset
|
||||
}
|
||||
|
||||
// Simulate 1ns
|
||||
#if (SYSTEMC_VERSION>=20070314)
|
||||
sc_start(1,SC_NS);
|
||||
#else
|
||||
sc_start(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Final model cleanup
|
||||
top->final();
|
||||
|
||||
// Close trace if opened
|
||||
#if VM_TRACE
|
||||
if (tfp) { tfp->close(); tfp = NULL; }
|
||||
#endif
|
||||
|
||||
// Coverage analysis (since test passed)
|
||||
#if VM_COVERAGE
|
||||
Verilated::mkdir("logs");
|
||||
VerilatedCov::write("logs/coverage.dat");
|
||||
#endif
|
||||
|
||||
// Destroy model
|
||||
delete top; top = NULL;
|
||||
|
||||
// Fin
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
// ======================================================================
|
||||
|
||||
module sub
|
||||
(
|
||||
input clk,
|
||||
input fastclk,
|
||||
input reset_l
|
||||
);
|
||||
|
||||
// Example counter/flop
|
||||
reg [31:0] count_f;
|
||||
always_ff @ (posedge fastclk) begin
|
||||
if (!reset_l) begin
|
||||
/*AUTORESET*/
|
||||
// Beginning of autoreset for uninitialized flops
|
||||
count_f <= 32'h0;
|
||||
// End of automatics
|
||||
end
|
||||
else begin
|
||||
count_f <= count_f + 1;
|
||||
end
|
||||
end
|
||||
|
||||
// Another example flop
|
||||
reg [31:0] count_c;
|
||||
always_ff @ (posedge clk) begin
|
||||
if (!reset_l) begin
|
||||
/*AUTORESET*/
|
||||
// Beginning of autoreset for uninitialized flops
|
||||
count_c <= 32'h0;
|
||||
// End of automatics
|
||||
end
|
||||
else begin
|
||||
count_c <= count_c + 1;
|
||||
if (count_c >= 3) begin
|
||||
$display("[%0t] fastclk is %0d times faster than clk\n",
|
||||
$time, count_f/count_c);
|
||||
// This write is a magic value the Makefile uses to make sure the
|
||||
// test completes successfully.
|
||||
$write("*-* All Finished *-*\n");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// An example assertion
|
||||
always_ff @ (posedge clk) begin
|
||||
AssertionExample: assert(!reset_l || count_c<100);
|
||||
end
|
||||
|
||||
// And example coverage analysis
|
||||
cover property (@(posedge clk) count_c==3);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,42 @@
|
||||
// DESCRIPTION: Verilator: Verilog example module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2003 by Wilson Snyder.
|
||||
// ======================================================================
|
||||
|
||||
// This is intended to be a complex example of several features, please also
|
||||
// see the simpler examples/hello_world_c.
|
||||
|
||||
module top
|
||||
(
|
||||
// Declare some signals so we can see how I/O works
|
||||
input clk,
|
||||
input fastclk,
|
||||
input reset_l,
|
||||
|
||||
output [1:0] out_small,
|
||||
output [39:0] out_quad,
|
||||
output [69:0] out_wide,
|
||||
input [1:0] in_small,
|
||||
input [39:0] in_quad,
|
||||
input [69:0] in_wide
|
||||
);
|
||||
|
||||
// Connect up the outputs, using some trivial logic
|
||||
wire [1:0] out_small = ~reset_l ? '0 : (in_small + 2'b1);
|
||||
wire [39:0] out_quad = ~reset_l ? '0 : (in_quad + 40'b1);
|
||||
wire [69:0] out_wide = ~reset_l ? '0 : (in_wide + 70'b1);
|
||||
|
||||
// And an example sub module. The submodule will print stuff.
|
||||
sub sub (/*AUTOINST*/
|
||||
// Inputs
|
||||
.clk (clk),
|
||||
.fastclk (fastclk),
|
||||
.reset_l (reset_l));
|
||||
|
||||
// Print some stuff as an example
|
||||
initial begin
|
||||
$display("[%0t] Model running...\n", $time);
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -1 +0,0 @@
|
||||
verilated.mk
|
||||
@@ -0,0 +1,2 @@
|
||||
verilated.mk
|
||||
verilated_config.h
|
||||
@@ -0,0 +1,547 @@
|
||||
/*
|
||||
FastLZ - lightning-fast lossless compression library
|
||||
|
||||
Copyright (C) 2007 Ariya Hidayat ([email protected])
|
||||
Copyright (C) 2006 Ariya Hidayat ([email protected])
|
||||
Copyright (C) 2005 Ariya Hidayat ([email protected])
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "fastlz.h"
|
||||
|
||||
#if !defined(FASTLZ__COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR)
|
||||
|
||||
/*
|
||||
* Always check for bound when decompressing.
|
||||
* Generally it is best to leave it defined.
|
||||
*/
|
||||
#define FASTLZ_SAFE
|
||||
|
||||
|
||||
/*
|
||||
* Give hints to the compiler for branch prediction optimization.
|
||||
*/
|
||||
#if defined(__GNUC__) && (__GNUC__ > 2)
|
||||
#define FASTLZ_EXPECT_CONDITIONAL(c) (__builtin_expect((c), 1))
|
||||
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (__builtin_expect((c), 0))
|
||||
#else
|
||||
#define FASTLZ_EXPECT_CONDITIONAL(c) (c)
|
||||
#define FASTLZ_UNEXPECT_CONDITIONAL(c) (c)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Use inlined functions for supported systems.
|
||||
*/
|
||||
#if defined(__GNUC__) || defined(__DMC__) || defined(__POCC__) || defined(__WATCOMC__) || defined(__SUNPRO_C)
|
||||
#define FASTLZ_INLINE inline
|
||||
#elif defined(__BORLANDC__) || defined(_MSC_VER) || defined(__LCC__)
|
||||
#define FASTLZ_INLINE __inline
|
||||
#else
|
||||
#define FASTLZ_INLINE
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prevent accessing more than 8-bit at once, except on x86 architectures.
|
||||
*/
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
#define FASTLZ_STRICT_ALIGN
|
||||
#if defined(__i386__) || defined(__386) /* GNU C, Sun Studio */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__amd64) /* GNU C */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(_M_IX86) /* Intel, MSVC */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(__386)
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(_X86_) /* MinGW */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#elif defined(__I86__) /* Digital Mars */
|
||||
#undef FASTLZ_STRICT_ALIGN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* prototypes */
|
||||
int fastlz_compress(const void* input, int length, void* output);
|
||||
int fastlz_compress_level(int level, const void* input, int length, void* output);
|
||||
int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
||||
|
||||
#define MAX_COPY 32
|
||||
#define MAX_LEN 264 /* 256 + 8 */
|
||||
#define MAX_DISTANCE 8192
|
||||
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
#define FASTLZ_READU16(p) *((const flzuint16*)(p))
|
||||
#else
|
||||
#define FASTLZ_READU16(p) ((p)[0] | (p)[1]<<8)
|
||||
#endif
|
||||
|
||||
#define HASH_LOG 13
|
||||
#define HASH_SIZE (1<< HASH_LOG)
|
||||
#define HASH_MASK (HASH_SIZE-1)
|
||||
#define HASH_FUNCTION(v,p) { v = FASTLZ_READU16(p); v ^= FASTLZ_READU16(p+1)^(v>>(16-HASH_LOG));v &= HASH_MASK; }
|
||||
|
||||
#undef FASTLZ_LEVEL
|
||||
#define FASTLZ_LEVEL 1
|
||||
|
||||
#undef FASTLZ_COMPRESSOR
|
||||
#undef FASTLZ_DECOMPRESSOR
|
||||
#define FASTLZ_COMPRESSOR fastlz1_compress
|
||||
#define FASTLZ_DECOMPRESSOR fastlz1_decompress
|
||||
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
|
||||
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
|
||||
#include "fastlz.c"
|
||||
|
||||
#undef FASTLZ_LEVEL
|
||||
#define FASTLZ_LEVEL 2
|
||||
|
||||
#undef MAX_DISTANCE
|
||||
#define MAX_DISTANCE 8191
|
||||
#define MAX_FARDISTANCE (65535+MAX_DISTANCE-1)
|
||||
|
||||
#undef FASTLZ_COMPRESSOR
|
||||
#undef FASTLZ_DECOMPRESSOR
|
||||
#define FASTLZ_COMPRESSOR fastlz2_compress
|
||||
#define FASTLZ_DECOMPRESSOR fastlz2_decompress
|
||||
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output);
|
||||
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout);
|
||||
#include "fastlz.c"
|
||||
|
||||
int fastlz_compress(const void* input, int length, void* output)
|
||||
{
|
||||
/* for short block, choose fastlz1 */
|
||||
if(length < 65536)
|
||||
return fastlz1_compress(input, length, output);
|
||||
|
||||
/* else... */
|
||||
return fastlz2_compress(input, length, output);
|
||||
}
|
||||
|
||||
int fastlz_decompress(const void* input, int length, void* output, int maxout)
|
||||
{
|
||||
/* magic identifier for compression level */
|
||||
int level = ((*(const flzuint8*)input) >> 5) + 1;
|
||||
|
||||
if(level == 1)
|
||||
return fastlz1_decompress(input, length, output, maxout);
|
||||
if(level == 2)
|
||||
return fastlz2_decompress(input, length, output, maxout);
|
||||
|
||||
/* unknown level, trigger error */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fastlz_compress_level(int level, const void* input, int length, void* output)
|
||||
{
|
||||
if(level == 1)
|
||||
return fastlz1_compress(input, length, output);
|
||||
if(level == 2)
|
||||
return fastlz2_compress(input, length, output);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
|
||||
|
||||
static FASTLZ_INLINE int FASTLZ_COMPRESSOR(const void* input, int length, void* output)
|
||||
{
|
||||
const flzuint8* ip = (const flzuint8*) input;
|
||||
const flzuint8* ip_bound = ip + length - 2;
|
||||
const flzuint8* ip_limit = ip + length - 12;
|
||||
flzuint8* op = (flzuint8*) output;
|
||||
|
||||
const flzuint8* htab[HASH_SIZE];
|
||||
const flzuint8** hslot;
|
||||
flzuint32 hval;
|
||||
|
||||
flzuint32 copy;
|
||||
|
||||
/* sanity check */
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(length < 4))
|
||||
{
|
||||
if(length)
|
||||
{
|
||||
/* create literal copy only */
|
||||
*op++ = length-1;
|
||||
ip_bound++;
|
||||
while(ip <= ip_bound)
|
||||
*op++ = *ip++;
|
||||
return length+1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* initializes hash table */
|
||||
for (hslot = htab; hslot < htab + HASH_SIZE; hslot++)
|
||||
*hslot = ip;
|
||||
|
||||
/* we start with literal copy */
|
||||
copy = 2;
|
||||
*op++ = MAX_COPY-1;
|
||||
*op++ = *ip++;
|
||||
*op++ = *ip++;
|
||||
|
||||
/* main loop */
|
||||
while(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
|
||||
{
|
||||
const flzuint8* ref;
|
||||
flzuint32 distance;
|
||||
|
||||
/* minimum match length */
|
||||
flzuint32 len = 3;
|
||||
|
||||
/* comparison starting-point */
|
||||
const flzuint8* anchor = ip;
|
||||
|
||||
/* check for a run */
|
||||
#if FASTLZ_LEVEL==2
|
||||
if(ip[0] == ip[-1] && FASTLZ_READU16(ip-1)==FASTLZ_READU16(ip+1))
|
||||
{
|
||||
distance = 1;
|
||||
/* ip += 3; */ /* scan-build, never used */
|
||||
ref = anchor - 1 + 3;
|
||||
goto match;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* find potential match */
|
||||
HASH_FUNCTION(hval,ip);
|
||||
hslot = htab + hval;
|
||||
ref = htab[hval];
|
||||
|
||||
/* calculate distance to the match */
|
||||
distance = anchor - ref;
|
||||
|
||||
/* update hash table */
|
||||
*hslot = anchor;
|
||||
|
||||
/* is this a match? check the first 3 bytes */
|
||||
if(distance==0 ||
|
||||
#if FASTLZ_LEVEL==1
|
||||
(distance >= MAX_DISTANCE) ||
|
||||
#else
|
||||
(distance >= MAX_FARDISTANCE) ||
|
||||
#endif
|
||||
*ref++ != *ip++ || *ref++!=*ip++ || *ref++!=*ip++)
|
||||
goto literal;
|
||||
|
||||
#if FASTLZ_LEVEL==2
|
||||
/* far, needs at least 5-byte match */
|
||||
if(distance >= MAX_DISTANCE)
|
||||
{
|
||||
if(*ip++ != *ref++ || *ip++!= *ref++)
|
||||
goto literal;
|
||||
len += 2;
|
||||
}
|
||||
|
||||
match:
|
||||
#endif
|
||||
|
||||
/* last matched byte */
|
||||
ip = anchor + len;
|
||||
|
||||
/* distance is biased */
|
||||
distance--;
|
||||
|
||||
if(!distance)
|
||||
{
|
||||
/* zero distance means a run */
|
||||
flzuint8 x = ip[-1];
|
||||
while(ip < ip_bound)
|
||||
if(*ref++ != x) break; else ip++;
|
||||
}
|
||||
else
|
||||
for(;;)
|
||||
{
|
||||
/* safe because the outer check against ip limit */
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
if(*ref++ != *ip++) break;
|
||||
while(ip < ip_bound)
|
||||
if(*ref++ != *ip++) break;
|
||||
break;
|
||||
}
|
||||
|
||||
/* if we have copied something, adjust the copy count */
|
||||
if(copy)
|
||||
/* copy is biased, '0' means 1 byte copy */
|
||||
*(op-copy-1) = copy-1;
|
||||
else
|
||||
/* back, to overwrite the copy count */
|
||||
op--;
|
||||
|
||||
/* reset literal counter */
|
||||
copy = 0;
|
||||
|
||||
/* length is biased, '1' means a match of 3 bytes */
|
||||
ip -= 3;
|
||||
len = ip - anchor;
|
||||
|
||||
/* encode the match */
|
||||
#if FASTLZ_LEVEL==2
|
||||
if(distance < MAX_DISTANCE)
|
||||
{
|
||||
if(len < 7)
|
||||
{
|
||||
*op++ = (len << 5) + (distance >> 8);
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
*op++ = (7 << 5) + (distance >> 8);
|
||||
for(len-=7; len >= 255; len-= 255)
|
||||
*op++ = 255;
|
||||
*op++ = len;
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* far away, but not yet in the another galaxy... */
|
||||
if(len < 7)
|
||||
{
|
||||
distance -= MAX_DISTANCE;
|
||||
*op++ = (len << 5) + 31;
|
||||
*op++ = 255;
|
||||
*op++ = distance >> 8;
|
||||
*op++ = distance & 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
distance -= MAX_DISTANCE;
|
||||
*op++ = (7 << 5) + 31;
|
||||
for(len-=7; len >= 255; len-= 255)
|
||||
*op++ = 255;
|
||||
*op++ = len;
|
||||
*op++ = 255;
|
||||
*op++ = distance >> 8;
|
||||
*op++ = distance & 255;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(len > MAX_LEN-2))
|
||||
while(len > MAX_LEN-2)
|
||||
{
|
||||
*op++ = (7 << 5) + (distance >> 8);
|
||||
*op++ = MAX_LEN - 2 - 7 -2;
|
||||
*op++ = (distance & 255);
|
||||
len -= MAX_LEN-2;
|
||||
}
|
||||
|
||||
if(len < 7)
|
||||
{
|
||||
*op++ = (len << 5) + (distance >> 8);
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
*op++ = (7 << 5) + (distance >> 8);
|
||||
*op++ = len - 7;
|
||||
*op++ = (distance & 255);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* update the hash at match boundary */
|
||||
HASH_FUNCTION(hval,ip);
|
||||
htab[hval] = ip++;
|
||||
HASH_FUNCTION(hval,ip);
|
||||
htab[hval] = ip++;
|
||||
|
||||
/* assuming literal copy */
|
||||
*op++ = MAX_COPY-1;
|
||||
|
||||
continue;
|
||||
|
||||
literal:
|
||||
*op++ = *anchor++;
|
||||
ip = anchor;
|
||||
copy++;
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(copy == MAX_COPY))
|
||||
{
|
||||
copy = 0;
|
||||
*op++ = MAX_COPY-1;
|
||||
}
|
||||
}
|
||||
|
||||
/* left-over as literal copy */
|
||||
ip_bound++;
|
||||
while(ip <= ip_bound)
|
||||
{
|
||||
*op++ = *ip++;
|
||||
copy++;
|
||||
if(copy == MAX_COPY)
|
||||
{
|
||||
copy = 0;
|
||||
*op++ = MAX_COPY-1;
|
||||
}
|
||||
}
|
||||
|
||||
/* if we have copied something, adjust the copy length */
|
||||
if(copy)
|
||||
*(op-copy-1) = copy-1;
|
||||
else
|
||||
op--;
|
||||
|
||||
#if FASTLZ_LEVEL==2
|
||||
/* marker for fastlz2 */
|
||||
*(flzuint8*)output |= (1 << 5);
|
||||
#endif
|
||||
|
||||
return op - (flzuint8*)output;
|
||||
}
|
||||
|
||||
static FASTLZ_INLINE int FASTLZ_DECOMPRESSOR(const void* input, int length, void* output, int maxout)
|
||||
{
|
||||
const flzuint8* ip = (const flzuint8*) input;
|
||||
const flzuint8* ip_limit = ip + length;
|
||||
flzuint8* op = (flzuint8*) output;
|
||||
flzuint8* op_limit = op + maxout;
|
||||
flzuint32 ctrl = (*ip++) & 31;
|
||||
int loop = 1;
|
||||
|
||||
do
|
||||
{
|
||||
const flzuint8* ref = op;
|
||||
flzuint32 len = ctrl >> 5;
|
||||
flzuint32 ofs = (ctrl & 31) << 8;
|
||||
|
||||
if(ctrl >= 32)
|
||||
{
|
||||
#if FASTLZ_LEVEL==2
|
||||
flzuint8 code;
|
||||
#endif
|
||||
len--;
|
||||
ref -= ofs;
|
||||
if (len == 7-1)
|
||||
#if FASTLZ_LEVEL==1
|
||||
len += *ip++;
|
||||
ref -= *ip++;
|
||||
#else
|
||||
do
|
||||
{
|
||||
code = *ip++;
|
||||
len += code;
|
||||
} while (code==255);
|
||||
code = *ip++;
|
||||
ref -= code;
|
||||
|
||||
/* match from 16-bit distance */
|
||||
if(FASTLZ_UNEXPECT_CONDITIONAL(code==255))
|
||||
if(FASTLZ_EXPECT_CONDITIONAL(ofs==(31 << 8)))
|
||||
{
|
||||
ofs = (*ip++) << 8;
|
||||
ofs += *ip++;
|
||||
ref = op - ofs - MAX_DISTANCE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FASTLZ_SAFE
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(op + len + 3 > op_limit))
|
||||
return 0;
|
||||
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(ref-1 < (flzuint8 *)output))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if(FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit))
|
||||
ctrl = *ip++;
|
||||
else
|
||||
loop = 0;
|
||||
|
||||
if(ref == op)
|
||||
{
|
||||
/* optimize copy for a run */
|
||||
flzuint8 b = ref[-1];
|
||||
*op++ = b;
|
||||
*op++ = b;
|
||||
*op++ = b;
|
||||
for(; len; --len)
|
||||
*op++ = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
const flzuint16* p;
|
||||
flzuint16* q;
|
||||
#endif
|
||||
/* copy from reference */
|
||||
ref--;
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
*op++ = *ref++;
|
||||
|
||||
#if !defined(FASTLZ_STRICT_ALIGN)
|
||||
/* copy a byte, so that now it's word aligned */
|
||||
if(len & 1)
|
||||
{
|
||||
*op++ = *ref++;
|
||||
len--;
|
||||
}
|
||||
|
||||
/* copy 16-bit at once */
|
||||
q = (flzuint16*) op;
|
||||
op += len;
|
||||
p = (const flzuint16*) ref;
|
||||
for(len>>=1; len > 4; len-=4)
|
||||
{
|
||||
*q++ = *p++;
|
||||
*q++ = *p++;
|
||||
*q++ = *p++;
|
||||
*q++ = *p++;
|
||||
}
|
||||
for(; len; --len)
|
||||
*q++ = *p++;
|
||||
#else
|
||||
for(; len; --len)
|
||||
*op++ = *ref++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ctrl++;
|
||||
#ifdef FASTLZ_SAFE
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(op + ctrl > op_limit))
|
||||
return 0;
|
||||
if (FASTLZ_UNEXPECT_CONDITIONAL(ip + ctrl > ip_limit))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
*op++ = *ip++;
|
||||
for(--ctrl; ctrl; ctrl--)
|
||||
*op++ = *ip++;
|
||||
|
||||
loop = FASTLZ_EXPECT_CONDITIONAL(ip < ip_limit);
|
||||
if(loop)
|
||||
ctrl = *ip++;
|
||||
}
|
||||
}
|
||||
while(FASTLZ_EXPECT_CONDITIONAL(loop));
|
||||
|
||||
return op - (flzuint8*)output;
|
||||
}
|
||||
|
||||
#endif /* !defined(FASTLZ_COMPRESSOR) && !defined(FASTLZ_DECOMPRESSOR) */
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
FastLZ - lightning-fast lossless compression library
|
||||
|
||||
Copyright (C) 2007 Ariya Hidayat ([email protected])
|
||||
Copyright (C) 2006 Ariya Hidayat ([email protected])
|
||||
Copyright (C) 2005 Ariya Hidayat ([email protected])
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef FASTLZ_H
|
||||
#define FASTLZ_H
|
||||
|
||||
#include <inttypes.h>
|
||||
|
||||
#define flzuint8 uint8_t
|
||||
#define flzuint16 uint16_t
|
||||
#define flzuint32 uint32_t
|
||||
|
||||
|
||||
#define FASTLZ_VERSION 0x000100
|
||||
|
||||
#define FASTLZ_VERSION_MAJOR 0
|
||||
#define FASTLZ_VERSION_MINOR 0
|
||||
#define FASTLZ_VERSION_REVISION 0
|
||||
|
||||
#define FASTLZ_VERSION_STRING "0.1.0"
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
Compress a block of data in the input buffer and returns the size of
|
||||
compressed block. The size of input buffer is specified by length. The
|
||||
minimum input buffer size is 16.
|
||||
|
||||
The output buffer must be at least 5% larger than the input buffer
|
||||
and can not be smaller than 66 bytes.
|
||||
|
||||
If the input is not compressible, the return value might be larger than
|
||||
length (input buffer size).
|
||||
|
||||
The input buffer and the output buffer can not overlap.
|
||||
*/
|
||||
|
||||
int fastlz_compress(const void* input, int length, void* output);
|
||||
|
||||
/**
|
||||
Decompress a block of compressed data and returns the size of the
|
||||
decompressed block. If error occurs, e.g. the compressed data is
|
||||
corrupted or the output buffer is not large enough, then 0 (zero)
|
||||
will be returned instead.
|
||||
|
||||
The input buffer and the output buffer can not overlap.
|
||||
|
||||
Decompression is memory safe and guaranteed not to write the output buffer
|
||||
more than what is specified in maxout.
|
||||
*/
|
||||
|
||||
int fastlz_decompress(const void* input, int length, void* output, int maxout);
|
||||
|
||||
/**
|
||||
Compress a block of data in the input buffer and returns the size of
|
||||
compressed block. The size of input buffer is specified by length. The
|
||||
minimum input buffer size is 16.
|
||||
|
||||
The output buffer must be at least 5% larger than the input buffer
|
||||
and can not be smaller than 66 bytes.
|
||||
|
||||
If the input is not compressible, the return value might be larger than
|
||||
length (input buffer size).
|
||||
|
||||
The input buffer and the output buffer can not overlap.
|
||||
|
||||
Compression level can be specified in parameter level. At the moment,
|
||||
only level 1 and level 2 are supported.
|
||||
Level 1 is the fastest compression and generally useful for short data.
|
||||
Level 2 is slightly slower but it gives better compression ratio.
|
||||
|
||||
Note that the compressed data, regardless of the level, can always be
|
||||
decompressed using the function fastlz_decompress above.
|
||||
*/
|
||||
|
||||
int fastlz_compress_level(int level, const void* input, int length, void* output);
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FASTLZ_H */
|
||||
@@ -0,0 +1,11 @@
|
||||
/* This file specifically for FST usage */
|
||||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix). */
|
||||
#if !defined(__MINGW32__)
|
||||
# define HAVE_ALLOCA_H 1
|
||||
#endif
|
||||
|
||||
/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */
|
||||
#define HAVE_FSEEKO 1
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,452 @@
|
||||
/*
|
||||
* Copyright (c) 2009-2018 Tony Bybell.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef FST_API_H
|
||||
#define FST_API_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <zlib.h>
|
||||
#include <inttypes.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#define FST_RDLOAD "FSTLOAD | "
|
||||
|
||||
typedef uint32_t fstHandle;
|
||||
typedef uint32_t fstEnumHandle;
|
||||
|
||||
enum fstWriterPackType {
|
||||
FST_WR_PT_ZLIB = 0,
|
||||
FST_WR_PT_FASTLZ = 1,
|
||||
FST_WR_PT_LZ4 = 2
|
||||
};
|
||||
|
||||
enum fstFileType {
|
||||
FST_FT_MIN = 0,
|
||||
|
||||
FST_FT_VERILOG = 0,
|
||||
FST_FT_VHDL = 1,
|
||||
FST_FT_VERILOG_VHDL = 2,
|
||||
|
||||
FST_FT_MAX = 2
|
||||
};
|
||||
|
||||
enum fstBlockType {
|
||||
FST_BL_HDR = 0,
|
||||
FST_BL_VCDATA = 1,
|
||||
FST_BL_BLACKOUT = 2,
|
||||
FST_BL_GEOM = 3,
|
||||
FST_BL_HIER = 4,
|
||||
FST_BL_VCDATA_DYN_ALIAS = 5,
|
||||
FST_BL_HIER_LZ4 = 6,
|
||||
FST_BL_HIER_LZ4DUO = 7,
|
||||
FST_BL_VCDATA_DYN_ALIAS2 = 8,
|
||||
|
||||
FST_BL_ZWRAPPER = 254, /* indicates that whole trace is gz wrapped */
|
||||
FST_BL_SKIP = 255 /* used while block is being written */
|
||||
};
|
||||
|
||||
enum fstScopeType {
|
||||
FST_ST_MIN = 0,
|
||||
|
||||
FST_ST_VCD_MODULE = 0,
|
||||
FST_ST_VCD_TASK = 1,
|
||||
FST_ST_VCD_FUNCTION = 2,
|
||||
FST_ST_VCD_BEGIN = 3,
|
||||
FST_ST_VCD_FORK = 4,
|
||||
FST_ST_VCD_GENERATE = 5,
|
||||
FST_ST_VCD_STRUCT = 6,
|
||||
FST_ST_VCD_UNION = 7,
|
||||
FST_ST_VCD_CLASS = 8,
|
||||
FST_ST_VCD_INTERFACE = 9,
|
||||
FST_ST_VCD_PACKAGE = 10,
|
||||
FST_ST_VCD_PROGRAM = 11,
|
||||
|
||||
FST_ST_VHDL_ARCHITECTURE = 12,
|
||||
FST_ST_VHDL_PROCEDURE = 13,
|
||||
FST_ST_VHDL_FUNCTION = 14,
|
||||
FST_ST_VHDL_RECORD = 15,
|
||||
FST_ST_VHDL_PROCESS = 16,
|
||||
FST_ST_VHDL_BLOCK = 17,
|
||||
FST_ST_VHDL_FOR_GENERATE = 18,
|
||||
FST_ST_VHDL_IF_GENERATE = 19,
|
||||
FST_ST_VHDL_GENERATE = 20,
|
||||
FST_ST_VHDL_PACKAGE = 21,
|
||||
|
||||
FST_ST_MAX = 21,
|
||||
|
||||
FST_ST_GEN_ATTRBEGIN = 252,
|
||||
FST_ST_GEN_ATTREND = 253,
|
||||
|
||||
FST_ST_VCD_SCOPE = 254,
|
||||
FST_ST_VCD_UPSCOPE = 255
|
||||
};
|
||||
|
||||
enum fstVarType {
|
||||
FST_VT_MIN = 0, /* start of vartypes */
|
||||
|
||||
FST_VT_VCD_EVENT = 0,
|
||||
FST_VT_VCD_INTEGER = 1,
|
||||
FST_VT_VCD_PARAMETER = 2,
|
||||
FST_VT_VCD_REAL = 3,
|
||||
FST_VT_VCD_REAL_PARAMETER = 4,
|
||||
FST_VT_VCD_REG = 5,
|
||||
FST_VT_VCD_SUPPLY0 = 6,
|
||||
FST_VT_VCD_SUPPLY1 = 7,
|
||||
FST_VT_VCD_TIME = 8,
|
||||
FST_VT_VCD_TRI = 9,
|
||||
FST_VT_VCD_TRIAND = 10,
|
||||
FST_VT_VCD_TRIOR = 11,
|
||||
FST_VT_VCD_TRIREG = 12,
|
||||
FST_VT_VCD_TRI0 = 13,
|
||||
FST_VT_VCD_TRI1 = 14,
|
||||
FST_VT_VCD_WAND = 15,
|
||||
FST_VT_VCD_WIRE = 16,
|
||||
FST_VT_VCD_WOR = 17,
|
||||
FST_VT_VCD_PORT = 18,
|
||||
FST_VT_VCD_SPARRAY = 19, /* used to define the rownum (index) port for a sparse array */
|
||||
FST_VT_VCD_REALTIME = 20,
|
||||
|
||||
FST_VT_GEN_STRING = 21, /* generic string type (max len is defined dynamically via fstWriterEmitVariableLengthValueChange) */
|
||||
|
||||
FST_VT_SV_BIT = 22,
|
||||
FST_VT_SV_LOGIC = 23,
|
||||
FST_VT_SV_INT = 24, /* declare as size = 32 */
|
||||
FST_VT_SV_SHORTINT = 25, /* declare as size = 16 */
|
||||
FST_VT_SV_LONGINT = 26, /* declare as size = 64 */
|
||||
FST_VT_SV_BYTE = 27, /* declare as size = 8 */
|
||||
FST_VT_SV_ENUM = 28, /* declare as appropriate type range */
|
||||
FST_VT_SV_SHORTREAL = 29, /* declare and emit same as FST_VT_VCD_REAL (needs to be emitted as double, not a float) */
|
||||
|
||||
FST_VT_MAX = 29 /* end of vartypes */
|
||||
};
|
||||
|
||||
enum fstVarDir {
|
||||
FST_VD_MIN = 0,
|
||||
|
||||
FST_VD_IMPLICIT = 0,
|
||||
FST_VD_INPUT = 1,
|
||||
FST_VD_OUTPUT = 2,
|
||||
FST_VD_INOUT = 3,
|
||||
FST_VD_BUFFER = 4,
|
||||
FST_VD_LINKAGE = 5,
|
||||
|
||||
FST_VD_MAX = 5
|
||||
};
|
||||
|
||||
enum fstHierType {
|
||||
FST_HT_MIN = 0,
|
||||
|
||||
FST_HT_SCOPE = 0,
|
||||
FST_HT_UPSCOPE = 1,
|
||||
FST_HT_VAR = 2,
|
||||
FST_HT_ATTRBEGIN = 3,
|
||||
FST_HT_ATTREND = 4,
|
||||
|
||||
/* FST_HT_TREEBEGIN and FST_HT_TREEEND are not yet used by FST but are currently used when fstHier bridges other formats */
|
||||
FST_HT_TREEBEGIN = 5,
|
||||
FST_HT_TREEEND = 6,
|
||||
|
||||
FST_HT_MAX = 6
|
||||
};
|
||||
|
||||
enum fstAttrType {
|
||||
FST_AT_MIN = 0,
|
||||
|
||||
FST_AT_MISC = 0, /* self-contained: does not need matching FST_HT_ATTREND */
|
||||
FST_AT_ARRAY = 1,
|
||||
FST_AT_ENUM = 2,
|
||||
FST_AT_PACK = 3,
|
||||
|
||||
FST_AT_MAX = 3
|
||||
};
|
||||
|
||||
enum fstMiscType {
|
||||
FST_MT_MIN = 0,
|
||||
|
||||
FST_MT_COMMENT = 0, /* use fstWriterSetComment() to emit */
|
||||
FST_MT_ENVVAR = 1, /* use fstWriterSetEnvVar() to emit */
|
||||
FST_MT_SUPVAR = 2, /* use fstWriterCreateVar2() to emit */
|
||||
FST_MT_PATHNAME = 3, /* reserved for fstWriterSetSourceStem() string -> number management */
|
||||
FST_MT_SOURCESTEM = 4, /* use fstWriterSetSourceStem() to emit */
|
||||
FST_MT_SOURCEISTEM = 5, /* use fstWriterSetSourceInstantiationStem() to emit */
|
||||
FST_MT_VALUELIST = 6, /* use fstWriterSetValueList() to emit, followed by fstWriterCreateVar*() */
|
||||
FST_MT_ENUMTABLE = 7, /* use fstWriterCreateEnumTable() and fstWriterEmitEnumTableRef() to emit */
|
||||
FST_MT_UNKNOWN = 8,
|
||||
|
||||
FST_MT_MAX = 8
|
||||
};
|
||||
|
||||
enum fstArrayType {
|
||||
FST_AR_MIN = 0,
|
||||
|
||||
FST_AR_NONE = 0,
|
||||
FST_AR_UNPACKED = 1,
|
||||
FST_AR_PACKED = 2,
|
||||
FST_AR_SPARSE = 3,
|
||||
|
||||
FST_AR_MAX = 3
|
||||
};
|
||||
|
||||
enum fstEnumValueType {
|
||||
FST_EV_SV_INTEGER = 0,
|
||||
FST_EV_SV_BIT = 1,
|
||||
FST_EV_SV_LOGIC = 2,
|
||||
FST_EV_SV_INT = 3,
|
||||
FST_EV_SV_SHORTINT = 4,
|
||||
FST_EV_SV_LONGINT = 5,
|
||||
FST_EV_SV_BYTE = 6,
|
||||
FST_EV_SV_UNSIGNED_INTEGER = 7,
|
||||
FST_EV_SV_UNSIGNED_BIT = 8,
|
||||
FST_EV_SV_UNSIGNED_LOGIC = 9,
|
||||
FST_EV_SV_UNSIGNED_INT = 10,
|
||||
FST_EV_SV_UNSIGNED_SHORTINT = 11,
|
||||
FST_EV_SV_UNSIGNED_LONGINT = 12,
|
||||
FST_EV_SV_UNSIGNED_BYTE = 13,
|
||||
|
||||
FST_EV_REG = 14,
|
||||
FST_EV_TIME = 15,
|
||||
|
||||
FST_EV_MAX = 15
|
||||
};
|
||||
|
||||
enum fstPackType {
|
||||
FST_PT_NONE = 0,
|
||||
FST_PT_UNPACKED = 1,
|
||||
FST_PT_PACKED = 2,
|
||||
FST_PT_TAGGED_PACKED = 3,
|
||||
|
||||
FST_PT_MAX = 3
|
||||
};
|
||||
|
||||
enum fstSupplementalVarType {
|
||||
FST_SVT_MIN = 0,
|
||||
|
||||
FST_SVT_NONE = 0,
|
||||
|
||||
FST_SVT_VHDL_SIGNAL = 1,
|
||||
FST_SVT_VHDL_VARIABLE = 2,
|
||||
FST_SVT_VHDL_CONSTANT = 3,
|
||||
FST_SVT_VHDL_FILE = 4,
|
||||
FST_SVT_VHDL_MEMORY = 5,
|
||||
|
||||
FST_SVT_MAX = 5
|
||||
};
|
||||
|
||||
enum fstSupplementalDataType {
|
||||
FST_SDT_MIN = 0,
|
||||
|
||||
FST_SDT_NONE = 0,
|
||||
|
||||
FST_SDT_VHDL_BOOLEAN = 1,
|
||||
FST_SDT_VHDL_BIT = 2,
|
||||
FST_SDT_VHDL_BIT_VECTOR = 3,
|
||||
FST_SDT_VHDL_STD_ULOGIC = 4,
|
||||
FST_SDT_VHDL_STD_ULOGIC_VECTOR = 5,
|
||||
FST_SDT_VHDL_STD_LOGIC = 6,
|
||||
FST_SDT_VHDL_STD_LOGIC_VECTOR = 7,
|
||||
FST_SDT_VHDL_UNSIGNED = 8,
|
||||
FST_SDT_VHDL_SIGNED = 9,
|
||||
FST_SDT_VHDL_INTEGER = 10,
|
||||
FST_SDT_VHDL_REAL = 11,
|
||||
FST_SDT_VHDL_NATURAL = 12,
|
||||
FST_SDT_VHDL_POSITIVE = 13,
|
||||
FST_SDT_VHDL_TIME = 14,
|
||||
FST_SDT_VHDL_CHARACTER = 15,
|
||||
FST_SDT_VHDL_STRING = 16,
|
||||
|
||||
FST_SDT_MAX = 16,
|
||||
|
||||
FST_SDT_SVT_SHIFT_COUNT = 10, /* FST_SVT_* is ORed in by fstWriterCreateVar2() to the left after shifting FST_SDT_SVT_SHIFT_COUNT */
|
||||
FST_SDT_ABS_MAX = ((1<<(FST_SDT_SVT_SHIFT_COUNT))-1)
|
||||
};
|
||||
|
||||
|
||||
struct fstHier
|
||||
{
|
||||
unsigned char htyp;
|
||||
|
||||
union {
|
||||
/* if htyp == FST_HT_SCOPE */
|
||||
struct fstHierScope {
|
||||
unsigned char typ; /* FST_ST_MIN ... FST_ST_MAX */
|
||||
const char *name;
|
||||
const char *component;
|
||||
uint32_t name_length; /* strlen(u.scope.name) */
|
||||
uint32_t component_length; /* strlen(u.scope.component) */
|
||||
} scope;
|
||||
|
||||
/* if htyp == FST_HT_VAR */
|
||||
struct fstHierVar {
|
||||
unsigned char typ; /* FST_VT_MIN ... FST_VT_MAX */
|
||||
unsigned char direction; /* FST_VD_MIN ... FST_VD_MAX */
|
||||
unsigned char svt_workspace; /* zeroed out by FST reader, for client code use */
|
||||
unsigned char sdt_workspace; /* zeroed out by FST reader, for client code use */
|
||||
unsigned int sxt_workspace; /* zeroed out by FST reader, for client code use */
|
||||
const char *name;
|
||||
uint32_t length;
|
||||
fstHandle handle;
|
||||
uint32_t name_length; /* strlen(u.var.name) */
|
||||
unsigned is_alias : 1;
|
||||
} var;
|
||||
|
||||
/* if htyp == FST_HT_ATTRBEGIN */
|
||||
struct fstHierAttr {
|
||||
unsigned char typ; /* FST_AT_MIN ... FST_AT_MAX */
|
||||
unsigned char subtype; /* from fstMiscType, fstArrayType, fstEnumValueType, fstPackType */
|
||||
const char *name;
|
||||
uint64_t arg; /* number of array elements, struct members, or some other payload (possibly ignored) */
|
||||
uint64_t arg_from_name; /* for when name is overloaded as a variable-length integer (FST_AT_MISC + FST_MT_SOURCESTEM) */
|
||||
uint32_t name_length; /* strlen(u.attr.name) */
|
||||
} attr;
|
||||
} u;
|
||||
};
|
||||
|
||||
|
||||
struct fstETab
|
||||
{
|
||||
char *name;
|
||||
uint32_t elem_count;
|
||||
char **literal_arr;
|
||||
char **val_arr;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* writer functions
|
||||
*/
|
||||
void fstWriterClose(void *ctx);
|
||||
void * fstWriterCreate(const char *nam, int use_compressed_hier);
|
||||
fstEnumHandle fstWriterCreateEnumTable(void *ctx, const char *name, uint32_t elem_count, unsigned int min_valbits, const char **literal_arr, const char **val_arr);
|
||||
/* used for Verilog/SV */
|
||||
fstHandle fstWriterCreateVar(void *ctx, enum fstVarType vt, enum fstVarDir vd,
|
||||
uint32_t len, const char *nam, fstHandle aliasHandle);
|
||||
/* future expansion for VHDL and other languages. The variable type, data type, etc map onto
|
||||
the current Verilog/SV one. The "type" string is optional for a more verbose or custom description */
|
||||
fstHandle fstWriterCreateVar2(void *ctx, enum fstVarType vt, enum fstVarDir vd,
|
||||
uint32_t len, const char *nam, fstHandle aliasHandle,
|
||||
const char *type, enum fstSupplementalVarType svt, enum fstSupplementalDataType sdt);
|
||||
void fstWriterEmitDumpActive(void *ctx, int enable);
|
||||
void fstWriterEmitEnumTableRef(void *ctx, fstEnumHandle handle);
|
||||
void fstWriterEmitValueChange(void *ctx, fstHandle handle, const void *val);
|
||||
void fstWriterEmitVariableLengthValueChange(void *ctx, fstHandle handle, const void *val, uint32_t len);
|
||||
void fstWriterEmitTimeChange(void *ctx, uint64_t tim);
|
||||
void fstWriterFlushContext(void *ctx);
|
||||
int fstWriterGetDumpSizeLimitReached(void *ctx);
|
||||
int fstWriterGetFseekFailed(void *ctx);
|
||||
void fstWriterSetAttrBegin(void *ctx, enum fstAttrType attrtype, int subtype,
|
||||
const char *attrname, uint64_t arg);
|
||||
void fstWriterSetAttrEnd(void *ctx);
|
||||
void fstWriterSetComment(void *ctx, const char *comm);
|
||||
void fstWriterSetDate(void *ctx, const char *dat);
|
||||
void fstWriterSetDumpSizeLimit(void *ctx, uint64_t numbytes);
|
||||
void fstWriterSetEnvVar(void *ctx, const char *envvar);
|
||||
void fstWriterSetFileType(void *ctx, enum fstFileType filetype);
|
||||
void fstWriterSetPackType(void *ctx, enum fstWriterPackType typ);
|
||||
void fstWriterSetParallelMode(void *ctx, int enable);
|
||||
void fstWriterSetRepackOnClose(void *ctx, int enable); /* type = 0 (none), 1 (libz) */
|
||||
void fstWriterSetScope(void *ctx, enum fstScopeType scopetype,
|
||||
const char *scopename, const char *scopecomp);
|
||||
void fstWriterSetSourceInstantiationStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath);
|
||||
void fstWriterSetSourceStem(void *ctx, const char *path, unsigned int line, unsigned int use_realpath);
|
||||
void fstWriterSetTimescale(void *ctx, int ts);
|
||||
void fstWriterSetTimescaleFromString(void *ctx, const char *s);
|
||||
void fstWriterSetTimezero(void *ctx, int64_t tim);
|
||||
void fstWriterSetUpscope(void *ctx);
|
||||
void fstWriterSetValueList(void *ctx, const char *vl);
|
||||
void fstWriterSetVersion(void *ctx, const char *vers);
|
||||
|
||||
|
||||
/*
|
||||
* reader functions
|
||||
*/
|
||||
void fstReaderClose(void *ctx);
|
||||
void fstReaderClrFacProcessMask(void *ctx, fstHandle facidx);
|
||||
void fstReaderClrFacProcessMaskAll(void *ctx);
|
||||
uint64_t fstReaderGetAliasCount(void *ctx);
|
||||
const char * fstReaderGetCurrentFlatScope(void *ctx);
|
||||
void * fstReaderGetCurrentScopeUserInfo(void *ctx);
|
||||
int fstReaderGetCurrentScopeLen(void *ctx);
|
||||
const char * fstReaderGetDateString(void *ctx);
|
||||
int fstReaderGetDoubleEndianMatchState(void *ctx);
|
||||
uint64_t fstReaderGetDumpActivityChangeTime(void *ctx, uint32_t idx);
|
||||
unsigned char fstReaderGetDumpActivityChangeValue(void *ctx, uint32_t idx);
|
||||
uint64_t fstReaderGetEndTime(void *ctx);
|
||||
int fstReaderGetFacProcessMask(void *ctx, fstHandle facidx);
|
||||
int fstReaderGetFileType(void *ctx);
|
||||
int fstReaderGetFseekFailed(void *ctx);
|
||||
fstHandle fstReaderGetMaxHandle(void *ctx);
|
||||
uint64_t fstReaderGetMemoryUsedByWriter(void *ctx);
|
||||
uint32_t fstReaderGetNumberDumpActivityChanges(void *ctx);
|
||||
uint64_t fstReaderGetScopeCount(void *ctx);
|
||||
uint64_t fstReaderGetStartTime(void *ctx);
|
||||
signed char fstReaderGetTimescale(void *ctx);
|
||||
int64_t fstReaderGetTimezero(void *ctx);
|
||||
uint64_t fstReaderGetValueChangeSectionCount(void *ctx);
|
||||
char * fstReaderGetValueFromHandleAtTime(void *ctx, uint64_t tim, fstHandle facidx, char *buf);
|
||||
uint64_t fstReaderGetVarCount(void *ctx);
|
||||
const char * fstReaderGetVersionString(void *ctx);
|
||||
struct fstHier *fstReaderIterateHier(void *ctx);
|
||||
int fstReaderIterateHierRewind(void *ctx);
|
||||
int fstReaderIterBlocks(void *ctx,
|
||||
void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value),
|
||||
void *user_callback_data_pointer, FILE *vcdhandle);
|
||||
int fstReaderIterBlocks2(void *ctx,
|
||||
void (*value_change_callback)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value),
|
||||
void (*value_change_callback_varlen)(void *user_callback_data_pointer, uint64_t time, fstHandle facidx, const unsigned char *value, uint32_t len),
|
||||
void *user_callback_data_pointer, FILE *vcdhandle);
|
||||
void fstReaderIterBlocksSetNativeDoublesOnCallback(void *ctx, int enable);
|
||||
void * fstReaderOpen(const char *nam);
|
||||
void * fstReaderOpenForUtilitiesOnly(void);
|
||||
const char * fstReaderPopScope(void *ctx);
|
||||
int fstReaderProcessHier(void *ctx, FILE *vcdhandle);
|
||||
const char * fstReaderPushScope(void *ctx, const char *nam, void *user_info);
|
||||
void fstReaderResetScope(void *ctx);
|
||||
void fstReaderSetFacProcessMask(void *ctx, fstHandle facidx);
|
||||
void fstReaderSetFacProcessMaskAll(void *ctx);
|
||||
void fstReaderSetLimitTimeRange(void *ctx, uint64_t start_time, uint64_t end_time);
|
||||
void fstReaderSetUnlimitedTimeRange(void *ctx);
|
||||
void fstReaderSetVcdExtensions(void *ctx, int enable);
|
||||
|
||||
|
||||
/*
|
||||
* utility functions
|
||||
*/
|
||||
int fstUtilityBinToEscConvertedLen(const unsigned char *s, int len); /* used for mallocs for fstUtilityBinToEsc() */
|
||||
int fstUtilityBinToEsc(unsigned char *d, const unsigned char *s, int len);
|
||||
int fstUtilityEscToBin(unsigned char *d, unsigned char *s, int len);
|
||||
struct fstETab *fstUtilityExtractEnumTableFromString(const char *s);
|
||||
void fstUtilityFreeEnumTable(struct fstETab *etab); /* must use to free fstETab properly */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,360 @@
|
||||
/*
|
||||
LZ4 - Fast LZ compression algorithm
|
||||
Header File
|
||||
Copyright (C) 2011-2015, Yann Collet.
|
||||
|
||||
BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
You can contact the author at :
|
||||
- LZ4 source repository : https://github.com/Cyan4973/lz4
|
||||
- LZ4 public forum : https://groups.google.com/forum/#!forum/lz4c
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if defined (__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* lz4.h provides block compression functions, and gives full buffer control to programmer.
|
||||
* If you need to generate inter-operable compressed data (respecting LZ4 frame specification),
|
||||
* and can let the library handle its own memory, please use lz4frame.h instead.
|
||||
*/
|
||||
|
||||
/**************************************
|
||||
* Version
|
||||
**************************************/
|
||||
#define LZ4_VERSION_MAJOR 1 /* for breaking interface changes */
|
||||
#define LZ4_VERSION_MINOR 7 /* for new (non-breaking) interface capabilities */
|
||||
#define LZ4_VERSION_RELEASE 1 /* for tweaks, bug-fixes, or development */
|
||||
#define LZ4_VERSION_NUMBER (LZ4_VERSION_MAJOR *100*100 + LZ4_VERSION_MINOR *100 + LZ4_VERSION_RELEASE)
|
||||
int LZ4_versionNumber (void);
|
||||
|
||||
/**************************************
|
||||
* Tuning parameter
|
||||
**************************************/
|
||||
/*
|
||||
* LZ4_MEMORY_USAGE :
|
||||
* Memory usage formula : N->2^N Bytes (examples : 10 -> 1KB; 12 -> 4KB ; 16 -> 64KB; 20 -> 1MB; etc.)
|
||||
* Increasing memory usage improves compression ratio
|
||||
* Reduced memory usage can improve speed, due to cache effect
|
||||
* Default value is 14, for 16KB, which nicely fits into Intel x86 L1 cache
|
||||
*/
|
||||
#define LZ4_MEMORY_USAGE 14
|
||||
|
||||
|
||||
/**************************************
|
||||
* Simple Functions
|
||||
**************************************/
|
||||
|
||||
int LZ4_compress_default(const char* source, char* dest, int sourceSize, int maxDestSize);
|
||||
int LZ4_decompress_safe (const char* source, char* dest, int compressedSize, int maxDecompressedSize);
|
||||
|
||||
/*
|
||||
LZ4_compress_default() :
|
||||
Compresses 'sourceSize' bytes from buffer 'source'
|
||||
into already allocated 'dest' buffer of size 'maxDestSize'.
|
||||
Compression is guaranteed to succeed if 'maxDestSize' >= LZ4_compressBound(sourceSize).
|
||||
It also runs faster, so it's a recommended setting.
|
||||
If the function cannot compress 'source' into a more limited 'dest' budget,
|
||||
compression stops *immediately*, and the function result is zero.
|
||||
As a consequence, 'dest' content is not valid.
|
||||
This function never writes outside 'dest' buffer, nor read outside 'source' buffer.
|
||||
sourceSize : Max supported value is LZ4_MAX_INPUT_VALUE
|
||||
maxDestSize : full or partial size of buffer 'dest' (which must be already allocated)
|
||||
return : the number of bytes written into buffer 'dest' (necessarily <= maxOutputSize)
|
||||
or 0 if compression fails
|
||||
|
||||
LZ4_decompress_safe() :
|
||||
compressedSize : is the precise full size of the compressed block.
|
||||
maxDecompressedSize : is the size of destination buffer, which must be already allocated.
|
||||
return : the number of bytes decompressed into destination buffer (necessarily <= maxDecompressedSize)
|
||||
If destination buffer is not large enough, decoding will stop and output an error code (<0).
|
||||
If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||
This function is protected against buffer overflow exploits, including malicious data packets.
|
||||
It never writes outside output buffer, nor reads outside input buffer.
|
||||
*/
|
||||
|
||||
|
||||
/**************************************
|
||||
* Advanced Functions
|
||||
**************************************/
|
||||
#define LZ4_MAX_INPUT_SIZE 0x7E000000 /* 2 113 929 216 bytes */
|
||||
#define LZ4_COMPRESSBOUND(isize) ((unsigned)(isize) > (unsigned)LZ4_MAX_INPUT_SIZE ? 0 : (isize) + ((isize)/255) + 16)
|
||||
|
||||
/*
|
||||
LZ4_compressBound() :
|
||||
Provides the maximum size that LZ4 compression may output in a "worst case" scenario (input data not compressible)
|
||||
This function is primarily useful for memory allocation purposes (destination buffer size).
|
||||
Macro LZ4_COMPRESSBOUND() is also provided for compilation-time evaluation (stack memory allocation for example).
|
||||
Note that LZ4_compress_default() compress faster when dest buffer size is >= LZ4_compressBound(srcSize)
|
||||
inputSize : max supported value is LZ4_MAX_INPUT_SIZE
|
||||
return : maximum output size in a "worst case" scenario
|
||||
or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE)
|
||||
*/
|
||||
int LZ4_compressBound(int inputSize);
|
||||
|
||||
/*
|
||||
LZ4_compress_fast() :
|
||||
Same as LZ4_compress_default(), but allows to select an "acceleration" factor.
|
||||
The larger the acceleration value, the faster the algorithm, but also the lesser the compression.
|
||||
It's a trade-off. It can be fine tuned, with each successive value providing roughly +~3% to speed.
|
||||
An acceleration value of "1" is the same as regular LZ4_compress_default()
|
||||
Values <= 0 will be replaced by ACCELERATION_DEFAULT (see lz4.c), which is 1.
|
||||
*/
|
||||
int LZ4_compress_fast (const char* source, char* dest, int sourceSize, int maxDestSize, int acceleration);
|
||||
|
||||
|
||||
/*
|
||||
LZ4_compress_fast_extState() :
|
||||
Same compression function, just using an externally allocated memory space to store compression state.
|
||||
Use LZ4_sizeofState() to know how much memory must be allocated,
|
||||
and allocate it on 8-bytes boundaries (using malloc() typically).
|
||||
Then, provide it as 'void* state' to compression function.
|
||||
*/
|
||||
int LZ4_sizeofState(void);
|
||||
int LZ4_compress_fast_extState (void* state, const char* source, char* dest, int inputSize, int maxDestSize, int acceleration);
|
||||
|
||||
|
||||
/*
|
||||
LZ4_compress_destSize() :
|
||||
Reverse the logic, by compressing as much data as possible from 'source' buffer
|
||||
into already allocated buffer 'dest' of size 'targetDestSize'.
|
||||
This function either compresses the entire 'source' content into 'dest' if it's large enough,
|
||||
or fill 'dest' buffer completely with as much data as possible from 'source'.
|
||||
*sourceSizePtr : will be modified to indicate how many bytes where read from 'source' to fill 'dest'.
|
||||
New value is necessarily <= old value.
|
||||
return : Nb bytes written into 'dest' (necessarily <= targetDestSize)
|
||||
or 0 if compression fails
|
||||
*/
|
||||
int LZ4_compress_destSize (const char* source, char* dest, int* sourceSizePtr, int targetDestSize);
|
||||
|
||||
|
||||
/*
|
||||
LZ4_decompress_fast() :
|
||||
originalSize : is the original and therefore uncompressed size
|
||||
return : the number of bytes read from the source buffer (in other words, the compressed size)
|
||||
If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||
Destination buffer must be already allocated. Its size must be a minimum of 'originalSize' bytes.
|
||||
note : This function fully respect memory boundaries for properly formed compressed data.
|
||||
It is a bit faster than LZ4_decompress_safe().
|
||||
However, it does not provide any protection against intentionally modified data stream (malicious input).
|
||||
Use this function in trusted environment only (data to decode comes from a trusted source).
|
||||
*/
|
||||
int LZ4_decompress_fast (const char* source, char* dest, int originalSize);
|
||||
|
||||
/*
|
||||
LZ4_decompress_safe_partial() :
|
||||
This function decompress a compressed block of size 'compressedSize' at position 'source'
|
||||
into destination buffer 'dest' of size 'maxDecompressedSize'.
|
||||
The function tries to stop decompressing operation as soon as 'targetOutputSize' has been reached,
|
||||
reducing decompression time.
|
||||
return : the number of bytes decoded in the destination buffer (necessarily <= maxDecompressedSize)
|
||||
Note : this number can be < 'targetOutputSize' should the compressed block to decode be smaller.
|
||||
Always control how many bytes were decoded.
|
||||
If the source stream is detected malformed, the function will stop decoding and return a negative result.
|
||||
This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets
|
||||
*/
|
||||
int LZ4_decompress_safe_partial (const char* source, char* dest, int compressedSize, int targetOutputSize, int maxDecompressedSize);
|
||||
|
||||
|
||||
/***********************************************
|
||||
* Streaming Compression Functions
|
||||
***********************************************/
|
||||
#define LZ4_STREAMSIZE_U64 ((1 << (LZ4_MEMORY_USAGE-3)) + 4)
|
||||
#define LZ4_STREAMSIZE (LZ4_STREAMSIZE_U64 * sizeof(long long))
|
||||
/*
|
||||
* LZ4_stream_t
|
||||
* information structure to track an LZ4 stream.
|
||||
* important : init this structure content before first use !
|
||||
* note : only allocated directly the structure if you are statically linking LZ4
|
||||
* If you are using liblz4 as a DLL, please use below construction methods instead.
|
||||
*/
|
||||
typedef struct { long long table[LZ4_STREAMSIZE_U64]; } LZ4_stream_t;
|
||||
|
||||
/*
|
||||
* LZ4_resetStream
|
||||
* Use this function to init an allocated LZ4_stream_t structure
|
||||
*/
|
||||
void LZ4_resetStream (LZ4_stream_t* streamPtr);
|
||||
|
||||
/*
|
||||
* LZ4_createStream will allocate and initialize an LZ4_stream_t structure
|
||||
* LZ4_freeStream releases its memory.
|
||||
* In the context of a DLL (liblz4), please use these methods rather than the static struct.
|
||||
* They are more future proof, in case of a change of LZ4_stream_t size.
|
||||
*/
|
||||
LZ4_stream_t* LZ4_createStream(void);
|
||||
int LZ4_freeStream (LZ4_stream_t* streamPtr);
|
||||
|
||||
/*
|
||||
* LZ4_loadDict
|
||||
* Use this function to load a static dictionary into LZ4_stream.
|
||||
* Any previous data will be forgotten, only 'dictionary' will remain in memory.
|
||||
* Loading a size of 0 is allowed.
|
||||
* Return : dictionary size, in bytes (necessarily <= 64 KB)
|
||||
*/
|
||||
int LZ4_loadDict (LZ4_stream_t* streamPtr, const char* dictionary, int dictSize);
|
||||
|
||||
/*
|
||||
* LZ4_compress_fast_continue
|
||||
* Compress buffer content 'src', using data from previously compressed blocks as dictionary to improve compression ratio.
|
||||
* Important : Previous data blocks are assumed to still be present and unmodified !
|
||||
* 'dst' buffer must be already allocated.
|
||||
* If maxDstSize >= LZ4_compressBound(srcSize), compression is guaranteed to succeed, and runs faster.
|
||||
* If not, and if compressed data cannot fit into 'dst' buffer size, compression stops, and function returns a zero.
|
||||
*/
|
||||
int LZ4_compress_fast_continue (LZ4_stream_t* streamPtr, const char* src, char* dst, int srcSize, int maxDstSize, int acceleration);
|
||||
|
||||
/*
|
||||
* LZ4_saveDict
|
||||
* If previously compressed data block is not guaranteed to remain available at its memory location
|
||||
* save it into a safer place (char* safeBuffer)
|
||||
* Note : you don't need to call LZ4_loadDict() afterwards,
|
||||
* dictionary is immediately usable, you can therefore call LZ4_compress_fast_continue()
|
||||
* Return : saved dictionary size in bytes (necessarily <= dictSize), or 0 if error
|
||||
*/
|
||||
int LZ4_saveDict (LZ4_stream_t* streamPtr, char* safeBuffer, int dictSize);
|
||||
|
||||
|
||||
/************************************************
|
||||
* Streaming Decompression Functions
|
||||
************************************************/
|
||||
|
||||
#define LZ4_STREAMDECODESIZE_U64 4
|
||||
#define LZ4_STREAMDECODESIZE (LZ4_STREAMDECODESIZE_U64 * sizeof(unsigned long long))
|
||||
typedef struct { unsigned long long table[LZ4_STREAMDECODESIZE_U64]; } LZ4_streamDecode_t;
|
||||
/*
|
||||
* LZ4_streamDecode_t
|
||||
* information structure to track an LZ4 stream.
|
||||
* init this structure content using LZ4_setStreamDecode or memset() before first use !
|
||||
*
|
||||
* In the context of a DLL (liblz4) please prefer usage of construction methods below.
|
||||
* They are more future proof, in case of a change of LZ4_streamDecode_t size in the future.
|
||||
* LZ4_createStreamDecode will allocate and initialize an LZ4_streamDecode_t structure
|
||||
* LZ4_freeStreamDecode releases its memory.
|
||||
*/
|
||||
LZ4_streamDecode_t* LZ4_createStreamDecode(void);
|
||||
int LZ4_freeStreamDecode (LZ4_streamDecode_t* LZ4_stream);
|
||||
|
||||
/*
|
||||
* LZ4_setStreamDecode
|
||||
* Use this function to instruct where to find the dictionary.
|
||||
* Setting a size of 0 is allowed (same effect as reset).
|
||||
* Return : 1 if OK, 0 if error
|
||||
*/
|
||||
int LZ4_setStreamDecode (LZ4_streamDecode_t* LZ4_streamDecode, const char* dictionary, int dictSize);
|
||||
|
||||
/*
|
||||
*_continue() :
|
||||
These decoding functions allow decompression of multiple blocks in "streaming" mode.
|
||||
Previously decoded blocks *must* remain available at the memory position where they were decoded (up to 64 KB)
|
||||
In the case of a ring buffers, decoding buffer must be either :
|
||||
- Exactly same size as encoding buffer, with same update rule (block boundaries at same positions)
|
||||
In which case, the decoding & encoding ring buffer can have any size, including very small ones ( < 64 KB).
|
||||
- Larger than encoding buffer, by a minimum of maxBlockSize more bytes.
|
||||
maxBlockSize is implementation dependent. It's the maximum size you intend to compress into a single block.
|
||||
In which case, encoding and decoding buffers do not need to be synchronized,
|
||||
and encoding ring buffer can have any size, including small ones ( < 64 KB).
|
||||
- _At least_ 64 KB + 8 bytes + maxBlockSize.
|
||||
In which case, encoding and decoding buffers do not need to be synchronized,
|
||||
and encoding ring buffer can have any size, including larger than decoding buffer.
|
||||
Whenever these conditions are not possible, save the last 64KB of decoded data into a safe buffer,
|
||||
and indicate where it is saved using LZ4_setStreamDecode()
|
||||
*/
|
||||
int LZ4_decompress_safe_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int compressedSize, int maxDecompressedSize);
|
||||
int LZ4_decompress_fast_continue (LZ4_streamDecode_t* LZ4_streamDecode, const char* source, char* dest, int originalSize);
|
||||
|
||||
|
||||
/*
|
||||
Advanced decoding functions :
|
||||
*_usingDict() :
|
||||
These decoding functions work the same as
|
||||
a combination of LZ4_setStreamDecode() followed by LZ4_decompress_x_continue()
|
||||
They are stand-alone. They don't need nor update an LZ4_streamDecode_t structure.
|
||||
*/
|
||||
int LZ4_decompress_safe_usingDict (const char* source, char* dest, int compressedSize, int maxDecompressedSize, const char* dictStart, int dictSize);
|
||||
int LZ4_decompress_fast_usingDict (const char* source, char* dest, int originalSize, const char* dictStart, int dictSize);
|
||||
|
||||
|
||||
|
||||
/**************************************
|
||||
* Obsolete Functions
|
||||
**************************************/
|
||||
/* Deprecate Warnings */
|
||||
/* Should these warnings messages be a problem,
|
||||
it is generally possible to disable them,
|
||||
with -Wno-deprecated-declarations for gcc
|
||||
or _CRT_SECURE_NO_WARNINGS in Visual for example.
|
||||
You can also define LZ4_DEPRECATE_WARNING_DEFBLOCK. */
|
||||
#ifndef LZ4_DEPRECATE_WARNING_DEFBLOCK
|
||||
# define LZ4_DEPRECATE_WARNING_DEFBLOCK
|
||||
# define LZ4_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
|
||||
# if (LZ4_GCC_VERSION >= 405) || defined(__clang__)
|
||||
# define LZ4_DEPRECATED(message) __attribute__((deprecated(message)))
|
||||
# elif (LZ4_GCC_VERSION >= 301)
|
||||
# define LZ4_DEPRECATED(message) __attribute__((deprecated))
|
||||
# elif defined(_MSC_VER)
|
||||
# define LZ4_DEPRECATED(message) __declspec(deprecated(message))
|
||||
# else
|
||||
# pragma message("WARNING: You need to implement LZ4_DEPRECATED for this compiler")
|
||||
# define LZ4_DEPRECATED(message)
|
||||
# endif
|
||||
#endif /* LZ4_DEPRECATE_WARNING_DEFBLOCK */
|
||||
|
||||
/* Obsolete compression functions */
|
||||
/* These functions are planned to start generate warnings by r131 approximately */
|
||||
int LZ4_compress (const char* source, char* dest, int sourceSize);
|
||||
int LZ4_compress_limitedOutput (const char* source, char* dest, int sourceSize, int maxOutputSize);
|
||||
int LZ4_compress_withState (void* state, const char* source, char* dest, int inputSize);
|
||||
int LZ4_compress_limitedOutput_withState (void* state, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||
int LZ4_compress_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize);
|
||||
int LZ4_compress_limitedOutput_continue (LZ4_stream_t* LZ4_streamPtr, const char* source, char* dest, int inputSize, int maxOutputSize);
|
||||
|
||||
/* Obsolete decompression functions */
|
||||
/* These function names are completely deprecated and must no longer be used.
|
||||
They are only provided here for compatibility with older programs.
|
||||
- LZ4_uncompress is the same as LZ4_decompress_fast
|
||||
- LZ4_uncompress_unknownOutputSize is the same as LZ4_decompress_safe
|
||||
These function prototypes are now disabled; uncomment them only if you really need them.
|
||||
It is highly recommended to stop using these prototypes and migrate to maintained ones */
|
||||
/* int LZ4_uncompress (const char* source, char* dest, int outputSize); */
|
||||
/* int LZ4_uncompress_unknownOutputSize (const char* source, char* dest, int isize, int maxOutputSize); */
|
||||
|
||||
/* Obsolete streaming functions; use new streaming interface whenever possible */
|
||||
LZ4_DEPRECATED("use LZ4_createStream() instead") void* LZ4_create (char* inputBuffer);
|
||||
LZ4_DEPRECATED("use LZ4_createStream() instead") int LZ4_sizeofStreamState(void);
|
||||
LZ4_DEPRECATED("use LZ4_resetStream() instead") int LZ4_resetStreamState(void* state, char* inputBuffer);
|
||||
LZ4_DEPRECATED("use LZ4_saveDict() instead") char* LZ4_slideInputBuffer (void* state);
|
||||
|
||||
/* Obsolete streaming decoding functions */
|
||||
LZ4_DEPRECATED("use LZ4_decompress_safe_usingDict() instead") int LZ4_decompress_safe_withPrefix64k (const char* src, char* dst, int compressedSize, int maxDstSize);
|
||||
LZ4_DEPRECATED("use LZ4_decompress_fast_usingDict() instead") int LZ4_decompress_fast_withPrefix64k (const char* src, char* dst, int originalSize);
|
||||
|
||||
|
||||
#if defined (__cplusplus)
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Tony Bybell.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef WAVE_ALLOCA_H
|
||||
#define WAVE_ALLOCA_H
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
#elif defined(__GNUC__)
|
||||
#ifndef __MINGW32__
|
||||
#ifndef alloca
|
||||
#define alloca __builtin_alloca
|
||||
#endif
|
||||
#else
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#elif defined(_MSC_VER)
|
||||
#include <malloc.h>
|
||||
#define alloca _alloca
|
||||
#endif
|
||||
#define wave_alloca alloca
|
||||
#endif
|
||||
|
||||
+2046
-242
File diff suppressed because it is too large
Load Diff
+1683
-774
File diff suppressed because it is too large
Load Diff
+110
-53
@@ -1,10 +1,10 @@
|
||||
# $Id$ -*- Makefile -*-
|
||||
# -*- Makefile -*-
|
||||
######################################################################
|
||||
# DESCRIPTION: Makefile commands for all verilated target files
|
||||
#
|
||||
# Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# General Public License or the Perl Artistic License.
|
||||
# Copyright 2003-2019 by Wilson Snyder. Verilator is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
# General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
######################################################################
|
||||
|
||||
PERL = @PERL@
|
||||
@@ -13,11 +13,33 @@ LINK = @CXX@
|
||||
AR = ar
|
||||
RANLIB = ranlib
|
||||
|
||||
CFG_WITH_CCWARN = @CFG_WITH_CCWARN@
|
||||
CFG_WITH_LONGTESTS = @CFG_WITH_LONGTESTS@
|
||||
|
||||
# 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
|
||||
CFG_CXXFLAGS_WEXTRA = @CFG_CXXFLAGS_WEXTRA@
|
||||
# Linker libraries for multithreading
|
||||
CFG_LDLIBS_THREADS = @CFG_LDLIBS_THREADS@
|
||||
|
||||
######################################################################
|
||||
# Programs
|
||||
|
||||
SP_PREPROC = sp_preproc
|
||||
SP_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer
|
||||
SP_INCLUDER = $(VERILATOR_INCLUDER)
|
||||
VERILATOR_COVERAGE = $(PERL) $(VERILATOR_ROOT)/bin/verilator_coverage
|
||||
VERILATOR_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer
|
||||
|
||||
######################################################################
|
||||
# Make checks
|
||||
|
||||
ifneq ($(words $(CURDIR)),1)
|
||||
$(error Unsupported: GNU Make cannot build in directories containing spaces, build elsewhere: '$(CURDIR)')
|
||||
endif
|
||||
|
||||
######################################################################
|
||||
# C Preprocessor flags
|
||||
@@ -26,39 +48,49 @@ SP_INCLUDER = $(PERL) $(VERILATOR_ROOT)/bin/verilator_includer
|
||||
VK_CPPFLAGS_ALWAYS += \
|
||||
-MMD \
|
||||
-I$(VERILATOR_ROOT)/include \
|
||||
-I$(VERILATOR_ROOT)/include/vltstd \
|
||||
-DVL_PRINTF=printf \
|
||||
-DVM_COVERAGE=$(VM_COVERAGE) \
|
||||
-DVM_SC=$(VM_SC) \
|
||||
-DVM_TRACE=$(VM_TRACE) \
|
||||
$(CFG_CXXFLAGS_NO_UNUSED) \
|
||||
|
||||
ifeq ($(VERILATOR_AUTHOR_SITE),1) # Local... Else don't burden users
|
||||
VK_CPPFLAGS_WALL += -Wall \
|
||||
-Wno-char-subscripts \
|
||||
-Wno-sign-compare \
|
||||
-Wno-unused-parameter \
|
||||
-Wno-unused-variable \
|
||||
-Wno-uninitialized \
|
||||
-Werror
|
||||
ifeq ($(CFG_WITH_CCWARN),yes) # Local... Else don't burden users
|
||||
VK_CPPFLAGS_WALL += -Wall $(CFG_CXXFLAGS_WEXTRA) -Werror
|
||||
endif
|
||||
|
||||
CPPFLAGS += -I. $(VK_CPPFLAGS_ALWAYS) $(VK_CPPFLAGS_WALL)
|
||||
CPPFLAGS += -I. $(VK_CPPFLAGS_WALL) $(VK_CPPFLAGS_ALWAYS)
|
||||
|
||||
VPATH += ..
|
||||
VPATH += $(VERILATOR_ROOT)/include
|
||||
VPATH += $(VERILATOR_ROOT)/include/vltstd
|
||||
|
||||
#OPT = -ggdb -DPRINTINITSTR -DDETECTCHANGE
|
||||
#OPT = -ggdb -DPRINTINITSTR -DDETECTCHANGE
|
||||
#OPT = -ggdb -DPRINTINITSTR
|
||||
CPPFLAGS += $(OPT)
|
||||
|
||||
CPPFLAGS += $(M32)
|
||||
LDFLAGS += $(M32)
|
||||
LDFLAGS += $(M32)
|
||||
|
||||
# Allow upper level user makefiles to specify flags they want.
|
||||
# These aren't ever set by Verilator, so users are free to override them.
|
||||
CPPFLAGS += $(USER_CPPFLAGS)
|
||||
LDFLAGS += $(USER_LDFLAGS)
|
||||
LDLIBS += $(USER_LDLIBS)
|
||||
|
||||
# Add flags from -CFLAGS and -LDFLAGS on Verilator command line
|
||||
CPPFLAGS += $(VM_USER_CFLAGS)
|
||||
LDFLAGS += $(VM_USER_LDFLAGS)
|
||||
LDLIBS += $(VM_USER_LDLIBS)
|
||||
|
||||
# See the benchmarking section of bin/verilator.
|
||||
# Support class optimizations. This includes the tracing and symbol table.
|
||||
# SystemC takes minutes to optimize, thus it is off by default.
|
||||
#OPT_SLOW =
|
||||
#OPT_SLOW =
|
||||
# Fast path optimizations. Most time is spent in these classes.
|
||||
#OPT_FAST = -O2 -fstrict-aliasing
|
||||
#OPT_FAST = -O
|
||||
#OPT_FAST =
|
||||
#OPT_FAST =
|
||||
|
||||
#######################################################################
|
||||
##### Aggregates
|
||||
@@ -67,47 +99,52 @@ VM_CLASSES += $(VM_CLASSES_FAST) $(VM_CLASSES_SLOW)
|
||||
VM_SUPPORT += $(VM_SUPPORT_FAST) $(VM_SUPPORT_SLOW)
|
||||
|
||||
#######################################################################
|
||||
##### SystemC or SystemPerl builds
|
||||
##### SystemC builds
|
||||
|
||||
ifeq ($(VM_SP_OR_SC),1)
|
||||
CPPFLAGS += $(SYSTEMC_CXX_FLAGS) -I$(SYSTEMC)/include
|
||||
LDFLAGS += $(SYSTEMC_CXX_FLAGS) -L$(SYSTEMC)/lib-$(VM_SC_TARGET_ARCH)
|
||||
LIBS += -lm -lstdc++
|
||||
ifeq ($(VM_SC),1)
|
||||
CPPFLAGS += $(SYSTEMC_CXX_FLAGS) -I$(SYSTEMC_INCLUDE)
|
||||
LDFLAGS += $(SYSTEMC_CXX_FLAGS) -L$(SYSTEMC_LIBDIR)
|
||||
SC_LIBS = -lsystemc
|
||||
ifneq ($(wildcard $(SYSTEMC)/lib-$(VM_SC_TARGET_ARCH)/*numeric_bit*),)
|
||||
ifneq ($(wildcard $(SYSTEMC_LIBDIR)/*numeric_bit*),)
|
||||
# Systemc 1.2.1beta
|
||||
SC_LIBS += -lnumeric_bit -lqt
|
||||
endif
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
##### SystemPerl builds
|
||||
##### Threaded builds
|
||||
|
||||
ifeq ($(VM_SP),1)
|
||||
CPPFLAGS += -I$(SYSTEMPERL) -I$(SYSTEMPERL)/src -DSYSTEMPERL
|
||||
VPATH += $(SYSTEMPERL) $(SYSTEMPERL)/src
|
||||
|
||||
VK_CLASSES_SP = $(addsuffix .sp, $(VM_CLASSES))
|
||||
|
||||
# This rule is called manually by the upper level makefile
|
||||
preproc:
|
||||
@echo " SP Preprocess" $(basename $(VM_CLASSES)) ...
|
||||
$(SP_PREPROC) -M sp_preproc.d --tree $(VM_PREFIX).sp_tree \
|
||||
--preproc $(VK_CLASSES_SP)
|
||||
else
|
||||
preproc:
|
||||
ifneq ($(VM_THREADS),0)
|
||||
ifneq ($(VM_THREADS),)
|
||||
CPPFLAGS += -DVL_THREADED
|
||||
VK_LIBS_THREADED=1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(VM_TRACE_THREADED),0)
|
||||
ifneq ($(VM_TRACE_THREADED),)
|
||||
CPPFLAGS += -DVL_TRACE_THREADED
|
||||
VK_LIBS_THREADED=1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(VK_LIBS_THREADED),0)
|
||||
ifneq ($(VK_LIBS_THREADED),)
|
||||
# Need C++11 at least, so always default to newest
|
||||
CPPFLAGS += $(CFG_CXXFLAGS_STD_NEWEST)
|
||||
LDLIBS += $(CFG_LDLIBS_THREADS)
|
||||
endif
|
||||
endif
|
||||
|
||||
#######################################################################
|
||||
##### Stub
|
||||
|
||||
preproc:
|
||||
|
||||
#######################################################################
|
||||
##### C/H builds
|
||||
|
||||
ifeq ($(VM_PCLI),1)
|
||||
LIBS += -lm -lstdc++
|
||||
ifeq ($(VM_TRACE),1)
|
||||
CPPFLAGS += -I$(SYSTEMPERL) -I$(SYSTEMPERL)/src
|
||||
VPATH += $(SYSTEMPERL) $(SYSTEMPERL)/src
|
||||
endif
|
||||
endif
|
||||
LIBS += -lm -lstdc++
|
||||
|
||||
#######################################################################
|
||||
# Overall Objects Linking
|
||||
@@ -119,15 +156,17 @@ VK_SUPPORT_CPP = $(addsuffix .cpp, $(VM_SUPPORT))
|
||||
|
||||
VK_USER_OBJS = $(addsuffix .o, $(VM_USER_CLASSES))
|
||||
|
||||
VK_GLOBAL_OBJS = $(addsuffix .o, $(VM_GLOBAL_FAST) $(VM_GLOBAL_SLOW))
|
||||
|
||||
ifneq ($(VM_PARALLEL_BUILDS),1)
|
||||
# Fast building, all .cpp's in one fell swoop
|
||||
# This saves about 5 sec per module, but can be slower if only a little changes
|
||||
VK_OBJS += $(VM_PREFIX)__ALLcls.o $(VM_PREFIX)__ALLsup.o
|
||||
all_cpp: $(VM_PREFIX)__ALLcls.cpp $(VM_PREFIX)__ALLsup.cpp
|
||||
$(VM_PREFIX)__ALLcls.cpp: $(VK_CLASSES_CPP)
|
||||
$(SP_INCLUDER) $^ > $@
|
||||
$(VERILATOR_INCLUDER) -DVL_INCLUDE_OPT=include $^ > $@
|
||||
$(VM_PREFIX)__ALLsup.cpp: $(VK_SUPPORT_CPP)
|
||||
$(SP_INCLUDER) $^ > $@
|
||||
$(VERILATOR_INCLUDER) -DVL_INCLUDE_OPT=include $^ > $@
|
||||
else
|
||||
#Slow way of building... Each .cpp file by itself
|
||||
VK_OBJS += $(addsuffix .o, $(VM_CLASSES) $(VM_SUPPORT))
|
||||
@@ -141,26 +180,44 @@ $(VM_PREFIX)__ALL.a: $(VK_OBJS)
|
||||
######################################################################
|
||||
### Compile rules
|
||||
|
||||
#Default rule embedded in make: (Not defined so user makefiles can override it)
|
||||
#.cpp.o:
|
||||
# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
ifneq ($(VM_DEFAULT_RULES),0)
|
||||
$(VM_PREFIX)__ALLcls.o: $(VM_PREFIX)__ALLcls.cpp
|
||||
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
|
||||
|
||||
$(VM_PREFIX)__ALLsup.o: $(VM_PREFIX)__ALLsup.cpp
|
||||
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $<
|
||||
|
||||
$(VM_PREFIX)__ALLcls.o: $(VM_PREFIX)__ALLcls.cpp
|
||||
# VM_GLOBAL_FAST files including verilated.o use this rule
|
||||
%.o: %.cpp
|
||||
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_FAST) -c -o $@ $<
|
||||
|
||||
%__Slow.o: %__Slow.cpp
|
||||
$(OBJCACHE) $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(OPT_SLOW) -c -o $@ $<
|
||||
|
||||
endif
|
||||
|
||||
#Default rule embedded in make:
|
||||
#.cpp.o:
|
||||
# $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
|
||||
|
||||
######################################################################
|
||||
### Debugging
|
||||
|
||||
debug::
|
||||
debug-make::
|
||||
@echo
|
||||
@echo CXXFLAGS: $(CXXFLAGS)
|
||||
@echo CPPFLAGS: $(CPPFLAGS)
|
||||
@echo OPT_FAST: $(OPT_FAST)
|
||||
@echo OPT_SLOW: $(OPT_SLOW)
|
||||
@echo VM_PREFIX: $(VM_PREFIX)
|
||||
@echo VM_PARALLEL_BUILDS: $(VM_PARALLEL_BUILDS)
|
||||
@echo VM_CLASSES_FAST: $(VM_CLASSES_FAST)
|
||||
@echo VM_CLASSES_SLOW: $(VM_CLASSES_SLOW)
|
||||
@echo VM_SUPPORT_FAST: $(VM_SUPPORT_FAST)
|
||||
@echo VM_SUPPORT_SLOW: $(VM_SUPPORT_SLOW)
|
||||
@echo VM_GLOBAL_FAST: $(VM_GLOBAL_FAST)
|
||||
@echo VM_GLOBAL_SLOW: $(VM_GLOBAL_SLOW)
|
||||
@echo VK_OBJS: $(VK_OBJS)
|
||||
@echo
|
||||
|
||||
######################################################################
|
||||
|
||||
+10
-14
@@ -1,19 +1,19 @@
|
||||
// $Id$ -*- C++ -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Code available from: http://www.veripool.com/verilator
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// General Public License or the Perl Artistic License.
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//
|
||||
//=========================================================================
|
||||
//
|
||||
// DESCRIPTION: Verilator: Include in verilog files to hide verilator defines
|
||||
@@ -22,15 +22,11 @@
|
||||
`define _VERILATED_V_ 1
|
||||
|
||||
// Hide verilator pragmas from other tools
|
||||
`ifdef verilator `else
|
||||
`ifdef VERILATOR `else
|
||||
`define coverage_block_off
|
||||
`endif
|
||||
|
||||
// Hide file descriptor difference
|
||||
`ifdef verilator
|
||||
`define verilator_file_descriptor reg [63:0]
|
||||
`else
|
||||
`define verilator_file_descriptor integer
|
||||
`endif
|
||||
|
||||
`endif // guard
|
||||
// Hide file descriptor difference - deprecated - for older versions
|
||||
`define verilator_file_descriptor integer
|
||||
|
||||
`endif // guard
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//*************************************************************************
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilator: Auto version information include for all Verilated C files
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//*************************************************************************
|
||||
|
||||
|
||||
///**** Product and Version name
|
||||
|
||||
// Autoconf substitutes this with the strings from AC_INIT.
|
||||
#define VERILATOR_PRODUCT "@PACKAGE_NAME@"
|
||||
#define VERILATOR_VERSION "@PACKAGE_VERSION@"
|
||||
@@ -0,0 +1,472 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilator coverage analysis
|
||||
///
|
||||
//=============================================================================
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h"
|
||||
#include "verilated_cov.h"
|
||||
#include "verilated_cov_key.h"
|
||||
|
||||
#include <deque>
|
||||
#include <fstream>
|
||||
#include <map>
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedCovImpBase
|
||||
/// Implementation base class for constants
|
||||
|
||||
struct VerilatedCovImpBase {
|
||||
// TYPES
|
||||
enum { MAX_KEYS = 33 }; /// Maximum user arguments + filename+lineno
|
||||
enum { KEY_UNDEF = 0 }; /// Magic key # for unspecified values
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedCovImpItem
|
||||
/// Implementation class for a VerilatedCov item
|
||||
|
||||
class VerilatedCovImpItem : VerilatedCovImpBase {
|
||||
public: // But only local to this file
|
||||
// MEMBERS
|
||||
int m_keys[MAX_KEYS]; ///< Key
|
||||
int m_vals[MAX_KEYS]; ///< Value for specified key
|
||||
// CONSTRUCTORS
|
||||
// Derived classes should call zero() in their constructor
|
||||
VerilatedCovImpItem() {
|
||||
for (int i=0; i<MAX_KEYS; ++i) {
|
||||
m_keys[i] = KEY_UNDEF;
|
||||
m_vals[i] = 0;
|
||||
}
|
||||
}
|
||||
virtual ~VerilatedCovImpItem() {}
|
||||
virtual vluint64_t count() const = 0;
|
||||
virtual void zero() const = 0;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
/// VerilatedCoverItem templated for a specific class
|
||||
/// Creates a new coverage item for the specified type.
|
||||
/// 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 : public VerilatedCovImpItem {
|
||||
private:
|
||||
// MEMBERS
|
||||
T* m_countp; ///< Count value
|
||||
public:
|
||||
// METHODS
|
||||
// cppcheck-suppress truncLongCastReturn
|
||||
virtual vluint64_t count() const { return *m_countp; }
|
||||
virtual void zero() const { *m_countp = 0; }
|
||||
// CONSTRUCTORS
|
||||
// cppcheck-suppress noExplicitConstructor
|
||||
VerilatedCoverItemSpec(T* countp) : m_countp(countp) { *m_countp = 0; }
|
||||
virtual ~VerilatedCoverItemSpec() {}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedCovImp
|
||||
/// Implementation class for VerilatedCov. See that class for public method information.
|
||||
/// All value and keys are indexed into a unique number. Thus we can greatly reduce
|
||||
/// the storage requirements for otherwise identical keys.
|
||||
|
||||
class VerilatedCovImp : VerilatedCovImpBase {
|
||||
private:
|
||||
// TYPES
|
||||
typedef std::map<std::string,int> ValueIndexMap;
|
||||
typedef std::map<int,std::string> IndexValueMap;
|
||||
typedef std::deque<VerilatedCovImpItem*> ItemList;
|
||||
|
||||
private:
|
||||
// MEMBERS
|
||||
VerilatedMutex m_mutex; ///< Protects all members, when VL_THREADED. Wrapper deals with setting it.
|
||||
ValueIndexMap m_valueIndexes VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value
|
||||
IndexValueMap m_indexValues VL_GUARDED_BY(m_mutex); ///< For each key/value a unique arbitrary index value
|
||||
ItemList m_items VL_GUARDED_BY(m_mutex); ///< List of all items
|
||||
|
||||
VerilatedCovImpItem* m_insertp VL_GUARDED_BY(m_mutex); ///< Item about to insert
|
||||
const char* m_insertFilenamep VL_GUARDED_BY(m_mutex); ///< Filename about to insert
|
||||
int m_insertLineno VL_GUARDED_BY(m_mutex); ///< Line number about to insert
|
||||
|
||||
// CONSTRUCTORS
|
||||
VerilatedCovImp() {
|
||||
m_insertp = NULL;
|
||||
m_insertFilenamep = NULL;
|
||||
m_insertLineno = 0;
|
||||
}
|
||||
VL_UNCOPYABLE(VerilatedCovImp);
|
||||
public:
|
||||
~VerilatedCovImp() { clearGuts(); }
|
||||
static VerilatedCovImp& imp() VL_MT_SAFE {
|
||||
static VerilatedCovImp s_singleton;
|
||||
return s_singleton;
|
||||
}
|
||||
|
||||
private:
|
||||
// PRIVATE METHODS
|
||||
int valueIndex(const std::string& value) VL_REQUIRES(m_mutex) {
|
||||
static int nextIndex = KEY_UNDEF+1;
|
||||
ValueIndexMap::iterator iter = m_valueIndexes.find(value);
|
||||
if (iter != m_valueIndexes.end()) return iter->second;
|
||||
nextIndex++; assert(nextIndex>0);
|
||||
m_valueIndexes.insert(std::make_pair(value, nextIndex));
|
||||
m_indexValues.insert(std::make_pair(nextIndex, value));
|
||||
return nextIndex;
|
||||
}
|
||||
static std::string dequote(const std::string& text) VL_PURE {
|
||||
// Quote any special characters
|
||||
std::string rtn;
|
||||
for (const char* pos = text.c_str(); *pos; ++pos) {
|
||||
if (!isprint(*pos) || *pos=='%' || *pos=='"') {
|
||||
char hex[10]; sprintf(hex, "%%%02X", pos[0]);
|
||||
rtn += hex;
|
||||
} else {
|
||||
rtn += *pos;
|
||||
}
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
static bool legalKey(const std::string& key) VL_PURE {
|
||||
// Because we compress long keys to a single letter, and
|
||||
// don't want applications to either get confused if they use
|
||||
// a letter differently, nor want them to rely on our compression...
|
||||
// (Considered using numeric keys, but will remain back compatible.)
|
||||
if (key.length()<2) return false;
|
||||
if (key.length()==2 && isdigit(key[1])) return false;
|
||||
return true;
|
||||
}
|
||||
static std::string keyValueFormatter(const std::string& key, const std::string& value) VL_PURE {
|
||||
std::string name;
|
||||
if (key.length()==1 && isalpha(key[0])) {
|
||||
name += std::string("\001")+key;
|
||||
} else {
|
||||
name += std::string("\001")+dequote(key);
|
||||
}
|
||||
name += std::string("\002")+dequote(value);
|
||||
return name;
|
||||
}
|
||||
static std::string combineHier(const std::string& old, const std::string& add) VL_PURE {
|
||||
// (foo.a.x, foo.b.x) => foo.*.x
|
||||
// (foo.a.x, foo.b.y) => foo.*
|
||||
// (foo.a.x, foo.b) => foo.*
|
||||
if (old == add) return add;
|
||||
if (old.empty()) return add;
|
||||
if (add.empty()) return old;
|
||||
|
||||
const char* a = old.c_str();
|
||||
const char* b = add.c_str();
|
||||
|
||||
// Scan forward to first mismatch
|
||||
const char* apre = a;
|
||||
const char* bpre = b;
|
||||
while (*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
|
||||
std::string prefix = std::string(a, apre-a);
|
||||
|
||||
// Scan backward to last mismatch
|
||||
const char* apost = a+strlen(a)-1;
|
||||
const char* bpost = b+strlen(b)-1;
|
||||
while (*apost == *bpost
|
||||
&& apost>apre && bpost>bpre) { apost--; bpost--; }
|
||||
|
||||
// Forward to . so we have a whole word
|
||||
std::string suffix = *bpost ? std::string(bpost+1) : "";
|
||||
|
||||
std::string out = prefix+"*"+suffix;
|
||||
|
||||
//cout << "\nch pre="<<prefix<<" s="<<suffix<<"\nch a="<<old<<"\nch b="<<add<<"\nch o="<<out<<endl;
|
||||
return out;
|
||||
}
|
||||
bool itemMatchesString(VerilatedCovImpItem* itemp, const std::string& match) VL_REQUIRES(m_mutex) {
|
||||
for (int i=0; i<MAX_KEYS; ++i) {
|
||||
if (itemp->m_keys[i] != KEY_UNDEF) {
|
||||
// We don't compare keys, only values
|
||||
std::string val = m_indexValues[itemp->m_vals[i]];
|
||||
if (std::string::npos != val.find(match)) { // Found
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
static void selftest() VL_MT_SAFE {
|
||||
// Little selftest
|
||||
if (combineHier("a.b.c","a.b.c") !="a.b.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||
if (combineHier("a.b.c","a.b") !="a.b*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||
if (combineHier("a.x.c","a.y.c") !="a.*.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||
if (combineHier("a.z.z.z.c","a.b.c") !="a.*.c") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||
if (combineHier("z","a") !="*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||
if (combineHier("q.a","q.b") !="q.*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||
if (combineHier("q.za","q.zb") !="q.z*") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||
if (combineHier("1.2.3.a","9.8.7.a") !="*.a") VL_FATAL_MT(__FILE__,__LINE__,"","%Error: selftest\n");
|
||||
}
|
||||
void clearGuts() VL_REQUIRES(m_mutex) {
|
||||
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||
VerilatedCovImpItem* itemp = *(it);
|
||||
delete itemp;
|
||||
}
|
||||
m_items.clear();
|
||||
m_indexValues.clear();
|
||||
m_valueIndexes.clear();
|
||||
}
|
||||
|
||||
public:
|
||||
// PUBLIC METHODS
|
||||
void clear() VL_EXCLUDES(m_mutex) {
|
||||
Verilated::quiesce();
|
||||
VerilatedLockGuard lock(m_mutex);
|
||||
clearGuts();
|
||||
}
|
||||
void clearNonMatch(const char* matchp) VL_EXCLUDES(m_mutex) {
|
||||
Verilated::quiesce();
|
||||
VerilatedLockGuard lock(m_mutex);
|
||||
if (matchp && matchp[0]) {
|
||||
ItemList newlist;
|
||||
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||
VerilatedCovImpItem* itemp = *(it);
|
||||
if (!itemMatchesString(itemp, matchp)) {
|
||||
delete itemp;
|
||||
} else {
|
||||
newlist.push_back(itemp);
|
||||
}
|
||||
}
|
||||
m_items = newlist;
|
||||
}
|
||||
}
|
||||
void zero() VL_EXCLUDES(m_mutex) {
|
||||
Verilated::quiesce();
|
||||
VerilatedLockGuard lock(m_mutex);
|
||||
for (ItemList::const_iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||
(*it)->zero();
|
||||
}
|
||||
}
|
||||
|
||||
// We assume there's always call to i/f/p in that order
|
||||
void inserti(VerilatedCovImpItem* itemp) VL_EXCLUDES(m_mutex) {
|
||||
VerilatedLockGuard lock(m_mutex);
|
||||
assert(!m_insertp);
|
||||
m_insertp = itemp;
|
||||
}
|
||||
void insertf(const char* filenamep, int lineno) VL_EXCLUDES(m_mutex) {
|
||||
VerilatedLockGuard lock(m_mutex);
|
||||
m_insertFilenamep = filenamep;
|
||||
m_insertLineno = lineno;
|
||||
}
|
||||
void insertp(const char* ckeyps[MAX_KEYS],
|
||||
const char* valps[MAX_KEYS]) VL_EXCLUDES(m_mutex) {
|
||||
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);
|
||||
ckeyps[1]="lineno"; valps[1]=linestr.c_str();
|
||||
// Default page if not specified
|
||||
const char* fnstartp = m_insertFilenamep;
|
||||
while (const char* foundp = strchr(fnstartp,'/')) fnstartp = foundp+1;
|
||||
const char* fnendp = fnstartp;
|
||||
while (*fnendp && *fnendp!='.') fnendp++;
|
||||
std::string page_default = "sp_user/"+std::string(fnstartp, fnendp-fnstartp);
|
||||
ckeyps[2]="page"; valps[2]=page_default.c_str();
|
||||
|
||||
// Keys -> strings
|
||||
std::string keys[MAX_KEYS];
|
||||
for (int i=0; i<MAX_KEYS; ++i) {
|
||||
if (ckeyps[i] && ckeyps[i][0]) {
|
||||
keys[i] = ckeyps[i];
|
||||
}
|
||||
}
|
||||
// Ignore empty keys
|
||||
for (int i=0; i<MAX_KEYS; ++i) {
|
||||
if (!keys[i].empty()) {
|
||||
for (int j=i+1; j<MAX_KEYS; ++j) {
|
||||
if (keys[i] == keys[j]) { // Duplicate key. Keep the last one
|
||||
keys[i] = "";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Insert the values
|
||||
int addKeynum = 0;
|
||||
for (int i=0; i<MAX_KEYS; ++i) {
|
||||
const std::string key = keys[i];
|
||||
if (!keys[i].empty()) {
|
||||
const std::string val = valps[i];
|
||||
//cout<<" "<<__FUNCTION__<<" "<<key<<" = "<<val<<endl;
|
||||
m_insertp->m_keys[addKeynum] = valueIndex(key);
|
||||
m_insertp->m_vals[addKeynum] = valueIndex(val);
|
||||
addKeynum++;
|
||||
if (!legalKey(key)) {
|
||||
std::string msg = "%Error: Coverage keys of one character, or letter+digit are illegal: "+key;
|
||||
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
m_items.push_back(m_insertp);
|
||||
// Prepare for next
|
||||
m_insertp = NULL;
|
||||
}
|
||||
|
||||
void write(const char* filename) VL_EXCLUDES(m_mutex) {
|
||||
Verilated::quiesce();
|
||||
VerilatedLockGuard lock(m_mutex);
|
||||
#ifndef VM_COVERAGE
|
||||
VL_FATAL_MT("", 0, "", "%Error: Called VerilatedCov::write when VM_COVERAGE disabled\n");
|
||||
#endif
|
||||
selftest();
|
||||
|
||||
std::ofstream os(filename);
|
||||
if (os.fail()) {
|
||||
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
|
||||
typedef std::map<std::string,std::pair<std::string,vluint64_t> > EventMap;
|
||||
EventMap eventCounts;
|
||||
for (ItemList::iterator it=m_items.begin(); it!=m_items.end(); ++it) {
|
||||
VerilatedCovImpItem* itemp = *(it);
|
||||
std::string name;
|
||||
std::string hier;
|
||||
bool per_instance = false;
|
||||
|
||||
for (int i=0; i<MAX_KEYS; ++i) {
|
||||
if (itemp->m_keys[i] != KEY_UNDEF) {
|
||||
std::string key = VerilatedCovKey::shortKey(m_indexValues[itemp->m_keys[i]]);
|
||||
std::string val = m_indexValues[itemp->m_vals[i]];
|
||||
if (key == VL_CIK_PER_INSTANCE) {
|
||||
if (val != "0") per_instance = true;
|
||||
}
|
||||
if (key == VL_CIK_HIER) {
|
||||
hier = val;
|
||||
} else {
|
||||
// Print it
|
||||
name += keyValueFormatter(key, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (per_instance) { // Not collapsing hierarchies
|
||||
name += keyValueFormatter(VL_CIK_HIER, hier);
|
||||
hier = "";
|
||||
}
|
||||
|
||||
// Group versus point labels don't matter here, downstream
|
||||
// deals with it. Seems bad for sizing though and doesn't
|
||||
// allow easy addition of new group codes (would be
|
||||
// inefficient)
|
||||
|
||||
// Find or insert the named event
|
||||
EventMap::iterator cit = eventCounts.find(name);
|
||||
if (cit != eventCounts.end()) {
|
||||
const std::string& oldhier = cit->second.first;
|
||||
cit->second.second += itemp->count();
|
||||
cit->second.first = combineHier(oldhier, hier);
|
||||
} else {
|
||||
eventCounts.insert(std::make_pair(name, make_pair(hier, itemp->count())));
|
||||
}
|
||||
}
|
||||
|
||||
// Output body
|
||||
for (EventMap::const_iterator it=eventCounts.begin(); it!=eventCounts.end(); ++it) {
|
||||
os<<"C '"<<std::dec;
|
||||
os<<it->first;
|
||||
if (!it->second.first.empty()) os<<keyValueFormatter(VL_CIK_HIER, it->second.first);
|
||||
os<<"' "<<it->second.second;
|
||||
os<<std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedCov
|
||||
|
||||
void VerilatedCov::clear() VL_MT_SAFE {
|
||||
VerilatedCovImp::imp().clear();
|
||||
}
|
||||
void VerilatedCov::clearNonMatch(const char* matchp) VL_MT_SAFE {
|
||||
VerilatedCovImp::imp().clearNonMatch(matchp);
|
||||
}
|
||||
void VerilatedCov::zero() VL_MT_SAFE {
|
||||
VerilatedCovImp::imp().zero();
|
||||
}
|
||||
void VerilatedCov::write(const char* filenamep) VL_MT_SAFE {
|
||||
VerilatedCovImp::imp().write(filenamep);
|
||||
}
|
||||
void VerilatedCov::_inserti(vluint32_t* itemp) VL_MT_SAFE {
|
||||
VerilatedCovImp::imp().inserti(new VerilatedCoverItemSpec<vluint32_t>(itemp));
|
||||
}
|
||||
void VerilatedCov::_inserti(vluint64_t* itemp) VL_MT_SAFE {
|
||||
VerilatedCovImp::imp().inserti(new VerilatedCoverItemSpec<vluint64_t>(itemp));
|
||||
}
|
||||
void VerilatedCov::_insertf(const char* filename, int lineno) VL_MT_SAFE {
|
||||
VerilatedCovImp::imp().insertf(filename, lineno);
|
||||
}
|
||||
|
||||
#define K(n) const char* key ## n
|
||||
#define A(n) const char* key ## n, const char* valp ## n // Argument list
|
||||
#define C(n) key ## n, valp ## n // Calling argument list
|
||||
#define N(n) "","" // Null argument list
|
||||
void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
|
||||
A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19),
|
||||
A(20),A(21),A(22),A(23),A(24),A(25),A(26),A(27),A(28),A(29)) VL_MT_SAFE {
|
||||
const char* keyps[VerilatedCovImpBase::MAX_KEYS]
|
||||
= {NULL,NULL,NULL, // filename,lineno,page
|
||||
key0,key1,key2,key3,key4,key5,key6,key7,key8,key9,
|
||||
key10,key11,key12,key13,key14,key15,key16,key17,key18,key19,
|
||||
key20,key21,key22,key23,key24,key25,key26,key27,key28,key29};
|
||||
const char* valps[VerilatedCovImpBase::MAX_KEYS]
|
||||
= {NULL,NULL,NULL, // filename,lineno,page
|
||||
valp0,valp1,valp2,valp3,valp4,valp5,valp6,valp7,valp8,valp9,
|
||||
valp10,valp11,valp12,valp13,valp14,valp15,valp16,valp17,valp18,valp19,
|
||||
valp20,valp21,valp22,valp23,valp24,valp25,valp26,valp27,valp28,valp29};
|
||||
VerilatedCovImp::imp().insertp(keyps, valps);
|
||||
}
|
||||
|
||||
// And versions with fewer arguments (oh for a language with named parameters!)
|
||||
void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)) VL_MT_SAFE {
|
||||
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
|
||||
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
|
||||
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
||||
}
|
||||
void VerilatedCov::_insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9),
|
||||
A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)) VL_MT_SAFE {
|
||||
_insertp(C(0),C(1),C(2),C(3),C(4),C(5),C(6),C(7),C(8),C(9),
|
||||
C(10),C(11),C(12),C(13),C(14),C(15),C(16),C(17),C(18),C(19),
|
||||
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
||||
}
|
||||
// Backward compatibility for Verilator
|
||||
void VerilatedCov::_insertp(A(0), A(1), K(2),int val2, K(3),int val3,
|
||||
K(4),const std::string& val4, A(5),A(6)) VL_MT_SAFE {
|
||||
std::string val2str = vlCovCvtToStr(val2);
|
||||
std::string val3str = vlCovCvtToStr(val3);
|
||||
_insertp(C(0),C(1),
|
||||
key2,val2str.c_str(), key3,val3str.c_str(), key4, val4.c_str(),
|
||||
C(5),C(6),N(7),N(8),N(9),
|
||||
N(10),N(11),N(12),N(13),N(14),N(15),N(16),N(17),N(18),N(19),
|
||||
N(20),N(21),N(22),N(23),N(24),N(25),N(26),N(27),N(28),N(29));
|
||||
}
|
||||
#undef A
|
||||
#undef C
|
||||
#undef N
|
||||
#undef K
|
||||
@@ -0,0 +1,132 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Coverage analysis support
|
||||
///
|
||||
//=============================================================================
|
||||
|
||||
#ifndef _VERILATED_COV_H_
|
||||
#define _VERILATED_COV_H_ 1
|
||||
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
//=============================================================================
|
||||
/// Conditionally compile coverage code
|
||||
|
||||
#ifdef VM_COVERAGE
|
||||
# define VL_IF_COVER(stmts) do { stmts ; } while(0)
|
||||
#else
|
||||
# define VL_IF_COVER(stmts) do { if(0) { stmts ; } } while(0)
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
/// Insert a item for coverage analysis.
|
||||
/// The first argument is a pointer to the count to be dumped.
|
||||
/// The remaining arguments occur in pairs: A string key, and a value.
|
||||
/// The value may be a string, or another type which will be auto-converted to a string.
|
||||
///
|
||||
/// Some typical keys:
|
||||
/// filename File the recording occurs in. Defaults to __FILE__
|
||||
/// lineno Line number the recording occurs in. Defaults to __LINE__
|
||||
/// column Column number (or occurrence# for dup file/lines). Defaults to undef.
|
||||
/// hier Hierarchical name. Defaults to name()
|
||||
/// type Type of coverage. Defaults to "user"
|
||||
/// Other types are 'block', 'fsm', 'toggle'.
|
||||
/// comment Description of the coverage event. Should be set by the user.
|
||||
/// Comments for type==block: 'if', 'else', 'elsif', 'case'
|
||||
/// thresh Threshold to consider fully covered.
|
||||
/// If unspecified, downstream tools will determine it.
|
||||
///
|
||||
/// Examples:
|
||||
///
|
||||
/// vluint32_t m_cases[10];
|
||||
/// constructor {
|
||||
/// for (int i=0; i<10; ++i) { m_cases[i]=0; }
|
||||
/// }
|
||||
/// for (int i=0; i<10; ++i) {
|
||||
/// VL_COVER_INSERT(&m_cases[i], "comment", "Coverage Case", "i", cvtToNumStr(i));
|
||||
/// }
|
||||
|
||||
#define VL_COVER_INSERT(countp,args...) \
|
||||
VL_IF_COVER(VerilatedCov::_inserti(countp); \
|
||||
VerilatedCov::_insertf(__FILE__,__LINE__); \
|
||||
VerilatedCov::_insertp("hier", name(), args))
|
||||
|
||||
//=============================================================================
|
||||
/// Convert VL_COVER_INSERT value arguments to strings
|
||||
|
||||
template< class T> std::string vlCovCvtToStr(const T& t) VL_PURE {
|
||||
std::ostringstream os; os<<t; return os.str();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedCov
|
||||
/// Verilator coverage global class
|
||||
////
|
||||
/// Global class with methods affecting all coverage data.
|
||||
/// All public methods in this class are thread safe.
|
||||
|
||||
class VerilatedCov {
|
||||
VL_UNCOPYABLE(VerilatedCov);
|
||||
public:
|
||||
// GLOBAL METHODS
|
||||
/// Return default filename
|
||||
static const char* defaultFilename() VL_PURE { return "coverage.dat"; }
|
||||
/// Write all coverage data to a file
|
||||
static void write(const char* filenamep = defaultFilename()) VL_MT_SAFE;
|
||||
/// 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)
|
||||
static void _inserti(vluint32_t* itemp) VL_MT_SAFE;
|
||||
static void _inserti(vluint64_t* itemp) VL_MT_SAFE;
|
||||
// _insert2: Set default filename and line number
|
||||
static void _insertf(const char* filename, int lineno) VL_MT_SAFE;
|
||||
// _insert3: Set parameters
|
||||
// We could have just the maximum argument version, but this compiles
|
||||
// much slower (nearly 2x) than having smaller versions also. However
|
||||
// there's not much more gain in having a version for each number of args.
|
||||
#define K(n) const char* key ## n
|
||||
#define A(n) const char* key ## n, const char* valp ## n // Argument list
|
||||
#define D(n) const char* key ## n = NULL, const char* valp ## n = NULL // Argument list
|
||||
static void _insertp(D(0),D(1),D(2),D(3),D(4),D(5),D(6),D(7),D(8),D(9));
|
||||
static void _insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)
|
||||
,A(10),D(11),D(12),D(13),D(14),D(15),D(16),D(17),D(18),D(19));
|
||||
static void _insertp(A(0),A(1),A(2),A(3),A(4),A(5),A(6),A(7),A(8),A(9)
|
||||
,A(10),A(11),A(12),A(13),A(14),A(15),A(16),A(17),A(18),A(19)
|
||||
,A(20),D(21),D(22),D(23),D(24),D(25),D(26),D(27),D(28),D(29));
|
||||
// Backward compatibility for Verilator
|
||||
static void _insertp(A(0), A(1), K(2),int val2, K(3),int val3,
|
||||
K(4),const std::string& val4, A(5),A(6));
|
||||
|
||||
#undef K
|
||||
#undef A
|
||||
#undef D
|
||||
/// Clear coverage points (and call delete on all items)
|
||||
static void clear() VL_MT_SAFE;
|
||||
/// Clear items not matching the provided string
|
||||
static void clearNonMatch(const char* matchp) VL_MT_SAFE;
|
||||
/// Zero coverage points
|
||||
static void zero() VL_MT_SAFE;
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
@@ -0,0 +1,143 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Coverage item keys
|
||||
///
|
||||
//=============================================================================
|
||||
|
||||
#ifndef _VERILATED_COV_KEY_H_
|
||||
#define _VERILATED_COV_KEY_H_ 1
|
||||
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
//=============================================================================
|
||||
// Data used to edit below file, using vlcovgen
|
||||
|
||||
#define VLCOVGEN_ITEM(string_parsed_by_vlcovgen)
|
||||
|
||||
VLCOVGEN_ITEM("name=>'col0_name', short=>'C0', group=>1, default=>undef, descr=>'The column title for the header line of this column'")
|
||||
VLCOVGEN_ITEM("name=>'col1_name', short=>'C1', group=>1, default=>undef, ")
|
||||
VLCOVGEN_ITEM("name=>'col2_name', short=>'C2', group=>1, default=>undef, ")
|
||||
VLCOVGEN_ITEM("name=>'col3_name', short=>'C3', group=>1, default=>undef, ")
|
||||
VLCOVGEN_ITEM("name=>'column', short=>'n', group=>1, default=>0, descr=>'Column number for the item. Used to disambiguate multiple coverage points on the same line number'")
|
||||
VLCOVGEN_ITEM("name=>'filename', short=>'f', group=>1, default=>undef, descr=>'Filename of the item'")
|
||||
VLCOVGEN_ITEM("name=>'groupdesc', short=>'d', group=>1, default=>'', descr=>'Description of the covergroup this item belongs to'")
|
||||
VLCOVGEN_ITEM("name=>'groupname', short=>'g', group=>1, default=>'', descr=>'Group name of the covergroup this item belongs to'")
|
||||
VLCOVGEN_ITEM("name=>'groupcmt', short=>'O', group=>1, default=>'', ")
|
||||
VLCOVGEN_ITEM("name=>'per_instance',short=>'P', group=>1, default=>0, descr=>'True if every hierarchy is independently counted; otherwise all hierarchies will be combined into a single count'")
|
||||
VLCOVGEN_ITEM("name=>'row0_name', short=>'R0', group=>1, default=>undef, descr=>'The row title for the header line of this row'")
|
||||
VLCOVGEN_ITEM("name=>'row1_name', short=>'R1', group=>1, default=>undef, ")
|
||||
VLCOVGEN_ITEM("name=>'row2_name', short=>'R2', group=>1, default=>undef, ")
|
||||
VLCOVGEN_ITEM("name=>'row3_name', short=>'R3', group=>1, default=>undef, ")
|
||||
VLCOVGEN_ITEM("name=>'table', short=>'T', group=>1, default=>undef, descr=>'The name of the table for automatically generated tables'")
|
||||
VLCOVGEN_ITEM("name=>'thresh', short=>'s', group=>1, default=>undef, ")
|
||||
VLCOVGEN_ITEM("name=>'type', short=>'t', group=>1, default=>'', descr=>'Type of coverage (block, line, fsm, etc)'")
|
||||
// Bin attributes
|
||||
VLCOVGEN_ITEM("name=>'col0', short=>'c0', group=>0, default=>undef, descr=>'The (enumeration) value name for this column in a table cross' ")
|
||||
VLCOVGEN_ITEM("name=>'col1', short=>'c1', group=>0, default=>undef, ")
|
||||
VLCOVGEN_ITEM("name=>'col2', short=>'c2', group=>0, default=>undef, ")
|
||||
VLCOVGEN_ITEM("name=>'col3', short=>'c3', group=>0, default=>undef, ")
|
||||
VLCOVGEN_ITEM("name=>'comment', short=>'o', group=>0, default=>'', descr=>'Textual description for the item'")
|
||||
VLCOVGEN_ITEM("name=>'hier', short=>'h', group=>0, default=>'', descr=>'Hierarchy path name for the item'")
|
||||
VLCOVGEN_ITEM("name=>'limit', short=>'L', group=>0, default=>undef, ")
|
||||
VLCOVGEN_ITEM("name=>'lineno', short=>'l', group=>0, default=>0, descr=>'Line number for the item'")
|
||||
VLCOVGEN_ITEM("name=>'row0', short=>'r0', group=>0, default=>undef, descr=>'The (enumeration) value name for this row in a table cross'")
|
||||
VLCOVGEN_ITEM("name=>'row1', short=>'r1', group=>0, default=>undef, ")
|
||||
VLCOVGEN_ITEM("name=>'row2', short=>'r2', group=>0, default=>undef, ")
|
||||
VLCOVGEN_ITEM("name=>'row3', short=>'r3', group=>0, default=>undef, ")
|
||||
VLCOVGEN_ITEM("name=>'weight', short=>'w', group=>0, default=>undef, descr=>'For totaling items, weight of this item'")
|
||||
|
||||
// VLCOVGEN_CIK_AUTO_EDIT_BEGIN
|
||||
#define VL_CIK_COL0 "c0"
|
||||
#define VL_CIK_COL0_NAME "C0"
|
||||
#define VL_CIK_COL1 "c1"
|
||||
#define VL_CIK_COL1_NAME "C1"
|
||||
#define VL_CIK_COL2 "c2"
|
||||
#define VL_CIK_COL2_NAME "C2"
|
||||
#define VL_CIK_COL3 "c3"
|
||||
#define VL_CIK_COL3_NAME "C3"
|
||||
#define VL_CIK_COLUMN "n"
|
||||
#define VL_CIK_COMMENT "o"
|
||||
#define VL_CIK_FILENAME "f"
|
||||
#define VL_CIK_GROUPCMT "O"
|
||||
#define VL_CIK_GROUPDESC "d"
|
||||
#define VL_CIK_GROUPNAME "g"
|
||||
#define VL_CIK_HIER "h"
|
||||
#define VL_CIK_LIMIT "L"
|
||||
#define VL_CIK_LINENO "l"
|
||||
#define VL_CIK_PER_INSTANCE "P"
|
||||
#define VL_CIK_ROW0 "r0"
|
||||
#define VL_CIK_ROW0_NAME "R0"
|
||||
#define VL_CIK_ROW1 "r1"
|
||||
#define VL_CIK_ROW1_NAME "R1"
|
||||
#define VL_CIK_ROW2 "r2"
|
||||
#define VL_CIK_ROW2_NAME "R2"
|
||||
#define VL_CIK_ROW3 "r3"
|
||||
#define VL_CIK_ROW3_NAME "R3"
|
||||
#define VL_CIK_TABLE "T"
|
||||
#define VL_CIK_THRESH "s"
|
||||
#define VL_CIK_TYPE "t"
|
||||
#define VL_CIK_WEIGHT "w"
|
||||
// VLCOVGEN_CIK_AUTO_EDIT_END
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedCovKey
|
||||
/// Verilator coverage global class.
|
||||
/// This class is thread safe.
|
||||
|
||||
class VerilatedCovKey {
|
||||
public:
|
||||
static std::string shortKey(const std::string& key) VL_PURE {
|
||||
// VLCOVGEN_SHORT_AUTO_EDIT_BEGIN
|
||||
if (key == "col0") return VL_CIK_COL0;
|
||||
if (key == "col0_name") return VL_CIK_COL0_NAME;
|
||||
if (key == "col1") return VL_CIK_COL1;
|
||||
if (key == "col1_name") return VL_CIK_COL1_NAME;
|
||||
if (key == "col2") return VL_CIK_COL2;
|
||||
if (key == "col2_name") return VL_CIK_COL2_NAME;
|
||||
if (key == "col3") return VL_CIK_COL3;
|
||||
if (key == "col3_name") return VL_CIK_COL3_NAME;
|
||||
if (key == "column") return VL_CIK_COLUMN;
|
||||
if (key == "comment") return VL_CIK_COMMENT;
|
||||
if (key == "filename") return VL_CIK_FILENAME;
|
||||
if (key == "groupcmt") return VL_CIK_GROUPCMT;
|
||||
if (key == "groupdesc") return VL_CIK_GROUPDESC;
|
||||
if (key == "groupname") return VL_CIK_GROUPNAME;
|
||||
if (key == "hier") return VL_CIK_HIER;
|
||||
if (key == "limit") return VL_CIK_LIMIT;
|
||||
if (key == "lineno") return VL_CIK_LINENO;
|
||||
if (key == "per_instance") return VL_CIK_PER_INSTANCE;
|
||||
if (key == "row0") return VL_CIK_ROW0;
|
||||
if (key == "row0_name") return VL_CIK_ROW0_NAME;
|
||||
if (key == "row1") return VL_CIK_ROW1;
|
||||
if (key == "row1_name") return VL_CIK_ROW1_NAME;
|
||||
if (key == "row2") return VL_CIK_ROW2;
|
||||
if (key == "row2_name") return VL_CIK_ROW2_NAME;
|
||||
if (key == "row3") return VL_CIK_ROW3;
|
||||
if (key == "row3_name") return VL_CIK_ROW3_NAME;
|
||||
if (key == "table") return VL_CIK_TABLE;
|
||||
if (key == "thresh") return VL_CIK_THRESH;
|
||||
if (key == "type") return VL_CIK_TYPE;
|
||||
if (key == "weight") return VL_CIK_WEIGHT;
|
||||
// VLCOVGEN_SHORT_AUTO_EDIT_END
|
||||
return key;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // guard
|
||||
@@ -0,0 +1,771 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2019 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//=========================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilator: DPI implementation code
|
||||
///
|
||||
/// This file must be compiled and linked against all objects
|
||||
/// created from Verilator or called by Verilator that use the DPI.
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//=========================================================================
|
||||
|
||||
#define _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
|
||||
#define DPI_PROTOTYPES
|
||||
#undef XXTERN
|
||||
#define XXTERN DPI_EXTERN DPI_DLLESPEC
|
||||
#undef EETERN
|
||||
#define EETERN DPI_EXTERN DPI_DLLESPEC
|
||||
|
||||
#include "vltstd/svdpi.h"
|
||||
|
||||
//======================================================================
|
||||
// Internal macros
|
||||
|
||||
// Not supported yet
|
||||
#define _VL_SVDPI_UNIMP() \
|
||||
VL_FATAL_MT(__FILE__,__LINE__,"",(std::string("%%Error: Unsupported DPI function: ")+VL_FUNC).c_str())
|
||||
|
||||
#define _VL_SVDPI_WARN(message...) \
|
||||
VL_PRINTF_MT(message)
|
||||
|
||||
// Function requires a "context" in the import declaration
|
||||
#define _VL_SVDPI_CONTEXT_WARN() \
|
||||
_VL_SVDPI_WARN("%%Warning: DPI C Function called by Verilog DPI import with missing 'context' keyword.\n");
|
||||
|
||||
//======================================================================
|
||||
//======================================================================
|
||||
//======================================================================
|
||||
// DPI ROUTINES
|
||||
|
||||
const char* svDpiVersion() {
|
||||
return "1800-2005";
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Bit-select utility functions.
|
||||
|
||||
svBit svGetBitselBit(const svBitVecVal* sp, int bit) {
|
||||
return VL_BITRSHIFT_W(sp,bit) & 1;
|
||||
}
|
||||
svLogic svGetBitselLogic(const svLogicVecVal* sp, int bit) {
|
||||
// Not VL_BITRSHIFT_W as sp is a different structure type
|
||||
// Verilator doesn't support X/Z so only aval
|
||||
return (((sp[VL_BITWORD_I(bit)].aval >> VL_BITBIT_I(bit)) & 1)
|
||||
| (((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 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)))
|
||||
| ((s&1)<<VL_BITBIT_I(bit)));
|
||||
dp[VL_BITWORD_I(bit)].bval
|
||||
= ((dp[VL_BITWORD_I(bit)].bval & ~(VL_UL(1)<<VL_BITBIT_I(bit)))
|
||||
| ((s&2)>>1<<VL_BITBIT_I(bit)));
|
||||
}
|
||||
|
||||
void svGetPartselBit(svBitVecVal* dp, const svBitVecVal* sp, int lsb, int width) {
|
||||
// See also VL_SEL_WWI
|
||||
int msb = lsb+width-1;
|
||||
int word_shift = VL_BITWORD_I(lsb);
|
||||
if (VL_BITBIT_I(lsb)==0) {
|
||||
// Just a word extract
|
||||
for (int i=0; i<VL_WORDS_I(width); ++i) dp[i] = sp[i+word_shift];
|
||||
} else {
|
||||
int loffset = lsb & VL_SIZEBITS_I;
|
||||
int nbitsfromlow = 32-loffset; // bits that end up in lword (know loffset!=0)
|
||||
// Middle words
|
||||
int words = VL_WORDS_I(msb-lsb+1);
|
||||
for (int i=0; i<words; ++i) {
|
||||
dp[i] = sp[i+word_shift]>>loffset;
|
||||
int upperword = i+word_shift+1;
|
||||
if (upperword <= static_cast<int>(VL_BITWORD_I(msb))) {
|
||||
dp[i] |= sp[upperword] << nbitsfromlow;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Clean result
|
||||
dp[VL_WORDS_I(width)-1] &= VL_MASK_I(width);
|
||||
}
|
||||
void svGetPartselLogic(svLogicVecVal* dp, const svLogicVecVal* sp, int lsb, int width) {
|
||||
int msb = lsb+width-1;
|
||||
int word_shift = VL_BITWORD_I(lsb);
|
||||
if (VL_BITBIT_I(lsb)==0) {
|
||||
// Just a word extract
|
||||
for (int i=0; i<VL_WORDS_I(width); ++i) dp[i] = sp[i+word_shift];
|
||||
} else {
|
||||
int loffset = lsb & VL_SIZEBITS_I;
|
||||
int nbitsfromlow = 32-loffset; // bits that end up in lword (know loffset!=0)
|
||||
// Middle words
|
||||
int words = VL_WORDS_I(msb-lsb+1);
|
||||
for (int i=0; i<words; ++i) {
|
||||
dp[i].aval = sp[i+word_shift].aval >> loffset;
|
||||
dp[i].bval = sp[i+word_shift].bval >> loffset;
|
||||
int upperword = i+word_shift+1;
|
||||
if (upperword <= static_cast<int>(VL_BITWORD_I(msb))) {
|
||||
dp[i].aval |= sp[upperword].aval << nbitsfromlow;
|
||||
dp[i].bval |= sp[upperword].bval << nbitsfromlow;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Clean result
|
||||
dp[VL_WORDS_I(width)-1].aval &= VL_MASK_I(width);
|
||||
dp[VL_WORDS_I(width)-1].bval &= VL_MASK_I(width);
|
||||
}
|
||||
void svPutPartselBit(svBitVecVal* dp, const svBitVecVal s, int lbit, int width) {
|
||||
// See also _VL_INSERT_WI
|
||||
int hbit = lbit+width-1;
|
||||
int hoffset = VL_BITBIT_I(hbit);
|
||||
int loffset = VL_BITBIT_I(lbit);
|
||||
if (hoffset==VL_SIZEBITS_I && loffset==0) {
|
||||
// Fast and common case, word based insertion
|
||||
dp[VL_BITWORD_I(lbit)] = s;
|
||||
}
|
||||
else {
|
||||
int hword = VL_BITWORD_I(hbit);
|
||||
int lword = VL_BITWORD_I(lbit);
|
||||
if (hword==lword) { // know < 32 bits because above checks it
|
||||
IData insmask = (VL_MASK_I(hoffset-loffset+1))<<loffset;
|
||||
dp[lword] = (dp[lword] & ~insmask) | ((s<<loffset) & insmask);
|
||||
} else {
|
||||
IData hinsmask = (VL_MASK_I(hoffset-0+1))<<0;
|
||||
IData linsmask = (VL_MASK_I(31-loffset+1))<<loffset;
|
||||
int nbitsonright = 32-loffset; // bits that end up in lword
|
||||
dp[lword] = (dp[lword] & ~linsmask) | ((s<<loffset) & linsmask);
|
||||
dp[hword] = (dp[hword] & ~hinsmask) | ((s>>nbitsonright) & hinsmask);
|
||||
}
|
||||
}
|
||||
}
|
||||
// cppcheck-suppress passedByValue
|
||||
void svPutPartselLogic(svLogicVecVal* dp, const svLogicVecVal s, int lbit, int width) {
|
||||
int hbit = lbit+width-1;
|
||||
int hoffset = VL_BITBIT_I(hbit);
|
||||
int loffset = VL_BITBIT_I(lbit);
|
||||
if (hoffset==VL_SIZEBITS_I && loffset==0) {
|
||||
// Fast and common case, word based insertion
|
||||
dp[VL_BITWORD_I(lbit)].aval = s.aval;
|
||||
dp[VL_BITWORD_I(lbit)].bval = s.bval;
|
||||
}
|
||||
else {
|
||||
int hword = VL_BITWORD_I(hbit);
|
||||
int lword = VL_BITWORD_I(lbit);
|
||||
if (hword==lword) { // know < 32 bits because above checks it
|
||||
IData insmask = (VL_MASK_I(hoffset-loffset+1))<<loffset;
|
||||
dp[lword].aval = (dp[lword].aval & ~insmask) | ((s.aval<<loffset) & insmask);
|
||||
dp[lword].bval = (dp[lword].bval & ~insmask) | ((s.bval<<loffset) & insmask);
|
||||
} else {
|
||||
IData hinsmask = (VL_MASK_I(hoffset-0+1))<<0;
|
||||
IData linsmask = (VL_MASK_I(31-loffset+1))<<loffset;
|
||||
int nbitsonright = 32-loffset; // bits that end up in lword
|
||||
dp[lword].aval = (dp[lword].aval & ~linsmask) | ((s.aval<<loffset) & linsmask);
|
||||
dp[lword].bval = (dp[lword].bval & ~linsmask) | ((s.bval<<loffset) & linsmask);
|
||||
dp[hword].aval = (dp[hword].aval & ~hinsmask) | ((s.aval>>nbitsonright) & hinsmask);
|
||||
dp[hword].bval = (dp[hword].bval & ~hinsmask) | ((s.bval>>nbitsonright) & hinsmask);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Open array internals
|
||||
|
||||
static inline const VerilatedDpiOpenVar* _vl_openhandle_varp(const svOpenArrayHandle h) {
|
||||
if (VL_UNLIKELY(!h)) {
|
||||
VL_FATAL_MT(__FILE__, __LINE__, "",
|
||||
"%%Error: DPI svOpenArrayHandle function called with NULL handle");
|
||||
}
|
||||
const VerilatedDpiOpenVar* 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");
|
||||
}
|
||||
return varp;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Open array querying functions
|
||||
|
||||
int svLeft(const svOpenArrayHandle h, int d) {
|
||||
return _vl_openhandle_varp(h)->left(d);
|
||||
}
|
||||
int svRight(const svOpenArrayHandle h, int d) {
|
||||
return _vl_openhandle_varp(h)->right(d);
|
||||
}
|
||||
int svLow(const svOpenArrayHandle h, int d) {
|
||||
return _vl_openhandle_varp(h)->low(d);
|
||||
}
|
||||
int svHigh(const svOpenArrayHandle h, int d) {
|
||||
return _vl_openhandle_varp(h)->high(d);
|
||||
}
|
||||
int svIncrement(const svOpenArrayHandle h, int d) {
|
||||
return _vl_openhandle_varp(h)->increment(d);
|
||||
}
|
||||
int svSize(const svOpenArrayHandle h, int d) {
|
||||
return _vl_openhandle_varp(h)->elements(d);
|
||||
}
|
||||
int svDimensions(const svOpenArrayHandle h) {
|
||||
return _vl_openhandle_varp(h)->udims();
|
||||
}
|
||||
/// Return pointer to open array data, or NULL if not in IEEE standard C layout
|
||||
void* svGetArrayPtr(const svOpenArrayHandle h) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h);
|
||||
if (VL_UNLIKELY(!varp->isDpiStdLayout())) return NULL;
|
||||
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);
|
||||
if (VL_UNLIKELY(!varp->isDpiStdLayout())) return 0;
|
||||
// Truncate 64 bits to int; DPI is limited to 4GB
|
||||
return static_cast<int>(varp->totalSize());
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Open array access internals
|
||||
|
||||
static void* _vl_sv_adjusted_datap(const VerilatedDpiOpenVar* varp,
|
||||
int nargs, int indx1, int indx2, int indx3) {
|
||||
void* datap = varp->datap();
|
||||
if (VL_UNLIKELY(nargs != varp->udims())) {
|
||||
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function called on"
|
||||
" %d dimensional array using %d dimensional function.\n",
|
||||
varp->udims(), nargs);
|
||||
return NULL;
|
||||
}
|
||||
if (nargs>=1) {
|
||||
datap = varp->datapAdjustIndex(datap, 1, indx1);
|
||||
if (VL_UNLIKELY(!datap)) {
|
||||
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function index 1 out of bounds; %d outside [%d:%d].\n",
|
||||
indx1, varp->left(1), varp->right(1));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (nargs>=2) {
|
||||
datap = varp->datapAdjustIndex(datap, 2, indx2);
|
||||
if (VL_UNLIKELY(!datap)) {
|
||||
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function index 2 out of bounds; %d outside [%d:%d].\n",
|
||||
indx2, varp->left(2), varp->right(2));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (nargs>=3) {
|
||||
datap = varp->datapAdjustIndex(datap, 3, indx3);
|
||||
if (VL_UNLIKELY(!datap)) {
|
||||
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function index 3 out of bounds; %d outside [%d:%d].\n",
|
||||
indx1, varp->left(3), varp->right(3));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return datap;
|
||||
}
|
||||
|
||||
static int _vl_sv_adjusted_bit(const VerilatedDpiOpenVar* varp, int indx) {
|
||||
if (VL_UNLIKELY(indx < varp->low(0) || indx > varp->high(0))) {
|
||||
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function packed index out of bounds; %d outside [%d:%d].\n",
|
||||
indx, varp->left(0), varp->right(0));
|
||||
return 0;
|
||||
}
|
||||
return indx - varp->low(0);
|
||||
}
|
||||
|
||||
/// Return pointer to simulator open array element, or NULL if outside range
|
||||
static void* _vl_svGetArrElemPtr(const svOpenArrayHandle h,
|
||||
int nargs, int indx1, int indx2, int indx3) VL_MT_SAFE {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h);
|
||||
if (VL_UNLIKELY(!varp->isDpiStdLayout())) return NULL;
|
||||
void* 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);
|
||||
if (VL_UNLIKELY(!datap)) return;
|
||||
switch (varp->vltype()) {
|
||||
case VLVT_UINT8: d[0] = *(reinterpret_cast<CData*>(datap)); return;
|
||||
case VLVT_UINT16: d[0] = *(reinterpret_cast<SData*>(datap)); return;
|
||||
case VLVT_UINT32: d[0] = *(reinterpret_cast<IData*>(datap)); return;
|
||||
case VLVT_UINT64: {
|
||||
WData lwp[2]; VL_SET_WQ(lwp, *(reinterpret_cast<QData*>(datap)));
|
||||
d[0] = lwp[0]; d[1] = lwp[1];
|
||||
break;
|
||||
}
|
||||
case VLVT_WDATA: {
|
||||
WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
|
||||
for (int i=0; i<VL_WORDS_I(varp->packed().elements()); ++i) d[i] = wdatap[i];
|
||||
return;
|
||||
}
|
||||
default:
|
||||
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
|
||||
return;
|
||||
}
|
||||
}
|
||||
/// 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);
|
||||
if (VL_UNLIKELY(!datap)) return;
|
||||
switch (varp->vltype()) {
|
||||
case VLVT_UINT8: d[0].aval = *(reinterpret_cast<CData*>(datap)); d[0].bval=0; return;
|
||||
case VLVT_UINT16: d[0].aval = *(reinterpret_cast<SData*>(datap)); d[0].bval=0; return;
|
||||
case VLVT_UINT32: d[0].aval = *(reinterpret_cast<IData*>(datap)); d[0].bval=0; return;
|
||||
case VLVT_UINT64: {
|
||||
WData lwp[2]; VL_SET_WQ(lwp, *(reinterpret_cast<QData*>(datap)));
|
||||
d[0].aval = lwp[0]; d[0].bval=0;
|
||||
d[1].aval = lwp[1]; d[0].bval=0;
|
||||
break;
|
||||
}
|
||||
case VLVT_WDATA: {
|
||||
WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
|
||||
for (int i=0; i<VL_WORDS_I(varp->packed().elements()); ++i) {
|
||||
d[i].aval = wdatap[i]; d[i].bval = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
default:
|
||||
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// 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);
|
||||
if (VL_UNLIKELY(!datap)) return;
|
||||
switch (varp->vltype()) {
|
||||
case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = s[0]; return;
|
||||
case VLVT_UINT16: *(reinterpret_cast<SData*>(datap)) = s[0]; return;
|
||||
case VLVT_UINT32: *(reinterpret_cast<IData*>(datap)) = s[0]; return;
|
||||
case VLVT_UINT64: *(reinterpret_cast<QData*>(datap)) = _VL_SET_QII(s[1], s[0]); break;
|
||||
case VLVT_WDATA: {
|
||||
WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
|
||||
for (int i=0; i<VL_WORDS_I(varp->packed().elements()); ++i) wdatap[i] = s[i];
|
||||
return;
|
||||
}
|
||||
default:
|
||||
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
|
||||
return;
|
||||
}
|
||||
}
|
||||
/// 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);
|
||||
if (VL_UNLIKELY(!datap)) return;
|
||||
switch (varp->vltype()) {
|
||||
case VLVT_UINT8: *(reinterpret_cast<CData*>(datap)) = s[0].aval; return;
|
||||
case VLVT_UINT16: *(reinterpret_cast<SData*>(datap)) = s[0].aval; return;
|
||||
case VLVT_UINT32: *(reinterpret_cast<IData*>(datap)) = s[0].aval; return;
|
||||
case VLVT_UINT64: *(reinterpret_cast<QData*>(datap)) = _VL_SET_QII(s[1].aval, s[0].aval); break;
|
||||
case VLVT_WDATA: {
|
||||
WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
|
||||
for (int i=0; i<VL_WORDS_I(varp->packed().elements()); ++i) wdatap[i] = s[i].aval;
|
||||
return;
|
||||
}
|
||||
default:
|
||||
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
// One extra index supported, as need bit number
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
|
||||
void* datap;
|
||||
int lsb;
|
||||
if (varp->packed().elements()) {
|
||||
datap = _vl_sv_adjusted_datap(varp, nargs-1, indx1, indx2, indx3);
|
||||
lsb = _vl_sv_adjusted_bit(varp, ((nargs==1) ? indx1
|
||||
: (nargs==2) ? indx2
|
||||
: (nargs==3) ? indx3
|
||||
: indx4));
|
||||
} else {
|
||||
datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
lsb = 0;
|
||||
}
|
||||
if (VL_UNLIKELY(!datap)) return 0;
|
||||
switch (varp->vltype()) {
|
||||
case VLVT_UINT8: return (*(reinterpret_cast<CData*>(datap)) >> lsb) & 1;
|
||||
case VLVT_UINT16: return (*(reinterpret_cast<SData*>(datap)) >> lsb) & 1;
|
||||
case VLVT_UINT32: return (*(reinterpret_cast<IData*>(datap)) >> lsb) & 1;
|
||||
case VLVT_UINT64: return (*(reinterpret_cast<QData*>(datap)) >> static_cast<QData>(lsb)) & VL_ULL(1);
|
||||
case VLVT_WDATA: {
|
||||
WDataOutP wdatap = (reinterpret_cast<WDataOutP>(datap));
|
||||
return VL_BITRSHIFT_W(wdatap, lsb) & 1;
|
||||
}
|
||||
default:
|
||||
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
/// 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 {
|
||||
// One extra index supported, as need bit number
|
||||
value &= 1; // Make sure clean
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
|
||||
void* datap;
|
||||
int lsb;
|
||||
if (varp->packed().elements()) {
|
||||
datap = _vl_sv_adjusted_datap(varp, nargs-1, indx1, indx2, indx3);
|
||||
lsb = _vl_sv_adjusted_bit(varp, ((nargs==1) ? indx1
|
||||
: (nargs==2) ? indx2
|
||||
: (nargs==3) ? indx3
|
||||
: indx4));
|
||||
} else {
|
||||
datap = _vl_sv_adjusted_datap(varp, nargs, indx1, indx2, indx3);
|
||||
lsb = 0;
|
||||
}
|
||||
if (VL_UNLIKELY(!datap)) return;
|
||||
switch (varp->vltype()) {
|
||||
case VLVT_UINT8: VL_ASSIGNBIT_II(-1, lsb, *(reinterpret_cast<CData*>(datap)), value); return;
|
||||
case VLVT_UINT16: VL_ASSIGNBIT_II(-1, lsb, *(reinterpret_cast<SData*>(datap)), value); return;
|
||||
case VLVT_UINT32: VL_ASSIGNBIT_II(-1, lsb, *(reinterpret_cast<IData*>(datap)), value); return;
|
||||
case VLVT_UINT64: VL_ASSIGNBIT_QI(-1, lsb, *(reinterpret_cast<QData*>(datap)), value); return;
|
||||
case VLVT_WDATA: VL_ASSIGNBIT_WI(-1, lsb, (reinterpret_cast<WDataOutP>(datap)), value); return;
|
||||
default:
|
||||
_VL_SVDPI_WARN("%%Warning: DPI svOpenArrayHandle function unsupported datatype (%d).\n", varp->vltype());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// DPI accessors that simply call above functions
|
||||
|
||||
void* svGetArrElemPtr(const svOpenArrayHandle h, int indx1, ...) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(h);
|
||||
void* datap;
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
// va_arg is a macro, so need temporaries as used below
|
||||
switch (varp->udims()) {
|
||||
case 1: datap = _vl_svGetArrElemPtr(h, 1, indx1, 0, 0); break;
|
||||
case 2: { 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);
|
||||
datap = _vl_svGetArrElemPtr(h, 3, indx1, indx2, indx3); break; }
|
||||
default: datap = _vl_svGetArrElemPtr(h, -1, 0, 0, 0); break; // Will error
|
||||
}
|
||||
va_end(ap);
|
||||
return datap;
|
||||
}
|
||||
void* svGetArrElemPtr1(const svOpenArrayHandle h, int indx1) {
|
||||
return _vl_svGetArrElemPtr(h, 1, indx1, 0, 0);
|
||||
}
|
||||
void* svGetArrElemPtr2(const svOpenArrayHandle h, int indx1, int indx2) {
|
||||
return _vl_svGetArrElemPtr(h, 2, indx1, indx2, 0);
|
||||
}
|
||||
void* svGetArrElemPtr3(const svOpenArrayHandle h, int indx1, int indx2, int indx3) {
|
||||
return _vl_svGetArrElemPtr(h, 3, indx1, indx2, indx3);
|
||||
}
|
||||
|
||||
void svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s,
|
||||
int indx1, ...) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
switch (varp->udims()) {
|
||||
case 1: _vl_svPutBitArrElemVecVal(d, s, 1, indx1, 0, 0); break;
|
||||
case 2: { int indx2=va_arg(ap,int);
|
||||
_vl_svPutBitArrElemVecVal(d, s, 2, indx1, indx2, 0); break; }
|
||||
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
|
||||
_vl_svPutBitArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; }
|
||||
default: _vl_svPutBitArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
void svPutBitArrElem1VecVal(const svOpenArrayHandle d, const svBitVecVal* s,
|
||||
int indx1) {
|
||||
_vl_svPutBitArrElemVecVal(d, s, 1, indx1, 0, 0);
|
||||
}
|
||||
void svPutBitArrElem2VecVal(const svOpenArrayHandle d, const svBitVecVal* s,
|
||||
int indx1, int indx2) {
|
||||
_vl_svPutBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
|
||||
}
|
||||
void svPutBitArrElem3VecVal(const svOpenArrayHandle d, const svBitVecVal* s,
|
||||
int indx1, int indx2, int indx3) {
|
||||
_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);
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
switch (varp->udims()) {
|
||||
case 1: _vl_svPutLogicArrElemVecVal(d, s, 1, indx1, 0, 0); break;
|
||||
case 2: { int indx2=va_arg(ap,int);
|
||||
_vl_svPutLogicArrElemVecVal(d, s, 2, indx1, indx2, 0); break; }
|
||||
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
|
||||
_vl_svPutLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; }
|
||||
default: _vl_svPutLogicArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
void svPutLogicArrElem1VecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
|
||||
int indx1) {
|
||||
_vl_svPutLogicArrElemVecVal(d, s, 1, indx1, 0, 0);
|
||||
}
|
||||
void svPutLogicArrElem2VecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
|
||||
int indx1, int indx2) {
|
||||
_vl_svPutLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
|
||||
}
|
||||
void svPutLogicArrElem3VecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
|
||||
int indx1, int indx2, int indx3) {
|
||||
_vl_svPutLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// From simulator storage into user space
|
||||
|
||||
void svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1, ...) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
switch (varp->udims()) {
|
||||
case 1: _vl_svGetBitArrElemVecVal(d, s, 1, indx1, 0, 0); break;
|
||||
case 2: { int indx2=va_arg(ap,int);
|
||||
_vl_svGetBitArrElemVecVal(d, s, 2, indx1, indx2, 0); break; }
|
||||
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
|
||||
_vl_svGetBitArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; }
|
||||
default: _vl_svGetBitArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
void svGetBitArrElem1VecVal(svBitVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1) {
|
||||
_vl_svGetBitArrElemVecVal(d, s, 1, indx1, 0, 0);
|
||||
}
|
||||
void svGetBitArrElem2VecVal(svBitVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1, int indx2) {
|
||||
_vl_svGetBitArrElemVecVal(d, s, 2, indx1, indx2, 0);
|
||||
}
|
||||
void svGetBitArrElem3VecVal(svBitVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1, int indx2, int indx3) {
|
||||
_vl_svGetBitArrElemVecVal(d, s, 3, indx1, indx2, indx3);
|
||||
}
|
||||
void svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1, ...) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
switch (varp->udims()) {
|
||||
case 1: _vl_svGetLogicArrElemVecVal(d, s, 1, indx1, 0, 0); break;
|
||||
case 2: { int indx2=va_arg(ap,int);
|
||||
_vl_svGetLogicArrElemVecVal(d, s, 2, indx1, indx2, 0); break; }
|
||||
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
|
||||
_vl_svGetLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3); break; }
|
||||
default: _vl_svGetLogicArrElemVecVal(d, s, -1, 0, 0, 0); break; // Will error
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
void svGetLogicArrElem1VecVal(svLogicVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1) {
|
||||
_vl_svGetLogicArrElemVecVal(d, s, 1, indx1, 0, 0);
|
||||
}
|
||||
void svGetLogicArrElem2VecVal(svLogicVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1, int indx2) {
|
||||
_vl_svGetLogicArrElemVecVal(d, s, 2, indx1, indx2, 0);
|
||||
}
|
||||
void svGetLogicArrElem3VecVal(svLogicVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1, int indx2, int indx3) {
|
||||
_vl_svGetLogicArrElemVecVal(d, s, 3, indx1, indx2, indx3);
|
||||
}
|
||||
|
||||
svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(s);
|
||||
svBit out;
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
switch (varp->udims()) {
|
||||
case 1: out = _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0); break;
|
||||
case 2: { int indx2=va_arg(ap,int);
|
||||
out = _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0); break; }
|
||||
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
|
||||
out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0); break; }
|
||||
case 4: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); int indx4=va_arg(ap,int);
|
||||
out = _vl_svGetBitArrElem(s, 4, indx1, indx2, indx3, indx4); break; }
|
||||
default: out = _vl_svGetBitArrElem(s, -1, 0, 0, 0, 0); break; // Will error
|
||||
}
|
||||
va_end(ap);
|
||||
return out;
|
||||
}
|
||||
svBit svGetBitArrElem1(const svOpenArrayHandle s, int indx1) {
|
||||
return _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0);
|
||||
}
|
||||
svBit svGetBitArrElem2(const svOpenArrayHandle s, int indx1, int indx2) {
|
||||
return _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0);
|
||||
}
|
||||
svBit svGetBitArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3) {
|
||||
return _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0);
|
||||
}
|
||||
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);
|
||||
svBit out;
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
switch (varp->udims()) {
|
||||
case 1: out = _vl_svGetBitArrElem(s, 1, indx1, 0, 0, 0); break;
|
||||
case 2: { int indx2=va_arg(ap,int);
|
||||
out = _vl_svGetBitArrElem(s, 2, indx1, indx2, 0, 0); break; }
|
||||
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
|
||||
out = _vl_svGetBitArrElem(s, 3, indx1, indx2, indx3, 0); break; }
|
||||
case 4: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); int indx4=va_arg(ap,int);
|
||||
out = _vl_svGetBitArrElem(s, 4, indx1, indx2, indx3, indx4); break; }
|
||||
default: out = _vl_svGetBitArrElem(s, -1, 0, 0, 0, 0); break; // Will error
|
||||
}
|
||||
va_end(ap);
|
||||
return out;
|
||||
}
|
||||
svLogic svGetLogicArrElem1(const svOpenArrayHandle s, int indx1) {
|
||||
// Verilator doesn't support X/Z so can just call Bit version
|
||||
return svGetBitArrElem1(s, indx1);
|
||||
}
|
||||
svLogic svGetLogicArrElem2(const svOpenArrayHandle s, int indx1, int indx2) {
|
||||
// Verilator doesn't support X/Z so can just call Bit version
|
||||
return svGetBitArrElem2(s, indx1, indx2);
|
||||
}
|
||||
svLogic svGetLogicArrElem3(const svOpenArrayHandle s, int indx1, int indx2, int indx3) {
|
||||
// Verilator doesn't support X/Z so can just call Bit version
|
||||
return svGetBitArrElem3(s, indx1, indx2, indx3);
|
||||
}
|
||||
|
||||
void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...) {
|
||||
const VerilatedDpiOpenVar* varp = _vl_openhandle_varp(d);
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
switch (varp->udims()) {
|
||||
case 1: _vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0); break;
|
||||
case 2: { int indx2=va_arg(ap,int);
|
||||
_vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0); break; }
|
||||
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
|
||||
_vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0); break; }
|
||||
case 4: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); int indx4=va_arg(ap,int);
|
||||
_vl_svPutBitArrElem(d, value, 4, indx1, indx2, indx3, indx4); break; }
|
||||
default: _vl_svPutBitArrElem(d, value, -1, 0, 0, 0, 0); break; // Will error
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
void svPutBitArrElem1(const svOpenArrayHandle d, svBit value, int indx1) {
|
||||
_vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0);
|
||||
}
|
||||
void svPutBitArrElem2(const svOpenArrayHandle d, svBit value, int indx1, int indx2) {
|
||||
_vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0);
|
||||
}
|
||||
void svPutBitArrElem3(const svOpenArrayHandle d, svBit value, int indx1, int indx2, int indx3) {
|
||||
_vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0);
|
||||
}
|
||||
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);
|
||||
va_list ap;
|
||||
va_start(ap, indx1);
|
||||
switch (varp->udims()) {
|
||||
case 1: _vl_svPutBitArrElem(d, value, 1, indx1, 0, 0, 0); break;
|
||||
case 2: { int indx2=va_arg(ap,int);
|
||||
_vl_svPutBitArrElem(d, value, 2, indx1, indx2, 0, 0); break; }
|
||||
case 3: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int);
|
||||
_vl_svPutBitArrElem(d, value, 3, indx1, indx2, indx3, 0); break; }
|
||||
case 4: { int indx2=va_arg(ap,int); int indx3=va_arg(ap,int); int indx4=va_arg(ap,int);
|
||||
_vl_svPutBitArrElem(d, value, 4, indx1, indx2, indx3, indx4); break; }
|
||||
default: _vl_svPutBitArrElem(d, value, -1, 0, 0, 0, 0); break; // Will error
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
void svPutLogicArrElem1(const svOpenArrayHandle d, svLogic value, int indx1) {
|
||||
// Verilator doesn't support X/Z so can just call Bit version
|
||||
svPutBitArrElem1(d, value, indx1);
|
||||
}
|
||||
void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value, int indx1, int indx2) {
|
||||
// Verilator doesn't support X/Z so can just call Bit version
|
||||
svPutBitArrElem2(d, value, indx1, indx2);
|
||||
}
|
||||
void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value, int indx1, int indx2, int indx3) {
|
||||
// Verilator doesn't support X/Z so can just call Bit version
|
||||
svPutBitArrElem3(d, value, indx1, indx2, indx3);
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Functions for working with DPI context
|
||||
|
||||
svScope svGetScope() {
|
||||
if (VL_UNLIKELY(!Verilated::dpiInContext())) { _VL_SVDPI_CONTEXT_WARN(); return NULL; }
|
||||
// NOLINTNEXTLINE(google-readability-casting)
|
||||
return (svScope)(Verilated::dpiScope());
|
||||
}
|
||||
|
||||
svScope svSetScope(const svScope scope) {
|
||||
const VerilatedScope* prevScopep = Verilated::dpiScope();
|
||||
const VerilatedScope* 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);
|
||||
return vscopep->name();
|
||||
}
|
||||
|
||||
svScope svGetScopeFromName(const char* scopeName) {
|
||||
// NOLINTNEXTLINE(google-readability-casting)
|
||||
return (svScope)(VerilatedImp::scopeFind(scopeName));
|
||||
}
|
||||
|
||||
int svPutUserData(const svScope scope, void* userKey, void* userData) {
|
||||
VerilatedImp::userInsert(scope,userKey,userData);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void* svGetUserData(const svScope scope, void* userKey) {
|
||||
return VerilatedImp::userFind(scope,userKey);
|
||||
}
|
||||
|
||||
int svGetCallerInfo(const char** fileNamepp, int *lineNumberp) {
|
||||
if (VL_UNLIKELY(!Verilated::dpiInContext())) { _VL_SVDPI_CONTEXT_WARN(); return false; }
|
||||
if (VL_LIKELY(fileNamepp)) *fileNamepp = Verilated::dpiFilenamep(); // thread local
|
||||
if (VL_LIKELY(lineNumberp)) *lineNumberp = Verilated::dpiLineno(); // thread local
|
||||
return true;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Disables
|
||||
|
||||
int svIsDisabledState() {
|
||||
return 0; // Disables not implemented
|
||||
}
|
||||
|
||||
void svAckDisabledState() {
|
||||
// Disables not implemented
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//*************************************************************************
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilator: Common include for all Verilated C files that use DPI
|
||||
///
|
||||
/// This file is included automatically by Verilator at the top of
|
||||
/// all C++ files it generates where DPI is used. It contains
|
||||
/// DPI interface functions required by the Verilated code.
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//*************************************************************************
|
||||
|
||||
|
||||
#ifndef _VERILATED_DPI_H_
|
||||
#define _VERILATED_DPI_H_ 1 ///< Header Guard
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h" // Also presumably included by caller
|
||||
#include "verilated_sym_props.h"
|
||||
|
||||
#include "svdpi.h"
|
||||
|
||||
//===================================================================
|
||||
// SETTING OPERATORS
|
||||
|
||||
/// Return WData from svBitVecVal
|
||||
static inline void VL_SET_W_SVBV(int obits, WDataOutP owp, const svBitVecVal* lwp) VL_MT_SAFE {
|
||||
int words = VL_WORDS_I(obits);
|
||||
for (int i=0; i<words-1; ++i) owp[i]=lwp[i];
|
||||
owp[words-1] = lwp[words-1] & VL_MASK_I(obits);
|
||||
}
|
||||
/// Return svBitVecVal from WData
|
||||
static inline void VL_SET_SVBV_W(int obits, svBitVecVal* owp, WDataInP lwp) VL_MT_SAFE {
|
||||
int words = VL_WORDS_I(obits);
|
||||
for (int i=0; i<words-1; ++i) owp[i]=lwp[i];
|
||||
owp[words-1] = lwp[words-1] & VL_MASK_I(obits);
|
||||
}
|
||||
|
||||
/// Convert svLogicVecVal to/from WData
|
||||
/// Note these functions ignore X/Z in svLogicVecVal
|
||||
static inline void VL_SET_W_SVLV(int obits, WDataOutP owp, const svLogicVecVal* lwp) VL_MT_SAFE {
|
||||
int words = VL_WORDS_I(obits);
|
||||
for (int i=0; i<words-1; ++i) owp[i]=lwp[i].aval;
|
||||
owp[words-1] = lwp[words-1].aval & VL_MASK_I(obits);
|
||||
}
|
||||
static inline QData VL_SET_Q_SVLV(const svLogicVecVal* lwp) VL_MT_SAFE {
|
||||
return _VL_SET_QII(lwp[1].aval, lwp[0].aval);
|
||||
}
|
||||
static inline IData VL_SET_I_SVLV(const svLogicVecVal* lwp) VL_MT_SAFE {
|
||||
return lwp[0].aval;
|
||||
}
|
||||
static inline void VL_SET_SVLV_W(int obits, svLogicVecVal* owp, WDataInP lwp) VL_MT_SAFE {
|
||||
int words = VL_WORDS_I(obits);
|
||||
for (int i=0; i<words; ++i) owp[i].bval=0;
|
||||
for (int i=0; i<words-1; ++i) owp[i].aval=lwp[i];
|
||||
owp[words-1].aval = lwp[words-1] & VL_MASK_I(obits);
|
||||
}
|
||||
static inline void VL_SET_SVLV_I(int, svLogicVecVal* owp, IData ld) VL_MT_SAFE {
|
||||
owp[0].aval=ld; owp[0].bval=0;
|
||||
}
|
||||
static inline void VL_SET_SVLV_Q(int, svLogicVecVal* owp, QData ld) VL_MT_SAFE {
|
||||
WData lwp[2]; VL_SET_WQ(lwp,ld);
|
||||
owp[0].aval=lwp[0]; owp[0].bval=0;
|
||||
owp[1].aval=lwp[1]; owp[1].bval=0;
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
|
||||
#endif // Guard
|
||||
@@ -0,0 +1,249 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief C++ Tracing in FST Format
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h"
|
||||
#include "verilated_fst_c.h"
|
||||
|
||||
// GTKWave configuration
|
||||
#ifdef VL_TRACE_THREADED
|
||||
# define HAVE_LIBPTHREAD
|
||||
# define FST_WRITER_PARALLEL
|
||||
#endif
|
||||
|
||||
// Include the GTKWave implementation directly
|
||||
#include "gtkwave/fastlz.c"
|
||||
#include "gtkwave/fstapi.c"
|
||||
#include "gtkwave/lz4.c"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cerrno>
|
||||
#include <ctime>
|
||||
#include <fcntl.h>
|
||||
#include <iterator>
|
||||
#include <sstream>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
|
||||
class VerilatedFstCallInfo {
|
||||
protected:
|
||||
friend class VerilatedFst;
|
||||
VerilatedFstCallback_t m_initcb; ///< Initialization Callback function
|
||||
VerilatedFstCallback_t m_fullcb; ///< Full Dumping Callback function
|
||||
VerilatedFstCallback_t m_changecb; ///< Incremental Dumping Callback function
|
||||
void* m_userthis; ///< Fake "this" for caller
|
||||
vluint32_t m_code; ///< Starting code number
|
||||
// CONSTRUCTORS
|
||||
VerilatedFstCallInfo(VerilatedFstCallback_t icb, VerilatedFstCallback_t fcb,
|
||||
VerilatedFstCallback_t changecb,
|
||||
void* ut, vluint32_t code)
|
||||
: m_initcb(icb), m_fullcb(fcb), m_changecb(changecb), m_userthis(ut), m_code(code) {};
|
||||
~VerilatedFstCallInfo() {}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedFst
|
||||
|
||||
VerilatedFst::VerilatedFst(void* fst)
|
||||
: m_fst(fst),
|
||||
m_fullDump(true),
|
||||
m_scopeEscape('.') {}
|
||||
|
||||
void VerilatedFst::open(const char* filename) VL_MT_UNSAFE {
|
||||
m_assertOne.check();
|
||||
m_fst = fstWriterCreate(filename, 1);
|
||||
fstWriterSetPackType(m_fst, FST_WR_PT_LZ4);
|
||||
#ifdef VL_TRACE_THREADED
|
||||
fstWriterSetParallelMode(m_fst, 1);
|
||||
#endif
|
||||
m_curScope.clear();
|
||||
|
||||
for (vluint32_t ent = 0; ent< m_callbacks.size(); ++ent) {
|
||||
VerilatedFstCallInfo* cip = m_callbacks[ent];
|
||||
cip->m_code = 1;
|
||||
(cip->m_initcb)(this, cip->m_userthis, cip->m_code);
|
||||
}
|
||||
|
||||
// Clear the scope stack
|
||||
std::list<std::string>::iterator it = m_curScope.begin();
|
||||
while (it != m_curScope.end()) {
|
||||
fstWriterSetUpscope(m_fst);
|
||||
it = m_curScope.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatedFst::module(const std::string& name) {
|
||||
m_module = name;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Decl
|
||||
|
||||
void VerilatedFst::declDTypeEnum(int dtypenum, const char* name, vluint32_t elements,
|
||||
unsigned int minValbits,
|
||||
const char** itemNamesp, const char** itemValuesp) {
|
||||
fstEnumHandle enumNum = fstWriterCreateEnumTable(m_fst, name, elements,
|
||||
minValbits, itemNamesp, itemValuesp);
|
||||
m_local2fstdtype[dtypenum] = enumNum;
|
||||
}
|
||||
|
||||
void VerilatedFst::declSymbol(vluint32_t code, const char* name,
|
||||
int dtypenum, fstVarDir vardir, fstVarType vartype,
|
||||
int arraynum, vluint32_t len) {
|
||||
std::pair<Code2SymbolType::iterator, bool> p
|
||||
= m_code2symbol.insert(std::make_pair(code, static_cast<fstHandle>(NULL)));
|
||||
std::istringstream nameiss(name);
|
||||
std::istream_iterator<std::string> beg(nameiss), end;
|
||||
std::list<std::string> tokens(beg, end); // Split name
|
||||
std::string symbol_name(tokens.back());
|
||||
tokens.pop_back(); // Remove symbol name from hierarchy
|
||||
tokens.insert(tokens.begin(), m_module); // Add current module to the hierarchy
|
||||
|
||||
// Find point where current and new scope diverge
|
||||
std::list<std::string>::iterator cur_it = m_curScope.begin();
|
||||
std::list<std::string>::iterator new_it = tokens.begin();
|
||||
while (cur_it != m_curScope.end() && new_it != tokens.end()) {
|
||||
if (*cur_it != *new_it)
|
||||
break;
|
||||
++cur_it;
|
||||
++new_it;
|
||||
}
|
||||
|
||||
// Go back to the common point
|
||||
while (cur_it != m_curScope.end()) {
|
||||
fstWriterSetUpscope(m_fst);
|
||||
cur_it = m_curScope.erase(cur_it);
|
||||
}
|
||||
|
||||
// Follow the hierarchy of the new variable from the common scope point
|
||||
while (new_it != tokens.end()) {
|
||||
fstWriterSetScope(m_fst, FST_ST_VCD_SCOPE, new_it->c_str(), NULL);
|
||||
m_curScope.push_back(*new_it);
|
||||
new_it = tokens.erase(new_it);
|
||||
}
|
||||
|
||||
std::stringstream name_ss;
|
||||
name_ss << symbol_name;
|
||||
if (arraynum >= 0)
|
||||
name_ss << "(" << arraynum << ")";
|
||||
std::string name_str = name_ss.str();
|
||||
|
||||
if (dtypenum > 0) {
|
||||
fstEnumHandle enumNum = m_local2fstdtype[dtypenum];
|
||||
fstWriterEmitEnumTableRef(m_fst, enumNum);
|
||||
}
|
||||
if (p.second) { // New
|
||||
p.first->second = fstWriterCreateVar(m_fst, vartype, vardir, len, name_str.c_str(), 0);
|
||||
assert(p.first->second);
|
||||
} else { // Alias
|
||||
fstWriterCreateVar(m_fst, vartype, vardir, len, name_str.c_str(), p.first->second);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Callbacks
|
||||
|
||||
void VerilatedFst::addCallback(
|
||||
VerilatedFstCallback_t initcb, VerilatedFstCallback_t fullcb,
|
||||
VerilatedFstCallback_t changecb, void* userthis) VL_MT_UNSAFE_ONE {
|
||||
m_assertOne.check();
|
||||
if (VL_UNLIKELY(isOpen())) {
|
||||
std::string msg = std::string("Internal: ")+__FILE__+"::"+__FUNCTION__+" called with already open file";
|
||||
VL_FATAL_MT(__FILE__,__LINE__,"",msg.c_str());
|
||||
}
|
||||
VerilatedFstCallInfo* vci = new VerilatedFstCallInfo(initcb, fullcb, changecb, userthis, 1);
|
||||
m_callbacks.push_back(vci);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Dumping
|
||||
|
||||
void VerilatedFst::dump(vluint64_t timeui) {
|
||||
if (!isOpen()) return;
|
||||
if (VL_UNLIKELY(m_fullDump)) {
|
||||
m_fullDump = false; // No need for more full dumps
|
||||
for (vluint32_t ent = 0; ent< m_callbacks.size(); ++ent) {
|
||||
VerilatedFstCallInfo* cip = m_callbacks[ent];
|
||||
(cip->m_fullcb)(this, cip->m_userthis, cip->m_code);
|
||||
}
|
||||
return;
|
||||
}
|
||||
fstWriterEmitTimeChange(m_fst, timeui);
|
||||
for (vluint32_t ent = 0; ent< m_callbacks.size(); ++ent) {
|
||||
VerilatedFstCallInfo* cip = m_callbacks[ent];
|
||||
(cip->m_changecb)(this, cip->m_userthis, cip->m_code);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Helpers
|
||||
|
||||
char* VerilatedFst::word2Str(vluint32_t newval, int bits) {
|
||||
m_valueStrBuffer.resize(bits+1);
|
||||
char* s = m_valueStrBuffer.data();
|
||||
for (int i = 0; i < bits; ++i) {
|
||||
*s = '0' + ((newval>>(bits-i-1))&1);
|
||||
++s;
|
||||
}
|
||||
*s = '\0';
|
||||
return m_valueStrBuffer.data();
|
||||
}
|
||||
|
||||
char* VerilatedFst::quad2Str(vluint64_t newval, int bits) {
|
||||
m_valueStrBuffer.resize(bits+1);
|
||||
char* s = m_valueStrBuffer.data();
|
||||
for (int i = 0; i < bits; ++i) {
|
||||
*s = '0' + ((newval>>(bits-i-1))&1);
|
||||
++s;
|
||||
}
|
||||
*s = '\0';
|
||||
return m_valueStrBuffer.data();
|
||||
}
|
||||
|
||||
char* VerilatedFst::array2Str(const vluint32_t* newval, int bits) {
|
||||
int bq = bits/32, br = bits%32;
|
||||
m_valueStrBuffer.resize(bits+1);
|
||||
char* s = m_valueStrBuffer.data();
|
||||
for (int i = 0; i < br; ++i) {
|
||||
*s = '0' + ((newval[bq]>>(br-i-1))&1);
|
||||
++s;
|
||||
}
|
||||
for (int w = bq-1; w >= 0; --w) {
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
*s = '0' + ((newval[w]>>(32-i-1))&1);
|
||||
++s;
|
||||
}
|
||||
}
|
||||
*s = '\0';
|
||||
return m_valueStrBuffer.data();
|
||||
}
|
||||
|
||||
//********************************************************************
|
||||
// Local Variables:
|
||||
// End:
|
||||
@@ -0,0 +1,230 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief C++ Tracing in FST Format
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
#ifndef _VERILATED_FST_C_H_
|
||||
#define _VERILATED_FST_C_H_ 1
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h"
|
||||
|
||||
#include "gtkwave/fstapi.h"
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class VerilatedFst;
|
||||
class VerilatedFstCallInfo;
|
||||
typedef void (*VerilatedFstCallback_t)(VerilatedFst* vcdp, void* userthis, vluint32_t code);
|
||||
|
||||
//=============================================================================
|
||||
// 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 {
|
||||
typedef std::map<vluint32_t, fstHandle> Code2SymbolType;
|
||||
typedef std::map<int, fstEnumHandle> Local2FstDtype;
|
||||
typedef std::vector<VerilatedFstCallInfo*> CallbackVec;
|
||||
private:
|
||||
void* m_fst;
|
||||
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
|
||||
bool m_fullDump;
|
||||
char m_scopeEscape;
|
||||
std::string m_module;
|
||||
CallbackVec m_callbacks; ///< Routines to perform dumping
|
||||
Code2SymbolType m_code2symbol;
|
||||
Local2FstDtype m_local2fstdtype;
|
||||
std::list<std::string> m_curScope;
|
||||
// CONSTRUCTORS
|
||||
VL_UNCOPYABLE(VerilatedFst);
|
||||
void declSymbol(vluint32_t code, const char* name,
|
||||
int dtypenum, fstVarDir vardir, fstVarType vartype,
|
||||
int arraynum, vluint32_t len);
|
||||
// helpers
|
||||
std::vector<char> m_valueStrBuffer;
|
||||
char* word2Str(vluint32_t newval, int bits);
|
||||
char* quad2Str(vluint64_t newval, int bits);
|
||||
char* array2Str(const vluint32_t *newval, int bits);
|
||||
public:
|
||||
explicit VerilatedFst(void* fst=NULL);
|
||||
~VerilatedFst() { if (m_fst == NULL) { fstWriterClose(m_fst); } }
|
||||
bool isOpen() const { return m_fst != NULL; }
|
||||
void open(const char* filename) VL_MT_UNSAFE;
|
||||
void flush() VL_MT_UNSAFE { fstWriterFlushContext(m_fst); }
|
||||
void close() VL_MT_UNSAFE {
|
||||
m_assertOne.check();
|
||||
fstWriterClose(m_fst);
|
||||
m_fst = NULL;
|
||||
}
|
||||
// void set_time_unit(const char* unitp); ///< Set time units (s/ms, defaults to ns)
|
||||
// void set_time_unit(const std::string& unit) { set_time_unit(unit.c_str()); }
|
||||
|
||||
// void set_time_resolution(const char* unitp); ///< Set time resolution (s/ms, defaults to ns)
|
||||
// void set_time_resolution(const std::string& unit) { set_time_resolution(unit.c_str()); }
|
||||
|
||||
// double timescaleToDouble(const char* unitp);
|
||||
// std::string doubleToTimescale(double value);
|
||||
|
||||
/// Change character that splits scopes. Note whitespace are ALWAYS escapes.
|
||||
void scopeEscape(char flag) { m_scopeEscape = flag; }
|
||||
/// Is this an escape?
|
||||
bool isScopeEscape(char c) { return isspace(c) || c==m_scopeEscape; }
|
||||
/// Inside dumping routines, called each cycle to make the dump
|
||||
void dump(vluint64_t timeui);
|
||||
/// Inside dumping routines, declare callbacks for tracings
|
||||
void addCallback(VerilatedFstCallback_t initcb, VerilatedFstCallback_t fullcb,
|
||||
VerilatedFstCallback_t changecb,
|
||||
void* userthis) VL_MT_UNSAFE_ONE;
|
||||
|
||||
/// Inside dumping routines, declare a module
|
||||
void module(const std::string& name);
|
||||
/// 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, fstVarType vartype,
|
||||
int arraynum) {
|
||||
declSymbol(code, name, dtypenum, vardir, vartype, arraynum, 1);
|
||||
}
|
||||
void declBus(vluint32_t code, const char* name,
|
||||
int dtypenum, fstVarDir vardir, fstVarType vartype,
|
||||
int arraynum, int msb, int lsb) {
|
||||
declSymbol(code, name, dtypenum, vardir, vartype, arraynum, msb - lsb + 1);
|
||||
}
|
||||
void declDouble(vluint32_t code, const char* name,
|
||||
int dtypenum, fstVarDir vardir, fstVarType vartype,
|
||||
int arraynum) {
|
||||
declSymbol(code, name, dtypenum, vardir, vartype, arraynum, 2);
|
||||
}
|
||||
void declFloat(vluint32_t code, const char* name,
|
||||
int dtypenum, fstVarDir vardir, fstVarType vartype,
|
||||
int arraynum) {
|
||||
declSymbol(code, name, dtypenum, vardir, vartype, arraynum, 1);
|
||||
}
|
||||
void declQuad(vluint32_t code, const char* name,
|
||||
int dtypenum, fstVarDir vardir, fstVarType vartype,
|
||||
int arraynum, int msb, int lsb) {
|
||||
declSymbol(code, name, dtypenum, vardir, vartype, arraynum, msb - lsb + 1);
|
||||
}
|
||||
void declArray(vluint32_t code, const char* name,
|
||||
int dtypenum, fstVarDir vardir, fstVarType vartype,
|
||||
int arraynum, int msb, int lsb) {
|
||||
declSymbol(code, name, dtypenum, vardir, vartype, arraynum, msb - lsb + 1);
|
||||
}
|
||||
|
||||
/// Inside dumping routines, dump one signal if it has changed
|
||||
void chgBit(vluint32_t code, const vluint32_t newval) {
|
||||
fstWriterEmitValueChange(m_fst, m_code2symbol[code], newval ? "1" : "0");
|
||||
}
|
||||
void chgBus(vluint32_t code, const vluint32_t newval, int bits) {
|
||||
fstWriterEmitValueChange(m_fst, m_code2symbol[code], word2Str(newval, bits));
|
||||
}
|
||||
void chgDouble(vluint32_t code, const double newval) {
|
||||
double val = newval;
|
||||
fstWriterEmitValueChange(m_fst, m_code2symbol[code], &val);
|
||||
}
|
||||
void chgFloat(vluint32_t code, const float newval) {
|
||||
double val = (double)newval;
|
||||
fstWriterEmitValueChange(m_fst, m_code2symbol[code], &val);
|
||||
}
|
||||
void chgQuad(vluint32_t code, const vluint64_t newval, int bits) {
|
||||
fstWriterEmitValueChange(m_fst, m_code2symbol[code], quad2Str(newval, bits));
|
||||
}
|
||||
void chgArray(vluint32_t code, const vluint32_t* newval, int bits) {
|
||||
fstWriterEmitValueChange(m_fst, m_code2symbol[code], array2Str(newval, bits));
|
||||
}
|
||||
|
||||
void fullBit(vluint32_t code, const vluint32_t newval) { chgBit(code, newval); }
|
||||
void fullBus(vluint32_t code, const vluint32_t newval, int bits) { chgBus(code, newval, bits); }
|
||||
void fullDouble(vluint32_t code, const double newval) { chgDouble(code, newval); }
|
||||
void fullFloat(vluint32_t code, const float newval) { chgFloat(code, newval); }
|
||||
void fullQuad(vluint32_t code, const vluint64_t newval, int bits) { chgQuad(code, newval, bits); }
|
||||
void fullArray(vluint32_t code, const vluint32_t* newval, int bits) { chgArray(code, newval, bits); }
|
||||
|
||||
void declTriBit (vluint32_t code, const char* name, int arraynum);
|
||||
void declTriBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
|
||||
void declTriQuad (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
|
||||
void declTriArray (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
|
||||
void fullTriBit(vluint32_t code, const vluint32_t newval, const vluint32_t newtri);
|
||||
void fullTriBus(vluint32_t code, const vluint32_t newval, const vluint32_t newtri, int bits);
|
||||
void fullTriQuad(vluint32_t code, const vluint64_t newval, const vluint32_t newtri, int bits);
|
||||
void fullTriArray(vluint32_t code, const vluint32_t* newvalp, const vluint32_t* newtrip, int bits);
|
||||
void fullBitX(vluint32_t code);
|
||||
void fullBusX(vluint32_t code, int bits);
|
||||
void fullQuadX(vluint32_t code, int bits);
|
||||
void fullArrayX(vluint32_t code, int bits);
|
||||
void chgTriBit(vluint32_t code, const vluint32_t newval, const vluint32_t newtri);
|
||||
void chgTriBus(vluint32_t code, const vluint32_t newval, const vluint32_t newtri, int bits);
|
||||
void chgTriQuad(vluint32_t code, const vluint64_t newval, const vluint32_t newtri, int bits);
|
||||
void chgTriArray(vluint32_t code, const vluint32_t* newvalp, const vluint32_t* newtrip, int bits);
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedFstC
|
||||
/// Create a FST dump file in C standalone (no SystemC) simulations.
|
||||
/// Also derived for use in SystemC simulations.
|
||||
/// Thread safety: Unless otherwise indicated, every function is VL_MT_UNSAFE_ONE
|
||||
|
||||
class VerilatedFstC {
|
||||
VerilatedFst m_sptrace; ///< Trace file being created
|
||||
|
||||
// CONSTRUCTORS
|
||||
VL_UNCOPYABLE(VerilatedFstC);
|
||||
public:
|
||||
explicit VerilatedFstC(void* filep=NULL) : m_sptrace(filep) {}
|
||||
~VerilatedFstC() {}
|
||||
public:
|
||||
// ACCESSORS
|
||||
/// Is file open?
|
||||
bool isOpen() const { return m_sptrace.isOpen(); }
|
||||
// METHODS
|
||||
/// Open a new FST file
|
||||
void open(const char* filename) VL_MT_UNSAFE_ONE { m_sptrace.open(filename); }
|
||||
/// Close dump
|
||||
void close() VL_MT_UNSAFE_ONE { m_sptrace.close(); }
|
||||
/// Flush dump
|
||||
void flush() VL_MT_UNSAFE_ONE { m_sptrace.flush(); }
|
||||
/// Write one cycle of dump data
|
||||
void dump(vluint64_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)); }
|
||||
/// Set time units (s/ms, defaults to ns)
|
||||
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
|
||||
void set_time_unit(const char* unit) { /* TODO */ }
|
||||
void set_time_unit(const std::string& unit) { set_time_unit(unit.c_str()); }
|
||||
/// Set time resolution (s/ms, defaults to ns)
|
||||
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
|
||||
void set_time_resolution(const char* unit) { /* TODO */ }
|
||||
void set_time_resolution(const std::string& unit) { set_time_resolution(unit.c_str()); }
|
||||
|
||||
/// Internal class access
|
||||
inline VerilatedFst* spTrace() { return &m_sptrace; };
|
||||
};
|
||||
|
||||
#endif // guard
|
||||
@@ -0,0 +1,91 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2010-2019 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//*************************************************************************
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilator: String include for all Verilated C files
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//*************************************************************************
|
||||
|
||||
|
||||
#ifndef _VERILATED_HEAVY_H_
|
||||
#define _VERILATED_HEAVY_H_ 1 ///< Header Guard
|
||||
|
||||
#include "verilated.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
//======================================================================
|
||||
// Conversion functions
|
||||
|
||||
extern std::string VL_CVT_PACK_STR_NW(int lwords, WDataInP lwp) VL_MT_SAFE;
|
||||
inline std::string VL_CVT_PACK_STR_NQ(QData lhs) VL_PURE {
|
||||
WData lw[2]; VL_SET_WQ(lw, lhs);
|
||||
return VL_CVT_PACK_STR_NW(2, lw);
|
||||
}
|
||||
inline std::string VL_CVT_PACK_STR_NN(const std::string& lhs) VL_PURE {
|
||||
return lhs;
|
||||
}
|
||||
inline std::string VL_CVT_PACK_STR_NI(IData lhs) VL_PURE {
|
||||
WData lw[1]; lw[0] = 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 IData VL_FOPEN_NI(const std::string& filename, IData mode) VL_MT_SAFE;
|
||||
extern void VL_READMEM_N(bool hex, int width, int depth, int array_lsb,
|
||||
const std::string& filename,
|
||||
void* memp, IData start, IData end) VL_MT_SAFE;
|
||||
extern void VL_WRITEMEM_N(bool hex, int width, int depth, int array_lsb,
|
||||
const std::string& filename,
|
||||
const void* memp, IData start, IData end) VL_MT_SAFE;
|
||||
extern IData VL_SSCANF_INX(int lbits, const std::string& ld, const char* formatp, ...) VL_MT_SAFE;
|
||||
extern void VL_SFORMAT_X(int obits_ignored, std::string& output, const char* formatp, ...) VL_MT_SAFE;
|
||||
extern std::string VL_SFORMATF_NX(const char* formatp, ...) VL_MT_SAFE;
|
||||
extern IData VL_VALUEPLUSARGS_INW(int rbits, const std::string& ld, WDataOutP rwp) VL_MT_SAFE;
|
||||
inline IData VL_VALUEPLUSARGS_INI(int rbits, const std::string& ld, IData& rdr) VL_MT_SAFE {
|
||||
WData rwp[2]; // WData must always be at least 2
|
||||
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
|
||||
if (got) rdr = rwp[0];
|
||||
return got;
|
||||
}
|
||||
inline IData VL_VALUEPLUSARGS_INQ(int rbits, const std::string& ld, QData& rdr) VL_MT_SAFE {
|
||||
WData rwp[2];
|
||||
IData got = VL_VALUEPLUSARGS_INW(rbits,ld,rwp);
|
||||
if (got) rdr = VL_SET_QW(rwp);
|
||||
return got;
|
||||
}
|
||||
extern IData VL_VALUEPLUSARGS_INN(int, const std::string& ld, std::string& rdr) VL_MT_SAFE;
|
||||
|
||||
#endif // Guard
|
||||
@@ -0,0 +1,408 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2019 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//=========================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilator: Implementation Header, only for verilated.cpp internals.
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//=========================================================================
|
||||
|
||||
|
||||
#ifndef _VERILATED_IMP_H_
|
||||
#define _VERILATED_IMP_H_ 1 ///< Header Guard
|
||||
|
||||
#if !defined(_VERILATED_CPP_) && !defined(_VERILATED_DPI_CPP_)
|
||||
# error "verilated_imp.h only to be included by verilated*.cpp internals"
|
||||
#endif
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h"
|
||||
#include "verilated_heavy.h"
|
||||
#include "verilated_syms.h"
|
||||
|
||||
#include <deque>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#ifdef VL_THREADED
|
||||
# include <functional>
|
||||
# include <queue>
|
||||
#endif
|
||||
|
||||
class VerilatedScope;
|
||||
|
||||
//======================================================================
|
||||
// Threaded message passing
|
||||
|
||||
#ifdef VL_THREADED
|
||||
/// Message, enqueued on an mtask, and consumed on the main eval thread
|
||||
class VerilatedMsg {
|
||||
public:
|
||||
// TYPES
|
||||
struct Cmp {
|
||||
bool operator() (const VerilatedMsg& a, const VerilatedMsg& b) const {
|
||||
return a.mtaskId() < b.mtaskId(); }
|
||||
};
|
||||
private:
|
||||
// MEMBERS
|
||||
vluint32_t m_mtaskId; ///< MTask that did enqueue
|
||||
std::function<void()> m_cb; ///< Lambda to execute when message received
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
VerilatedMsg(const std::function<void()>& cb)
|
||||
: m_mtaskId(Verilated::mtaskId()), m_cb(cb) {}
|
||||
~VerilatedMsg() {}
|
||||
// METHODS
|
||||
vluint32_t mtaskId() const { return m_mtaskId; }
|
||||
/// Execute the lambda function
|
||||
void run() const { m_cb(); }
|
||||
};
|
||||
|
||||
/// Each thread has a queue it pushes to
|
||||
/// This assumes no thread starts pushing the next tick until the previous has drained.
|
||||
/// If more aggressiveness is needed, a double-buffered scheme might work well.
|
||||
class VerilatedEvalMsgQueue {
|
||||
typedef std::multiset<VerilatedMsg, VerilatedMsg::Cmp> VerilatedThreadQueue;
|
||||
|
||||
std::atomic<vluint64_t> m_depth; ///< Current depth of queue (see comments below)
|
||||
|
||||
VerilatedMutex m_mutex; ///< Mutex protecting queue
|
||||
VerilatedThreadQueue m_queue VL_GUARDED_BY(m_mutex); ///< Message queue
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
VerilatedEvalMsgQueue() : m_depth(0) {
|
||||
assert(atomic_is_lock_free(&m_depth));
|
||||
}
|
||||
~VerilatedEvalMsgQueue() { }
|
||||
private:
|
||||
VL_UNCOPYABLE(VerilatedEvalMsgQueue);
|
||||
public:
|
||||
// METHODS
|
||||
//// Add message to queue (called by producer)
|
||||
void post(const VerilatedMsg& msg) VL_EXCLUDES(m_mutex) {
|
||||
VerilatedLockGuard lock(m_mutex);
|
||||
m_queue.insert(msg); // Pass by value to copy the message into queue
|
||||
++m_depth;
|
||||
}
|
||||
/// Service queue until completion (called by consumer)
|
||||
void process() VL_EXCLUDES(m_mutex) {
|
||||
// Tracking m_depth is redundant to e.g. getting the mutex and looking at queue size,
|
||||
// but on the reader side it's 4x faster to test an atomic then getting a mutex
|
||||
while (m_depth) {
|
||||
// Wait for a message to be added to the queue
|
||||
// We don't use unique_lock as want to unlock with the message copy still in scope
|
||||
m_mutex.lock();
|
||||
assert(!m_queue.empty()); // Otherwise m_depth is wrong
|
||||
// Unfortunately to release the lock we need to copy the message
|
||||
// (Or have the message be a pointer, but then new/delete cost on each message)
|
||||
// We assume messages are small, so copy
|
||||
auto it = m_queue.begin();
|
||||
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
|
||||
{
|
||||
VL_DEBUG_IF(VL_DBG_MSGF("Executing callback from mtaskId=%d\n", msg.mtaskId()););
|
||||
msg.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/// Each thread has a local queue to build up messages until the end of the eval() call
|
||||
class VerilatedThreadMsgQueue {
|
||||
std::queue<VerilatedMsg> m_queue;
|
||||
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.
|
||||
}
|
||||
private:
|
||||
VL_UNCOPYABLE(VerilatedThreadMsgQueue);
|
||||
// METHODS
|
||||
static VerilatedThreadMsgQueue& threadton() {
|
||||
static VL_THREAD_LOCAL VerilatedThreadMsgQueue t_s;
|
||||
return t_s;
|
||||
}
|
||||
public:
|
||||
/// Add message to queue, called by producer
|
||||
static void post(const VerilatedMsg& msg) VL_MT_SAFE {
|
||||
// Handle calls to threaded routines outside
|
||||
// of any mtask -- if an initial block calls $finish, say.
|
||||
if (Verilated::mtaskId() == 0) {
|
||||
// No queueing, just do the action immediately
|
||||
msg.run();
|
||||
} else {
|
||||
Verilated::endOfEvalReqdInc();
|
||||
threadton().m_queue.push(msg); // Pass by value to copy the message into queue
|
||||
}
|
||||
}
|
||||
/// Push all messages to the eval's queue
|
||||
static void flush(VerilatedEvalMsgQueue* evalMsgQp) VL_MT_SAFE {
|
||||
while (!threadton().m_queue.empty()) {
|
||||
evalMsgQp->post(threadton().m_queue.front());
|
||||
threadton().m_queue.pop();
|
||||
Verilated::endOfEvalReqdDec();
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif // VL_THREADED
|
||||
|
||||
//======================================================================
|
||||
// VerilatedImp
|
||||
|
||||
class VerilatedImp {
|
||||
// Whole class is internal use only - Global information shared between verilated*.cpp files.
|
||||
|
||||
// TYPES
|
||||
typedef std::vector<std::string> ArgVec;
|
||||
typedef std::map<std::pair<const void*,void*>,void*> UserMap;
|
||||
typedef std::map<const char*, int, VerilatedCStrCmp> ExportNameMap;
|
||||
|
||||
// MEMBERS
|
||||
static VerilatedImp s_s; ///< Static Singleton; One and only static this
|
||||
|
||||
// Nothing here is save-restored; users expected to re-register appropriately
|
||||
|
||||
VerilatedMutex m_argMutex; ///< Protect m_argVec, m_argVecLoaded
|
||||
ArgVec m_argVec VL_GUARDED_BY(m_argMutex); ///< Argument list (NOT save-restored, may want different results)
|
||||
bool m_argVecLoaded VL_GUARDED_BY(m_argMutex); ///< Ever loaded argument list
|
||||
|
||||
VerilatedMutex m_userMapMutex; ///< Protect m_userMap
|
||||
UserMap m_userMap VL_GUARDED_BY(m_userMapMutex); ///< Map of <(scope,userkey), userData>
|
||||
|
||||
VerilatedMutex m_nameMutex; ///< Protect m_nameMap
|
||||
VerilatedScopeNameMap m_nameMap VL_GUARDED_BY(m_nameMutex); ///< Map of <scope_name, scope pointer>
|
||||
// Slow - somewhat static:
|
||||
VerilatedMutex m_exportMutex; ///< Protect m_nameMap
|
||||
ExportNameMap m_exportMap VL_GUARDED_BY(m_exportMutex); ///< Map of <export_func_proto, func number>
|
||||
int m_exportNext VL_GUARDED_BY(m_exportMutex); ///< Next export funcnum
|
||||
|
||||
// File I/O
|
||||
VerilatedMutex m_fdMutex; ///< Protect m_fdps, m_fdFree
|
||||
std::vector<FILE*> m_fdps VL_GUARDED_BY(m_fdMutex); ///< File descriptors
|
||||
std::deque<IData> m_fdFree VL_GUARDED_BY(m_fdMutex); ///< List of free descriptors (SLOW - FOPEN/CLOSE only)
|
||||
|
||||
public: // But only for verilated*.cpp
|
||||
// CONSTRUCTORS
|
||||
VerilatedImp()
|
||||
: m_argVecLoaded(false), m_exportNext(0) {
|
||||
m_fdps.resize(3);
|
||||
m_fdps[0] = stdin;
|
||||
m_fdps[1] = stdout;
|
||||
m_fdps[2] = stderr;
|
||||
}
|
||||
~VerilatedImp() {}
|
||||
private:
|
||||
VL_UNCOPYABLE(VerilatedImp);
|
||||
public:
|
||||
// METHODS - debug
|
||||
static void internalsDump() VL_MT_SAFE;
|
||||
static void versionDump() VL_MT_SAFE;
|
||||
|
||||
// METHODS - arguments
|
||||
public:
|
||||
static void commandArgs(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex);
|
||||
static void commandArgsAdd(int argc, const char** argv) VL_EXCLUDES(s_s.m_argMutex);
|
||||
static std::string argPlusMatch(const char* prefixp) VL_EXCLUDES(s_s.m_argMutex) {
|
||||
VerilatedLockGuard lock(s_s.m_argMutex);
|
||||
// Note prefixp does not include the leading "+"
|
||||
size_t len = strlen(prefixp);
|
||||
if (VL_UNLIKELY(!s_s.m_argVecLoaded)) {
|
||||
s_s.m_argVecLoaded = true; // Complain only once
|
||||
VL_FATAL_MT("unknown", 0, "",
|
||||
"%Error: Verilog called $test$plusargs or $value$plusargs without"
|
||||
" testbench C first calling Verilated::commandArgs(argc,argv).");
|
||||
}
|
||||
for (ArgVec::const_iterator it=s_s.m_argVec.begin(); it!=s_s.m_argVec.end(); ++it) {
|
||||
if ((*it)[0]=='+') {
|
||||
if (0==strncmp(prefixp, it->c_str()+1, len)) return *it;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
private:
|
||||
static void commandArgsAddGuts(int argc, const char** argv) VL_REQUIRES(s_s.m_argMutex);
|
||||
static void commandArgVl(const std::string& arg);
|
||||
static bool commandArgVlValue(const std::string& arg,
|
||||
const std::string& prefix, std::string& valuer);
|
||||
|
||||
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.
|
||||
static inline void userInsert(const void* scopep, void* userKey, void* userData) VL_MT_SAFE {
|
||||
VerilatedLockGuard lock(s_s.m_userMapMutex);
|
||||
UserMap::iterator it=s_s.m_userMap.find(std::make_pair(scopep, userKey));
|
||||
if (it != s_s.m_userMap.end()) it->second = userData;
|
||||
// When we support VL_THREADs, we need a lock around this insert, as it's runtime
|
||||
else s_s.m_userMap.insert(it, std::make_pair(std::make_pair(scopep, userKey), userData));
|
||||
}
|
||||
static inline void* userFind(const void* scopep, void* userKey) VL_MT_SAFE {
|
||||
VerilatedLockGuard lock(s_s.m_userMapMutex);
|
||||
UserMap::const_iterator it=s_s.m_userMap.find(std::make_pair(scopep, userKey));
|
||||
if (VL_LIKELY(it != s_s.m_userMap.end())) return it->second;
|
||||
else return NULL;
|
||||
}
|
||||
private:
|
||||
/// 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.
|
||||
VerilatedLockGuard lock(s_s.m_userMapMutex);
|
||||
for (UserMap::iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ) {
|
||||
if (it->first.first == scopep) {
|
||||
s_s.m_userMap.erase(it++);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void userDump() VL_MT_SAFE {
|
||||
VerilatedLockGuard lock(s_s.m_userMapMutex); // Avoid it changing in middle of dump
|
||||
bool first = true;
|
||||
for (UserMap::const_iterator it=s_s.m_userMap.begin(); it!=s_s.m_userMap.end(); ++it) {
|
||||
if (first) { VL_PRINTF_MT(" userDump:\n"); first=false; }
|
||||
VL_PRINTF_MT(" DPI_USER_DATA scope %p key %p: %p\n",
|
||||
it->first.first, it->first.second, it->second);
|
||||
}
|
||||
}
|
||||
|
||||
public: // But only for verilated*.cpp
|
||||
// METHODS - scope name
|
||||
static void scopeInsert(const VerilatedScope* scopep) VL_MT_SAFE {
|
||||
// Slow ok - called once/scope at construction
|
||||
VerilatedLockGuard lock(s_s.m_nameMutex);
|
||||
VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
|
||||
if (it == s_s.m_nameMap.end()) {
|
||||
s_s.m_nameMap.insert(it, std::make_pair(scopep->name(), scopep));
|
||||
}
|
||||
}
|
||||
static inline const VerilatedScope* scopeFind(const char* namep) VL_MT_SAFE {
|
||||
VerilatedLockGuard lock(s_s.m_nameMutex);
|
||||
// If too slow, can assume this is only VL_MT_SAFE_POSINIT
|
||||
VerilatedScopeNameMap::const_iterator it=s_s.m_nameMap.find(namep);
|
||||
if (VL_LIKELY(it != s_s.m_nameMap.end())) return it->second;
|
||||
else return NULL;
|
||||
}
|
||||
static void scopeErase(const VerilatedScope* scopep) VL_MT_SAFE {
|
||||
// Slow ok - called once/scope at destruction
|
||||
VerilatedLockGuard lock(s_s.m_nameMutex);
|
||||
userEraseScope(scopep);
|
||||
VerilatedScopeNameMap::iterator it=s_s.m_nameMap.find(scopep->name());
|
||||
if (it != s_s.m_nameMap.end()) s_s.m_nameMap.erase(it);
|
||||
}
|
||||
static void scopesDump() VL_MT_SAFE {
|
||||
VerilatedLockGuard lock(s_s.m_nameMutex);
|
||||
VL_PRINTF_MT(" scopesDump:\n");
|
||||
for (VerilatedScopeNameMap::const_iterator it=s_s.m_nameMap.begin();
|
||||
it!=s_s.m_nameMap.end(); ++it) {
|
||||
const VerilatedScope* scopep = it->second;
|
||||
scopep->scopeDump();
|
||||
}
|
||||
VL_PRINTF_MT("\n");
|
||||
}
|
||||
static const VerilatedScopeNameMap* scopeNameMap() VL_MT_SAFE_POSTINIT {
|
||||
// Thread save only assuming this is called only after model construction completed
|
||||
return &s_s.m_nameMap;
|
||||
}
|
||||
|
||||
public: // But only for verilated*.cpp
|
||||
// METHODS - export names
|
||||
|
||||
// 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
|
||||
// can't know at Verilation time what scopes will exist in other modules
|
||||
// in the design that also happen to have our same callback function.
|
||||
// Rather than a 2D map, the integer scheme saves 500ish ns on a likely
|
||||
// miss at the cost of a multiply, and all lookups move to slowpath.
|
||||
static int exportInsert(const char* namep) VL_MT_SAFE {
|
||||
// Slow ok - called once/function at creation
|
||||
VerilatedLockGuard lock(s_s.m_exportMutex);
|
||||
ExportNameMap::iterator it=s_s.m_exportMap.find(namep);
|
||||
if (it == s_s.m_exportMap.end()) {
|
||||
s_s.m_exportMap.insert(it, std::make_pair(namep, s_s.m_exportNext++));
|
||||
return s_s.m_exportNext++;
|
||||
} else {
|
||||
return it->second;
|
||||
}
|
||||
}
|
||||
static int exportFind(const char* namep) VL_MT_SAFE {
|
||||
VerilatedLockGuard lock(s_s.m_exportMutex);
|
||||
ExportNameMap::const_iterator it=s_s.m_exportMap.find(namep);
|
||||
if (VL_LIKELY(it != s_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");
|
||||
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
|
||||
VerilatedLockGuard lock(s_s.m_exportMutex);
|
||||
for (ExportNameMap::const_iterator it=s_s.m_exportMap.begin();
|
||||
it!=s_s.m_exportMap.end(); ++it) {
|
||||
if (it->second == funcnum) return it->first;
|
||||
}
|
||||
return "*UNKNOWN*";
|
||||
}
|
||||
static void exportsDump() VL_MT_SAFE {
|
||||
VerilatedLockGuard lock(s_s.m_exportMutex);
|
||||
bool first = true;
|
||||
for (ExportNameMap::const_iterator it=s_s.m_exportMap.begin();
|
||||
it!=s_s.m_exportMap.end(); ++it) {
|
||||
if (first) { VL_PRINTF_MT(" exportDump:\n"); first=false; }
|
||||
VL_PRINTF_MT(" DPI_EXPORT_NAME %05d: %s\n", it->second, it->first);
|
||||
}
|
||||
}
|
||||
// We don't free up m_exportMap until the end, because we can't be sure
|
||||
// what other models are using the assigned funcnum's.
|
||||
|
||||
public: // But only for verilated*.cpp
|
||||
// METHODS - file IO
|
||||
static IData fdNew(FILE* fp) VL_MT_SAFE {
|
||||
if (VL_UNLIKELY(!fp)) return 0;
|
||||
// Bit 31 indicates it's a descriptor not a MCD
|
||||
VerilatedLockGuard lock(s_s.m_fdMutex);
|
||||
if (s_s.m_fdFree.empty()) {
|
||||
// Need to create more space in m_fdps and m_fdFree
|
||||
size_t start = s_s.m_fdps.size();
|
||||
s_s.m_fdps.resize(start*2);
|
||||
for (size_t i=start; i<start*2; ++i) s_s.m_fdFree.push_back(static_cast<IData>(i));
|
||||
}
|
||||
IData idx = s_s.m_fdFree.back(); s_s.m_fdFree.pop_back();
|
||||
s_s.m_fdps[idx] = fp;
|
||||
return (idx | (1UL<<31)); // bit 31 indicates not MCD
|
||||
}
|
||||
static void fdDelete(IData fdi) VL_MT_SAFE {
|
||||
IData idx = VL_MASK_I(31) & fdi;
|
||||
VerilatedLockGuard lock(s_s.m_fdMutex);
|
||||
if (VL_UNLIKELY(!(fdi & (1ULL<<31)) || idx >= s_s.m_fdps.size())) return;
|
||||
if (VL_UNLIKELY(!s_s.m_fdps[idx])) return; // Already free
|
||||
s_s.m_fdps[idx] = NULL;
|
||||
s_s.m_fdFree.push_back(idx);
|
||||
}
|
||||
static inline FILE* fdToFp(IData fdi) VL_MT_SAFE {
|
||||
IData idx = VL_MASK_I(31) & fdi;
|
||||
VerilatedLockGuard lock(s_s.m_fdMutex); // This might get slow, if it does we can cache it
|
||||
if (VL_UNLIKELY(!(fdi & (1ULL<<31)) || idx >= s_s.m_fdps.size())) return NULL;
|
||||
return s_s.m_fdps[idx];
|
||||
}
|
||||
};
|
||||
|
||||
//======================================================================
|
||||
|
||||
#endif // Guard
|
||||
@@ -0,0 +1,240 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief C++ Tracing in VCD Format
|
||||
///
|
||||
//=============================================================================
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h"
|
||||
#include "verilated_save.h"
|
||||
|
||||
#include <cerrno>
|
||||
#include <fcntl.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifndef O_LARGEFILE // For example on WIN32
|
||||
# define O_LARGEFILE 0
|
||||
#endif
|
||||
#ifndef O_NONBLOCK
|
||||
# define O_NONBLOCK 0
|
||||
#endif
|
||||
#ifndef O_CLOEXEC
|
||||
# define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
// CONSTANTS
|
||||
static const char* const VLTSAVE_HEADER_STR = "verilatorsave01\n"; ///< Value of first bytes of each file
|
||||
static const char* const VLTSAVE_TRAILER_STR = "vltsaved"; ///< Value of last bytes of each file
|
||||
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Searalization
|
||||
|
||||
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;
|
||||
while (size--) {
|
||||
miss |= (*dp++ ^ *m_cp++);
|
||||
}
|
||||
return (miss!=0);
|
||||
}
|
||||
|
||||
VerilatedDeserialize& VerilatedDeserialize::readAssert(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
||||
if (VL_UNLIKELY(readDiffers(datap, size))) {
|
||||
std::string fn = filename();
|
||||
std::string msg = std::string("Can't deserialize save-restore file as was made from different model");
|
||||
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
||||
close();
|
||||
}
|
||||
return *this; // For function chaining
|
||||
}
|
||||
|
||||
void VerilatedSerialize::header() VL_MT_UNSAFE_ONE {
|
||||
VerilatedSerialize& os = *this; // So can cut and paste standard << code below
|
||||
assert((strlen(VLTSAVE_HEADER_STR) & 7) == 0); // Keep aligned
|
||||
os.write(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR));
|
||||
|
||||
// Verilated doesn't do it itself, as if we're not using save/restore
|
||||
// it doesn't need to compile this stuff in
|
||||
os.write(Verilated::serializedPtr(), Verilated::serializedSize());
|
||||
}
|
||||
|
||||
void VerilatedDeserialize::header() VL_MT_UNSAFE_ONE {
|
||||
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
|
||||
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_HEADER_STR, strlen(VLTSAVE_HEADER_STR)))) {
|
||||
std::string fn = filename();
|
||||
std::string msg = std::string("Can't deserialize; file has wrong header signature");
|
||||
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
||||
close();
|
||||
}
|
||||
os.read(Verilated::serializedPtr(), Verilated::serializedSize());
|
||||
}
|
||||
|
||||
void VerilatedSerialize::trailer() VL_MT_UNSAFE_ONE {
|
||||
VerilatedSerialize& os = *this; // So can cut and paste standard << code below
|
||||
assert((strlen(VLTSAVE_TRAILER_STR) & 7) == 0); // Keep aligned
|
||||
os.write(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR));
|
||||
}
|
||||
|
||||
void VerilatedDeserialize::trailer() VL_MT_UNSAFE_ONE {
|
||||
VerilatedDeserialize& os = *this; // So can cut and paste standard >> code below
|
||||
if (VL_UNLIKELY(os.readDiffers(VLTSAVE_TRAILER_STR, strlen(VLTSAVE_TRAILER_STR)))) {
|
||||
std::string fn = filename();
|
||||
std::string msg = std::string("Can't deserialize; file has wrong end-of-file signature");
|
||||
VL_FATAL_MT(fn.c_str(), 0, "", msg.c_str());
|
||||
close();
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Opening/Closing
|
||||
|
||||
void VerilatedSave::open(const char* filenamep) VL_MT_UNSAFE_ONE {
|
||||
m_assertOne.check();
|
||||
if (isOpen()) return;
|
||||
VL_DEBUG_IF(VL_DBG_MSGF("- save: opening save file %s\n", filenamep););
|
||||
|
||||
if (filenamep[0]=='|') {
|
||||
assert(0); // Not supported yet.
|
||||
} else {
|
||||
// cppcheck-suppress duplicateExpression
|
||||
m_fd = ::open(filenamep, O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK|O_CLOEXEC
|
||||
, 0666);
|
||||
if (m_fd<0) {
|
||||
// User code can check isOpen()
|
||||
m_isOpen = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_isOpen = true;
|
||||
m_filename = filenamep;
|
||||
m_cp = m_bufp;
|
||||
header();
|
||||
}
|
||||
|
||||
void VerilatedRestore::open(const char* filenamep) VL_MT_UNSAFE_ONE {
|
||||
m_assertOne.check();
|
||||
if (isOpen()) return;
|
||||
VL_DEBUG_IF(VL_DBG_MSGF("- restore: opening restore file %s\n", filenamep););
|
||||
|
||||
if (filenamep[0]=='|') {
|
||||
assert(0); // Not supported yet.
|
||||
} else {
|
||||
// cppcheck-suppress duplicateExpression
|
||||
m_fd = ::open(filenamep, O_CREAT|O_RDONLY|O_LARGEFILE|O_CLOEXEC
|
||||
, 0666);
|
||||
if (m_fd<0) {
|
||||
// User code can check isOpen()
|
||||
m_isOpen = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_isOpen = true;
|
||||
m_filename = filenamep;
|
||||
m_cp = m_bufp;
|
||||
m_endp = m_bufp;
|
||||
header();
|
||||
}
|
||||
|
||||
void VerilatedSave::close() VL_MT_UNSAFE_ONE {
|
||||
if (!isOpen()) return;
|
||||
trailer();
|
||||
flush();
|
||||
m_isOpen = false;
|
||||
::close(m_fd); // May get error, just ignore it
|
||||
}
|
||||
|
||||
void VerilatedRestore::close() VL_MT_UNSAFE_ONE {
|
||||
if (!isOpen()) return;
|
||||
trailer();
|
||||
flush();
|
||||
m_isOpen = false;
|
||||
::close(m_fd); // May get error, just ignore it
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Buffer management
|
||||
|
||||
void VerilatedSave::flush() VL_MT_UNSAFE_ONE {
|
||||
m_assertOne.check();
|
||||
if (VL_UNLIKELY(!isOpen())) return;
|
||||
vluint8_t* wp = m_bufp;
|
||||
while (1) {
|
||||
ssize_t remaining = (m_cp - wp);
|
||||
if (remaining==0) break;
|
||||
errno = 0;
|
||||
ssize_t got = ::write(m_fd, wp, remaining);
|
||||
if (got>0) {
|
||||
wp += got;
|
||||
} else if (got < 0) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
// write failed, presume error (perhaps out of disk space)
|
||||
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
|
||||
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||
close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
m_cp = m_bufp; // Reset buffer
|
||||
}
|
||||
|
||||
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
|
||||
m_endp = m_bufp + (m_endp - m_cp);
|
||||
m_cp = m_bufp; // Reset buffer
|
||||
// Read into buffer starting at m_endp
|
||||
while (1) {
|
||||
ssize_t remaining = (m_bufp+bufferSize() - m_endp);
|
||||
if (remaining==0) break;
|
||||
errno = 0;
|
||||
ssize_t got = ::read(m_fd, m_endp, remaining);
|
||||
if (got>0) {
|
||||
m_endp += got;
|
||||
} else if (got < 0) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
// write failed, presume error (perhaps out of disk space)
|
||||
std::string msg = std::string(__FUNCTION__)+": "+strerror(errno);
|
||||
VL_FATAL_MT("", 0, "", msg.c_str());
|
||||
close();
|
||||
break;
|
||||
}
|
||||
} else { // got==0, EOF
|
||||
// Fill buffer from here to end with NULLs so reader's don't
|
||||
// need to check eof each character.
|
||||
while (m_endp < m_bufp+bufferSize()) *m_endp++ = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Serialization of types
|
||||
@@ -0,0 +1,251 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2012-2019 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Save-restore serialization of verilated modules
|
||||
///
|
||||
//=============================================================================
|
||||
|
||||
#ifndef _VERILATED_SAVE_C_H_
|
||||
#define _VERILATED_SAVE_C_H_ 1
|
||||
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedSerialize - convert structures to a stream representation
|
||||
// This class is not thread safe, it must be called by a single thread
|
||||
|
||||
class VerilatedSerialize {
|
||||
protected:
|
||||
// MEMBERS
|
||||
// For speed, keep m_cp as the first member of this structure
|
||||
vluint8_t* m_cp; ///< Current pointer into m_bufp buffer
|
||||
vluint8_t* m_bufp; ///< Output buffer
|
||||
bool m_isOpen; ///< True indicates open file/stream
|
||||
std::string m_filename; ///< Filename, for error messages
|
||||
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
|
||||
|
||||
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
|
||||
inline static size_t bufferInsertSize() { return 16*1024; }
|
||||
|
||||
void header() VL_MT_UNSAFE_ONE;
|
||||
void trailer() VL_MT_UNSAFE_ONE;
|
||||
|
||||
// CONSTRUCTORS
|
||||
VL_UNCOPYABLE(VerilatedSerialize);
|
||||
public:
|
||||
VerilatedSerialize() {
|
||||
m_isOpen = false;
|
||||
m_bufp = new vluint8_t [bufferSize()];
|
||||
m_cp = m_bufp;
|
||||
}
|
||||
virtual ~VerilatedSerialize() {
|
||||
close();
|
||||
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
|
||||
}
|
||||
// METHODS
|
||||
bool isOpen() const { return m_isOpen; }
|
||||
std::string filename() const { return m_filename; }
|
||||
virtual void close() VL_MT_UNSAFE_ONE { flush(); }
|
||||
virtual void flush() VL_MT_UNSAFE_ONE {}
|
||||
inline VerilatedSerialize& write(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
||||
const vluint8_t* __restrict dp = (const vluint8_t* __restrict)datap;
|
||||
while (size) {
|
||||
bufferCheck();
|
||||
size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize();
|
||||
const vluint8_t* __restrict maxp = dp + blk;
|
||||
while (dp < maxp) *m_cp++ = *dp++;
|
||||
size -= blk;
|
||||
}
|
||||
return *this; // For function chaining
|
||||
}
|
||||
private:
|
||||
VerilatedSerialize& bufferCheck() VL_MT_UNSAFE_ONE {
|
||||
// Flush the write buffer if there's not enough space left for new information
|
||||
// We only call this once per vector, so we need enough slop for a very wide "b###" line
|
||||
if (VL_UNLIKELY(m_cp > (m_bufp+(bufferSize()-bufferInsertSize())))) {
|
||||
flush();
|
||||
}
|
||||
return *this; // For function chaining
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedDeserial - load structures from a stream representation
|
||||
// This class is not thread safe, it must be called by a single thread
|
||||
|
||||
class VerilatedDeserialize {
|
||||
protected:
|
||||
// MEMBERS
|
||||
// For speed, keep m_cp as the first member of this structure
|
||||
vluint8_t* m_cp; ///< Current pointer into m_bufp buffer
|
||||
vluint8_t* m_bufp; ///< Output buffer
|
||||
vluint8_t* m_endp; ///< Last valid byte in m_bufp buffer
|
||||
bool m_isOpen; ///< True indicates open file/stream
|
||||
std::string m_filename; ///< Filename, for error messages
|
||||
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
|
||||
|
||||
inline static size_t bufferSize() { return 256*1024; } // See below for slack calculation
|
||||
inline static size_t bufferInsertSize() { return 16*1024; }
|
||||
|
||||
virtual void fill() = 0;
|
||||
void header() VL_MT_UNSAFE_ONE;
|
||||
void trailer() VL_MT_UNSAFE_ONE;
|
||||
|
||||
// CONSTRUCTORS
|
||||
VL_UNCOPYABLE(VerilatedDeserialize);
|
||||
public:
|
||||
VerilatedDeserialize() {
|
||||
m_isOpen = false;
|
||||
m_bufp = new vluint8_t [bufferSize()];
|
||||
m_cp = m_bufp;
|
||||
m_endp = NULL;
|
||||
}
|
||||
virtual ~VerilatedDeserialize() {
|
||||
close();
|
||||
if (m_bufp) { delete m_bufp; m_bufp=NULL; }
|
||||
}
|
||||
// METHODS
|
||||
bool isOpen() const { return m_isOpen; }
|
||||
std::string filename() const { return m_filename; }
|
||||
virtual void close() VL_MT_UNSAFE_ONE { flush(); }
|
||||
virtual void flush() VL_MT_UNSAFE_ONE {}
|
||||
inline VerilatedDeserialize& read(void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE {
|
||||
vluint8_t* __restrict dp = (vluint8_t* __restrict)datap;
|
||||
while (size) {
|
||||
bufferCheck();
|
||||
size_t blk = size; if (blk>bufferInsertSize()) blk = bufferInsertSize();
|
||||
const vluint8_t* __restrict maxp = dp + blk;
|
||||
while (dp < maxp) *dp++ = *m_cp++;
|
||||
size -= blk;
|
||||
}
|
||||
return *this; // For function chaining
|
||||
}
|
||||
// Read a datum and compare with expected value
|
||||
VerilatedDeserialize& readAssert(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE;
|
||||
VerilatedDeserialize& readAssert(vluint64_t data) VL_MT_UNSAFE_ONE {
|
||||
return readAssert(&data, sizeof(data)); }
|
||||
private:
|
||||
bool readDiffers(const void* __restrict datap, size_t size) VL_MT_UNSAFE_ONE;
|
||||
VerilatedDeserialize& bufferCheck() VL_MT_UNSAFE_ONE {
|
||||
// Flush the write buffer if there's not enough space left for new information
|
||||
// We only call this once per vector, so we need enough slop for a very wide "b###" line
|
||||
if (VL_UNLIKELY((m_cp+bufferInsertSize()) > m_endp)) {
|
||||
fill();
|
||||
}
|
||||
return *this; // For function chaining
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedSave - serialize to a file
|
||||
// This class is not thread safe, it must be called by a single thread
|
||||
|
||||
class VerilatedSave : public VerilatedSerialize {
|
||||
private:
|
||||
int m_fd; ///< File descriptor we're writing to
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
VerilatedSave() { m_fd=-1; }
|
||||
virtual ~VerilatedSave() { close(); }
|
||||
// METHODS
|
||||
void open(const char* filenamep) VL_MT_UNSAFE_ONE; ///< Open the file; call isOpen() to see if errors
|
||||
void open(const std::string& filename) VL_MT_UNSAFE_ONE { open(filename.c_str()); }
|
||||
virtual void close() VL_MT_UNSAFE_ONE;
|
||||
virtual void flush() VL_MT_UNSAFE_ONE;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedRestore - deserialize from a file
|
||||
// This class is not thread safe, it must be called by a single thread
|
||||
|
||||
class VerilatedRestore : public VerilatedDeserialize {
|
||||
private:
|
||||
int m_fd; ///< File descriptor we're writing to
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
VerilatedRestore() { m_fd=-1; }
|
||||
virtual ~VerilatedRestore() { close(); }
|
||||
|
||||
// METHODS
|
||||
void open(const char* filenamep) VL_MT_UNSAFE_ONE; ///< Open the file; call isOpen() to see if errors
|
||||
void open(const std::string& filename) VL_MT_UNSAFE_ONE { open(filename.c_str()); }
|
||||
virtual void close() VL_MT_UNSAFE_ONE;
|
||||
virtual void flush() VL_MT_UNSAFE_ONE {}
|
||||
virtual void fill() VL_MT_UNSAFE_ONE;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint64_t& rhs) {
|
||||
return os.write(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint64_t& rhs){
|
||||
return os.read(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint32_t& rhs) {
|
||||
return os.write(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint32_t& rhs) {
|
||||
return os.read(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint16_t& rhs) {
|
||||
return os.write(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint16_t& rhs) {
|
||||
return os.read(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, vluint8_t& rhs) {
|
||||
return os.write(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, vluint8_t& rhs) {
|
||||
return os.read(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, bool& rhs) {
|
||||
return os.write(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, bool& rhs) {
|
||||
return os.read(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, double& rhs) {
|
||||
return os.write(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, double& rhs) {
|
||||
return os.read(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, float& rhs) {
|
||||
return os.write(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, float& rhs) {
|
||||
return os.read(&rhs, sizeof(rhs));
|
||||
}
|
||||
inline VerilatedSerialize& operator<<(VerilatedSerialize& os, std::string& rhs) {
|
||||
vluint32_t len = rhs.length();
|
||||
os<<len;
|
||||
return os.write(rhs.data(), len);
|
||||
}
|
||||
inline VerilatedDeserialize& operator>>(VerilatedDeserialize& os, std::string& rhs) {
|
||||
vluint32_t len = 0;
|
||||
os>>len;
|
||||
rhs.resize(len);
|
||||
return os.read((void*)rhs.data(), len);
|
||||
}
|
||||
|
||||
#endif // Guard
|
||||
@@ -0,0 +1,53 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2019 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//*************************************************************************
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilator: Common include for all Verilated SystemC files
|
||||
///
|
||||
/// This file is included automatically by Verilator at the top of
|
||||
/// all SystemC files it generates.
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//*************************************************************************
|
||||
|
||||
|
||||
#ifndef _VERILATED_SC_H_
|
||||
#define _VERILATED_SC_H_ 1 ///< Header Guard
|
||||
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include "systemc.h"
|
||||
|
||||
//=============================================================================
|
||||
// VL_SC_BV_DATAP
|
||||
// We want to get a pointer to m_data in the sc_bv_base class,
|
||||
// but it is protected. So make an exposing class, then use
|
||||
// cast magic to get at it. Saves patching get_datap in SystemC.
|
||||
// This class is thread safe (though most of SystemC is not).
|
||||
|
||||
#define VL_SC_BV_DATAP(bv) (VlScBvExposer::sp_datap(bv))
|
||||
class VlScBvExposer : public sc_bv_base {
|
||||
public:
|
||||
static const vluint32_t* sp_datap(const sc_bv_base& base) VL_MT_SAFE {
|
||||
return static_cast<const VlScBvExposer*>(&base)->sp_datatp(); }
|
||||
const vluint32_t* sp_datatp() const { return reinterpret_cast<vluint32_t*>(m_data); }
|
||||
// Above reads this protected element in sc_bv_base:
|
||||
// sc_digit* m_data; // data array
|
||||
};
|
||||
|
||||
//=========================================================================
|
||||
|
||||
#endif // Guard
|
||||
@@ -0,0 +1,226 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//*************************************************************************
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilator: Include to provide information about symbol inspection
|
||||
///
|
||||
/// This file is for inclusion by internal files that need to inspect
|
||||
/// specific symbols.
|
||||
///
|
||||
/// User routines wanting to inspect the symbol table should use
|
||||
/// verilated_syms.h instead.
|
||||
///
|
||||
/// These classes are thread safe, and read only.
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//*************************************************************************
|
||||
|
||||
|
||||
#ifndef _VERILATED_SYM_PROPS_H_
|
||||
#define _VERILATED_SYM_PROPS_H_ 1 ///< Header Guard
|
||||
|
||||
#include "verilatedos.h"
|
||||
|
||||
//===========================================================================
|
||||
/// Verilator range
|
||||
/// Thread safety: Assume is constructed only with model, then any number of readers
|
||||
|
||||
// See also V3Ast::VNumRange
|
||||
class VerilatedRange {
|
||||
int m_left;
|
||||
int m_right;
|
||||
protected:
|
||||
friend class VerilatedVarProps;
|
||||
friend class VerilatedScope;
|
||||
VerilatedRange() : m_left(0), m_right(0) {}
|
||||
VerilatedRange(int left, int right) : m_left(left), m_right(right) {}
|
||||
void init(int left, int right) { m_left=left; m_right=right; }
|
||||
public:
|
||||
~VerilatedRange() {}
|
||||
int left() const { return m_left; }
|
||||
int right() const { return m_right; }
|
||||
int low() const { return (m_left < m_right) ? m_left : m_right; }
|
||||
int high() const { return (m_left > m_right) ? m_left : m_right; }
|
||||
int elements() const {
|
||||
return (VL_LIKELY(m_left>=m_right) ? (m_left-m_right+1) : (m_right-m_left+1)); }
|
||||
int increment() const { return (m_left >= m_right) ? 1 : -1; }
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
/// Verilator variable
|
||||
/// Thread safety: Assume is constructed only with model, then any number of readers
|
||||
|
||||
class VerilatedVarProps {
|
||||
// TYPES
|
||||
enum { MAGIC = 0xddc4f829 };
|
||||
// MEMBERS
|
||||
const vluint32_t m_magic; // Magic number
|
||||
const VerilatedVarType m_vltype; // Data type
|
||||
const VerilatedVarFlags m_vlflags; // Direction
|
||||
const int m_pdims; // Packed dimensions
|
||||
const int m_udims; // Unpacked dimensions
|
||||
VerilatedRange m_packed; // Packed array range
|
||||
VerilatedRange m_unpacked[3]; // Unpacked array range
|
||||
// CONSTRUCTORS
|
||||
protected:
|
||||
friend class VerilatedScope;
|
||||
VerilatedVarProps(VerilatedVarType vltype, VerilatedVarFlags vlflags,
|
||||
int pdims, int udims)
|
||||
: m_magic(MAGIC), m_vltype(vltype), m_vlflags(vlflags), m_pdims(pdims), m_udims(udims) {}
|
||||
public:
|
||||
class Unpacked {};
|
||||
// Without packed
|
||||
VerilatedVarProps(VerilatedVarType vltype, int vlflags)
|
||||
: m_magic(MAGIC), m_vltype(vltype),
|
||||
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(0) { }
|
||||
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
|
||||
Unpacked, int u0l, int u0r)
|
||||
: m_magic(MAGIC), m_vltype(vltype),
|
||||
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(1) {
|
||||
m_unpacked[0].init(u0l, u0r); }
|
||||
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
|
||||
Unpacked, int u0l, int u0r, int u1l, int u1r)
|
||||
: m_magic(MAGIC), m_vltype(vltype),
|
||||
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(2) {
|
||||
m_unpacked[0].init(u0l, u0r); m_unpacked[1].init(u1l, u1r); }
|
||||
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
|
||||
Unpacked, int u0l, int u0r, int u1l, int u1r, int u2l, int u2r)
|
||||
: m_magic(MAGIC), m_vltype(vltype),
|
||||
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(0), m_udims(3) {
|
||||
m_unpacked[0].init(u0l, u0r); m_unpacked[1].init(u1l, u1r); m_unpacked[2].init(u2l, u2r); }
|
||||
// With packed
|
||||
class Packed {};
|
||||
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
|
||||
Packed, int pl, int pr)
|
||||
: m_magic(MAGIC), m_vltype(vltype),
|
||||
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(0), m_packed(pl,pr) { }
|
||||
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
|
||||
Packed, int pl, int pr,
|
||||
Unpacked, int u0l, int u0r)
|
||||
: m_magic(MAGIC), m_vltype(vltype),
|
||||
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(1), m_packed(pl,pr) {
|
||||
m_unpacked[0].init(u0l, u0r); }
|
||||
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
|
||||
Packed, int pl, int pr,
|
||||
Unpacked, int u0l, int u0r, int u1l, int u1r)
|
||||
: m_magic(MAGIC), m_vltype(vltype), m_vlflags(VerilatedVarFlags(vlflags)),
|
||||
m_pdims(1), m_udims(2), m_packed(pl,pr) {
|
||||
m_unpacked[0].init(u0l, u0r); m_unpacked[1].init(u1l, u1r); }
|
||||
VerilatedVarProps(VerilatedVarType vltype, int vlflags,
|
||||
Packed, int pl, int pr,
|
||||
Unpacked, int u0l, int u0r, int u1l, int u1r, int u2l, int u2r)
|
||||
: m_magic(MAGIC), m_vltype(vltype),
|
||||
m_vlflags(VerilatedVarFlags(vlflags)), m_pdims(1), m_udims(3), m_packed(pl,pr) {
|
||||
m_unpacked[0].init(u0l, u0r); m_unpacked[1].init(u1l, u1r); m_unpacked[2].init(u2l, u2r); }
|
||||
public:
|
||||
~VerilatedVarProps() {}
|
||||
// METHODS
|
||||
bool magicOk() const { return m_magic==MAGIC; }
|
||||
VerilatedVarType vltype() const { return m_vltype; }
|
||||
VerilatedVarFlags vldir() const {
|
||||
return static_cast<VerilatedVarFlags>(static_cast<int>(m_vlflags) & VLVF_MASK_DIR); }
|
||||
vluint32_t entSize() const;
|
||||
bool isPublicRW() const { return ((m_vlflags & VLVF_PUB_RW) != 0); }
|
||||
/// DPI compatible C standard layout
|
||||
bool isDpiCLayout() const { return ((m_vlflags & VLVF_DPI_CLAY) != 0); }
|
||||
int udims() const { return m_udims; }
|
||||
int dims() const { return m_pdims + m_udims; }
|
||||
const VerilatedRange& packed() const { return m_packed; }
|
||||
const VerilatedRange& unpacked() const { return m_unpacked[0]; }
|
||||
// DPI accessors
|
||||
int left(int dim) const {
|
||||
return dim==0 ? m_packed.left() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].left() : 0;
|
||||
}
|
||||
int right(int dim) const {
|
||||
return dim==0 ? m_packed.right() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].right() : 0;
|
||||
}
|
||||
int low(int dim) const {
|
||||
return dim==0 ? m_packed.low() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].low() : 0;
|
||||
}
|
||||
int high(int dim) const {
|
||||
return dim==0 ? m_packed.high() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].high() : 0;
|
||||
}
|
||||
int increment(int dim) const {
|
||||
return dim==0 ? m_packed.increment() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].increment() : 0;
|
||||
}
|
||||
int elements(int dim) const {
|
||||
return dim==0 ? m_packed.elements() : VL_LIKELY(dim>=1 && dim<=3) ? m_unpacked[dim-1].elements() : 0;
|
||||
}
|
||||
/// Total size in bytes (note DPI limited to 4GB)
|
||||
size_t totalSize() const;
|
||||
/// Adjust a data pointer to access a given array element, NuLL if something goes bad
|
||||
void* datapAdjustIndex(void* datap, int dim, int indx) const;
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
/// Verilator DPI open array variable
|
||||
|
||||
class VerilatedDpiOpenVar {
|
||||
// MEMBERS
|
||||
const VerilatedVarProps* m_propsp; // Variable properties
|
||||
void* m_datap; // Location of data (local to thread always, so safe)
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
VerilatedDpiOpenVar(const VerilatedVarProps* propsp, void* datap)
|
||||
: m_propsp(propsp), m_datap(datap) {}
|
||||
VerilatedDpiOpenVar(const VerilatedVarProps* propsp, const void* datap)
|
||||
: m_propsp(propsp), m_datap(const_cast<void*>(datap)) {}
|
||||
~VerilatedDpiOpenVar() {}
|
||||
// METHODS
|
||||
void* datap() const { return m_datap; }
|
||||
// METHODS - from VerilatedVarProps
|
||||
bool magicOk() const { return m_propsp->magicOk(); }
|
||||
VerilatedVarType vltype() const { return m_propsp->vltype(); }
|
||||
bool isDpiStdLayout() const { return m_propsp->isDpiCLayout(); }
|
||||
const VerilatedRange& packed() const { return m_propsp->packed(); }
|
||||
const VerilatedRange& unpacked() const { return m_propsp->unpacked(); }
|
||||
int udims() const { return m_propsp->udims(); }
|
||||
int left(int dim) const { return m_propsp->left(dim); }
|
||||
int right(int dim) const { return m_propsp->right(dim); }
|
||||
int low(int dim) const { return m_propsp->low(dim); }
|
||||
int high(int dim) const { return m_propsp->high(dim); }
|
||||
int increment(int dim) const { return m_propsp->increment(dim); }
|
||||
int elements(int dim) const { return m_propsp->elements(dim); }
|
||||
size_t totalSize() const { return m_propsp->totalSize(); }
|
||||
void* datapAdjustIndex(void* datap, int dim, int indx) const {
|
||||
return m_propsp->datapAdjustIndex(datap, dim, indx); }
|
||||
};
|
||||
|
||||
//===========================================================================
|
||||
/// Verilator variable
|
||||
/// Thread safety: Assume is constructed only with model, then any number of readers
|
||||
|
||||
class VerilatedVar : public VerilatedVarProps {
|
||||
// MEMBERS
|
||||
void* m_datap; // Location of data
|
||||
const char* m_namep; // Name - slowpath
|
||||
protected:
|
||||
friend class VerilatedScope;
|
||||
// CONSTRUCTORS
|
||||
VerilatedVar(const char* namep, void* datap,
|
||||
VerilatedVarType vltype, VerilatedVarFlags vlflags, int dims)
|
||||
: VerilatedVarProps(vltype, vlflags, (dims>0?1:0), ((dims>1)?dims-1:0))
|
||||
, m_datap(datap), m_namep(namep) {}
|
||||
public:
|
||||
~VerilatedVar() {}
|
||||
// ACCESSORS
|
||||
void* datap() const { return m_datap; }
|
||||
const VerilatedRange& range() const { return packed(); } // Deprecated
|
||||
const VerilatedRange& array() const { return unpacked(); } // Deprecated
|
||||
const char* name() const { return m_namep; }
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
@@ -0,0 +1,66 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//*************************************************************************
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilator: Include to allow symbol inspection
|
||||
///
|
||||
/// This file is for inclusion by files that need to inspect the symbol
|
||||
/// table. It is not included in verilated.h (instead see
|
||||
/// verilated_sym_props.h) as it requires some heavyweight C++ classes.
|
||||
///
|
||||
/// These classes are thread safe and read only. It is constructed only
|
||||
/// when a model is built (from the main thread).
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//*************************************************************************
|
||||
|
||||
|
||||
#ifndef _VERILATED_SYMS_H_
|
||||
#define _VERILATED_SYMS_H_ 1 ///< Header Guard
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated_heavy.h"
|
||||
#include "verilated_sym_props.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
//======================================================================
|
||||
/// Types
|
||||
|
||||
/// Class to sort maps keyed by const char*'s
|
||||
struct VerilatedCStrCmp {
|
||||
bool operator() (const char *a, const char *b) const {
|
||||
return std::strcmp(a, b) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
/// Map of sorted scope names to find associated scope class
|
||||
class VerilatedScopeNameMap
|
||||
: public std::map<const char*, const VerilatedScope*, VerilatedCStrCmp> {
|
||||
public:
|
||||
VerilatedScopeNameMap() {}
|
||||
~VerilatedScopeNameMap() {}
|
||||
};
|
||||
|
||||
/// Map of sorted variable names to find associated variable class
|
||||
class VerilatedVarNameMap
|
||||
: public std::map<const char*, VerilatedVar, VerilatedCStrCmp> {
|
||||
public:
|
||||
VerilatedVarNameMap() {}
|
||||
~VerilatedVarNameMap() {}
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
@@ -0,0 +1,230 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2012-2019 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Thread pool for verilated modules
|
||||
///
|
||||
//=============================================================================
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated_threads.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
std::atomic<vluint64_t> VlNotification::s_yields;
|
||||
|
||||
VL_THREAD_LOCAL VlThreadPool::ProfileTrace* VlThreadPool::t_profilep = NULL;
|
||||
|
||||
//=============================================================================
|
||||
// VlMTaskVertex
|
||||
|
||||
VlMTaskVertex::VlMTaskVertex(vluint32_t upstreamDepCount)
|
||||
: m_upstreamDepsDone(0),
|
||||
m_upstreamDepCount(upstreamDepCount) {
|
||||
assert(atomic_is_lock_free(&m_upstreamDepsDone));
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// VlWorkerThread
|
||||
|
||||
VlWorkerThread::VlWorkerThread(VlThreadPool* poolp, bool profiling)
|
||||
: m_poolp(poolp)
|
||||
, m_profiling(profiling)
|
||||
, m_exiting(false)
|
||||
// Must init this last -- after setting up fields that it might read:
|
||||
, m_cthread(startWorker, this) {}
|
||||
|
||||
VlWorkerThread::~VlWorkerThread() {
|
||||
m_exiting.store(true, std::memory_order_release);
|
||||
{
|
||||
VerilatedLockGuard lk(m_mutex);
|
||||
if (sleeping()) {
|
||||
wakeUp();
|
||||
}
|
||||
}
|
||||
// The thread should exit; join it.
|
||||
m_cthread.join();
|
||||
}
|
||||
|
||||
void VlWorkerThread::workerLoop() {
|
||||
if (VL_UNLIKELY(m_profiling)) {
|
||||
m_poolp->setupProfilingClientThread();
|
||||
}
|
||||
|
||||
VlNotification alarm;
|
||||
ExecRec work;
|
||||
work.m_fnp = NULL;
|
||||
|
||||
while (1) {
|
||||
bool sleep = false;
|
||||
if (VL_UNLIKELY(!work.m_fnp)) {
|
||||
// Look for work
|
||||
VerilatedLockGuard lk(m_mutex);
|
||||
if (VL_LIKELY(!m_ready.empty())) {
|
||||
dequeWork(&work);
|
||||
} else {
|
||||
// No work available, prepare to sleep. Pass alarm/work
|
||||
// into m_sleepAlarm so wakeUp will tall this function.
|
||||
//
|
||||
// Must modify m_sleepAlarm in the same critical section as
|
||||
// the check for ready work, otherwise we could race with
|
||||
// another thread enqueueing work and never be awoken.
|
||||
m_sleepAlarm.first = &alarm;
|
||||
m_sleepAlarm.second = &work;
|
||||
sleep = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Do this here, not above, to avoid a race with the destructor.
|
||||
if (VL_UNLIKELY(m_exiting.load(std::memory_order_acquire)))
|
||||
break;
|
||||
|
||||
if (VL_UNLIKELY(sleep)) {
|
||||
alarm.waitForNotification(); // ZZZzzzzz
|
||||
alarm.reset();
|
||||
}
|
||||
if (VL_LIKELY(work.m_fnp)) {
|
||||
work.m_fnp(work.m_evenCycle, work.m_sym);
|
||||
work.m_fnp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (VL_UNLIKELY(m_profiling)) {
|
||||
m_poolp->tearDownProfilingClientThread();
|
||||
}
|
||||
}
|
||||
|
||||
void VlWorkerThread::startWorker(VlWorkerThread* workerp) {
|
||||
workerp->workerLoop();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// VlThreadPool
|
||||
|
||||
VlThreadPool::VlThreadPool(int nThreads, bool profiling)
|
||||
: m_profiling(profiling) {
|
||||
// --threads N passes nThreads=N-1, as the "main" threads counts as 1
|
||||
unsigned cpus = std::thread::hardware_concurrency();
|
||||
if (cpus < nThreads+1) {
|
||||
VL_PRINTF_MT("%%Warning: System has %u CPUs but model Verilated with"
|
||||
" --threads %d; may run slow.\n", cpus, nThreads+1);
|
||||
}
|
||||
// Create'em
|
||||
for (int i=0; i<nThreads; ++i) {
|
||||
m_workers.push_back(new VlWorkerThread(this, profiling));
|
||||
}
|
||||
// Set up a profile buffer for the current thread too -- on the
|
||||
// assumption that it's the same thread that calls eval and may be
|
||||
// donated to run mtasks during the eval.
|
||||
if (VL_UNLIKELY(m_profiling)) {
|
||||
setupProfilingClientThread();
|
||||
}
|
||||
}
|
||||
|
||||
VlThreadPool::~VlThreadPool() {
|
||||
for (int i = 0; i < m_workers.size(); ++i) {
|
||||
// Each ~WorkerThread will wait for its thread to exit.
|
||||
delete m_workers[i];
|
||||
}
|
||||
if (VL_UNLIKELY(m_profiling)) {
|
||||
tearDownProfilingClientThread();
|
||||
}
|
||||
}
|
||||
|
||||
void VlThreadPool::tearDownProfilingClientThread() {
|
||||
assert(t_profilep);
|
||||
delete t_profilep;
|
||||
t_profilep = NULL;
|
||||
}
|
||||
|
||||
void VlThreadPool::setupProfilingClientThread() {
|
||||
assert(!t_profilep);
|
||||
t_profilep = new ProfileTrace;
|
||||
// Reserve some space in the thread-local profiling buffer;
|
||||
// try not to malloc while collecting profiling.
|
||||
t_profilep->reserve(4096);
|
||||
{
|
||||
VerilatedLockGuard lk(m_mutex);
|
||||
m_allProfiles.insert(t_profilep);
|
||||
}
|
||||
}
|
||||
|
||||
void VlThreadPool::profileAppendAll(const VlProfileRec& rec) {
|
||||
VerilatedLockGuard lk(m_mutex);
|
||||
for (ProfileSet::iterator it = m_allProfiles.begin();
|
||||
it != m_allProfiles.end(); ++it) {
|
||||
// Every thread's profile trace gets a copy of rec.
|
||||
(*it)->emplace_back(rec);
|
||||
}
|
||||
}
|
||||
|
||||
void VlThreadPool::profileDump(const char* filenamep, vluint64_t ticksElapsed) {
|
||||
VerilatedLockGuard lk(m_mutex);
|
||||
VL_DEBUG_IF(VL_DBG_MSGF("+prof+threads writing to '%s'\n", filenamep););
|
||||
|
||||
FILE* fp = fopen(filenamep, "w");
|
||||
if (VL_UNLIKELY(!fp)) {
|
||||
VL_FATAL_MT(filenamep, 0, "", "+prof+threads+file file not writable");
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO Perhaps merge with verilated_coverage output format, so can
|
||||
// have a common merging and reporting tool, etc.
|
||||
fprintf(fp, "VLPROFTHREAD 1.0 # Verilator thread profile dump version 1.0\n");
|
||||
fprintf(fp, "VLPROF arg --threads %" VL_PRI64 "u\n",
|
||||
vluint64_t(m_workers.size()+1));
|
||||
fprintf(fp, "VLPROF arg +verilator+prof+threads+start+%" VL_PRI64 "u\n",
|
||||
Verilated::profThreadsStart());
|
||||
fprintf(fp, "VLPROF arg +verilator+prof+threads+window+%u\n",
|
||||
Verilated::profThreadsWindow());
|
||||
fprintf(fp, "VLPROF stat yields %" VL_PRI64 "u\n",
|
||||
VlNotification::yields());
|
||||
|
||||
vluint32_t thread_id = 0;
|
||||
for (ProfileSet::iterator pit = m_allProfiles.begin();
|
||||
pit != m_allProfiles.end(); ++pit) {
|
||||
++thread_id;
|
||||
|
||||
bool printing = false; // False while in warmup phase
|
||||
for (ProfileTrace::iterator eit = (*pit)->begin();
|
||||
eit != (*pit)->end(); ++eit) {
|
||||
switch (eit->m_type) {
|
||||
case VlProfileRec::TYPE_BARRIER:
|
||||
printing = true;
|
||||
break;
|
||||
case VlProfileRec::TYPE_MTASK_RUN:
|
||||
if (!printing) break;
|
||||
fprintf(fp, "VLPROF mtask %d"
|
||||
" start %" VL_PRI64"u end %" VL_PRI64"u elapsed %" VL_PRI64 "u"
|
||||
" predict_time %u cpu %u on thread %u\n",
|
||||
eit->m_mtaskId,
|
||||
eit->m_startTime,
|
||||
eit->m_endTime,
|
||||
(eit->m_endTime - eit->m_startTime),
|
||||
eit->m_predictTime,
|
||||
eit->m_cpu,
|
||||
thread_id);
|
||||
break;
|
||||
default: assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
fprintf(fp, "VLPROF stat ticks %" VL_PRI64 "u\n",
|
||||
ticksElapsed);
|
||||
|
||||
fclose(fp);
|
||||
}
|
||||
@@ -0,0 +1,330 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2012-2019 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Thread pool and profiling for Verilated modules
|
||||
///
|
||||
//=============================================================================
|
||||
|
||||
#ifndef _VERILATED_THREADS_H_
|
||||
#define _VERILATED_THREADS_H_
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h" // for VerilatedMutex and clang annotations
|
||||
|
||||
#include <sched.h> // For sched_getcpu()
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#if defined(__APPLE__)
|
||||
# include <cpuid.h> // For __cpuid_count()
|
||||
#endif
|
||||
|
||||
// VlMTaskVertex and VlThreadpool will work with multiple symbol table types.
|
||||
// Since the type is opaque to VlMTaskVertex and VlThreadPool, represent it
|
||||
// as a void* here.
|
||||
typedef void* VlThrSymTab;
|
||||
|
||||
class VlNotification {
|
||||
// MEMBERS
|
||||
std::atomic<bool> m_notified; // Notification pending
|
||||
static std::atomic<vluint64_t> s_yields; // Statistics
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
VlNotification()
|
||||
: m_notified(false) {
|
||||
assert(atomic_is_lock_free(&m_notified));
|
||||
}
|
||||
~VlNotification() {}
|
||||
|
||||
// METHODS
|
||||
static vluint64_t yields() { return s_yields; }
|
||||
|
||||
// Block until notify() has occurred, then return.
|
||||
// If notify() has already occurred, return immediately.
|
||||
//
|
||||
// This is logically const: the object will remain in notified state
|
||||
// after WaitForNotification() returns, so you could notify more than
|
||||
// one thread of the same event.
|
||||
inline void waitForNotification() {
|
||||
unsigned ct = 0;
|
||||
while (VL_UNLIKELY(!notified())) {
|
||||
VL_CPU_RELAX();
|
||||
ct++;
|
||||
if (VL_UNLIKELY(ct > VL_LOCK_SPINS)) {
|
||||
ct = 0;
|
||||
++s_yields; // Statistics
|
||||
std::this_thread::yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The 'inline' keyword here means nothing to the compiler, it's
|
||||
// implicit on methods defined within the class body anyway.
|
||||
//
|
||||
// 'inline' is attached the this method, and others in this file,
|
||||
// to remind humans that some routines in this file are called many
|
||||
// times per cycle in threaded mode. Such routines should be
|
||||
// inlinable; that's why they're declared in the .h and not the .cpp.
|
||||
inline bool notified() {
|
||||
return m_notified.load(std::memory_order_acquire);
|
||||
}
|
||||
// Set notified state. If state is already notified,
|
||||
// it remains so.
|
||||
inline void notify() {
|
||||
m_notified.store(true, std::memory_order_release);
|
||||
}
|
||||
// Reset the state to un-notified state, which is also the
|
||||
// state of a new Notification object.
|
||||
inline void reset() {
|
||||
m_notified.store(false, std::memory_order_relaxed);
|
||||
}
|
||||
};
|
||||
|
||||
typedef void (*VlExecFnp)(bool, VlThrSymTab);
|
||||
|
||||
/// Track dependencies for a single MTask.
|
||||
class VlMTaskVertex {
|
||||
// MEMBERS
|
||||
|
||||
// On even cycles, _upstreamDepsDone increases as upstream
|
||||
// dependencies complete. When it reaches _upstreamDepCount,
|
||||
// this MTaskVertex is ready.
|
||||
//
|
||||
// On odd cycles, _upstreamDepsDone decreases as upstream
|
||||
// dependencies complete, and when it reaches zero this MTaskVertex
|
||||
// is ready.
|
||||
//
|
||||
// An atomic is smaller than a mutex, and lock-free.
|
||||
//
|
||||
// (Why does the size of this class matter? If an mtask has many
|
||||
// downstream mtasks to notify, we hope these will pack into a
|
||||
// small number of cache lines to reduce the cost of pointer chasing
|
||||
// during done-notification. Nobody's quantified that cost though.
|
||||
// If we were really serious about shrinking this class, we could
|
||||
// use 16-bit types here...)
|
||||
std::atomic<vluint32_t> m_upstreamDepsDone;
|
||||
const vluint32_t m_upstreamDepCount;
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
|
||||
// 'upstreamDepCount' is the number of upstream MTaskVertex's
|
||||
// that must notify this MTaskVertex before it will become ready
|
||||
// to run.
|
||||
explicit VlMTaskVertex(vluint32_t upstreamDepCount);
|
||||
~VlMTaskVertex() {}
|
||||
|
||||
// Upstream mtasks must call this when they complete.
|
||||
// Returns true when the current MTaskVertex becomes ready to execute,
|
||||
// false while it's still waiting on more dependencies.
|
||||
inline bool signalUpstreamDone(bool evenCycle) {
|
||||
if (evenCycle) {
|
||||
vluint32_t upstreamDepsDone
|
||||
= 1 + m_upstreamDepsDone.fetch_add(1, std::memory_order_release);
|
||||
assert(upstreamDepsDone <= m_upstreamDepCount);
|
||||
return (upstreamDepsDone == m_upstreamDepCount);
|
||||
} else {
|
||||
vluint32_t upstreamDepsDone_prev
|
||||
= m_upstreamDepsDone.fetch_sub(1, std::memory_order_release);
|
||||
assert(upstreamDepsDone_prev > 0);
|
||||
return (upstreamDepsDone_prev == 1);
|
||||
}
|
||||
}
|
||||
inline bool areUpstreamDepsDone(bool evenCycle) const {
|
||||
vluint32_t target = evenCycle ? m_upstreamDepCount : 0;
|
||||
return m_upstreamDepsDone.load(std::memory_order_acquire) == target;
|
||||
}
|
||||
inline void waitUntilUpstreamDone(bool evenCycle) const {
|
||||
while (VL_UNLIKELY(!areUpstreamDepsDone(evenCycle))) {
|
||||
VL_CPU_RELAX();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Profiling support
|
||||
class VlProfileRec {
|
||||
protected:
|
||||
friend class VlThreadPool;
|
||||
enum VlProfileE {
|
||||
TYPE_MTASK_RUN,
|
||||
TYPE_BARRIER
|
||||
};
|
||||
VlProfileE m_type; // Record type
|
||||
vluint32_t m_mtaskId; // Mtask we're logging
|
||||
vluint32_t m_predictTime; // How long scheduler predicted would take
|
||||
vluint64_t m_startTime; // Tick at start of execution
|
||||
vluint64_t m_endTime; // Tick at end of execution
|
||||
unsigned m_cpu; // Execution CPU number (at start anyways)
|
||||
public:
|
||||
class Barrier {};
|
||||
VlProfileRec() {}
|
||||
explicit VlProfileRec(Barrier) {
|
||||
m_type = TYPE_BARRIER;
|
||||
m_mtaskId = 0;
|
||||
m_predictTime = 0;
|
||||
m_startTime = 0;
|
||||
m_cpu = getcpu();
|
||||
}
|
||||
void startRecord(vluint64_t time, uint32_t mtask, uint32_t predict) {
|
||||
m_type = VlProfileRec::TYPE_MTASK_RUN;
|
||||
m_mtaskId = mtask;
|
||||
m_predictTime = predict;
|
||||
m_startTime = time;
|
||||
m_cpu = getcpu();
|
||||
}
|
||||
void endRecord(vluint64_t time) {
|
||||
m_endTime = time;
|
||||
}
|
||||
static int getcpu() { // Return current executing CPU
|
||||
#if defined(__linux)
|
||||
return sched_getcpu();
|
||||
#elif defined(__APPLE__)
|
||||
vluint32_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;
|
||||
}
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class VlThreadPool;
|
||||
|
||||
class VlWorkerThread {
|
||||
private:
|
||||
// TYPES
|
||||
struct ExecRec {
|
||||
VlExecFnp m_fnp; // Function to execute
|
||||
VlThrSymTab m_sym; // Symbol table to execute
|
||||
bool m_evenCycle; // Even/odd for flag alternation
|
||||
ExecRec() : m_fnp(NULL), m_sym(NULL), m_evenCycle(false) {}
|
||||
ExecRec(VlExecFnp fnp, bool evenCycle, VlThrSymTab sym)
|
||||
: m_fnp(fnp), m_sym(sym), m_evenCycle(evenCycle) {}
|
||||
};
|
||||
|
||||
// MEMBERS
|
||||
VerilatedMutex m_mutex;
|
||||
|
||||
// Why a vector? We expect the pending list to be very short, typically
|
||||
// 0 or 1 or 2, so popping from the front shouldn't be
|
||||
// expensive. Revisit if we ever have longer queues...
|
||||
std::vector<ExecRec> m_ready VL_GUARDED_BY(m_mutex);
|
||||
|
||||
VlThreadPool* m_poolp; // Our associated thread pool
|
||||
|
||||
// If values stored are non-NULL, the thread is asleep pending new
|
||||
// work. If the thread is not asleep, both parts of m_sleepAlarm must
|
||||
// be NULL.
|
||||
std::pair<VlNotification*, ExecRec*> m_sleepAlarm VL_GUARDED_BY(m_mutex);
|
||||
|
||||
bool m_profiling; // Is profiling enabled?
|
||||
std::atomic<bool> m_exiting; // Worker thread should exit
|
||||
std::thread m_cthread; // Underlying C++ thread record
|
||||
|
||||
VL_UNCOPYABLE(VlWorkerThread);
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
explicit VlWorkerThread(VlThreadPool* poolp, bool profiling);
|
||||
~VlWorkerThread();
|
||||
|
||||
// METHODS
|
||||
inline void dequeWork(ExecRec* workp) VL_REQUIRES(m_mutex) {
|
||||
// As noted above this is inefficient if our ready list is ever
|
||||
// long (but it shouldn't be)
|
||||
*workp = m_ready.front();
|
||||
m_ready.erase(m_ready.begin());
|
||||
}
|
||||
inline void wakeUp() VL_REQUIRES(m_mutex) {
|
||||
VlNotification* notifyp = m_sleepAlarm.first;
|
||||
m_sleepAlarm.first = NULL; // NULL+NULL means wake
|
||||
m_sleepAlarm.second = NULL;
|
||||
notifyp->notify();
|
||||
}
|
||||
inline bool sleeping() VL_REQUIRES(m_mutex) {
|
||||
return (m_sleepAlarm.first != NULL);
|
||||
}
|
||||
inline void addTask(VlExecFnp fnp, bool evenCycle, VlThrSymTab sym) {
|
||||
VerilatedLockGuard lk(m_mutex);
|
||||
m_ready.emplace_back(fnp, evenCycle, sym);
|
||||
if (VL_LIKELY(sleeping())) { // Generally queue is waiting for work
|
||||
// Awaken thread
|
||||
dequeWork(m_sleepAlarm.second);
|
||||
wakeUp();
|
||||
}
|
||||
}
|
||||
void workerLoop();
|
||||
static void startWorker(VlWorkerThread* workerp);
|
||||
};
|
||||
|
||||
class VlThreadPool {
|
||||
// TYPES
|
||||
typedef std::vector<VlProfileRec> ProfileTrace;
|
||||
typedef std::set<ProfileTrace*> ProfileSet;
|
||||
|
||||
// MEMBERS
|
||||
std::vector<VlWorkerThread*> m_workers; // our workers
|
||||
bool m_profiling; // is profiling enabled?
|
||||
|
||||
// Support profiling -- 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.
|
||||
static VL_THREAD_LOCAL ProfileTrace* t_profilep;
|
||||
ProfileSet m_allProfiles VL_GUARDED_BY(m_mutex);
|
||||
VerilatedMutex m_mutex;
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
// Construct a thread pool with 'nThreads' dedicated threads. The thread
|
||||
// pool will create these threads and make them available to execute tasks
|
||||
// via this->workerp(index)->addTask(...)
|
||||
VlThreadPool(int nThreads, bool profiling);
|
||||
~VlThreadPool();
|
||||
|
||||
// METHODS
|
||||
inline int numThreads() const {
|
||||
return m_workers.size();
|
||||
}
|
||||
inline VlWorkerThread* workerp(int index) {
|
||||
assert(index >= 0);
|
||||
assert(index < m_workers.size());
|
||||
return m_workers[index];
|
||||
}
|
||||
inline VlProfileRec* profileAppend() {
|
||||
t_profilep->emplace_back();
|
||||
return &(t_profilep->back());
|
||||
}
|
||||
void profileAppendAll(const VlProfileRec& rec);
|
||||
void profileDump(const char* filenamep, vluint64_t ticksElapsed);
|
||||
// In profiling mode, each executing thread must call
|
||||
// this once to setup profiling state:
|
||||
void setupProfilingClientThread();
|
||||
void tearDownProfilingClientThread();
|
||||
private:
|
||||
VL_UNCOPYABLE(VlThreadPool);
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,547 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
// DESCRIPTION: Verilator: pre-C++11 replacements for std::unordered_set
|
||||
// and std::unordered_map.
|
||||
//
|
||||
// Code available from: http://www.veripool.org/verilator
|
||||
//
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License
|
||||
// Version 2.0.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
|
||||
//*************************************************************************
|
||||
// This file has clones of the std::unordered_set and std::unordered_map
|
||||
// hash table types. They are here so that Verilator can use hash tables
|
||||
// in pre-C++11 compilers, and the same client code can link against the
|
||||
// std:: types when they are available.
|
||||
//
|
||||
// The implementations in this file do not implement the complete APIs
|
||||
// of the std:: types. Nor are they correct in every detail,
|
||||
// notably, the const_iterators do not enforce constness. We can extend
|
||||
// these implementations to cover more of the std API as needed.
|
||||
//
|
||||
// TODO: In the future, when Verilator requires C++11 to compile,
|
||||
// remove this entire file and switch to the std:: types.
|
||||
//
|
||||
//*************************************************************************
|
||||
|
||||
#ifndef _V3_UNORDERED_SET_MAP_H_
|
||||
#define _V3_UNORDERED_SET_MAP_H_
|
||||
|
||||
#include "verilatedos.h"
|
||||
|
||||
#include <list>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
// Abstract 'vl_hash' and 'vl_equal_to' templates.
|
||||
template <typename T> struct vl_hash {
|
||||
size_t operator()(const T& k) const;
|
||||
};
|
||||
|
||||
template <typename T> struct vl_equal_to {
|
||||
bool operator()(const T& a, const T& b) const;
|
||||
};
|
||||
|
||||
// Specializations of 'vl_hash' and 'vl_equal_to'.
|
||||
inline size_t vl_hash_bytes(const void* vbufp, size_t nbytes) {
|
||||
const vluint8_t* bufp = static_cast<const vluint8_t*>(vbufp);
|
||||
size_t hash = 0;
|
||||
for (size_t i = 0; i < nbytes; i++) {
|
||||
hash = bufp[i] + 31u * hash; // the K&R classic!
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
template <> inline size_t
|
||||
vl_hash<unsigned int>::operator()(const unsigned int& k) const {
|
||||
return k;
|
||||
}
|
||||
|
||||
template <> inline bool
|
||||
vl_equal_to<unsigned int>::operator()(const unsigned int& a,
|
||||
const unsigned int& b) const {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
template <> inline size_t
|
||||
vl_hash<std::string>::operator()(const std::string& k) const {
|
||||
return vl_hash_bytes(k.data(), k.size());
|
||||
}
|
||||
|
||||
template <> inline bool
|
||||
vl_equal_to<std::string>::operator()(const std::string& a,
|
||||
const std::string& b) const {
|
||||
// Don't scan the strings if the sizes are different.
|
||||
if (a.size() != b.size()) {
|
||||
return false;
|
||||
}
|
||||
return (0 == a.compare(b)); // Must scan.
|
||||
}
|
||||
|
||||
template <typename T> struct vl_hash<T*> {
|
||||
size_t operator()(T* kp) const {
|
||||
return ((sizeof(size_t) == sizeof(kp))
|
||||
? reinterpret_cast<size_t>(kp)
|
||||
: vl_hash_bytes(&kp, sizeof(kp)));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T> struct vl_equal_to<T*> {
|
||||
bool operator()(T* ap, T* bp) const {
|
||||
return ap == bp;
|
||||
}
|
||||
};
|
||||
|
||||
//===================================================================
|
||||
//
|
||||
/// Functional clone of the std::unordered_set hash table.
|
||||
template <class T_Key,
|
||||
class T_Hash = vl_hash<T_Key>,
|
||||
class T_Equal = vl_equal_to<T_Key> >
|
||||
class vl_unordered_set {
|
||||
public:
|
||||
// TYPES
|
||||
typedef std::list<T_Key> Bucket;
|
||||
enum RehashType {GROW, SHRINK};
|
||||
|
||||
template <class KK, class VV,
|
||||
class HH, class EQ> friend class vl_unordered_map;
|
||||
|
||||
class iterator {
|
||||
protected:
|
||||
// MEMBERS
|
||||
size_t m_bucketIdx; // Bucket this iterator points into
|
||||
typename Bucket::iterator m_bit; // Bucket-local iterator
|
||||
const vl_unordered_set* m_setp; // The containing set
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
iterator(size_t bucketIdx, typename Bucket::iterator bit,
|
||||
const vl_unordered_set* setp)
|
||||
: m_bucketIdx(bucketIdx), m_bit(bit), m_setp(setp) {}
|
||||
|
||||
// METHODS
|
||||
const T_Key& operator*() const {
|
||||
return *m_bit;
|
||||
}
|
||||
// This should really be 'const T_Key*' type for unordered_set,
|
||||
// however this iterator is shared with unordered_map whose
|
||||
// operator-> returns a non-const ValueType*, so keep this
|
||||
// non-const to avoid having to define a whole separate iterator
|
||||
// for unordered_map.
|
||||
T_Key* operator->() const {
|
||||
return &(*m_bit);
|
||||
}
|
||||
bool operator==(const iterator& other) const {
|
||||
return ((m_bucketIdx == other.m_bucketIdx)
|
||||
&& (m_bit == other.m_bit));
|
||||
}
|
||||
bool operator!=(const iterator& other) const {
|
||||
return (!this->operator==(other));
|
||||
}
|
||||
void advanceUntilValid() {
|
||||
while (1) {
|
||||
if (m_bit != m_setp->m_bucketsp[m_bucketIdx].end()) {
|
||||
// Valid iterator in this bucket; we're done.
|
||||
return;
|
||||
}
|
||||
|
||||
// Try the next bucket?
|
||||
m_bucketIdx++;
|
||||
if (m_bucketIdx == m_setp->numBuckets()) {
|
||||
// Ran past the end of buckets, set to end().
|
||||
*this = m_setp->end();
|
||||
return;
|
||||
}
|
||||
m_bit = m_setp->m_bucketsp[m_bucketIdx].begin();
|
||||
}
|
||||
}
|
||||
void operator++() {
|
||||
++m_bit;
|
||||
advanceUntilValid();
|
||||
}
|
||||
|
||||
typename Bucket::iterator bit() const { return m_bit; }
|
||||
};
|
||||
|
||||
// TODO: there's no real const enforcement on the 'const_iterator'.
|
||||
typedef iterator const_iterator;
|
||||
|
||||
private:
|
||||
// MEMBERS
|
||||
size_t m_numElements; // Number of entries present.
|
||||
size_t m_log2Buckets; // Log-base-2 of the number of buckets.
|
||||
mutable Bucket* m_bucketsp; // Hash table buckets. May be NULL;
|
||||
// // we'll allocate it on the fly when
|
||||
// // the first entries are created.
|
||||
Bucket m_emptyBucket; // A fake bucket, used to construct end().
|
||||
T_Hash m_hash; // Hash function provider.
|
||||
T_Equal m_equal; // Equal-to function provider.
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
vl_unordered_set()
|
||||
: m_numElements(0)
|
||||
, m_log2Buckets(initLog2Buckets())
|
||||
, m_bucketsp(NULL)
|
||||
, m_hash()
|
||||
, m_equal() { }
|
||||
|
||||
vl_unordered_set(const vl_unordered_set& other)
|
||||
: m_numElements(other.m_numElements)
|
||||
, m_log2Buckets(other.m_log2Buckets)
|
||||
, m_bucketsp(NULL)
|
||||
, m_hash()
|
||||
, m_equal() {
|
||||
if (other.m_bucketsp) {
|
||||
m_bucketsp = new Bucket[numBuckets()];
|
||||
for (size_t i = 0; i < numBuckets(); i++) {
|
||||
m_bucketsp[i] = other.m_bucketsp[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
~vl_unordered_set() {
|
||||
delete [] m_bucketsp; VL_DANGLING(m_bucketsp);
|
||||
}
|
||||
|
||||
vl_unordered_set& operator=(const vl_unordered_set& other) {
|
||||
if (this != &other) {
|
||||
clear();
|
||||
delete [] m_bucketsp;
|
||||
m_numElements = other.m_numElements;
|
||||
m_log2Buckets = other.m_log2Buckets;
|
||||
if (other.m_bucketsp) {
|
||||
m_bucketsp = new Bucket[numBuckets()];
|
||||
for (size_t i = 0; i < numBuckets(); i++) {
|
||||
m_bucketsp[i] = other.m_bucketsp[i];
|
||||
}
|
||||
} else {
|
||||
m_bucketsp = NULL;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// METHODS
|
||||
static size_t initLog2Buckets() { return 4; }
|
||||
|
||||
iterator begin() {
|
||||
if (m_numElements) {
|
||||
initBuckets();
|
||||
iterator result = iterator(0, m_bucketsp[0].begin(), this);
|
||||
result.advanceUntilValid();
|
||||
return result;
|
||||
}
|
||||
return end();
|
||||
}
|
||||
const_iterator begin() const {
|
||||
if (m_numElements) {
|
||||
initBuckets();
|
||||
const_iterator result = iterator(0, m_bucketsp[0].begin(), this);
|
||||
result.advanceUntilValid();
|
||||
return result;
|
||||
}
|
||||
return end();
|
||||
}
|
||||
const_iterator end() const {
|
||||
return iterator(VL_ULL(0xFFFFFFFFFFFFFFFF),
|
||||
const_cast<Bucket&>(m_emptyBucket).begin(), this);
|
||||
}
|
||||
|
||||
bool empty() const { return m_numElements == 0; }
|
||||
|
||||
size_t size() const { return m_numElements; }
|
||||
|
||||
size_t count(const T_Key& key) const {
|
||||
return (find(key) == end()) ? 0 : 1;
|
||||
}
|
||||
|
||||
size_t hashToBucket(size_t hashVal) const {
|
||||
return hashToBucket(hashVal, m_log2Buckets);
|
||||
}
|
||||
static size_t hashToBucket(size_t hashVal, unsigned log2Buckets) {
|
||||
// Fibonacci hashing
|
||||
// See https://probablydance.com/2018/06/16/fibonacci-hashing-the-optimization-that-the-world-forgot-or-a-better-alternative-to-integer-modulo/
|
||||
//
|
||||
// * The magic numbers below are UINT_MAX/phi where phi is the
|
||||
// golden ratio number (1.618...) for either 64- or 32-bit
|
||||
// values of UINT_MAX.
|
||||
//
|
||||
// * Fibonacci hashing mixes the result of the client's hash
|
||||
// function further. This permits the use of very fast client
|
||||
// hash funcs (like just returning the int or pointer value as
|
||||
// is!) and tolerates crappy client hash functions pretty well.
|
||||
size_t mult = hashVal * ((sizeof(size_t) == 8)
|
||||
? VL_ULL(11400714819323198485)
|
||||
: 2654435769lu);
|
||||
size_t result = (mult >> (((sizeof(size_t) == 8)
|
||||
? 64 : 32) - log2Buckets));
|
||||
return result;
|
||||
}
|
||||
|
||||
iterator find_internal(const T_Key& key, size_t& bucketIdxOut) {
|
||||
size_t hash = m_hash.operator()(key);
|
||||
bucketIdxOut = hashToBucket(hash);
|
||||
initBuckets();
|
||||
Bucket* bucketp = &m_bucketsp[bucketIdxOut];
|
||||
|
||||
for (typename Bucket::iterator it = bucketp->begin();
|
||||
it != bucketp->end(); ++it) {
|
||||
if (m_equal.operator()(*it, key)) {
|
||||
return iterator(bucketIdxOut, it, this);
|
||||
}
|
||||
}
|
||||
return end();
|
||||
}
|
||||
|
||||
const_iterator find(const T_Key& key) const {
|
||||
size_t bucketIdx;
|
||||
return const_cast<vl_unordered_set*>(this)->find_internal(key,
|
||||
bucketIdx);
|
||||
}
|
||||
|
||||
iterator find(const T_Key& key) {
|
||||
size_t bucketIdx;
|
||||
return find_internal(key, bucketIdx);
|
||||
}
|
||||
|
||||
std::pair<iterator, bool> insert(const T_Key &val) {
|
||||
size_t bucketIdx;
|
||||
iterator existIt = find_internal(val, bucketIdx);
|
||||
if (existIt != end()) {
|
||||
// Collision with existing element.
|
||||
//
|
||||
// An element may be inserted only if it is not
|
||||
// equal to an existing element. So fail.
|
||||
return std::pair<iterator, bool>(end(), false);
|
||||
}
|
||||
|
||||
// No collision, so insert it.
|
||||
m_numElements++;
|
||||
|
||||
m_bucketsp[bucketIdx].push_front(val);
|
||||
|
||||
// Compute result iterator. This pointer will be valid
|
||||
// if we don't rehash:
|
||||
iterator result_it(bucketIdx, m_bucketsp[bucketIdx].begin(), this);
|
||||
|
||||
if (needToRehash(GROW)) {
|
||||
rehash(GROW);
|
||||
// ... since we rehashed, do a lookup to get the result iterator.
|
||||
result_it = find(val);
|
||||
}
|
||||
|
||||
return std::pair<iterator, bool>(result_it, true);
|
||||
}
|
||||
|
||||
iterator erase(iterator it) {
|
||||
iterator next_it = it;
|
||||
++next_it;
|
||||
erase(*it);
|
||||
return next_it;
|
||||
}
|
||||
|
||||
size_t erase(const T_Key &key) {
|
||||
size_t bucketIdx;
|
||||
iterator it = find_internal(key, bucketIdx);
|
||||
if (it != end()) {
|
||||
m_bucketsp[bucketIdx].erase(it.bit());
|
||||
m_numElements--;
|
||||
// Rehashing to handle a shrinking data set is important
|
||||
// for the Scoreboard in V3Partition, which begins tracking
|
||||
// a huge number of vertices and then tracks a successively
|
||||
// smaller number over time.
|
||||
if (needToRehash(SHRINK)) {
|
||||
rehash(SHRINK);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clear() {
|
||||
if (m_bucketsp) {
|
||||
delete [] m_bucketsp;
|
||||
m_bucketsp = NULL;
|
||||
}
|
||||
m_numElements = 0;
|
||||
m_log2Buckets = initLog2Buckets();
|
||||
}
|
||||
|
||||
private:
|
||||
size_t numBuckets() const { return (VL_ULL(1) << m_log2Buckets); }
|
||||
|
||||
Bucket* getBucket(size_t idx) {
|
||||
initBuckets();
|
||||
return &m_bucketsp[idx];
|
||||
}
|
||||
|
||||
void initBuckets() const {
|
||||
if (!m_bucketsp) m_bucketsp = new Bucket[numBuckets()];
|
||||
}
|
||||
|
||||
bool needToRehash(RehashType rt) const {
|
||||
if (rt == GROW) {
|
||||
return ((4 * numBuckets()) < m_numElements);
|
||||
} else {
|
||||
return (numBuckets() > (4 * m_numElements));
|
||||
}
|
||||
}
|
||||
|
||||
void rehash(RehashType rt) {
|
||||
size_t new_log2Buckets;
|
||||
if (rt == GROW) {
|
||||
new_log2Buckets = m_log2Buckets + 2;
|
||||
} else {
|
||||
if (m_log2Buckets <= 4) {
|
||||
// On shrink, saturate m_log2Buckets at its
|
||||
// initial size of 2^4 == 16 buckets. Don't risk
|
||||
// underflowing!
|
||||
return;
|
||||
}
|
||||
new_log2Buckets = m_log2Buckets - 2;
|
||||
}
|
||||
|
||||
size_t new_num_buckets = VL_ULL(1) << new_log2Buckets;
|
||||
Bucket* new_bucketsp = new Bucket[new_num_buckets];
|
||||
|
||||
for (size_t i=0; i<numBuckets(); i++) {
|
||||
while (!m_bucketsp[i].empty()) {
|
||||
typename Bucket::iterator bit = m_bucketsp[i].begin();
|
||||
size_t hash = m_hash.operator()(*bit);
|
||||
size_t new_idx = hashToBucket(hash, new_log2Buckets);
|
||||
// Avoid mallocing one list elem and freeing another;
|
||||
// splice just moves it over.
|
||||
new_bucketsp[new_idx].splice(new_bucketsp[new_idx].begin(),
|
||||
m_bucketsp[i], bit);
|
||||
}
|
||||
}
|
||||
|
||||
delete[] m_bucketsp;
|
||||
m_bucketsp = new_bucketsp;
|
||||
m_log2Buckets = new_log2Buckets;
|
||||
}
|
||||
};
|
||||
|
||||
//===================================================================
|
||||
//
|
||||
/// Functional clone of the std::unordered_map hash table.
|
||||
template <class T_Key,
|
||||
class T_Value,
|
||||
class T_Hash = vl_hash<T_Key>,
|
||||
class T_Equal = vl_equal_to<T_Key> >
|
||||
class vl_unordered_map {
|
||||
private:
|
||||
// TYPES
|
||||
typedef std::pair<T_Key, T_Value> KeyValPair;
|
||||
|
||||
class KeyHash {
|
||||
private:
|
||||
T_Hash key_hash;
|
||||
public:
|
||||
KeyHash() {}
|
||||
size_t operator()(const KeyValPair& kv_pair) const {
|
||||
return key_hash.operator()(kv_pair.first);
|
||||
}
|
||||
};
|
||||
|
||||
class KeyEqual {
|
||||
private:
|
||||
T_Equal key_eq;
|
||||
public:
|
||||
KeyEqual() {}
|
||||
bool operator()(const KeyValPair& kv_a, const KeyValPair& kv_b) const {
|
||||
return key_eq.operator()(kv_a.first, kv_b.first);
|
||||
}
|
||||
};
|
||||
|
||||
// MEMBERS
|
||||
typedef vl_unordered_set<KeyValPair, KeyHash, KeyEqual> MapSet;
|
||||
MapSet m_set; // Wrap this vl_unordered_set which holds all state.
|
||||
|
||||
public:
|
||||
// CONSTRUCTORS
|
||||
vl_unordered_map() {}
|
||||
~vl_unordered_map() {}
|
||||
|
||||
typedef typename MapSet::iterator iterator;
|
||||
typedef typename MapSet::const_iterator const_iterator;
|
||||
|
||||
// METHODS
|
||||
iterator begin() { return m_set.begin(); }
|
||||
const_iterator begin() const { return m_set.begin(); }
|
||||
const_iterator end() const { return m_set.end(); }
|
||||
bool empty() const { return m_set.empty(); }
|
||||
iterator find(const T_Key& k) {
|
||||
// We can't assume that T_Value() is defined.
|
||||
// ie, this does not work:
|
||||
// return m_set.find(std::make_pair(k, T_Value()));
|
||||
|
||||
// So, do this instead:
|
||||
T_Hash mapHash;
|
||||
T_Equal mapEq;
|
||||
size_t hash = mapHash.operator()(k);
|
||||
size_t bucketIdxOut = m_set.hashToBucket(hash);
|
||||
typename MapSet::Bucket* bucketp = m_set.getBucket(bucketIdxOut);
|
||||
|
||||
for (typename MapSet::Bucket::iterator it = bucketp->begin();
|
||||
it != bucketp->end(); ++it) {
|
||||
if (mapEq.operator()(it->first, k)) {
|
||||
return iterator(bucketIdxOut, it, &m_set);
|
||||
}
|
||||
}
|
||||
return end();
|
||||
}
|
||||
const_iterator find(const T_Key& k) const {
|
||||
return const_cast<vl_unordered_map*>(this)->find(k);
|
||||
}
|
||||
std::pair<iterator, bool> insert(const KeyValPair& val) {
|
||||
return m_set.insert(val);
|
||||
}
|
||||
iterator erase(iterator it) { return m_set.erase(it); }
|
||||
size_t erase(const T_Key& k) {
|
||||
iterator it = find(k);
|
||||
if (it == end()) { return 0; }
|
||||
m_set.erase(it);
|
||||
return 1;
|
||||
}
|
||||
T_Value& operator[](const T_Key& k) {
|
||||
// Here we can assume T_Value() is defined, as
|
||||
// std::unordered_map::operator[] relies on it too.
|
||||
KeyValPair dummy = std::make_pair(k, T_Value());
|
||||
iterator it = m_set.find(dummy);
|
||||
if (it == m_set.end()) {
|
||||
it = m_set.insert(dummy).first;
|
||||
}
|
||||
// For the 'set', it's generally not safe to modify
|
||||
// the value after deref. For the 'map' though, we know
|
||||
// it's safe to modify the value field and we can allow it:
|
||||
return it->second;
|
||||
}
|
||||
T_Value& at(const T_Key& k) {
|
||||
iterator it = find(k);
|
||||
if (it == end()) { throw std::out_of_range("sorry"); }
|
||||
return it->second;
|
||||
}
|
||||
const T_Value& at(const T_Key& k) const {
|
||||
iterator it = find(k);
|
||||
if (it == end()) { throw std::out_of_range("sorry"); }
|
||||
return it->second;
|
||||
}
|
||||
void clear() { m_set.clear(); }
|
||||
size_t size() const { return m_set.size(); }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,802 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief C++ Tracing in VCD Format
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h"
|
||||
#include "verilated_vcd_c.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cerrno>
|
||||
#include <ctime>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
|
||||
# include <io.h>
|
||||
#else
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
// SPDIFF_ON
|
||||
|
||||
#ifndef O_LARGEFILE // For example on WIN32
|
||||
# define O_LARGEFILE 0
|
||||
#endif
|
||||
#ifndef O_NONBLOCK
|
||||
# define O_NONBLOCK 0
|
||||
#endif
|
||||
#ifndef O_CLOEXEC
|
||||
# define O_CLOEXEC 0
|
||||
#endif
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedVcdImp
|
||||
/// Base class to hold some static state
|
||||
/// This is an internally used class
|
||||
|
||||
class VerilatedVcdSingleton {
|
||||
private:
|
||||
typedef std::vector<VerilatedVcd*> VcdVec;
|
||||
struct Singleton {
|
||||
VerilatedMutex s_vcdMutex; ///< Protect the singleton
|
||||
VcdVec s_vcdVecp VL_GUARDED_BY(s_vcdMutex); ///< List of all created traces
|
||||
};
|
||||
static Singleton& singleton() { static Singleton s; return s; }
|
||||
public:
|
||||
static void pushVcd(VerilatedVcd* vcdp) VL_EXCLUDES(singleton().s_vcdMutex) {
|
||||
VerilatedLockGuard lock(singleton().s_vcdMutex);
|
||||
singleton().s_vcdVecp.push_back(vcdp);
|
||||
}
|
||||
static void removeVcd(const VerilatedVcd* vcdp) VL_EXCLUDES(singleton().s_vcdMutex) {
|
||||
VerilatedLockGuard lock(singleton().s_vcdMutex);
|
||||
VcdVec::iterator pos = find(singleton().s_vcdVecp.begin(), singleton().s_vcdVecp.end(), vcdp);
|
||||
if (pos != singleton().s_vcdVecp.end()) { singleton().s_vcdVecp.erase(pos); }
|
||||
}
|
||||
static void flush_all() VL_EXCLUDES(singleton().s_vcdMutex) VL_MT_UNSAFE_ONE {
|
||||
// Thread safety: Although this function is protected by a mutex so perhaps
|
||||
// in the future we can allow tracing in separate threads, vcdp->flush() assumes call from single thread
|
||||
VerilatedLockGuard lock(singleton().s_vcdMutex);
|
||||
for (VcdVec::const_iterator it=singleton().s_vcdVecp.begin(); it!=singleton().s_vcdVecp.end(); ++it) {
|
||||
VerilatedVcd* vcdp = *it;
|
||||
vcdp->flush();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedVcdCallInfo
|
||||
/// Internal callback routines for each module being traced.
|
||||
////
|
||||
/// Each module that wishes to be traced registers a set of
|
||||
/// callbacks stored in this class. When the trace file is being
|
||||
/// constructed, this class provides the callback routines to be executed.
|
||||
|
||||
class VerilatedVcdCallInfo {
|
||||
protected:
|
||||
friend class VerilatedVcd;
|
||||
VerilatedVcdCallback_t m_initcb; ///< Initialization Callback function
|
||||
VerilatedVcdCallback_t m_fullcb; ///< Full Dumping Callback function
|
||||
VerilatedVcdCallback_t m_changecb; ///< Incremental Dumping Callback function
|
||||
void* m_userthis; ///< Fake "this" for caller
|
||||
vluint32_t m_code; ///< Starting code number
|
||||
// CONSTRUCTORS
|
||||
VerilatedVcdCallInfo(VerilatedVcdCallback_t icb, VerilatedVcdCallback_t fcb,
|
||||
VerilatedVcdCallback_t changecb,
|
||||
void* ut, vluint32_t code)
|
||||
: m_initcb(icb), m_fullcb(fcb), m_changecb(changecb), m_userthis(ut), m_code(code) {};
|
||||
~VerilatedVcdCallInfo() {}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// VerilatedVcdFile
|
||||
|
||||
bool VerilatedVcdFile::open(const std::string& name) VL_MT_UNSAFE {
|
||||
m_fd = ::open(name.c_str(), O_CREAT|O_WRONLY|O_TRUNC|O_LARGEFILE|O_NONBLOCK|O_CLOEXEC, 0666);
|
||||
return (m_fd>=0);
|
||||
}
|
||||
|
||||
void VerilatedVcdFile::close() VL_MT_UNSAFE {
|
||||
::close(m_fd);
|
||||
}
|
||||
|
||||
ssize_t VerilatedVcdFile::write(const char* bufp, ssize_t len) VL_MT_UNSAFE {
|
||||
return ::write(m_fd, bufp, len);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
//=============================================================================
|
||||
// Opening/Closing
|
||||
|
||||
VerilatedVcd::VerilatedVcd(VerilatedVcdFile* filep)
|
||||
: m_isOpen(false), m_rolloverMB(0), m_modDepth(0), m_nextCode(1) {
|
||||
// Not in header to avoid link issue if header is included without this .cpp file
|
||||
m_fileNewed = (filep == NULL);
|
||||
m_filep = m_fileNewed ? new VerilatedVcdFile : filep;
|
||||
m_namemapp = NULL;
|
||||
m_timeRes = m_timeUnit = 1e-9;
|
||||
m_timeLastDump = 0;
|
||||
m_sigs_oldvalp = NULL;
|
||||
m_evcd = false;
|
||||
m_scopeEscape = '.'; // Backward compatibility
|
||||
m_fullDump = true;
|
||||
m_wrChunkSize = 8*1024;
|
||||
m_wrBufp = new char [m_wrChunkSize*8];
|
||||
m_wrFlushp = m_wrBufp + m_wrChunkSize * 6;
|
||||
m_writep = m_wrBufp;
|
||||
m_wroteBytes = 0;
|
||||
}
|
||||
|
||||
void VerilatedVcd::open(const char* filename) {
|
||||
m_assertOne.check();
|
||||
if (isOpen()) return;
|
||||
|
||||
// Set member variables
|
||||
m_filename = filename;
|
||||
VerilatedVcdSingleton::pushVcd(this);
|
||||
|
||||
// SPDIFF_OFF
|
||||
// Set callback so an early exit will flush us
|
||||
Verilated::flushCb(&flush_all);
|
||||
|
||||
// SPDIFF_ON
|
||||
openNext(m_rolloverMB!=0);
|
||||
if (!isOpen()) return;
|
||||
|
||||
dumpHeader();
|
||||
|
||||
// Allocate space now we know the number of codes
|
||||
if (!m_sigs_oldvalp) {
|
||||
m_sigs_oldvalp = new vluint32_t [m_nextCode+10];
|
||||
}
|
||||
|
||||
if (m_rolloverMB) {
|
||||
openNext(true);
|
||||
if (!isOpen()) return;
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatedVcd::openNext(bool incFilename) {
|
||||
// Open next filename in concat sequence, mangle filename if
|
||||
// incFilename is true.
|
||||
m_assertOne.check();
|
||||
closePrev(); // Close existing
|
||||
if (incFilename) {
|
||||
// Find _0000.{ext} in filename
|
||||
std::string name = m_filename;
|
||||
size_t pos = name.rfind('.');
|
||||
if (pos>8 && 0==strncmp("_cat",name.c_str()+pos-8,4)
|
||||
&& isdigit(name.c_str()[pos-4])
|
||||
&& isdigit(name.c_str()[pos-3])
|
||||
&& isdigit(name.c_str()[pos-2])
|
||||
&& isdigit(name.c_str()[pos-1])) {
|
||||
// Increment code.
|
||||
if ((++(name[pos-1])) > '9') {
|
||||
name[pos-1] = '0';
|
||||
if ((++(name[pos-2])) > '9') {
|
||||
name[pos-2] = '0';
|
||||
if ((++(name[pos-3])) > '9') {
|
||||
name[pos-3] = '0';
|
||||
if ((++(name[pos-4])) > '9') {
|
||||
name[pos-4] = '0';
|
||||
}}}}
|
||||
} else {
|
||||
// Append _cat0000
|
||||
name.insert(pos,"_cat0000");
|
||||
}
|
||||
m_filename = name;
|
||||
}
|
||||
if (m_filename[0]=='|') {
|
||||
assert(0); // Not supported yet.
|
||||
} else {
|
||||
// cppcheck-suppress duplicateExpression
|
||||
if (!m_filep->open(m_filename)) {
|
||||
// User code can check isOpen()
|
||||
m_isOpen = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_isOpen = true;
|
||||
m_fullDump = true; // First dump must be full
|
||||
m_wroteBytes = 0;
|
||||
}
|
||||
|
||||
void VerilatedVcd::makeNameMap() {
|
||||
// Take signal information from each module and build m_namemapp
|
||||
deleteNameMap();
|
||||
m_nextCode = 1;
|
||||
m_namemapp = new NameMap;
|
||||
for (vluint32_t ent = 0; ent< m_callbacks.size(); ent++) {
|
||||
VerilatedVcdCallInfo* cip = m_callbacks[ent];
|
||||
cip->m_code = m_nextCode;
|
||||
(cip->m_initcb)(this, cip->m_userthis, cip->m_code);
|
||||
}
|
||||
|
||||
// Though not speced, it's illegal to generate a vcd with signals
|
||||
// not under any module - it crashes at least two viewers.
|
||||
// If no scope was specified, prefix everything with a "top"
|
||||
// This comes from user instantiations with no name - IE Vtop("").
|
||||
bool nullScope = false;
|
||||
for (NameMap::const_iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
|
||||
const std::string& hiername = it->first;
|
||||
if (!hiername.empty() && hiername[0] == '\t') nullScope=true;
|
||||
}
|
||||
if (nullScope) {
|
||||
NameMap* newmapp = new NameMap;
|
||||
for (NameMap::const_iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
|
||||
const std::string& hiername = it->first;
|
||||
const std::string& decl = it->second;
|
||||
std::string newname = std::string("top");
|
||||
if (hiername[0] != '\t') newname += ' ';
|
||||
newname += hiername;
|
||||
newmapp->insert(std::make_pair(newname,decl));
|
||||
}
|
||||
deleteNameMap();
|
||||
m_namemapp = newmapp;
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatedVcd::deleteNameMap() {
|
||||
if (m_namemapp) { delete m_namemapp; m_namemapp=NULL; }
|
||||
}
|
||||
|
||||
VerilatedVcd::~VerilatedVcd() {
|
||||
close();
|
||||
if (m_wrBufp) { delete[] m_wrBufp; m_wrBufp=NULL; }
|
||||
if (m_sigs_oldvalp) { delete[] m_sigs_oldvalp; m_sigs_oldvalp=NULL; }
|
||||
deleteNameMap();
|
||||
if (m_filep && m_fileNewed) { delete m_filep; m_filep = NULL; }
|
||||
for (CallbackVec::const_iterator it=m_callbacks.begin(); it!=m_callbacks.end(); ++it) {
|
||||
delete (*it);
|
||||
}
|
||||
m_callbacks.clear();
|
||||
VerilatedVcdSingleton::removeVcd(this);
|
||||
}
|
||||
|
||||
void VerilatedVcd::closePrev() {
|
||||
// This function is on the flush() call path
|
||||
if (!isOpen()) return;
|
||||
|
||||
bufferFlush();
|
||||
m_isOpen = false;
|
||||
m_filep->close();
|
||||
}
|
||||
|
||||
void VerilatedVcd::closeErr() {
|
||||
// This function is on the flush() call path
|
||||
// Close due to an error. We might abort before even getting here,
|
||||
// depending on the definition of vl_fatal.
|
||||
if (!isOpen()) return;
|
||||
|
||||
// No buffer flush, just fclose
|
||||
m_isOpen = false;
|
||||
m_filep->close(); // May get error, just ignore it
|
||||
}
|
||||
|
||||
void VerilatedVcd::close() {
|
||||
// This function is on the flush() call path
|
||||
m_assertOne.check();
|
||||
if (!isOpen()) return;
|
||||
if (m_evcd) {
|
||||
printStr("$vcdclose ");
|
||||
printTime(m_timeLastDump);
|
||||
printStr(" $end\n");
|
||||
}
|
||||
closePrev();
|
||||
}
|
||||
|
||||
void VerilatedVcd::printStr(const char* str) {
|
||||
// Not fast...
|
||||
while (*str) {
|
||||
*m_writep++ = *str++;
|
||||
bufferCheck();
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatedVcd::printQuad(vluint64_t n) {
|
||||
char buf [100];
|
||||
sprintf(buf,"%" VL_PRI64 "u", n);
|
||||
printStr(buf);
|
||||
}
|
||||
|
||||
void VerilatedVcd::printTime(vluint64_t timeui) {
|
||||
// VCD file format specification does not allow non-integers for timestamps
|
||||
// Dinotrace doesn't mind, but Cadence vvision seems to choke
|
||||
if (VL_UNLIKELY(timeui < m_timeLastDump)) {
|
||||
timeui = m_timeLastDump;
|
||||
static VL_THREAD_LOCAL bool backTime = false;
|
||||
if (!backTime) {
|
||||
backTime = true;
|
||||
VL_PRINTF_MT("%%Warning: VCD time is moving backwards, wave file may be incorrect.\n");
|
||||
}
|
||||
}
|
||||
m_timeLastDump = timeui;
|
||||
printQuad(timeui);
|
||||
}
|
||||
|
||||
void VerilatedVcd::bufferResize(vluint64_t minsize) {
|
||||
// minsize is size of largest write. We buffer at least 8 times as much data,
|
||||
// writing when we are 3/4 full (with thus 2*minsize remaining free)
|
||||
if (VL_UNLIKELY(minsize > m_wrChunkSize)) {
|
||||
char* oldbufp = m_wrBufp;
|
||||
m_wrChunkSize = minsize*2;
|
||||
m_wrBufp = new char [m_wrChunkSize * 8];
|
||||
memcpy(m_wrBufp, oldbufp, m_writep - oldbufp);
|
||||
m_writep = m_wrBufp + (m_writep - oldbufp);
|
||||
m_wrFlushp = m_wrBufp + m_wrChunkSize * 6;
|
||||
delete [] oldbufp; oldbufp=NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatedVcd::bufferFlush() VL_MT_UNSAFE_ONE {
|
||||
// This function is on the flush() call path
|
||||
// We add output data to m_writep.
|
||||
// When it gets nearly full we dump it using this routine which calls write()
|
||||
// This is much faster than using buffered I/O
|
||||
m_assertOne.check();
|
||||
if (VL_UNLIKELY(!isOpen())) return;
|
||||
char* wp = m_wrBufp;
|
||||
while (1) {
|
||||
ssize_t remaining = (m_writep - wp);
|
||||
if (remaining==0) break;
|
||||
errno = 0;
|
||||
ssize_t got = m_filep->write(wp, remaining);
|
||||
if (got>0) {
|
||||
wp += got;
|
||||
m_wroteBytes += got;
|
||||
} else if (got < 0) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
// write failed, presume error (perhaps out of disk space)
|
||||
std::string msg = std::string("VerilatedVcd::bufferFlush: ")+strerror(errno);
|
||||
VL_FATAL_MT("",0,"",msg.c_str());
|
||||
closeErr();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reset buffer
|
||||
m_writep = m_wrBufp;
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Simple methods
|
||||
|
||||
void VerilatedVcd::set_time_unit(const char* unitp) {
|
||||
//cout<<" set_time_unit("<<unitp<<") == "<<timescaleToDouble(unitp)
|
||||
// <<" == "<<doubleToTimescale(timescaleToDouble(unitp))<<endl;
|
||||
m_timeUnit = timescaleToDouble(unitp);
|
||||
}
|
||||
|
||||
void VerilatedVcd::set_time_resolution(const char* unitp) {
|
||||
//cout<<"set_time_resolution("<<unitp<<") == "<<timescaleToDouble(unitp)
|
||||
// <<" == "<<doubleToTimescale(timescaleToDouble(unitp))<<endl;
|
||||
m_timeRes = timescaleToDouble(unitp);
|
||||
}
|
||||
|
||||
double VerilatedVcd::timescaleToDouble(const char* unitp) {
|
||||
char* endp;
|
||||
double value = strtod(unitp, &endp);
|
||||
if (value==0.0 && endp==unitp) value=1; // On error so we allow just "ns" to return 1e-9.
|
||||
unitp=endp;
|
||||
while (*unitp && isspace(*unitp)) unitp++;
|
||||
switch (*unitp) {
|
||||
case 's': value *= 1e1; break;
|
||||
case 'm': value *= 1e-3; break;
|
||||
case 'u': value *= 1e-6; break;
|
||||
case 'n': value *= 1e-9; break;
|
||||
case 'p': value *= 1e-12; break;
|
||||
case 'f': value *= 1e-15; break;
|
||||
case 'a': value *= 1e-18; break;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
std::string VerilatedVcd::doubleToTimescale(double value) {
|
||||
const char* suffixp = "s";
|
||||
if (value>=1e0) { suffixp="s"; value *= 1e0; }
|
||||
else if (value>=1e-3 ) { suffixp="ms"; value *= 1e3; }
|
||||
else if (value>=1e-6 ) { suffixp="us"; value *= 1e6; }
|
||||
else if (value>=1e-9 ) { suffixp="ns"; value *= 1e9; }
|
||||
else if (value>=1e-12) { suffixp="ps"; value *= 1e12; }
|
||||
else if (value>=1e-15) { suffixp="fs"; value *= 1e15; }
|
||||
else if (value>=1e-18) { suffixp="as"; value *= 1e18; }
|
||||
char valuestr[100]; sprintf(valuestr,"%3.0f%s", value, suffixp);
|
||||
return valuestr; // Gets converted to string, so no ref to stack
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Definitions
|
||||
|
||||
void VerilatedVcd::printIndent(int level_change) {
|
||||
if (level_change<0) m_modDepth += level_change;
|
||||
assert(m_modDepth>=0);
|
||||
for (int i=0; i<m_modDepth; i++) printStr(" ");
|
||||
if (level_change>0) m_modDepth += level_change;
|
||||
}
|
||||
|
||||
void VerilatedVcd::dumpHeader() {
|
||||
printStr("$version Generated by VerilatedVcd $end\n");
|
||||
time_t time_str = time(NULL);
|
||||
printStr("$date "); printStr(ctime(&time_str)); printStr(" $end\n");
|
||||
|
||||
printStr("$timescale ");
|
||||
const std::string& timeResStr = doubleToTimescale(m_timeRes);
|
||||
printStr(timeResStr.c_str());
|
||||
printStr(" $end\n");
|
||||
|
||||
makeNameMap();
|
||||
|
||||
// Signal header
|
||||
assert(m_modDepth==0);
|
||||
printIndent(1);
|
||||
printStr("\n");
|
||||
|
||||
// We detect the spaces in module names to determine hierarchy. This
|
||||
// allows signals to be declared without fixed ordering, which is
|
||||
// required as Verilog signals might be separately declared from
|
||||
// SC module signals.
|
||||
|
||||
// Print the signal names
|
||||
const char* lastName = "";
|
||||
for (NameMap::const_iterator it=m_namemapp->begin(); it!=m_namemapp->end(); ++it) {
|
||||
const std::string& hiernamestr = it->first;
|
||||
const std::string& decl = it->second;
|
||||
|
||||
// Determine difference between the old and new names
|
||||
const char* hiername = hiernamestr.c_str();
|
||||
const char* lp = lastName;
|
||||
const char* np = hiername;
|
||||
lastName = hiername;
|
||||
|
||||
// Skip common prefix, it must break at a space or tab
|
||||
for (; *np && (*np == *lp); np++, lp++) {}
|
||||
while (np!=hiername && *np && *np!=' ' && *np!='\t') { np--; lp--; }
|
||||
//printf("hier %s\n lp=%s\n np=%s\n",hiername,lp,np);
|
||||
|
||||
// Any extra spaces in last name are scope ups we need to do
|
||||
bool first = true;
|
||||
for (; *lp; lp++) {
|
||||
if (*lp==' ' || (first && *lp!='\t')) {
|
||||
printIndent(-1);
|
||||
printStr("$upscope $end\n");
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
|
||||
// Any new spaces are scope downs we need to do
|
||||
while (*np) {
|
||||
if (*np==' ') np++;
|
||||
if (*np=='\t') break; // tab means signal name starts
|
||||
printIndent(1);
|
||||
printStr("$scope module ");
|
||||
for (; *np && *np!=' ' && *np!='\t'; np++) {
|
||||
if (*np=='[') printStr("(");
|
||||
else if (*np==']') printStr(")");
|
||||
else *m_writep++=*np;
|
||||
}
|
||||
printStr(" $end\n");
|
||||
}
|
||||
|
||||
printIndent(0);
|
||||
printStr(decl.c_str());
|
||||
}
|
||||
|
||||
while (m_modDepth>1) {
|
||||
printIndent(-1);
|
||||
printStr("$upscope $end\n");
|
||||
}
|
||||
|
||||
printIndent(-1);
|
||||
printStr("$enddefinitions $end\n\n\n");
|
||||
assert(m_modDepth==0);
|
||||
|
||||
// Reclaim storage
|
||||
deleteNameMap();
|
||||
}
|
||||
|
||||
void VerilatedVcd::module(const std::string& name) {
|
||||
m_assertOne.check();
|
||||
m_modName = name;
|
||||
}
|
||||
|
||||
void VerilatedVcd::declare(vluint32_t code, const char* name, const char* wirep,
|
||||
int arraynum, bool tri, bool bussed, int msb, int lsb) {
|
||||
if (!code) { VL_FATAL_MT(__FILE__,__LINE__,"","Internal: internal trace problem, code 0 is illegal"); }
|
||||
|
||||
int bits = ((msb>lsb)?(msb-lsb):(lsb-msb))+1;
|
||||
int codesNeeded = 1+int(bits/32);
|
||||
if (tri) codesNeeded *= 2; // Space in change array for __en signals
|
||||
|
||||
// Make sure array is large enough
|
||||
m_nextCode = std::max(m_nextCode, code+codesNeeded);
|
||||
if (m_sigs.capacity() <= m_nextCode) {
|
||||
m_sigs.reserve(m_nextCode*2); // Power-of-2 allocation speeds things up
|
||||
}
|
||||
|
||||
// Make sure write buffer is large enough (one character per bit), plus header
|
||||
bufferResize(bits+1024);
|
||||
|
||||
// Save declaration info
|
||||
VerilatedVcdSig sig = VerilatedVcdSig(code, bits);
|
||||
m_sigs.push_back(sig);
|
||||
|
||||
// Split name into basename
|
||||
// Spaces and tabs aren't legal in VCD signal names, so:
|
||||
// Space separates each level of scope
|
||||
// Tab separates final scope from signal name
|
||||
// Tab sorts before spaces, so signals nicely will print before scopes
|
||||
// Note the hiername may be nothing, if so we'll add "\t{name}"
|
||||
std::string nameasstr = name;
|
||||
if (!m_modName.empty()) {
|
||||
nameasstr = m_modName+m_scopeEscape+nameasstr; // Optional ->module prefix
|
||||
}
|
||||
std::string hiername;
|
||||
std::string basename;
|
||||
for (const char* cp=nameasstr.c_str(); *cp; cp++) {
|
||||
if (isScopeEscape(*cp)) {
|
||||
// Ahh, we've just read a scope, not a basename
|
||||
if (!hiername.empty()) hiername += " ";
|
||||
hiername += basename;
|
||||
basename = "";
|
||||
} else {
|
||||
basename += *cp;
|
||||
}
|
||||
}
|
||||
hiername += "\t"+basename;
|
||||
|
||||
// Print reference
|
||||
std::string decl = "$var ";
|
||||
if (m_evcd) decl += "port"; else decl += wirep; // usually "wire"
|
||||
char buf [1000];
|
||||
sprintf(buf, " %2d ", bits);
|
||||
decl += buf;
|
||||
if (m_evcd) {
|
||||
sprintf(buf, "<%u", code);
|
||||
decl += buf;
|
||||
} else {
|
||||
decl += stringCode(code);
|
||||
}
|
||||
decl += " ";
|
||||
decl += basename;
|
||||
if (arraynum>=0) {
|
||||
sprintf(buf, "(%d)", arraynum);
|
||||
decl += buf;
|
||||
hiername += buf;
|
||||
}
|
||||
if (bussed) {
|
||||
sprintf(buf, " [%d:%d]", msb, lsb);
|
||||
decl += buf;
|
||||
}
|
||||
decl += " $end\n";
|
||||
m_namemapp->insert(std::make_pair(hiername,decl));
|
||||
}
|
||||
|
||||
void VerilatedVcd::declBit (vluint32_t code, const char* name, int arraynum)
|
||||
{ declare(code, name, "wire", arraynum, false, false, 0, 0); }
|
||||
void VerilatedVcd::declBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb)
|
||||
{ declare(code, name, "wire", arraynum, false, true, msb, lsb); }
|
||||
void VerilatedVcd::declQuad (vluint32_t code, const char* name, int arraynum, int msb, int lsb)
|
||||
{ declare(code, name, "wire", arraynum, false, true, msb, lsb); }
|
||||
void VerilatedVcd::declArray (vluint32_t code, const char* name, int arraynum, int msb, int lsb)
|
||||
{ declare(code, name, "wire", arraynum, false, true, msb, lsb); }
|
||||
void VerilatedVcd::declTriBit (vluint32_t code, const char* name, int arraynum)
|
||||
{ declare(code, name, "wire", arraynum, true, false, 0, 0); }
|
||||
void VerilatedVcd::declTriBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb)
|
||||
{ declare(code, name, "wire", arraynum, true, true, msb, lsb); }
|
||||
void VerilatedVcd::declTriQuad (vluint32_t code, const char* name, int arraynum, int msb, int lsb)
|
||||
{ declare(code, name, "wire", arraynum, true, true, msb, lsb); }
|
||||
void VerilatedVcd::declTriArray (vluint32_t code, const char* name, int arraynum, int msb, int lsb)
|
||||
{ declare(code, name, "wire", arraynum, true, true, msb, lsb); }
|
||||
void VerilatedVcd::declFloat (vluint32_t code, const char* name, int arraynum)
|
||||
{ declare(code, name, "real", arraynum, false, false, 31, 0); }
|
||||
void VerilatedVcd::declDouble (vluint32_t code, const char* name, int arraynum)
|
||||
{ declare(code, name, "real", arraynum, false, false, 63, 0); }
|
||||
|
||||
//=============================================================================
|
||||
|
||||
void VerilatedVcd::fullDouble(vluint32_t code, const double newval) {
|
||||
// cppcheck-suppress invalidPointerCast
|
||||
(*(reinterpret_cast<double*>(&m_sigs_oldvalp[code]))) = newval;
|
||||
// Buffer can't overflow before sprintf; we sized during declaration
|
||||
sprintf(m_writep, "r%.16g", newval);
|
||||
m_writep += strlen(m_writep);
|
||||
*m_writep++=' '; printCode(code); *m_writep++='\n';
|
||||
bufferCheck();
|
||||
}
|
||||
void VerilatedVcd::fullFloat(vluint32_t code, const float newval) {
|
||||
// cppcheck-suppress invalidPointerCast
|
||||
(*(reinterpret_cast<float*>(&m_sigs_oldvalp[code]))) = newval;
|
||||
// Buffer can't overflow before sprintf; we sized during declaration
|
||||
sprintf(m_writep, "r%.16g", static_cast<double>(newval));
|
||||
m_writep += strlen(m_writep);
|
||||
*m_writep++=' '; printCode(code); *m_writep++='\n';
|
||||
bufferCheck();
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Callbacks
|
||||
|
||||
void VerilatedVcd::addCallback(
|
||||
VerilatedVcdCallback_t initcb, VerilatedVcdCallback_t fullcb, VerilatedVcdCallback_t changecb,
|
||||
void* userthis) VL_MT_UNSAFE_ONE
|
||||
{
|
||||
m_assertOne.check();
|
||||
if (VL_UNLIKELY(isOpen())) {
|
||||
std::string msg = std::string("Internal: ")+__FILE__+"::"+__FUNCTION__+" called with already open file";
|
||||
VL_FATAL_MT(__FILE__,__LINE__,"",msg.c_str());
|
||||
}
|
||||
VerilatedVcdCallInfo* vci = new VerilatedVcdCallInfo(initcb, fullcb, changecb, userthis, m_nextCode);
|
||||
m_callbacks.push_back(vci);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
// Dumping
|
||||
|
||||
void VerilatedVcd::dumpFull(vluint64_t timeui) {
|
||||
m_assertOne.check();
|
||||
dumpPrep(timeui);
|
||||
Verilated::quiesce();
|
||||
for (vluint32_t ent = 0; ent< m_callbacks.size(); ent++) {
|
||||
VerilatedVcdCallInfo* cip = m_callbacks[ent];
|
||||
(cip->m_fullcb)(this, cip->m_userthis, cip->m_code);
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatedVcd::dump(vluint64_t timeui) {
|
||||
m_assertOne.check();
|
||||
if (!isOpen()) return;
|
||||
if (VL_UNLIKELY(m_fullDump)) {
|
||||
m_fullDump = false; // No need for more full dumps
|
||||
dumpFull(timeui);
|
||||
return;
|
||||
}
|
||||
if (VL_UNLIKELY(m_rolloverMB && m_wroteBytes > this->m_rolloverMB)) {
|
||||
openNext(true);
|
||||
if (!isOpen()) return;
|
||||
}
|
||||
dumpPrep(timeui);
|
||||
Verilated::quiesce();
|
||||
for (vluint32_t ent = 0; ent< m_callbacks.size(); ++ent) {
|
||||
VerilatedVcdCallInfo* cip = m_callbacks[ent];
|
||||
(cip->m_changecb)(this, cip->m_userthis, cip->m_code);
|
||||
}
|
||||
}
|
||||
|
||||
void VerilatedVcd::dumpPrep(vluint64_t timeui) {
|
||||
printStr("#");
|
||||
printTime(timeui);
|
||||
printStr("\n");
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
// Static members
|
||||
|
||||
void VerilatedVcd::flush_all() VL_MT_UNSAFE_ONE {
|
||||
VerilatedVcdSingleton::flush_all();
|
||||
}
|
||||
|
||||
//======================================================================
|
||||
//======================================================================
|
||||
//======================================================================
|
||||
|
||||
#ifdef VERILATED_VCD_TEST
|
||||
vluint32_t v1, v2, s1, s2[3];
|
||||
vluint32_t tri96[3];
|
||||
vluint32_t tri96__tri[3];
|
||||
vluint8_t ch;
|
||||
vluint64_t timestamp = 1;
|
||||
double doub = 0;
|
||||
|
||||
void vcdInit(VerilatedVcd* vcdp, void* userthis, vluint32_t code) {
|
||||
vcdp->scopeEscape('.');
|
||||
vcdp->module("top");
|
||||
vcdp->declBus(0x2, "v1",-1,5,1);
|
||||
vcdp->declBus(0x3, "v2",-1,6,0);
|
||||
vcdp->module("top.sub1");
|
||||
vcdp->declBit(0x4, "s1",-1);
|
||||
vcdp->declBit(0x5, "ch",-1);
|
||||
vcdp->module("top.sub2");
|
||||
vcdp->declArray(0x6, "s2",-1, 40,3);
|
||||
// Note need to add 3 for next code.
|
||||
vcdp->module("top2");
|
||||
vcdp->declBus(0x2, "t2v1",-1,4,1);
|
||||
vcdp->declTriBit (0x10, "io1", -1);
|
||||
vcdp->declTriBus (0x12, "io5", -1,4,0);
|
||||
vcdp->declTriArray(0x16, "io96",-1,95,0);
|
||||
// Note need to add 6 for next code.
|
||||
vcdp->declDouble (0x1c, "doub",-1);
|
||||
// Note need to add 2 for next code.
|
||||
}
|
||||
|
||||
void vcdFull(VerilatedVcd* vcdp, void* userthis, vluint32_t code) {
|
||||
vcdp->fullBus (0x2, v1,5);
|
||||
vcdp->fullBus (0x3, v2,7);
|
||||
vcdp->fullBit (0x4, s1);
|
||||
vcdp->fullBus (0x5, ch,2);
|
||||
vcdp->fullArray(0x6, &s2[0], 38);
|
||||
vcdp->fullTriBit (0x10, tri96[0]&1, tri96__tri[0]&1);
|
||||
vcdp->fullTriBus (0x12, tri96[0]&0x1f, tri96__tri[0]&0x1f, 5);
|
||||
vcdp->fullTriArray(0x16, tri96, tri96__tri, 96);
|
||||
vcdp->fullDouble(0x1c, doub);
|
||||
}
|
||||
|
||||
void vcdChange(VerilatedVcd* vcdp, void* userthis, vluint32_t code) {
|
||||
vcdp->chgBus (0x2, v1,5);
|
||||
vcdp->chgBus (0x3, v2,7);
|
||||
vcdp->chgBit (0x4, s1);
|
||||
vcdp->chgBus (0x5, ch,2);
|
||||
vcdp->chgArray(0x6, &s2[0], 38);
|
||||
vcdp->chgTriBit (0x10, tri96[0]&1, tri96__tri[0]&1);
|
||||
vcdp->chgTriBus (0x12, tri96[0]&0x1f, tri96__tri[0]&0x1f, 5);
|
||||
vcdp->chgTriArray (0x16, tri96, tri96__tri, 96);
|
||||
vcdp->chgDouble (0x1c, doub);
|
||||
}
|
||||
|
||||
main() {
|
||||
cout<<"test: O_LARGEFILE="<<O_LARGEFILE<<endl;
|
||||
|
||||
v1 = v2 = s1 = 0;
|
||||
s2[0] = s2[1] = s2[2] = 0;
|
||||
tri96[2] = tri96[1] = tri96[0] = 0;
|
||||
tri96__tri[2] = tri96__tri[1] = tri96__tri[0] = ~0;
|
||||
ch = 0;
|
||||
doub = 0;
|
||||
{
|
||||
VerilatedVcdC* vcdp = new VerilatedVcdC;
|
||||
vcdp->spTrace()->addCallback(&vcdInit, &vcdFull, &vcdChange, 0);
|
||||
vcdp->open("test.vcd");
|
||||
// Dumping
|
||||
vcdp->dump(timestamp++);
|
||||
v1 = 0xfff;
|
||||
tri96[2] = 4; tri96[1] = 2; tri96[0] = 1;
|
||||
tri96__tri[2] = tri96__tri[1] = tri96__tri[0] = ~0; // Still tri
|
||||
doub = 1.5;
|
||||
vcdp->dump(timestamp++);
|
||||
v2 = 0x1;
|
||||
s2[1] = 2;
|
||||
tri96__tri[2] = tri96__tri[1] = tri96__tri[0] = 0; // enable w/o data change
|
||||
doub = -1.66e13;
|
||||
vcdp->dump(timestamp++);
|
||||
ch = 2;
|
||||
tri96[2] = ~4; tri96[1] = ~2; tri96[0] = ~1;
|
||||
doub = -3.33e-13;
|
||||
vcdp->dump(timestamp++);
|
||||
vcdp->dump(timestamp++);
|
||||
# ifdef VERILATED_VCD_TEST_64BIT
|
||||
vluint64_t bytesPerDump = 15ULL;
|
||||
for (vluint64_t i=0; i<((1ULL<<32) / bytesPerDump); i++) {
|
||||
v1 = i;
|
||||
vcdp->dump(timestamp++);
|
||||
}
|
||||
# endif
|
||||
vcdp->close();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//********************************************************************
|
||||
// Local Variables:
|
||||
// compile-command: "mkdir -p ../test_dir && cd ../test_dir && c++ -DVERILATED_VCD_TEST ../src/verilated_vcd_c.cpp -o verilated_vcd_c && ./verilated_vcd_c && cat test.vcd"
|
||||
// End:
|
||||
@@ -0,0 +1,460 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief C++ Tracing in VCD Format
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
#ifndef _VERILATED_VCD_C_H_
|
||||
#define _VERILATED_VCD_C_H_ 1
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h"
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class VerilatedVcd;
|
||||
class VerilatedVcdCallInfo;
|
||||
|
||||
// SPDIFF_ON
|
||||
//=============================================================================
|
||||
// VerilatedFile
|
||||
/// File handling routines, which can be overrode for e.g. socket I/O
|
||||
|
||||
class VerilatedVcdFile {
|
||||
private:
|
||||
int m_fd; ///< File descriptor we're writing to
|
||||
public:
|
||||
// METHODS
|
||||
VerilatedVcdFile() : m_fd(0) {}
|
||||
virtual ~VerilatedVcdFile() {}
|
||||
virtual bool open(const std::string& name) VL_MT_UNSAFE;
|
||||
virtual void close() VL_MT_UNSAFE;
|
||||
virtual ssize_t write(const char* bufp, ssize_t len) VL_MT_UNSAFE;
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedVcdSig
|
||||
/// Internal data on one signal being traced.
|
||||
|
||||
class VerilatedVcdSig {
|
||||
protected:
|
||||
friend class VerilatedVcd;
|
||||
vluint32_t m_code; ///< VCD file code number
|
||||
int m_bits; ///< Size of value in bits
|
||||
VerilatedVcdSig(vluint32_t code, int bits)
|
||||
: m_code(code), m_bits(bits) {}
|
||||
public:
|
||||
~VerilatedVcdSig() {}
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
|
||||
typedef void (*VerilatedVcdCallback_t)(VerilatedVcd* vcdp, void* userthis, vluint32_t code);
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedVcd
|
||||
/// Base class to create a Verilator VCD dump
|
||||
/// This is an internally used class - see VerilatedVcdC for what to call from applications
|
||||
|
||||
class VerilatedVcd {
|
||||
private:
|
||||
VerilatedVcdFile* m_filep; ///< File we're writing to
|
||||
bool m_fileNewed; ///< m_filep needs destruction
|
||||
bool m_isOpen; ///< True indicates open file
|
||||
bool m_evcd; ///< True for evcd format
|
||||
std::string m_filename; ///< Filename we're writing to (if open)
|
||||
vluint64_t m_rolloverMB; ///< MB of file size to rollover at
|
||||
char m_scopeEscape; ///< Character to separate scope components
|
||||
int m_modDepth; ///< Depth of module hierarchy
|
||||
bool m_fullDump; ///< True indicates dump ignoring if changed
|
||||
vluint32_t m_nextCode; ///< Next code number to assign
|
||||
std::string m_modName; ///< Module name being traced now
|
||||
double m_timeRes; ///< Time resolution (ns/ms etc)
|
||||
double m_timeUnit; ///< Time units (ns/ms etc)
|
||||
vluint64_t m_timeLastDump; ///< Last time we did a dump
|
||||
|
||||
char* m_wrBufp; ///< Output buffer
|
||||
char* m_wrFlushp; ///< Output buffer flush trigger location
|
||||
char* m_writep; ///< Write pointer into output buffer
|
||||
vluint64_t m_wrChunkSize; ///< Output buffer size
|
||||
vluint64_t m_wroteBytes; ///< Number of bytes written to this file
|
||||
|
||||
vluint32_t* m_sigs_oldvalp; ///< Pointer to old signal values
|
||||
typedef std::vector<VerilatedVcdSig> SigVec;
|
||||
SigVec m_sigs; ///< Pointer to signal information
|
||||
typedef std::vector<VerilatedVcdCallInfo*> CallbackVec;
|
||||
CallbackVec m_callbacks; ///< Routines to perform dumping
|
||||
typedef std::map<std::string,std::string> NameMap;
|
||||
NameMap* m_namemapp; ///< List of names for the header
|
||||
|
||||
VerilatedAssertOneThread m_assertOne; ///< Assert only called from single thread
|
||||
|
||||
void bufferResize(vluint64_t minsize);
|
||||
void bufferFlush() VL_MT_UNSAFE_ONE;
|
||||
inline void bufferCheck() {
|
||||
// Flush the write buffer if there's not enough space left for new information
|
||||
// We only call this once per vector, so we need enough slop for a very wide "b###" line
|
||||
if (VL_UNLIKELY(m_writep > m_wrFlushp)) {
|
||||
bufferFlush();
|
||||
}
|
||||
}
|
||||
void closePrev();
|
||||
void closeErr();
|
||||
void openNext();
|
||||
void makeNameMap();
|
||||
void deleteNameMap();
|
||||
void printIndent(int level_change);
|
||||
void printStr(const char* str);
|
||||
void printQuad(vluint64_t n);
|
||||
void printTime(vluint64_t timeui);
|
||||
void declare(vluint32_t code, const char* name, const char* wirep,
|
||||
int arraynum, bool tri, bool bussed, int msb, int lsb);
|
||||
|
||||
void dumpHeader();
|
||||
void dumpPrep(vluint64_t timeui);
|
||||
void dumpFull(vluint64_t timeui);
|
||||
// cppcheck-suppress functionConst
|
||||
void dumpDone();
|
||||
inline void printCode(vluint32_t code) {
|
||||
*m_writep++ = static_cast<char>('!' + code % 94);
|
||||
code /= 94;
|
||||
while (code) {
|
||||
code--;
|
||||
*m_writep++ = static_cast<char>('!' + code % 94);
|
||||
code /= 94;
|
||||
}
|
||||
}
|
||||
static std::string stringCode(vluint32_t code) VL_PURE {
|
||||
std::string out;
|
||||
out += static_cast<char>('!' + code % 94);
|
||||
code /= 94;
|
||||
while (code) {
|
||||
code--;
|
||||
out += static_cast<char>('!' + code % 94);
|
||||
code /= 94;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
// CONSTRUCTORS
|
||||
VL_UNCOPYABLE(VerilatedVcd);
|
||||
public:
|
||||
explicit VerilatedVcd(VerilatedVcdFile* filep=NULL);
|
||||
~VerilatedVcd();
|
||||
|
||||
// ACCESSORS
|
||||
/// Set size in megabytes after which new file should be created
|
||||
void rolloverMB(vluint64_t rolloverMB) { m_rolloverMB=rolloverMB; };
|
||||
/// Is file open?
|
||||
bool isOpen() const { return m_isOpen; }
|
||||
/// Change character that splits scopes. Note whitespace are ALWAYS escapes.
|
||||
void scopeEscape(char flag) { m_scopeEscape = flag; }
|
||||
/// Is this an escape?
|
||||
inline bool isScopeEscape(char c) { return isspace(c) || c==m_scopeEscape; }
|
||||
|
||||
// METHODS
|
||||
void open(const char* filename) VL_MT_UNSAFE_ONE; ///< Open the file; call isOpen() to see if errors
|
||||
void openNext(bool incFilename); ///< Open next data-only file
|
||||
void close() VL_MT_UNSAFE_ONE; ///< Close the file
|
||||
/// Flush any remaining data to this file
|
||||
void flush() VL_MT_UNSAFE_ONE { bufferFlush(); }
|
||||
/// Flush any remaining data from all files
|
||||
static void flush_all() VL_MT_UNSAFE_ONE;
|
||||
|
||||
void set_time_unit(const char* unitp); ///< Set time units (s/ms, defaults to ns)
|
||||
void set_time_unit(const std::string& unit) { set_time_unit(unit.c_str()); }
|
||||
|
||||
void set_time_resolution(const char* unitp); ///< Set time resolution (s/ms, defaults to ns)
|
||||
void set_time_resolution(const std::string& unit) { set_time_resolution(unit.c_str()); }
|
||||
|
||||
double timescaleToDouble(const char* unitp);
|
||||
std::string doubleToTimescale(double value);
|
||||
|
||||
/// Inside dumping routines, called each cycle to make the dump
|
||||
void dump(vluint64_t timeui);
|
||||
/// Call dump with a absolute unscaled time in seconds
|
||||
void dumpSeconds(double secs) { dump(static_cast<vluint64_t>(secs * m_timeRes)); }
|
||||
|
||||
/// Inside dumping routines, declare callbacks for tracings
|
||||
void addCallback(VerilatedVcdCallback_t initcb, VerilatedVcdCallback_t fullcb,
|
||||
VerilatedVcdCallback_t changecb,
|
||||
void* userthis) VL_MT_UNSAFE_ONE;
|
||||
|
||||
/// Inside dumping routines, declare a module
|
||||
void module(const std::string& name);
|
||||
/// Inside dumping routines, declare a signal
|
||||
void declBit (vluint32_t code, const char* name, int arraynum);
|
||||
void declBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
|
||||
void declQuad (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
|
||||
void declArray (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
|
||||
void declTriBit (vluint32_t code, const char* name, int arraynum);
|
||||
void declTriBus (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
|
||||
void declTriQuad (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
|
||||
void declTriArray (vluint32_t code, const char* name, int arraynum, int msb, int lsb);
|
||||
void declDouble (vluint32_t code, const char* name, int arraynum);
|
||||
void declFloat (vluint32_t code, const char* name, int arraynum);
|
||||
// ... other module_start for submodules (based on cell name)
|
||||
|
||||
/// Inside dumping routines, dump one signal
|
||||
void fullBit(vluint32_t code, const vluint32_t newval) {
|
||||
// Note the &1, so we don't require clean input -- makes more common no change case faster
|
||||
m_sigs_oldvalp[code] = newval;
|
||||
*m_writep++=('0'+static_cast<char>(newval&1)); printCode(code); *m_writep++='\n';
|
||||
bufferCheck();
|
||||
}
|
||||
void fullBus(vluint32_t code, const vluint32_t newval, int bits) {
|
||||
m_sigs_oldvalp[code] = newval;
|
||||
*m_writep++='b';
|
||||
for (int bit=bits-1; bit>=0; --bit) {
|
||||
*m_writep++=((newval&(1L<<bit))?'1':'0');
|
||||
}
|
||||
*m_writep++=' '; printCode(code); *m_writep++='\n';
|
||||
bufferCheck();
|
||||
}
|
||||
void fullQuad(vluint32_t code, const vluint64_t newval, int bits) {
|
||||
(*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) = newval;
|
||||
*m_writep++='b';
|
||||
for (int bit=bits-1; bit>=0; --bit) {
|
||||
*m_writep++=((newval&(1ULL<<bit))?'1':'0');
|
||||
}
|
||||
*m_writep++=' '; printCode(code); *m_writep++='\n';
|
||||
bufferCheck();
|
||||
}
|
||||
void fullArray(vluint32_t code, const vluint32_t* newval, int bits) {
|
||||
for (int word=0; word<(((bits-1)/32)+1); ++word) {
|
||||
m_sigs_oldvalp[code+word] = newval[word];
|
||||
}
|
||||
*m_writep++='b';
|
||||
for (int bit=bits-1; bit>=0; --bit) {
|
||||
*m_writep++=((newval[(bit/32)]&(1L<<(bit&0x1f)))?'1':'0');
|
||||
}
|
||||
*m_writep++=' '; printCode(code); *m_writep++='\n';
|
||||
bufferCheck();
|
||||
}
|
||||
void fullTriBit(vluint32_t code, const vluint32_t newval, const vluint32_t newtri) {
|
||||
m_sigs_oldvalp[code] = newval;
|
||||
m_sigs_oldvalp[code+1] = newtri;
|
||||
*m_writep++ = "01zz"[m_sigs_oldvalp[code]
|
||||
| (m_sigs_oldvalp[code+1]<<1)];
|
||||
printCode(code); *m_writep++='\n';
|
||||
bufferCheck();
|
||||
}
|
||||
void fullTriBus(vluint32_t code, const vluint32_t newval, const vluint32_t newtri, int bits) {
|
||||
m_sigs_oldvalp[code] = newval;
|
||||
m_sigs_oldvalp[code+1] = newtri;
|
||||
*m_writep++='b';
|
||||
for (int bit=bits-1; bit>=0; --bit) {
|
||||
*m_writep++ = "01zz"[((newval >> bit)&1)
|
||||
| (((newtri >> bit)&1)<<1)];
|
||||
}
|
||||
*m_writep++=' '; printCode(code); *m_writep++='\n';
|
||||
bufferCheck();
|
||||
}
|
||||
void fullTriQuad(vluint32_t code, const vluint64_t newval, const vluint32_t newtri, int bits) {
|
||||
(*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) = newval;
|
||||
(*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code+1]))) = newtri;
|
||||
*m_writep++='b';
|
||||
for (int bit=bits-1; bit>=0; --bit) {
|
||||
*m_writep++ = "01zz"[((newval >> bit)&1ULL)
|
||||
| (((newtri >> bit)&1ULL)<<1ULL)];
|
||||
}
|
||||
*m_writep++=' '; printCode(code); *m_writep++='\n';
|
||||
bufferCheck();
|
||||
}
|
||||
void fullTriArray(vluint32_t code, const vluint32_t* newvalp, const vluint32_t* newtrip, int bits) {
|
||||
for (int word=0; word<(((bits-1)/32)+1); ++word) {
|
||||
m_sigs_oldvalp[code+word*2] = newvalp[word];
|
||||
m_sigs_oldvalp[code+word*2+1] = newtrip[word];
|
||||
}
|
||||
*m_writep++='b';
|
||||
for (int bit=bits-1; bit>=0; --bit) {
|
||||
vluint32_t valbit = (newvalp[(bit/32)]>>(bit&0x1f)) & 1;
|
||||
vluint32_t tribit = (newtrip[(bit/32)]>>(bit&0x1f)) & 1;
|
||||
*m_writep++ = "01zz"[valbit | (tribit<<1)];
|
||||
}
|
||||
*m_writep++=' '; printCode(code); *m_writep++='\n';
|
||||
bufferCheck();
|
||||
}
|
||||
void fullDouble(vluint32_t code, const double newval);
|
||||
void fullFloat(vluint32_t code, const float newval);
|
||||
|
||||
/// Inside dumping routines, dump one signal as unknowns
|
||||
/// Presently this code doesn't change the oldval vector.
|
||||
/// Thus this is for special standalone applications that after calling
|
||||
/// fullBitX, must when then value goes non-X call fullBit.
|
||||
inline void fullBitX(vluint32_t code) {
|
||||
*m_writep++='x'; printCode(code); *m_writep++='\n';
|
||||
bufferCheck();
|
||||
}
|
||||
inline void fullBusX(vluint32_t code, int bits) {
|
||||
*m_writep++='b';
|
||||
for (int bit=bits-1; bit>=0; --bit) {
|
||||
*m_writep++='x';
|
||||
}
|
||||
*m_writep++=' '; printCode(code); *m_writep++='\n';
|
||||
bufferCheck();
|
||||
}
|
||||
inline void fullQuadX(vluint32_t code, int bits) { fullBusX(code, bits); }
|
||||
inline void fullArrayX(vluint32_t code, int bits) { fullBusX(code, bits); }
|
||||
|
||||
/// Inside dumping routines, dump one signal if it has changed
|
||||
inline void chgBit(vluint32_t code, const vluint32_t newval) {
|
||||
vluint32_t diff = m_sigs_oldvalp[code] ^ newval;
|
||||
if (VL_UNLIKELY(diff)) {
|
||||
// Verilator 3.510 and newer provide clean input, so the below is only for back compatibility
|
||||
if (VL_UNLIKELY(diff & 1)) { // Change after clean?
|
||||
fullBit(code, newval);
|
||||
}
|
||||
}
|
||||
}
|
||||
inline void chgBus(vluint32_t code, const vluint32_t newval, int bits) {
|
||||
vluint32_t diff = m_sigs_oldvalp[code] ^ newval;
|
||||
if (VL_UNLIKELY(diff)) {
|
||||
if (VL_UNLIKELY(bits==32 || (diff & ((1U<<bits)-1) ))) {
|
||||
fullBus(code, newval, bits);
|
||||
}
|
||||
}
|
||||
}
|
||||
inline void chgQuad(vluint32_t code, const vluint64_t newval, int bits) {
|
||||
vluint64_t diff = (*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) ^ newval;
|
||||
if (VL_UNLIKELY(diff)) {
|
||||
if (VL_UNLIKELY(bits==64 || (diff & ((1ULL<<bits)-1) ))) {
|
||||
fullQuad(code, newval, bits);
|
||||
}
|
||||
}
|
||||
}
|
||||
inline void chgArray(vluint32_t code, const vluint32_t* newval, int bits) {
|
||||
for (int word=0; word<(((bits-1)/32)+1); ++word) {
|
||||
if (VL_UNLIKELY(m_sigs_oldvalp[code+word] ^ newval[word])) {
|
||||
fullArray(code,newval,bits);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
inline void chgTriBit(vluint32_t code, const vluint32_t newval, const vluint32_t newtri) {
|
||||
vluint32_t diff = ((m_sigs_oldvalp[code] ^ newval)
|
||||
| (m_sigs_oldvalp[code+1] ^ newtri));
|
||||
if (VL_UNLIKELY(diff)) {
|
||||
// Verilator 3.510 and newer provide clean input, so the below is only for back compatibility
|
||||
if (VL_UNLIKELY(diff & 1)) { // Change after clean?
|
||||
fullTriBit(code, newval, newtri);
|
||||
}
|
||||
}
|
||||
}
|
||||
inline void chgTriBus(vluint32_t code, const vluint32_t newval, const vluint32_t newtri, int bits) {
|
||||
vluint32_t diff = ((m_sigs_oldvalp[code] ^ newval)
|
||||
| (m_sigs_oldvalp[code+1] ^ newtri));
|
||||
if (VL_UNLIKELY(diff)) {
|
||||
if (VL_UNLIKELY(bits==32 || (diff & ((1U<<bits)-1) ))) {
|
||||
fullTriBus(code, newval, newtri, bits);
|
||||
}
|
||||
}
|
||||
}
|
||||
inline void chgTriQuad(vluint32_t code, const vluint64_t newval, const vluint32_t newtri, int bits) {
|
||||
vluint64_t diff = ( ((*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code]))) ^ newval)
|
||||
| ((*(reinterpret_cast<vluint64_t*>(&m_sigs_oldvalp[code+1]))) ^ newtri));
|
||||
if (VL_UNLIKELY(diff)) {
|
||||
if (VL_UNLIKELY(bits==64 || (diff & ((1ULL<<bits)-1) ))) {
|
||||
fullTriQuad(code, newval, newtri, bits);
|
||||
}
|
||||
}
|
||||
}
|
||||
inline void chgTriArray(vluint32_t code, const vluint32_t* newvalp, const vluint32_t* newtrip, int bits) {
|
||||
for (int word=0; word<(((bits-1)/32)+1); ++word) {
|
||||
if (VL_UNLIKELY((m_sigs_oldvalp[code+word*2] ^ newvalp[word])
|
||||
| (m_sigs_oldvalp[code+word*2+1] ^ newtrip[word]))) {
|
||||
fullTriArray(code,newvalp,newtrip,bits);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
inline void chgDouble(vluint32_t code, const double newval) {
|
||||
// cppcheck-suppress invalidPointerCast
|
||||
if (VL_UNLIKELY((*(reinterpret_cast<double*>(&m_sigs_oldvalp[code]))) != newval)) {
|
||||
fullDouble(code, newval);
|
||||
}
|
||||
}
|
||||
inline void chgFloat(vluint32_t code, const float newval) {
|
||||
// cppcheck-suppress invalidPointerCast
|
||||
if (VL_UNLIKELY((*(reinterpret_cast<float*>(&m_sigs_oldvalp[code]))) != newval)) {
|
||||
fullFloat(code, newval);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
// METHODS
|
||||
void evcd(bool flag) { m_evcd = flag; }
|
||||
};
|
||||
|
||||
//=============================================================================
|
||||
// VerilatedVcdC
|
||||
/// Create a VCD dump file in C standalone (no SystemC) simulations.
|
||||
/// Also derived for use in SystemC simulations.
|
||||
/// Thread safety: Unless otherwise indicated, every function is VL_MT_UNSAFE_ONE
|
||||
|
||||
class VerilatedVcdC {
|
||||
VerilatedVcd m_sptrace; ///< Trace file being created
|
||||
|
||||
// CONSTRUCTORS
|
||||
VL_UNCOPYABLE(VerilatedVcdC);
|
||||
public:
|
||||
explicit VerilatedVcdC(VerilatedVcdFile* filep=NULL) : m_sptrace(filep) {}
|
||||
~VerilatedVcdC() {}
|
||||
public:
|
||||
// ACCESSORS
|
||||
/// Is file open?
|
||||
bool isOpen() const { return m_sptrace.isOpen(); }
|
||||
// METHODS
|
||||
/// Open a new VCD file
|
||||
/// This includes a complete header dump each time it is called,
|
||||
/// just as if this object was deleted and reconstructed.
|
||||
void open(const char* filename) VL_MT_UNSAFE_ONE { m_sptrace.open(filename); }
|
||||
/// Continue a VCD dump by rotating to a new file name
|
||||
/// The header is only in the first file created, this allows
|
||||
/// "cat" to be used to combine the header plus any number of data files.
|
||||
void openNext(bool incFilename=true) VL_MT_UNSAFE_ONE { m_sptrace.openNext(incFilename); }
|
||||
/// Set size in megabytes after which new file should be created
|
||||
void rolloverMB(size_t rolloverMB) { m_sptrace.rolloverMB(rolloverMB); };
|
||||
/// Close dump
|
||||
void close() VL_MT_UNSAFE_ONE { m_sptrace.close(); }
|
||||
/// Flush dump
|
||||
void flush() VL_MT_UNSAFE_ONE { m_sptrace.flush(); }
|
||||
/// Write one cycle of dump data
|
||||
void dump(vluint64_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)); }
|
||||
/// Set time units (s/ms, defaults to ns)
|
||||
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
|
||||
void set_time_unit(const char* unit) { m_sptrace.set_time_unit(unit); }
|
||||
void set_time_unit(const std::string& unit) { set_time_unit(unit.c_str()); }
|
||||
/// Set time resolution (s/ms, defaults to ns)
|
||||
/// See also VL_TIME_PRECISION, and VL_TIME_MULTIPLIER in verilated.h
|
||||
void set_time_resolution(const char* unit) { m_sptrace.set_time_resolution(unit); }
|
||||
void set_time_resolution(const std::string& unit) { set_time_resolution(unit.c_str()); }
|
||||
|
||||
/// Internal class access
|
||||
inline VerilatedVcd* spTrace() { return &m_sptrace; };
|
||||
};
|
||||
|
||||
#endif // guard
|
||||
@@ -0,0 +1,165 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilator tracing in VCD Format
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated_vcd_sc.h"
|
||||
|
||||
// SPDIFF_ON
|
||||
//======================================================================
|
||||
//======================================================================
|
||||
|
||||
//--------------------------------------------------
|
||||
#if (SYSTEMC_VERSION>=20050714)
|
||||
// SystemC 2.1.v1
|
||||
// cppcheck-suppress unusedFunction
|
||||
void VerilatedVcdSc::write_comment(const std::string &) {}
|
||||
void VerilatedVcdSc::trace(const unsigned int &, const std::string &, const char **) {}
|
||||
|
||||
# define DECL_TRACE_METHOD_A(tp) \
|
||||
void VerilatedVcdSc::trace( const tp& object, const std::string& name ) {}
|
||||
# define DECL_TRACE_METHOD_B(tp) \
|
||||
void VerilatedVcdSc::trace( const tp& object, const std::string& name, int width ) {}
|
||||
|
||||
#if (SYSTEMC_VERSION>=20171012)
|
||||
DECL_TRACE_METHOD_A( sc_event )
|
||||
DECL_TRACE_METHOD_A( sc_time )
|
||||
#endif
|
||||
|
||||
DECL_TRACE_METHOD_A( bool )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_bit )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_logic )
|
||||
|
||||
DECL_TRACE_METHOD_B( unsigned 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 )
|
||||
DECL_TRACE_METHOD_B( long )
|
||||
DECL_TRACE_METHOD_B( sc_dt::int64 )
|
||||
DECL_TRACE_METHOD_B( sc_dt::uint64 )
|
||||
|
||||
DECL_TRACE_METHOD_A( float )
|
||||
DECL_TRACE_METHOD_A( double )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_int_base )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_uint_base )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_signed )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_unsigned )
|
||||
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxval )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxval_fast )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxnum )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxnum_fast )
|
||||
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_bv_base )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_lv_base )
|
||||
|
||||
//--------------------------------------------------
|
||||
#elif (SYSTEMC_VERSION>20011000)
|
||||
// SystemC 2.0.1
|
||||
// cppcheck-suppress unusedFunction
|
||||
void VerilatedVcdSc::write_comment(const sc_string &) {}
|
||||
void VerilatedVcdSc::trace(const unsigned int &, const sc_string &, const char **) {}
|
||||
|
||||
#define DECL_TRACE_METHOD_A(tp) \
|
||||
void VerilatedVcdSc::trace( const tp& object, const sc_string& name ) {}
|
||||
#define DECL_TRACE_METHOD_B(tp) \
|
||||
void VerilatedVcdSc::trace( const tp& object, const sc_string& name, int width ) {}
|
||||
|
||||
DECL_TRACE_METHOD_A( bool )
|
||||
DECL_TRACE_METHOD_A( sc_bit )
|
||||
DECL_TRACE_METHOD_A( sc_logic )
|
||||
DECL_TRACE_METHOD_B( unsigned 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
|
||||
#if (SYSTEMC_VERSION>20041000)
|
||||
DECL_TRACE_METHOD_B( unsigned long long)
|
||||
DECL_TRACE_METHOD_B( long long)
|
||||
#endif
|
||||
DECL_TRACE_METHOD_B( char )
|
||||
DECL_TRACE_METHOD_B( short )
|
||||
DECL_TRACE_METHOD_B( int )
|
||||
DECL_TRACE_METHOD_B( long )
|
||||
DECL_TRACE_METHOD_A( float )
|
||||
DECL_TRACE_METHOD_A( double )
|
||||
DECL_TRACE_METHOD_A( sc_int_base )
|
||||
DECL_TRACE_METHOD_A( sc_uint_base )
|
||||
DECL_TRACE_METHOD_A( sc_signed )
|
||||
DECL_TRACE_METHOD_A( sc_unsigned )
|
||||
DECL_TRACE_METHOD_A( sc_fxval )
|
||||
DECL_TRACE_METHOD_A( sc_fxval_fast )
|
||||
DECL_TRACE_METHOD_A( sc_fxnum )
|
||||
DECL_TRACE_METHOD_A( sc_fxnum_fast )
|
||||
DECL_TRACE_METHOD_A( sc_bv_base )
|
||||
DECL_TRACE_METHOD_A( sc_lv_base )
|
||||
|
||||
//--------------------------------------------------
|
||||
#else
|
||||
// SystemC 1.2.1beta
|
||||
// cppcheck-suppress unusedFunction
|
||||
void VerilatedVcdSc::write_comment(const sc_string &) {}
|
||||
void VerilatedVcdSc::trace(const unsigned int &, const sc_string &, const char **) {}
|
||||
|
||||
#define DECL_TRACE_METHOD_A(tp) \
|
||||
void VerilatedVcdSc::trace( const tp& object, const sc_string& name ) {}
|
||||
#define DECL_TRACE_METHOD_B(tp) \
|
||||
void VerilatedVcdSc::trace( const tp& object, const sc_string& name, int width ) {}
|
||||
|
||||
DECL_TRACE_METHOD_A( bool )
|
||||
DECL_TRACE_METHOD_B( unsigned char )
|
||||
DECL_TRACE_METHOD_B( short unsigned int )
|
||||
DECL_TRACE_METHOD_B( unsigned int )
|
||||
DECL_TRACE_METHOD_B( long unsigned int )
|
||||
DECL_TRACE_METHOD_B( char )
|
||||
DECL_TRACE_METHOD_B( short int )
|
||||
DECL_TRACE_METHOD_B( int )
|
||||
DECL_TRACE_METHOD_B( long int )
|
||||
DECL_TRACE_METHOD_A( float )
|
||||
DECL_TRACE_METHOD_A( double )
|
||||
DECL_TRACE_METHOD_A( sc_bit )
|
||||
DECL_TRACE_METHOD_A( sc_logic )
|
||||
DECL_TRACE_METHOD_A( sc_bool_vector )
|
||||
DECL_TRACE_METHOD_A( sc_logic_vector )
|
||||
DECL_TRACE_METHOD_A( sc_signal_bool_vector )
|
||||
DECL_TRACE_METHOD_A( sc_signal_logic_vector )
|
||||
DECL_TRACE_METHOD_A( sc_uint_base )
|
||||
DECL_TRACE_METHOD_A( sc_int_base )
|
||||
DECL_TRACE_METHOD_A( sc_unsigned )
|
||||
DECL_TRACE_METHOD_A( sc_signed )
|
||||
DECL_TRACE_METHOD_A( sc_signal_resolved )
|
||||
DECL_TRACE_METHOD_A( sc_signal_resolved_vector )
|
||||
DECL_TRACE_METHOD_A( sc_bv_ns::sc_bv_base )
|
||||
DECL_TRACE_METHOD_A( sc_bv_ns::sc_lv_base )
|
||||
#endif
|
||||
|
||||
#undef DECL_TRACE_METHOD_A
|
||||
#undef DECL_TRACE_METHOD_B
|
||||
|
||||
//********************************************************************
|
||||
@@ -0,0 +1,224 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//=============================================================================
|
||||
//
|
||||
// THIS MODULE IS PUBLICLY LICENSED
|
||||
//
|
||||
// Copyright 2001-2019 by Wilson Snyder. This program is free software;
|
||||
// you can redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
//
|
||||
// This is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
// for more details.
|
||||
//
|
||||
//=============================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilator tracing in VCD format
|
||||
///
|
||||
/// This class is not threadsafe, as the SystemC kernel is not threadsafe.
|
||||
///
|
||||
//=============================================================================
|
||||
// SPDIFF_OFF
|
||||
|
||||
#ifndef _VERILATED_VCD_SC_H_
|
||||
#define _VERILATED_VCD_SC_H_ 1
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated_sc.h"
|
||||
#include "verilated_vcd_c.h"
|
||||
|
||||
// SPDIFF_ON
|
||||
//=============================================================================
|
||||
// VerilatedVcdSc
|
||||
///
|
||||
/// This class is passed to the SystemC simulation kernel, just like a
|
||||
/// documented SystemC trace format.
|
||||
|
||||
class VerilatedVcdSc
|
||||
: sc_trace_file
|
||||
, public VerilatedVcdC
|
||||
{
|
||||
// CONSTRUCTORS
|
||||
VL_UNCOPYABLE(VerilatedVcdSc);
|
||||
public:
|
||||
VerilatedVcdSc() {
|
||||
sc_get_curr_simcontext()->add_trace_file(this);
|
||||
# if (SYSTEMC_VERSION>=20060505)
|
||||
// We want to avoid a depreciated warning, but still be back compatible.
|
||||
// Turning off the message just for this still results in an annoying "to turn off" message.
|
||||
sc_time t1sec(1,SC_SEC);
|
||||
if (t1sec.to_default_time_units()!=0) {
|
||||
sc_time tunits(1.0/t1sec.to_default_time_units(),SC_SEC);
|
||||
spTrace()->set_time_unit(tunits.to_string());
|
||||
}
|
||||
spTrace()->set_time_resolution(sc_get_time_resolution().to_string());
|
||||
# elif (SYSTEMC_VERSION>20011000)
|
||||
// To confuse matters 2.1.beta returns a char* here, while 2.1.v1 returns a std::string
|
||||
// we allow both flavors with overloaded set_time_* functions.
|
||||
spTrace()->set_time_unit(sc_get_default_time_unit().to_string());
|
||||
spTrace()->set_time_resolution(sc_get_time_resolution().to_string());
|
||||
# endif
|
||||
}
|
||||
virtual ~VerilatedVcdSc() {}
|
||||
|
||||
// METHODS
|
||||
/// Called by SystemC simulate()
|
||||
virtual void cycle(bool delta_cycle) {
|
||||
# if (SYSTEMC_VERSION>20011000)
|
||||
if (!delta_cycle) { this->dump(sc_time_stamp().to_double()); }
|
||||
# else
|
||||
// VCD files must have integer timestamps, so we write all times in increments of time_resolution
|
||||
if (!delta_cycle) { this->dump(sc_time_stamp().to_double()); }
|
||||
# endif
|
||||
}
|
||||
|
||||
private:
|
||||
/// Fake outs for linker
|
||||
|
||||
#ifdef NC_SYSTEMC
|
||||
// Cadence Incisive has these as abstract functions so we must create them
|
||||
virtual void set_time_unit(int exponent10_seconds) {} // deprecated
|
||||
#endif
|
||||
#if defined(NC_SYSTEMC) || (SYSTEMC_VERSION>=20111100)
|
||||
virtual void set_time_unit(double v, sc_time_unit tu) {}
|
||||
#endif
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
# if (SYSTEMC_VERSION>=20050714)
|
||||
// SystemC 2.1.v1
|
||||
# define DECL_TRACE_METHOD_A(tp) \
|
||||
virtual void trace(const tp& object, const std::string& name);
|
||||
# define DECL_TRACE_METHOD_B(tp) \
|
||||
virtual void trace(const tp& object, const std::string& name, int width);
|
||||
|
||||
virtual void write_comment(const std::string &);
|
||||
virtual void trace(const unsigned int &, const std::string &, const char **);
|
||||
|
||||
#if (SYSTEMC_VERSION>=20171012)
|
||||
DECL_TRACE_METHOD_A( sc_event )
|
||||
DECL_TRACE_METHOD_A( sc_time )
|
||||
#endif
|
||||
|
||||
DECL_TRACE_METHOD_A( bool )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_bit )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_logic )
|
||||
|
||||
DECL_TRACE_METHOD_B( unsigned 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 )
|
||||
DECL_TRACE_METHOD_B( long )
|
||||
DECL_TRACE_METHOD_B( sc_dt::int64 )
|
||||
DECL_TRACE_METHOD_B( sc_dt::uint64 )
|
||||
|
||||
DECL_TRACE_METHOD_A( float )
|
||||
DECL_TRACE_METHOD_A( double )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_int_base )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_uint_base )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_signed )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_unsigned )
|
||||
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxval )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxval_fast )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxnum )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_fxnum_fast )
|
||||
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_bv_base )
|
||||
DECL_TRACE_METHOD_A( sc_dt::sc_lv_base )
|
||||
|
||||
//--------------------------------------------------
|
||||
# elif (SYSTEMC_VERSION>20011000)
|
||||
// SystemC 2.0.1
|
||||
# define DECL_TRACE_METHOD_A(tp) \
|
||||
virtual void trace(const tp& object, const sc_string& name);
|
||||
# define DECL_TRACE_METHOD_B(tp) \
|
||||
virtual void trace(const tp& object, const sc_string& name, int width);
|
||||
|
||||
virtual void write_comment(const sc_string &);
|
||||
virtual void trace(const unsigned int &, const sc_string &, const char **);
|
||||
virtual void delta_cycles(bool) {}
|
||||
virtual void space(int n) {}
|
||||
|
||||
DECL_TRACE_METHOD_A( bool )
|
||||
DECL_TRACE_METHOD_A( sc_bit )
|
||||
DECL_TRACE_METHOD_A( sc_logic )
|
||||
DECL_TRACE_METHOD_B( unsigned 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
|
||||
#if (SYSTEMC_VERSION>20041000)
|
||||
DECL_TRACE_METHOD_B( unsigned long long)
|
||||
DECL_TRACE_METHOD_B( long long)
|
||||
#endif
|
||||
DECL_TRACE_METHOD_B( char )
|
||||
DECL_TRACE_METHOD_B( short )
|
||||
DECL_TRACE_METHOD_B( int )
|
||||
DECL_TRACE_METHOD_B( long )
|
||||
DECL_TRACE_METHOD_A( float )
|
||||
DECL_TRACE_METHOD_A( double )
|
||||
DECL_TRACE_METHOD_A( sc_int_base )
|
||||
DECL_TRACE_METHOD_A( sc_uint_base )
|
||||
DECL_TRACE_METHOD_A( sc_signed )
|
||||
DECL_TRACE_METHOD_A( sc_unsigned )
|
||||
DECL_TRACE_METHOD_A( sc_fxval )
|
||||
DECL_TRACE_METHOD_A( sc_fxval_fast )
|
||||
DECL_TRACE_METHOD_A( sc_fxnum )
|
||||
DECL_TRACE_METHOD_A( sc_fxnum_fast )
|
||||
DECL_TRACE_METHOD_A( sc_bv_base )
|
||||
DECL_TRACE_METHOD_A( sc_lv_base )
|
||||
|
||||
//--------------------------------------------------
|
||||
# else
|
||||
// SystemC 1.2.1beta
|
||||
# define DECL_TRACE_METHOD_A(tp) \
|
||||
virtual void trace(const tp& object, const sc_string& name);
|
||||
# define DECL_TRACE_METHOD_B(tp) \
|
||||
virtual void trace(const tp& object, const sc_string& name, int width);
|
||||
|
||||
virtual void write_comment(const sc_string &);
|
||||
virtual void trace(const unsigned int &, const sc_string &, const char **);
|
||||
|
||||
DECL_TRACE_METHOD_A( bool )
|
||||
DECL_TRACE_METHOD_B( unsigned char )
|
||||
DECL_TRACE_METHOD_B( short unsigned int )
|
||||
DECL_TRACE_METHOD_B( unsigned int )
|
||||
DECL_TRACE_METHOD_B( long unsigned int )
|
||||
DECL_TRACE_METHOD_B( char )
|
||||
DECL_TRACE_METHOD_B( short int )
|
||||
DECL_TRACE_METHOD_B( int )
|
||||
DECL_TRACE_METHOD_B( long int )
|
||||
DECL_TRACE_METHOD_A( float )
|
||||
DECL_TRACE_METHOD_A( double )
|
||||
DECL_TRACE_METHOD_A( sc_bit )
|
||||
DECL_TRACE_METHOD_A( sc_logic )
|
||||
DECL_TRACE_METHOD_A( sc_bool_vector )
|
||||
DECL_TRACE_METHOD_A( sc_logic_vector )
|
||||
DECL_TRACE_METHOD_A( sc_signal_bool_vector )
|
||||
DECL_TRACE_METHOD_A( sc_signal_logic_vector )
|
||||
DECL_TRACE_METHOD_A( sc_uint_base )
|
||||
DECL_TRACE_METHOD_A( sc_int_base )
|
||||
DECL_TRACE_METHOD_A( sc_unsigned )
|
||||
DECL_TRACE_METHOD_A( sc_signed )
|
||||
DECL_TRACE_METHOD_A( sc_signal_resolved )
|
||||
DECL_TRACE_METHOD_A( sc_signal_resolved_vector )
|
||||
DECL_TRACE_METHOD_A( sc_bv_ns::sc_bv_base )
|
||||
DECL_TRACE_METHOD_A( sc_bv_ns::sc_lv_base )
|
||||
# endif
|
||||
|
||||
# undef DECL_TRACE_METHOD_A
|
||||
# undef DECL_TRACE_METHOD_B
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,52 @@
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2009-2019 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//=========================================================================
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilator: VPI implementation code
|
||||
///
|
||||
/// This file must be compiled and linked against all objects
|
||||
/// created from Verilator or called by Verilator that use the VPI.
|
||||
///
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//=========================================================================
|
||||
|
||||
#ifndef _VERILATED_VPI_H_
|
||||
#define _VERILATED_VPI_H_ 1 ///< Header Guard
|
||||
|
||||
#include "verilatedos.h"
|
||||
#include "verilated.h"
|
||||
#include "verilated_syms.h"
|
||||
|
||||
//======================================================================
|
||||
// From IEEE 1800-2009 annex K
|
||||
|
||||
#include "vltstd/vpi_user.h"
|
||||
|
||||
//======================================================================
|
||||
|
||||
class VerilatedVpi {
|
||||
public:
|
||||
/// Call timed callbacks
|
||||
/// Users should call this from their main loops
|
||||
static void callTimedCbs() VL_MT_UNSAFE_ONE;
|
||||
/// Call value based callbacks
|
||||
/// Users should call this from their main loops
|
||||
static void callValueCbs() VL_MT_UNSAFE_ONE;
|
||||
/// Self test, for internal use only
|
||||
static void selfTest() VL_MT_UNSAFE_ONE;
|
||||
};
|
||||
|
||||
#endif // Guard
|
||||
+330
-67
@@ -1,136 +1,399 @@
|
||||
// $Id$ -*- C++ -*-
|
||||
// -*- mode: C++; c-file-style: "cc-mode" -*-
|
||||
//*************************************************************************
|
||||
//
|
||||
// Copyright 2003-2007 by Wilson Snyder. This program is free software; you can
|
||||
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
|
||||
// redistribute it and/or modify it under the terms of either the GNU
|
||||
// General Public License or the Perl Artistic License.
|
||||
// Lesser General Public License Version 3 or the Perl Artistic License.
|
||||
// Version 2.0.
|
||||
//
|
||||
// Verilator is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
//
|
||||
//*************************************************************************
|
||||
///
|
||||
/// \file
|
||||
/// \brief Verilator: Common include for OS portability (verilated & verilator)
|
||||
///
|
||||
/// This header is used by both the Verilator source code (run on the
|
||||
/// build and host system), and the Verilated output (run on the target
|
||||
/// system). Code needed by only the host system goes into
|
||||
/// config_build.h.in, code needed by Verilated code only goes into
|
||||
/// verilated.h, and code needed by both goes here (verilatedos.h).
|
||||
/// This header is used by both the Verilator source code (run on the
|
||||
/// build and host system), and the Verilated output (run on the target
|
||||
/// system). Code needed by only the host system goes into
|
||||
/// config_build.h.in, code needed by Verilated code only goes into
|
||||
/// verilated.h, and code needed by both goes here (verilatedos.h).
|
||||
///
|
||||
/// Code available from: http://www.veripool.com/verilator
|
||||
/// Code available from: http://www.veripool.org/verilator
|
||||
///
|
||||
//*************************************************************************
|
||||
|
||||
|
||||
#ifndef _VERILATEDOS_H_
|
||||
#define _VERILATEDOS_H_ 1 ///< Header Guard
|
||||
#define _VERILATEDOS_H_ 1 ///< Header Guard
|
||||
|
||||
//=========================================================================
|
||||
// Compiler pragma abstraction
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define VL_ATTR_PRINTF(fmtArgNum) __attribute__ ((format (printf, fmtArgNum, fmtArgNum+1)))
|
||||
# define VL_ATTR_ALIGNED(alignment) __attribute__ ((aligned (alignment)))
|
||||
# define VL_ATTR_ALWINLINE __attribute__ ((always_inline))
|
||||
# define VL_ATTR_NORETURN __attribute__ ((noreturn))
|
||||
# define VL_ATTR_PRINTF(fmtArgNum) __attribute__ ((format (printf, (fmtArgNum), (fmtArgNum)+1)))
|
||||
# define VL_ATTR_PURE __attribute__ ((pure))
|
||||
# define VL_ATTR_UNUSED __attribute__ ((unused))
|
||||
# define VL_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
# define VL_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
#else
|
||||
# define VL_ATTR_PRINTF(fmtArgNum) ///< Function with printf format checking
|
||||
# define VL_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment
|
||||
# define VL_ATTR_NORETURN ///< Function does not ever return
|
||||
# define VL_ATTR_UNUSED ///< Function that may be never used
|
||||
# define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true then false
|
||||
# define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false then true
|
||||
# define VL_FUNC __func__
|
||||
# if defined(__clang__) && defined(VL_THREADED)
|
||||
# define VL_ACQUIRE(...) __attribute__ ((acquire_capability(__VA_ARGS__)))
|
||||
# define VL_ACQUIRE_SHARED(...) __attribute__ ((acquire_shared_capability(__VA_ARGS__)))
|
||||
# define VL_RELEASE(...) __attribute__ ((release_capability(__VA_ARGS__)))
|
||||
# define VL_RELEASE_SHARED(...) __attribute__ ((release_shared_capability(__VA_ARGS__)))
|
||||
# define VL_TRY_ACQUIRE(...) __attribute__ ((try_acquire_capability(__VA_ARGS__)))
|
||||
# define VL_TRY_ACQUIRE_SHARED(...) __attribute__ ((try_acquire_shared_capability(__VA_ARGS__)))
|
||||
# define VL_CAPABILITY(x) __attribute__ ((capability(x)))
|
||||
# define VL_REQUIRES(x) __attribute__ ((requires_capability(x)))
|
||||
# define VL_GUARDED_BY(x) __attribute__ ((guarded_by(x)))
|
||||
# define VL_EXCLUDES(x) __attribute__ ((locks_excluded(x)))
|
||||
# define VL_SCOPED_CAPABILITY __attribute__ ((scoped_lockable))
|
||||
# endif
|
||||
# define VL_LIKELY(x) __builtin_expect(!!(x), 1)
|
||||
# define VL_UNLIKELY(x) __builtin_expect(!!(x), 0)
|
||||
# define VL_UNREACHABLE __builtin_unreachable();
|
||||
# define VL_PREFETCH_RD(p) __builtin_prefetch((p),0)
|
||||
# define VL_PREFETCH_RW(p) __builtin_prefetch((p),1)
|
||||
#elif defined(_MSC_VER)
|
||||
# define VL_FUNC __FUNCTION__
|
||||
#endif
|
||||
|
||||
// Defaults for unsupported compiler features
|
||||
#ifndef VL_ATTR_ALIGNED
|
||||
# define VL_ATTR_ALIGNED(alignment) ///< Align structure to specified byte alignment
|
||||
#endif
|
||||
#ifndef VL_ATTR_ALWINLINE
|
||||
# define VL_ATTR_ALWINLINE ///< Inline, even when not optimizing
|
||||
#endif
|
||||
#ifndef VL_ATTR_NORETURN
|
||||
# define VL_ATTR_NORETURN ///< Function does not ever return
|
||||
#endif
|
||||
#ifndef VL_ATTR_PRINTF
|
||||
# define VL_ATTR_PRINTF(fmtArgNum) ///< Function with printf format checking
|
||||
#endif
|
||||
#ifndef VL_ATTR_PURE
|
||||
# define VL_ATTR_PURE ///< Function is pure (and thus also VL_MT_SAFE)
|
||||
#endif
|
||||
#ifndef VL_ATTR_UNUSED
|
||||
# define VL_ATTR_UNUSED ///< Function that may be never used
|
||||
#endif
|
||||
#ifndef VL_FUNC
|
||||
# define VL_FUNC "__func__" ///< Name of current function for error macros
|
||||
#endif
|
||||
#ifndef VL_CAPABILITY
|
||||
# define VL_ACQUIRE(...) ///< Function requires a capability/lock (-fthread-safety)
|
||||
# define VL_ACQUIRE_SHARED(...) ///< Function aquires a shared capability/lock (-fthread-safety)
|
||||
# define VL_RELEASE(...) ///< Function releases a capability/lock (-fthread-safety)
|
||||
# define VL_RELEASE_SHARED(...) ///< Function releases a shared capability/lock (-fthread-safety)
|
||||
# define VL_TRY_ACQUIRE(...) ///< Function returns bool if aquired a capability (-fthread-safety)
|
||||
# define VL_TRY_ACQUIRE_SHARED(...) ///< Function returns bool if aquired a shared capability (-fthread-safety)
|
||||
# define VL_REQUIRES(x) ///< Function requires a capability inbound (-fthread-safety)
|
||||
# define VL_EXCLUDES(x) ///< Function requires not having a capability inbound (-fthread-safety)
|
||||
# define VL_CAPABILITY(x) ///< Name of capability/lock (-fthread-safety)
|
||||
# define VL_GUARDED_BY(x) ///< Name of mutex protecting this variable (-fthread-safety)
|
||||
# define VL_SCOPED_CAPABILITY ///< Scoped threaded capability/lock (-fthread-safety)
|
||||
#endif
|
||||
#ifndef VL_LIKELY
|
||||
# define VL_LIKELY(x) (!!(x)) ///< Boolean expression more often true than false
|
||||
# define VL_UNLIKELY(x) (!!(x)) ///< Boolean expression more often false than true
|
||||
#endif
|
||||
#ifndef VL_UNREACHABLE
|
||||
# define VL_UNREACHABLE ///< Point that may never be reached
|
||||
#endif
|
||||
#ifndef VL_PREFETCH_RD
|
||||
# define VL_PREFETCH_RD(p) ///< Prefetch data with read intent
|
||||
#endif
|
||||
#ifndef VL_PREFETCH_RW
|
||||
# define VL_PREFETCH_RW(p) ///< Prefetch data with read/write intent
|
||||
#endif
|
||||
|
||||
#ifdef VL_THREADED
|
||||
# ifdef __GNUC__
|
||||
# define VL_THREAD __thread ///< Storage class for thread-local storage
|
||||
# if (__cplusplus < 201103L) && !defined(VL_THREADED_NO_C11_WARNING)
|
||||
# error "VL_THREADED/--threads support requires C++-11 or newer only; use newer compiler"
|
||||
# endif
|
||||
# else
|
||||
# error "Unsupported compiler for VL_THREADED: No thread-local declarator"
|
||||
# endif
|
||||
# define VL_THREAD_LOCAL thread_local ///< Use new C++ static local thread
|
||||
#else
|
||||
# define VL_THREAD ///< Storage class for thread-local storage
|
||||
# define VL_THREAD_LOCAL ///< Use new C++ static local thread
|
||||
#endif
|
||||
#define VL_THREAD ///< Deprecated
|
||||
#define VL_STATIC_OR_THREAD static ///< Deprecated
|
||||
|
||||
#define VL_PURE ///< Comment tag that Function is pure (and thus also VL_MT_SAFE)
|
||||
#define VL_MT_SAFE ///< Comment tag that function is threadsafe when VL_THREADED
|
||||
#define VL_MT_SAFE_POSTINIT ///< Comment tag that function is threadsafe when VL_THREADED, only during normal operation (post-init)
|
||||
#define VL_MT_UNSAFE ///< Comment tag that function is not threadsafe when VL_THREADED
|
||||
#define VL_MT_UNSAFE_ONE ///< Comment tag that function is not threadsafe when VL_THREADED, protected to make sure single-caller
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define VL_ULL(c) (c##ui64) ///< Add appropriate suffix to 64-bit constant
|
||||
# define VL_ULL(c) (c##ui64) ///< Add appropriate suffix to 64-bit constant
|
||||
#else
|
||||
# define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant
|
||||
# define VL_ULL(c) (c##ULL) ///< Add appropriate suffix to 64-bit constant
|
||||
#endif
|
||||
|
||||
// This is not necessarily the same as #UL, depending on what the IData typedef is.
|
||||
#define VL_UL(c) (static_cast<IData>(c##UL)) ///< Add appropriate suffix to 32-bit constant
|
||||
|
||||
#if defined(VL_CPPCHECK) || defined(__clang_analyzer__)
|
||||
# define VL_DANGLING(v)
|
||||
#else
|
||||
# define VL_DANGLING(v) do { (v) = NULL; } while(0) ///< After e.g. delete, set variable to NULL to indicate must not use later
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// C++-2011
|
||||
|
||||
#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__)
|
||||
# define VL_EQ_DELETE = delete
|
||||
# define vl_unique_ptr std::unique_ptr
|
||||
// By default we use std:: types in C++11.
|
||||
// Define VL_USE_UNORDERED_TYPES to test these pre-C++11 classes
|
||||
# ifdef VL_USE_UNORDERED_TYPES
|
||||
# define VL_INCLUDE_UNORDERED_MAP "verilated_unordered_set_map.h"
|
||||
# define VL_INCLUDE_UNORDERED_SET "verilated_unordered_set_map.h"
|
||||
# else
|
||||
# define vl_unordered_map std::unordered_map
|
||||
# define vl_unordered_set std::unordered_set
|
||||
# define VL_INCLUDE_UNORDERED_MAP <unordered_map>
|
||||
# define VL_INCLUDE_UNORDERED_SET <unordered_set>
|
||||
# endif
|
||||
#else
|
||||
# define VL_EQ_DELETE
|
||||
# define vl_unique_ptr std::auto_ptr
|
||||
# define VL_INCLUDE_UNORDERED_MAP "verilated_unordered_set_map.h"
|
||||
# define VL_INCLUDE_UNORDERED_SET "verilated_unordered_set_map.h"
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// Optimization
|
||||
|
||||
#ifndef VL_INLINE_OPT
|
||||
# define VL_INLINE_OPT ///< "inline" if compiling all objects in single compiler run
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// Warning disabled
|
||||
|
||||
#ifndef VL_WARNINGS
|
||||
# ifdef _MSC_VER
|
||||
# pragma warning(disable:4099) // C4099: type name first seen using 'class' now seen using 'struct' (V3AstNode)
|
||||
# pragma warning(disable:4100) // C4100: unreferenced formal parameter (L4)
|
||||
# pragma warning(disable:4127) // C4127: conditional expression is constant (L4)
|
||||
# pragma warning(disable:4146) // C4146: unary minus operator applied to unsigned type, result still unsigned
|
||||
# pragma warning(disable:4189) // C4189: local variable is initialized but not referenced (L4)
|
||||
# pragma warning(disable:4244) // C4244: conversion from 'uint64_t' to 'uint_32_t', possible loss of data
|
||||
# pragma warning(disable:4245) // C4245: conversion from 'int' to 'unsigned', signed/unsigned mismatch
|
||||
# pragma warning(disable:4996) // C4996: sscanf/fopen/etc may be unsafe
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// Basic integer types
|
||||
|
||||
#ifdef VL_UINTS_DEFINED
|
||||
#elif defined(__CYGWIN__)
|
||||
#if defined(__CYGWIN__)
|
||||
|
||||
# include <stdint.h>
|
||||
typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward compatibility)
|
||||
typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility)
|
||||
typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility)
|
||||
typedef unsigned char vluint8_t; ///< 8-bit unsigned type
|
||||
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
|
||||
typedef long vlsint32_t; ///< 32-bit signed type
|
||||
typedef unsigned long vluint32_t; ///< 32-bit unsigned type
|
||||
typedef long long vlsint64_t; ///< 64-bit signed type
|
||||
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||
#elif defined(_WIN32)
|
||||
typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward compatibility)
|
||||
typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility)
|
||||
typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility)
|
||||
typedef unsigned char vluint8_t; ///< 8-bit unsigned type
|
||||
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
|
||||
typedef int vlsint32_t; ///< 32-bit signed type
|
||||
typedef unsigned int vluint32_t; ///< 32-bit unsigned type
|
||||
typedef __int64 vlsint64_t; ///< 64-bit signed type
|
||||
typedef unsigned __int64 vluint64_t; ///< 64-bit unsigned type
|
||||
#else // Linux or compliant Unix flavors, -m64
|
||||
# include <stdint.h> // Linux and most flavors
|
||||
# include <inttypes.h> // Solaris
|
||||
typedef uint8_t vluint8_t; ///< 32-bit unsigned type
|
||||
typedef uint16_t vluint16_t; ///< 32-bit unsigned type
|
||||
typedef int vlsint32_t; ///< 32-bit signed type
|
||||
typedef uint32_t vluint32_t; ///< 32-bit signed type
|
||||
typedef long long vlsint64_t; ///< 64-bit signed type
|
||||
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||
# include <sys/types.h> // __WORDSIZE
|
||||
# include <unistd.h> // ssize_t
|
||||
typedef unsigned char uint8_t; ///< 8-bit unsigned type (backward compatibility)
|
||||
typedef unsigned short int uint16_t; ///< 16-bit unsigned type (backward compatibility)
|
||||
typedef unsigned char vluint8_t; ///< 8-bit unsigned type
|
||||
typedef unsigned short int vluint16_t; ///< 16-bit unsigned type
|
||||
# if defined(__uint32_t_defined) || defined(___int32_t_defined) // Newer Cygwin uint32_t in stdint.h as an unsigned int
|
||||
typedef int32_t vlsint32_t; ///< 32-bit signed type
|
||||
typedef uint32_t vluint32_t; ///< 32-bit unsigned type
|
||||
# else // Older Cygwin has long==uint32_t
|
||||
typedef unsigned long uint32_t; ///< 32-bit unsigned type (backward compatibility)
|
||||
typedef long vlsint32_t; ///< 32-bit signed type
|
||||
typedef unsigned long vluint32_t; ///< 32-bit unsigned type
|
||||
# endif
|
||||
# if defined(__WORDSIZE) && (__WORDSIZE == 64)
|
||||
typedef long vlsint64_t; ///< 64-bit signed type
|
||||
typedef unsigned long vluint64_t; ///< 64-bit unsigned type
|
||||
# else
|
||||
typedef long long vlsint64_t; ///< 64-bit signed type
|
||||
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||
# endif
|
||||
|
||||
#elif defined(_WIN32) && defined(_MSC_VER)
|
||||
|
||||
typedef unsigned __int8 uint8_t; ///< 8-bit unsigned type (backward compatibility)
|
||||
typedef unsigned __int16 uint16_t; ///< 16-bit unsigned type (backward compatibility)
|
||||
typedef unsigned __int32 uint32_t; ///< 32-bit unsigned type (backward compatibility)
|
||||
typedef unsigned __int8 vluint8_t; ///< 8-bit unsigned type
|
||||
typedef unsigned __int16 vluint16_t; ///< 16-bit unsigned type
|
||||
typedef signed __int32 vlsint32_t; ///< 32-bit signed type
|
||||
typedef unsigned __int32 vluint32_t; ///< 32-bit unsigned type
|
||||
typedef signed __int64 vlsint64_t; ///< 64-bit signed type
|
||||
typedef unsigned __int64 vluint64_t; ///< 64-bit unsigned type
|
||||
|
||||
# ifndef _SSIZE_T_DEFINED
|
||||
# ifdef _WIN64
|
||||
typedef signed __int64 ssize_t; ///< signed size_t; returned from read()
|
||||
# else
|
||||
typedef signed __int32 ssize_t; ///< signed size_t; returned from read()
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#else // Linux or compliant Unix flavors, -m64
|
||||
|
||||
# include <inttypes.h> // Solaris
|
||||
# include <stdint.h> // Linux and most flavors
|
||||
# include <sys/types.h> // __WORDSIZE
|
||||
# include <unistd.h> // ssize_t
|
||||
typedef uint8_t vluint8_t; ///< 32-bit unsigned type
|
||||
typedef uint16_t vluint16_t; ///< 32-bit unsigned type
|
||||
typedef int vlsint32_t; ///< 32-bit signed type
|
||||
typedef uint32_t vluint32_t; ///< 32-bit signed type
|
||||
# if defined(__WORDSIZE) && (__WORDSIZE == 64)
|
||||
typedef long vlsint64_t; ///< 64-bit signed type
|
||||
typedef unsigned long vluint64_t; ///< 64-bit unsigned type
|
||||
# else
|
||||
typedef long long vlsint64_t; ///< 64-bit signed type
|
||||
typedef unsigned long long vluint64_t; ///< 64-bit unsigned type
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// Printing printf/scanf formats
|
||||
// Alas cinttypes isn't that standard yet
|
||||
|
||||
// Use Microsoft-specific format specifiers for Microsoft Visual C++ only
|
||||
#ifdef _MSC_VER
|
||||
# define VL_PRI64 "I64"
|
||||
#else // use standard C99 format specifiers
|
||||
# ifdef __MINGW32__
|
||||
# define __USE_MINGW_ANSI_STDIO 1 // Force old MinGW (GCC 5 and older) to use C99 formats
|
||||
# define __STDC_FORMAT_MACROS 1 // Otherwise MinGW doesn't get PRId64 for fstapi.c
|
||||
# endif
|
||||
# if defined(__WORDSIZE) && (__WORDSIZE == 64)
|
||||
# define VL_PRI64 "l"
|
||||
# else
|
||||
# define VL_PRI64 "ll"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32) && defined(_MSC_VER)
|
||||
# if (_MSC_VER < 1900)
|
||||
# define VL_SNPRINTF _snprintf
|
||||
# else
|
||||
# define VL_SNPRINTF snprintf
|
||||
# endif
|
||||
# define VL_VSNPRINTF vsnprintf
|
||||
#else
|
||||
# define VL_SNPRINTF snprintf
|
||||
# define VL_VSNPRINTF vsnprintf
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// File system functions
|
||||
|
||||
#ifdef _WIN32
|
||||
# define VL_DEV_NULL "nul"
|
||||
#else // Linux or compliant Unix flavors
|
||||
# define VL_DEV_NULL "/dev/null"
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// Integer size macros
|
||||
|
||||
#define VL_WORDSIZE 32 ///< Bits in a word
|
||||
#define VL_QUADSIZE 64 ///< Bits in a quadword
|
||||
#define VL_WORDSIZE_LOG2 5 ///< log2(VL_WORDSIZE)
|
||||
#define VL_BYTESIZE 8 ///< Bits in a byte
|
||||
#define VL_SHORTSIZE 16 ///< Bits in a short
|
||||
#define VL_WORDSIZE 32 ///< Bits in a word
|
||||
#define VL_QUADSIZE 64 ///< Bits in a quadword
|
||||
#define VL_WORDSIZE_LOG2 5 ///< log2(VL_WORDSIZE)
|
||||
|
||||
/// Bytes this number of bits needs (1 bit=1 byte)
|
||||
#define VL_BYTES_I(nbits) (((nbits)+(VL_BYTESIZE-1))/VL_BYTESIZE)
|
||||
/// Words this number of bits needs (1 bit=1 word)
|
||||
#define VL_WORDS_I(nbits) (((nbits)+(VL_WORDSIZE-1))/VL_WORDSIZE)
|
||||
|
||||
//=========================================================================
|
||||
// Class definition helpers
|
||||
|
||||
// Used to declare a class as uncopyable; put after a private:
|
||||
#define VL_UNCOPYABLE(Type) \
|
||||
Type(const Type& other) VL_EQ_DELETE; \
|
||||
Type& operator= (const Type&) VL_EQ_DELETE
|
||||
|
||||
//=========================================================================
|
||||
// Verilated function size macros
|
||||
|
||||
#define VL_MULS_MAX_WORDS 16 ///< Max size in words of MULS operation
|
||||
#define VL_TO_STRING_MAX_WORDS 64 ///< Max size in words of String conversion operation
|
||||
#define VL_MULS_MAX_WORDS 16 ///< Max size in words of MULS operation
|
||||
#define VL_TO_STRING_MAX_WORDS 64 ///< Max size in words of String conversion operation
|
||||
|
||||
//=========================================================================
|
||||
// Base macros
|
||||
|
||||
#define VL_SIZEBITS_I (VL_WORDSIZE-1) ///< Bit mask for bits in a word
|
||||
#define VL_SIZEBITS_Q (VL_QUADSIZE-1) ///< Bit mask for bits in a quad
|
||||
#define VL_SIZEBITS_I (VL_WORDSIZE-1) ///< Bit mask for bits in a word
|
||||
#define VL_SIZEBITS_Q (VL_QUADSIZE-1) ///< Bit mask for bits in a quad
|
||||
|
||||
/// Mask for words with 1's where relevant bits are (0=all bits)
|
||||
#define VL_MASK_I(nbits) (((nbits) & VL_SIZEBITS_I) \
|
||||
? ((1U << ((nbits) & VL_SIZEBITS_I) )-1) : ~0)
|
||||
? ((1U << ((nbits) & VL_SIZEBITS_I) )-1) : ~0)
|
||||
/// Mask for quads with 1's where relevant bits are (0=all bits)
|
||||
#define VL_MASK_Q(nbits) (((nbits) & VL_SIZEBITS_Q) \
|
||||
? ((VL_ULL(1) << ((nbits) & VL_SIZEBITS_Q) )-VL_ULL(1)) : VL_ULL(~0))
|
||||
#define VL_BITWORD_I(bit) ((bit)/VL_WORDSIZE) ///< Word number for a wide quantity
|
||||
#define VL_BITBIT_I(bit) ((bit)&VL_SIZEBITS_I) ///< Bit number for a bit in a long
|
||||
#define VL_BITBIT_Q(bit) ((bit)&VL_SIZEBITS_Q) ///< Bit number for a bit in a quad
|
||||
? ((VL_ULL(1) << ((nbits) & VL_SIZEBITS_Q) )-VL_ULL(1)) : VL_ULL(~0))
|
||||
#define VL_BITWORD_I(bit) ((bit)/VL_WORDSIZE) ///< Word number for a wide quantity
|
||||
#define VL_BITBIT_I(bit) ((bit)&VL_SIZEBITS_I) ///< Bit number for a bit in a long
|
||||
#define VL_BITBIT_Q(bit) ((bit)&VL_SIZEBITS_Q) ///< Bit number for a bit in a quad
|
||||
|
||||
//=========================================================================
|
||||
// Floating point
|
||||
// #defines, to avoid requiring math.h on all compile runs
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# define VL_TRUNC(n) (((n)<0) ? ceil((n)) : floor((n)))
|
||||
# define VL_ROUND(n) (((n)<0) ? ceil((n)-0.5) : floor((n)+0.5))
|
||||
#else
|
||||
# define VL_TRUNC(n) trunc(n)
|
||||
# define VL_ROUND(n) round(n)
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// Performance counters
|
||||
|
||||
/// The vluint64_t argument is loaded with a high-performance counter for profiling
|
||||
/// or 0x0 if not implemeted on this platform
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
# define VL_RDTSC(val) { \
|
||||
vluint32_t hi, lo; \
|
||||
asm volatile("rdtsc" : "=a" (lo), "=d" (hi)); \
|
||||
(val) = ((vluint64_t)lo) | (((vluint64_t)hi)<<32); \
|
||||
}
|
||||
#elif defined(__aarch64__)
|
||||
# define VL_RDTSC(val) asm volatile("mrs %[rt],PMCCNTR_EL0" : [rt] "=r" (val));
|
||||
#else
|
||||
// We just silently ignore unknown OSes, as only leads to missing statistics
|
||||
# define VL_RDTSC(val) (val) = 0;
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
// Threading related OS-specific functions
|
||||
|
||||
#if VL_THREADED
|
||||
# if defined(__i386__) || defined(__x86_64__)
|
||||
/// For more efficient busy waiting on SMT CPUs, let the processor know
|
||||
/// we're just waiting so it can let another thread run
|
||||
# define VL_CPU_RELAX() asm volatile("rep; nop" ::: "memory")
|
||||
# elif defined(__ia64__)
|
||||
# define VL_CPU_RELAX() asm volatile("hint @pause" ::: "memory")
|
||||
# elif defined(__aarch64__)
|
||||
# define VL_CPU_RELAX() asm volatile("yield" ::: "memory")
|
||||
# elif defined(__powerpc64__)
|
||||
# define VL_CPU_RELAX() asm volatile("or 1, 1, 1; or 2, 2, 2;" ::: "memory")
|
||||
# else
|
||||
# error "Missing VL_CPU_RELAX() definition. Or, don't use VL_THREADED"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
//=========================================================================
|
||||
|
||||
|
||||
@@ -0,0 +1,495 @@
|
||||
/* -*- C -*-
|
||||
*
|
||||
* svdpi.h
|
||||
*
|
||||
* SystemVerilog Direct Programming Interface (DPI).
|
||||
*
|
||||
* This file contains the constant definitions, structure definitions,
|
||||
* and routine declarations used by SystemVerilog DPI.
|
||||
*
|
||||
* This file is from the SystemVerilog IEEE 1800-2017 Annex I.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDED_SVDPI
|
||||
#define INCLUDED_SVDPI
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Define size-critical types on all OS platforms. */
|
||||
#if defined (_MSC_VER)
|
||||
typedef unsigned __int64 uint64_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef signed __int64 int64_t;
|
||||
typedef signed __int32 int32_t;
|
||||
typedef signed __int8 int8_t;
|
||||
#elif defined(__MINGW32__)
|
||||
#include <stdint.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <stdint.h>
|
||||
#elif defined(__linux) || (defined(__APPLE__) && defined(__MACH__))
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
/* Use to import a symbol into dll */
|
||||
#ifndef DPI_DLLISPEC
|
||||
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
|
||||
#define DPI_DLLISPEC __declspec(dllimport)
|
||||
#else
|
||||
#define DPI_DLLISPEC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Use to export a symbol from dll */
|
||||
#ifndef DPI_DLLESPEC
|
||||
#if (defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__))
|
||||
#define DPI_DLLESPEC __declspec(dllexport)
|
||||
#else
|
||||
#define DPI_DLLESPEC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Use to mark a function as external */
|
||||
#ifndef DPI_EXTERN
|
||||
#define DPI_EXTERN
|
||||
#endif
|
||||
|
||||
#ifndef DPI_PROTOTYPES
|
||||
#define DPI_PROTOTYPES
|
||||
/* object is defined imported by the application */
|
||||
#define XXTERN DPI_EXTERN DPI_DLLISPEC
|
||||
/* object is exported by the application */
|
||||
#define EETERN DPI_EXTERN DPI_DLLESPEC
|
||||
#endif
|
||||
|
||||
/* canonical representation */
|
||||
#define sv_0 0
|
||||
#define sv_1 1
|
||||
#define sv_z 2
|
||||
#define sv_x 3
|
||||
|
||||
/* common type for 'bit' and 'logic' scalars. */
|
||||
typedef uint8_t svScalar;
|
||||
typedef svScalar svBit; /* scalar */
|
||||
typedef svScalar svLogic; /* scalar */
|
||||
|
||||
/*
|
||||
* DPI representation of packed arrays.
|
||||
* 2-state and 4-state vectors, exactly the same as PLI's avalue/bvalue.
|
||||
*/
|
||||
#ifndef VPI_VECVAL
|
||||
#define VPI_VECVAL
|
||||
typedef struct t_vpi_vecval {
|
||||
uint32_t aval;
|
||||
uint32_t bval;
|
||||
} s_vpi_vecval, *p_vpi_vecval;
|
||||
#endif
|
||||
|
||||
/* (a chunk of) packed logic array */
|
||||
typedef s_vpi_vecval svLogicVecVal;
|
||||
|
||||
/* (a chunk of) packed bit array */
|
||||
typedef uint32_t svBitVecVal;
|
||||
|
||||
/* Number of chunks required to represent the given width packed array */
|
||||
#define SV_PACKED_DATA_NELEMS(WIDTH) (((WIDTH) + 31) >> 5)
|
||||
|
||||
/*
|
||||
* Because the contents of the unused bits is undetermined,
|
||||
* the following macros can be handy.
|
||||
*/
|
||||
#define SV_MASK(N) (~(-1 << (N)))
|
||||
|
||||
#define SV_GET_UNSIGNED_BITS(VALUE, N) \
|
||||
((N) == 32 ? (VALUE) : ((VALUE) & SV_MASK(N)))
|
||||
|
||||
#define SV_GET_SIGNED_BITS(VALUE, N) \
|
||||
((N) == 32 ? (VALUE) : \
|
||||
(((VALUE) & (1 << (N))) ? ((VALUE) | ~SV_MASK(N)) : ((VALUE) & SV_MASK(N))))
|
||||
|
||||
/*
|
||||
* Implementation-dependent representation.
|
||||
*/
|
||||
/*
|
||||
* Return implementation version information string ("1800-2005" or "SV3.1a").
|
||||
*/
|
||||
XXTERN const char* svDpiVersion( void );
|
||||
|
||||
/* a handle to a scope (an instance of a module or interface) */
|
||||
XXTERN typedef void* svScope;
|
||||
|
||||
/* a handle to a generic object (actually, unsized array) */
|
||||
XXTERN typedef void* svOpenArrayHandle;
|
||||
|
||||
/*
|
||||
* Bit-select utility functions.
|
||||
*
|
||||
* Packed arrays are assumed to be indexed n-1:0,
|
||||
* where 0 is the index of LSB
|
||||
*/
|
||||
|
||||
/* s=source, i=bit-index */
|
||||
XXTERN svBit svGetBitselBit(const svBitVecVal* s, int i);
|
||||
XXTERN svLogic svGetBitselLogic(const svLogicVecVal* s, int i);
|
||||
|
||||
/* d=destination, i=bit-index, s=scalar */
|
||||
XXTERN void svPutBitselBit(svBitVecVal* d, int i, svBit s);
|
||||
XXTERN void svPutBitselLogic(svLogicVecVal* d, int i, svLogic s);
|
||||
|
||||
/*
|
||||
* Part-select utility functions.
|
||||
*
|
||||
* A narrow (<=32 bits) part-select is extracted from the
|
||||
* source representation and written into the destination word.
|
||||
*
|
||||
* Normalized ranges and indexing [n-1:0] are used for both arrays.
|
||||
*
|
||||
* s=source, d=destination, i=starting bit index, w=width
|
||||
* like for variable part-selects; limitations: w <= 32
|
||||
*/
|
||||
XXTERN void svGetPartselBit(svBitVecVal* d, const svBitVecVal* s, int i, int w);
|
||||
XXTERN void svGetPartselLogic(svLogicVecVal* d, const svLogicVecVal* s, int i, int w);
|
||||
|
||||
XXTERN void svPutPartselBit(svBitVecVal* d, const svBitVecVal s, int i, int w);
|
||||
XXTERN void svPutPartselLogic(svLogicVecVal* d, const svLogicVecVal s, int i, int w);
|
||||
|
||||
/*
|
||||
* Open array querying functions
|
||||
* These functions are modeled upon the SystemVerilog array
|
||||
* querying functions and use the same semantics.
|
||||
*
|
||||
* If the dimension is 0, then the query refers to the
|
||||
* packed part of an array (which is one-dimensional).
|
||||
* Dimensions > 0 refer to the unpacked part of an array.
|
||||
*/
|
||||
/* h= handle to open array, d=dimension */
|
||||
XXTERN int svLeft(const svOpenArrayHandle h, int d);
|
||||
XXTERN int svRight(const svOpenArrayHandle h, int d);
|
||||
XXTERN int svLow(const svOpenArrayHandle h, int d);
|
||||
XXTERN int svHigh(const svOpenArrayHandle h, int d);
|
||||
XXTERN int svIncrement(const svOpenArrayHandle h, int d);
|
||||
XXTERN int svSize(const svOpenArrayHandle h, int d);
|
||||
XXTERN int svDimensions(const svOpenArrayHandle h);
|
||||
|
||||
/*
|
||||
* Pointer to the actual representation of the whole array of any type
|
||||
* NULL if not in C layout
|
||||
*/
|
||||
XXTERN void *svGetArrayPtr(const svOpenArrayHandle);
|
||||
|
||||
/* total size in bytes or 0 if not in C layout */
|
||||
XXTERN int svSizeOfArray(const svOpenArrayHandle);
|
||||
|
||||
/*
|
||||
* Return a pointer to an element of the array
|
||||
* or NULL if index outside the range or null pointer
|
||||
*/
|
||||
XXTERN void *svGetArrElemPtr(const svOpenArrayHandle, int indx1, ...);
|
||||
|
||||
/* specialized versions for 1-, 2- and 3-dimensional arrays: */
|
||||
XXTERN void *svGetArrElemPtr1(const svOpenArrayHandle, int indx1);
|
||||
XXTERN void *svGetArrElemPtr2(const svOpenArrayHandle, int indx1, int indx2);
|
||||
XXTERN void *svGetArrElemPtr3(const svOpenArrayHandle, int indx1, int indx2,
|
||||
int indx3);
|
||||
|
||||
/*
|
||||
* Functions for copying between simulator storage and user space.
|
||||
* These functions copy the whole packed array in either direction.
|
||||
* The user is responsible for allocating an array to hold the
|
||||
* canonical representation.
|
||||
*/
|
||||
|
||||
/* s=source, d=destination */
|
||||
/* From user space into simulator storage */
|
||||
XXTERN void svPutBitArrElemVecVal(const svOpenArrayHandle d, const svBitVecVal* s,
|
||||
int indx1, ...);
|
||||
XXTERN void svPutBitArrElem1VecVal(const svOpenArrayHandle d, const svBitVecVal* s,
|
||||
int indx1);
|
||||
XXTERN void svPutBitArrElem2VecVal(const svOpenArrayHandle d, const svBitVecVal* s,
|
||||
int indx1, int indx2);
|
||||
XXTERN void svPutBitArrElem3VecVal(const svOpenArrayHandle d, const svBitVecVal* s,
|
||||
int indx1, int indx2, int indx3);
|
||||
|
||||
XXTERN void svPutLogicArrElemVecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
|
||||
int indx1, ...);
|
||||
XXTERN void svPutLogicArrElem1VecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
|
||||
int indx1);
|
||||
XXTERN void svPutLogicArrElem2VecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
|
||||
int indx1, int indx2);
|
||||
XXTERN void svPutLogicArrElem3VecVal(const svOpenArrayHandle d, const svLogicVecVal* s,
|
||||
int indx1, int indx2, int indx3);
|
||||
|
||||
/* From simulator storage into user space */
|
||||
XXTERN void svGetBitArrElemVecVal(svBitVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1, ...);
|
||||
XXTERN void svGetBitArrElem1VecVal(svBitVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1);
|
||||
XXTERN void svGetBitArrElem2VecVal(svBitVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1, int indx2);
|
||||
XXTERN void svGetBitArrElem3VecVal(svBitVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1, int indx2, int indx3);
|
||||
XXTERN void svGetLogicArrElemVecVal(svLogicVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1, ...);
|
||||
XXTERN void svGetLogicArrElem1VecVal(svLogicVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1);
|
||||
XXTERN void svGetLogicArrElem2VecVal(svLogicVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1, int indx2);
|
||||
XXTERN void svGetLogicArrElem3VecVal(svLogicVecVal* d, const svOpenArrayHandle s,
|
||||
int indx1, int indx2, int indx3);
|
||||
|
||||
XXTERN svBit svGetBitArrElem(const svOpenArrayHandle s, int indx1, ...);
|
||||
XXTERN svBit svGetBitArrElem1(const svOpenArrayHandle s, int indx1);
|
||||
XXTERN svBit svGetBitArrElem2(const svOpenArrayHandle s, int indx1, int indx2);
|
||||
XXTERN svBit svGetBitArrElem3(const svOpenArrayHandle s, int indx1, int indx2,
|
||||
int indx3);
|
||||
XXTERN svLogic svGetLogicArrElem(const svOpenArrayHandle s, int indx1, ...);
|
||||
XXTERN svLogic svGetLogicArrElem1(const svOpenArrayHandle s, int indx1);
|
||||
XXTERN svLogic svGetLogicArrElem2(const svOpenArrayHandle s, int indx1, int indx2);
|
||||
XXTERN svLogic svGetLogicArrElem3(const svOpenArrayHandle s, int indx1, int indx2,
|
||||
int indx3);
|
||||
XXTERN void svPutLogicArrElem(const svOpenArrayHandle d, svLogic value, int indx1,
|
||||
...);
|
||||
XXTERN void svPutLogicArrElem1(const svOpenArrayHandle d, svLogic value, int indx1);
|
||||
XXTERN void svPutLogicArrElem2(const svOpenArrayHandle d, svLogic value, int indx1,
|
||||
int indx2);
|
||||
XXTERN void svPutLogicArrElem3(const svOpenArrayHandle d, svLogic value, int indx1,
|
||||
int indx2, int indx3);
|
||||
XXTERN void svPutBitArrElem(const svOpenArrayHandle d, svBit value, int indx1, ...);
|
||||
XXTERN void svPutBitArrElem1(const svOpenArrayHandle d, svBit value, int indx1);
|
||||
XXTERN void svPutBitArrElem2(const svOpenArrayHandle d, svBit value, int indx1,
|
||||
int indx2);
|
||||
XXTERN void svPutBitArrElem3(const svOpenArrayHandle d, svBit value, int indx1,
|
||||
int indx2, int indx3);
|
||||
|
||||
/* Functions for working with DPI context */
|
||||
|
||||
/*
|
||||
* Retrieve the active instance scope currently associated with the executing
|
||||
* imported function. Unless a prior call to svSetScope has occurred, this
|
||||
* is the scope of the function's declaration site, not call site.
|
||||
* Returns NULL if called from C code that is *not* an imported function.
|
||||
*/
|
||||
XXTERN svScope svGetScope( void );
|
||||
|
||||
/*
|
||||
* Set context for subsequent export function execution.
|
||||
* This function must be called before calling an export function, unless
|
||||
* the export function is called while executing an import function. In that
|
||||
* case the export function shall inherit the scope of the surrounding import
|
||||
* function. This is known as the "default scope".
|
||||
* The return is the previous active scope (per svGetScope)
|
||||
*/
|
||||
XXTERN svScope svSetScope(const svScope scope);
|
||||
|
||||
/* Gets the fully qualified name of a scope handle */
|
||||
XXTERN const char* svGetNameFromScope(const svScope);
|
||||
|
||||
/*
|
||||
* Retrieve svScope to instance scope of an arbitrary function declaration.
|
||||
* (can be either module, program, interface, or generate scope)
|
||||
* The return value shall be NULL for unrecognized scope names.
|
||||
*/
|
||||
XXTERN svScope svGetScopeFromName(const char* scopeName);
|
||||
|
||||
/*
|
||||
* Store an arbitrary user data pointer for later retrieval by svGetUserData()
|
||||
* The userKey is generated by the user. It must be guaranteed by the user to
|
||||
* be unique from all other userKey's for all unique data storage requirements
|
||||
* It is recommended that the address of static functions or variables in the
|
||||
* user's C code be used as the userKey.
|
||||
* It is illegal to pass in NULL values for either the scope or userData
|
||||
* arguments. It is also an error to call svPutUserData() with an invalid
|
||||
* svScope. This function returns -1 for all error cases, 0 upon success. It is
|
||||
* suggested that userData values of 0 (NULL) not be used as otherwise it can
|
||||
* be impossible to discern error status returns when calling svGetUserData()
|
||||
*/
|
||||
XXTERN int svPutUserData(const svScope scope, void *userKey, void* userData);
|
||||
|
||||
/*
|
||||
* Retrieve an arbitrary user data pointer that was previously
|
||||
* stored by a call to svPutUserData(). See the comment above
|
||||
* svPutUserData() for an explanation of userKey, as well as
|
||||
* restrictions on NULL and illegal svScope and userKey values.
|
||||
* This function returns NULL for all error cases, 0 upon success.
|
||||
* This function also returns NULL in the event that a prior call
|
||||
* to svPutUserData() was never made.
|
||||
*/
|
||||
XXTERN void* svGetUserData(const svScope scope, void* userKey);
|
||||
|
||||
/*
|
||||
* Returns the file and line number in the SV code from which the import call
|
||||
* was made. If this information available, returns TRUE and updates fileName
|
||||
* and lineNumber to the appropriate values. Behavior is unpredictable if
|
||||
* fileName or lineNumber are not appropriate pointers. If this information is
|
||||
* not available return FALSE and contents of fileName and lineNumber not
|
||||
* modified. Whether this information is available or not is implementation-
|
||||
* specific. Note that the string provided (if any) is owned by the SV
|
||||
* implementation and is valid only until the next call to any SV function.
|
||||
* Applications must not modify this string or free it
|
||||
*/
|
||||
XXTERN int svGetCallerInfo(const char** fileName, int *lineNumber);
|
||||
|
||||
/*
|
||||
* Returns 1 if the current execution thread is in the disabled state.
|
||||
* Disable protocol must be adhered to if in the disabled state.
|
||||
*/
|
||||
XXTERN int svIsDisabledState( void );
|
||||
|
||||
/*
|
||||
* Imported functions call this API function during disable processing to
|
||||
* acknowledge that they are correctly participating in the DPI disable protocol.
|
||||
* This function must be called before returning from an imported function that is
|
||||
* in the disabled state.
|
||||
*/
|
||||
XXTERN void svAckDisabledState( void );
|
||||
|
||||
/*
|
||||
**********************************************************
|
||||
* DEPRECATED PORTION OF FILE STARTS FROM HERE.
|
||||
* IEEE-1800-compliant tools may not provide
|
||||
* support for the following functionality.
|
||||
**********************************************************
|
||||
*/
|
||||
|
||||
/*
|
||||
* Canonical representation of packed arrays
|
||||
* 2-state and 4-state vectors, modeled upon PLI's avalue/bvalue
|
||||
*/
|
||||
#define SV_CANONICAL_SIZE(WIDTH) (((WIDTH)+31)>>5)
|
||||
typedef unsigned int svBitVec32;/* (a chunk of) packed bit array */
|
||||
typedef struct { unsigned int c; unsigned int d;}
|
||||
svLogicVec32; /* (a chunk of) packed logic array */
|
||||
|
||||
/* reference to a standalone packed array */
|
||||
typedef void* svBitPackedArrRef;
|
||||
typedef void* svLogicPackedArrRef;
|
||||
|
||||
/*
|
||||
* total size in bytes of the simulator's representation of a packed array
|
||||
* width in bits
|
||||
*/
|
||||
XXTERN int svSizeOfBitPackedArr(int width);
|
||||
XXTERN int svSizeOfLogicPackedArr(int width);
|
||||
|
||||
/* Translation between the actual representation and the canonical representation */
|
||||
|
||||
/* s=source, d=destination, w=width */
|
||||
/* actual <-- canonical */
|
||||
XXTERN void svPutBitVec32(svBitPackedArrRef d, const svBitVec32* s, int w);
|
||||
XXTERN void svPutLogicVec32(svLogicPackedArrRef d, const svLogicVec32* s, int w);
|
||||
|
||||
/* canonical <-- actual */
|
||||
XXTERN void svGetBitVec32(svBitVec32* d, const svBitPackedArrRef s, int w);
|
||||
XXTERN void svGetLogicVec32(svLogicVec32* d, const svLogicPackedArrRef s, int w);
|
||||
|
||||
/*
|
||||
* Bit-select functions
|
||||
* Packed arrays are assumed to be indexed n-1:0,
|
||||
* where 0 is the index of LSB
|
||||
*/
|
||||
|
||||
/* s=source, i=bit-index */
|
||||
XXTERN svBit svGetSelectBit(const svBitPackedArrRef s, int i);
|
||||
XXTERN svLogic svGetSelectLogic(const svLogicPackedArrRef s, int i);
|
||||
|
||||
/* d=destination, i=bit-index, s=scalar */
|
||||
XXTERN void svPutSelectBit(svBitPackedArrRef d, int i, svBit s);
|
||||
XXTERN void svPutSelectLogic(svLogicPackedArrRef d, int i, svLogic s);
|
||||
|
||||
/*
|
||||
* functions for part-select
|
||||
*
|
||||
* a narrow (<=32 bits) part-select is copied between
|
||||
* the implementation representation and a single chunk of
|
||||
* canonical representation
|
||||
* Normalized ranges and indexing [n-1:0] are used for both arrays:
|
||||
* the array in the implementation representation and the canonical array.
|
||||
*
|
||||
* s=source, d=destination, i=starting bit index, w=width
|
||||
* like for variable part-selects; limitations: w <= 32
|
||||
*/
|
||||
|
||||
/* canonical <-- actual */
|
||||
XXTERN void svGetPartSelectBit(svBitVec32* d, const svBitPackedArrRef s,
|
||||
int i, int w);
|
||||
XXTERN svBitVec32 svGetBits(const svBitPackedArrRef s, int i, int w);
|
||||
XXTERN svBitVec32 svGet32Bits(const svBitPackedArrRef s, int i); /* 32-bits */
|
||||
|
||||
XXTERN uint64_t svGet64Bits(const svBitPackedArrRef s, int i);
|
||||
|
||||
/* 64-bits */
|
||||
XXTERN void svGetPartSelectLogic(svLogicVec32* d, const svLogicPackedArrRef s,
|
||||
int i, int w);
|
||||
/* actual <-- canonical */
|
||||
XXTERN void svPutPartSelectBit(svBitPackedArrRef d, const svBitVec32 s,
|
||||
int i, int w);
|
||||
XXTERN void svPutPartSelectLogic(svLogicPackedArrRef d, const svLogicVec32* s,
|
||||
int i, int w);
|
||||
|
||||
/*
|
||||
* Functions for open array translation between simulator and canonical
|
||||
* representations. These functions copy the whole packed array in either
|
||||
* direction. The user is responsible for allocating an array in the
|
||||
* canonical representation.
|
||||
*/
|
||||
|
||||
/* s=source, d=destination */
|
||||
/* actual <-- canonical */
|
||||
XXTERN void svPutBitArrElemVec32(const svOpenArrayHandle d, const svBitVec32* s,
|
||||
int indx1, ...);
|
||||
XXTERN void svPutBitArrElem1Vec32(const svOpenArrayHandle d, const svBitVec32* s,
|
||||
int indx1);
|
||||
XXTERN void svPutBitArrElem2Vec32(const svOpenArrayHandle d, const svBitVec32* s,
|
||||
int indx1, int indx2);
|
||||
XXTERN void svPutBitArrElem3Vec32(const svOpenArrayHandle d, const svBitVec32* s,
|
||||
int indx1, int indx2, int indx3);
|
||||
XXTERN void svPutLogicArrElemVec32(const svOpenArrayHandle d, const svLogicVec32* s,
|
||||
int indx1, ...);
|
||||
XXTERN void svPutLogicArrElem1Vec32(const svOpenArrayHandle d, const svLogicVec32* s,
|
||||
int indx1);
|
||||
XXTERN void svPutLogicArrElem2Vec32(const svOpenArrayHandle d, const svLogicVec32* s,
|
||||
int indx1, int indx2);
|
||||
XXTERN void svPutLogicArrElem3Vec32(const svOpenArrayHandle d, const svLogicVec32* s,
|
||||
int indx1, int indx2, int indx3);
|
||||
|
||||
/* canonical <-- actual */
|
||||
XXTERN void svGetBitArrElemVec32(svBitVec32* d, const svOpenArrayHandle s,
|
||||
int indx1, ...);
|
||||
XXTERN void svGetBitArrElem1Vec32(svBitVec32* d, const svOpenArrayHandle s,
|
||||
int indx1);
|
||||
XXTERN void svGetBitArrElem2Vec32(svBitVec32* d, const svOpenArrayHandle s,
|
||||
int indx1, int indx2);
|
||||
XXTERN void svGetBitArrElem3Vec32(svBitVec32* d, const svOpenArrayHandle s,
|
||||
int indx1, int indx2, int indx3);
|
||||
XXTERN void svGetLogicArrElemVec32(svLogicVec32* d, const svOpenArrayHandle s,
|
||||
int indx1, ...);
|
||||
XXTERN void svGetLogicArrElem1Vec32(svLogicVec32* d, const svOpenArrayHandle s,
|
||||
int indx1);
|
||||
XXTERN void svGetLogicArrElem2Vec32(svLogicVec32* d, const svOpenArrayHandle s,
|
||||
int indx1, int indx2);
|
||||
XXTERN void svGetLogicArrElem3Vec32(svLogicVec32* d, const svOpenArrayHandle s,
|
||||
int indx1, int indx2, int indx3);
|
||||
|
||||
/*
|
||||
**********************************************************
|
||||
* DEPRECATED PORTION OF FILE ENDS HERE.
|
||||
**********************************************************
|
||||
*/
|
||||
|
||||
#undef DPI_EXTERN
|
||||
|
||||
#ifdef DPI_PROTOTYPES
|
||||
#undef DPI_PROTOTYPES
|
||||
#undef XXTERN
|
||||
#undef EETERN
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
+8
-8
@@ -115,7 +115,7 @@ fi
|
||||
if [ x"$dir_arg" != x ]; then
|
||||
dst=$src
|
||||
src=""
|
||||
|
||||
|
||||
if [ -d $dst ]; then
|
||||
instcmd=:
|
||||
else
|
||||
@@ -124,7 +124,7 @@ if [ x"$dir_arg" != x ]; then
|
||||
else
|
||||
|
||||
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# might cause directories to be created, which would be especially bad
|
||||
# if $src (and thus $dsttmp) contains '*'.
|
||||
|
||||
if [ -f $src -o -d $src ]
|
||||
@@ -134,7 +134,7 @@ else
|
||||
echo "install: $src does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ x"$dst" = x ]
|
||||
then
|
||||
echo "install: no destination specified"
|
||||
@@ -162,7 +162,7 @@ dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
|
||||
|
||||
# Skip lots of stat calls in the usual case.
|
||||
if [ ! -d "$dstdir" ]; then
|
||||
defaultIFS='
|
||||
defaultIFS='
|
||||
'
|
||||
IFS="${IFS-${defaultIFS}}"
|
||||
|
||||
@@ -201,17 +201,17 @@ else
|
||||
|
||||
# If we're going to rename the final executable, determine the name now.
|
||||
|
||||
if [ x"$transformarg" = x ]
|
||||
if [ x"$transformarg" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
dstfile=`basename $dst $transformbasename |
|
||||
sed $transformarg`$transformbasename
|
||||
fi
|
||||
|
||||
# don't allow the sed command to completely eliminate the filename
|
||||
|
||||
if [ x"$dstfile" = x ]
|
||||
if [ x"$dstfile" = x ]
|
||||
then
|
||||
dstfile=`basename $dst`
|
||||
else
|
||||
@@ -242,7 +242,7 @@ else
|
||||
# Now rename the file to the real destination.
|
||||
|
||||
$doit $rmcmd -f $dstdir/$dstfile &&
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
$doit $mvcmd $dsttmp $dstdir/$dstfile
|
||||
|
||||
fi &&
|
||||
|
||||
|
||||
+1006
File diff suppressed because it is too large
Load Diff
Executable
+85
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2007-2019 by Wilson Snyder. This package is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
######################################################################
|
||||
|
||||
# DESCRIPTION: Diff bison files
|
||||
|
||||
use Getopt::Long;
|
||||
use IO::File;
|
||||
use strict;
|
||||
|
||||
our $Debug;
|
||||
our $Opt_Unsup;
|
||||
|
||||
if (! GetOptions (
|
||||
#"help" => \&usage,
|
||||
"debug" => sub { $Debug = 1; },
|
||||
"unsup!" => \$Opt_Unsup, # Ignore unsupported
|
||||
)) {
|
||||
die "usage();"
|
||||
}
|
||||
|
||||
diff($ARGV[0],$ARGV[1]);
|
||||
|
||||
sub diff {
|
||||
my $a=shift;
|
||||
my $b=shift;
|
||||
|
||||
my $ta = "/tmp/bisondiff.$$.a";
|
||||
my $tb = "/tmp/bisondiff.$$.b";
|
||||
|
||||
prep($a,$ta);
|
||||
prep($b,$tb);
|
||||
|
||||
system("diff -u -w $ta $tb");
|
||||
}
|
||||
|
||||
sub prep {
|
||||
my $filename = shift;
|
||||
my $wfilename = shift;
|
||||
|
||||
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename";
|
||||
my $fho = IO::File->new(">$wfilename") or die "%Error: $! writing $wfilename";
|
||||
|
||||
my %declared;
|
||||
my %used;
|
||||
|
||||
my $body = 0;
|
||||
my $rule = "";
|
||||
my $skip = 1;
|
||||
while (defined(my $line = $fh->getline)) {
|
||||
if ($skip == 1) {
|
||||
next if $line !~ /%token/;
|
||||
$skip = 2;
|
||||
}
|
||||
|
||||
if ($Opt_Unsup) {
|
||||
$line =~ s!//UNSUP!|!g;
|
||||
$line =~ s!(\s+)\|(\s+)!$1$2!g; # As "UNSUP" often replaces "|"
|
||||
}
|
||||
|
||||
# %type<foo>
|
||||
$line =~ s/^(%\S+)<(\S+)>/$1/;
|
||||
# rule<foo>
|
||||
$line =~ s/^([a-zA-Z0-9_]+)<\S+>:/$1:/;
|
||||
# Productions
|
||||
$line =~ s/[ \t]{[^}]*?}/\t{}/g;
|
||||
|
||||
$fho->print($line);
|
||||
}
|
||||
}
|
||||
|
||||
# Local Variables:
|
||||
# compile-command: "./bisondiff --unsup $VP/Parser/VParseBison.y ../src/verilog.y"
|
||||
# End:
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2007-2019 by Wilson Snyder. This package is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
######################################################################
|
||||
|
||||
# DESCRIPTION: Debugging of bison output
|
||||
|
||||
use strict;
|
||||
|
||||
my $Debug;
|
||||
|
||||
my %declared;
|
||||
my %used;
|
||||
|
||||
my $body = 0;
|
||||
my $rule = "";
|
||||
my $lineno = 0;
|
||||
foreach my $line (<STDIN>) {
|
||||
$lineno++;
|
||||
chomp $line;
|
||||
$line =~ s!//.*$!!g;
|
||||
$line =~ s!\s+! !g;
|
||||
next if $line eq '';
|
||||
if ($line =~ m!^\%\%!) {
|
||||
$body++;
|
||||
} elsif ($body == 1) {
|
||||
$rule .= $line;
|
||||
if ($line =~ m!^\s*;\s*$!) {
|
||||
#print "Rule: $rule\n";
|
||||
($rule =~ /^([a-zA-Z0-9_]+)(<\S+>)?:(.*)$/) or die "%Error: No rule name: $1\n";
|
||||
my $rulename = $1; my $preaction = $3;
|
||||
$declared{$rulename} = $lineno;
|
||||
$preaction =~ s/\{[^\}]*\}/ /g;
|
||||
#print "RULEN $rulename PA $preaction\n" if $Debug;
|
||||
$rule = '';
|
||||
foreach my $ref (split /\s+/, $preaction) {
|
||||
next if $ref !~ /^[a-zA-Z]/;
|
||||
next if $ref eq $rulename;
|
||||
if (!$used{$ref} && $declared{$ref}) {
|
||||
print " %Warning: $lineno: $ref used by $rulename after declaration\n";
|
||||
}
|
||||
$used{$ref} = $lineno;
|
||||
print " ref $ref\n" if $Debug;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Local Variables:
|
||||
# compile-command: "./bisonreader < ../src/verilog.y"
|
||||
# End:
|
||||
Executable
+161
@@ -0,0 +1,161 @@
|
||||
#!/usr/bin/perl -w
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
require 5.006_001;
|
||||
use Getopt::Long;
|
||||
use IO::File;
|
||||
use Pod::Usage;
|
||||
use Data::Dumper; $Data::Dumper::Indent=1;
|
||||
use strict;
|
||||
use vars qw($Debug);
|
||||
|
||||
#======================================================================
|
||||
|
||||
our @Header;
|
||||
our %Vertexes;
|
||||
our @Edges;
|
||||
our %Edges;
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
$Debug = 0;
|
||||
my $opt_filename;
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
if (! GetOptions(
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
usage();
|
||||
}
|
||||
|
||||
dotread($opt_filename);
|
||||
cwrite("graph_export.cpp");
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sub debug {
|
||||
$Debug = 1;
|
||||
}
|
||||
|
||||
sub parameter {
|
||||
my $param = shift;
|
||||
if (!$opt_filename) {
|
||||
$opt_filename = $param;
|
||||
} else {
|
||||
die "%Error: Unknown parameter: $param\n";
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
|
||||
sub dotread {
|
||||
my $filename = shift;
|
||||
|
||||
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
|
||||
my $header = 1;
|
||||
my $vnum = 0;
|
||||
while (defined (my $line = $fh->getline)) {
|
||||
if ($line =~ /^\t([a-zA-Z0-9_]+)\t(.*)$/) {
|
||||
next if $1 eq 'nTITLE';
|
||||
$header = 0;
|
||||
$Vertexes{$1} = {num => $vnum++,
|
||||
line => $line,
|
||||
name => $1,};
|
||||
}
|
||||
elsif ($line =~ /^\t([a-zA-Z0-9_]+)\s+->\s+([a-zA-Z0-9_]+)\s+(.*)$/) {
|
||||
my $from=$1; my $to=$2;
|
||||
my $weight = 1; $weight = $1 if $line =~ /weight=(\d+)/;
|
||||
my $cutable = undef; $cutable = $1 if $line =~ /style=(\S+)/;
|
||||
my $edge = {num => $vnum++,
|
||||
line => $line,
|
||||
weight => $weight,
|
||||
cutable => $cutable,
|
||||
from => $from,
|
||||
to => $to,};
|
||||
push @Edges, $edge;
|
||||
$Edges{$from}{$to} = $edge;
|
||||
}
|
||||
elsif ($header) {
|
||||
push @Header, $line;
|
||||
print "IGNORE: $line";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
|
||||
sub cwrite {
|
||||
my $filename = shift;
|
||||
|
||||
my $fh = IO::File->new(">$filename") or die "%Error: $! $filename,";
|
||||
$fh->print("void V3GraphTestImport::dotImport() {\n");
|
||||
$fh->print(" DfaGraph* gp = &m_graph;\n");
|
||||
foreach my $ver (sort {$a->{num} <=> $b->{num}} (values %Vertexes)) {
|
||||
$fh->printf(" V3GraphTestVertex* %s = new V3GraphTestVertex(gp, \"%s\"); if (%s) {}\n",
|
||||
$ver->{name}, $ver->{name}, $ver->{name});
|
||||
}
|
||||
$fh->print("\n");
|
||||
foreach my $edge (@Edges) {
|
||||
$fh->printf(" new V3GraphEdge(gp, %s, %s, %s, %s);\n",
|
||||
$edge->{from}, $edge->{to},
|
||||
$edge->{weight}, $edge->{cutable}?"true":"false");
|
||||
}
|
||||
$fh->print("}\n");
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
dot_importer - Take graph .dot file and convert into .cpp file
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
dot_importer a.dot
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Dot_importer takes a graphvis .dot file and converts into .cpp file. This
|
||||
.cpp file is then manually included in V3GraphTest.cpp to verify various
|
||||
sub-algorithms.
|
||||
|
||||
=head1 ARGUMENTS
|
||||
|
||||
=over 4
|
||||
|
||||
=item --help
|
||||
|
||||
Displays this message and program version and exits.
|
||||
|
||||
=back
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2019 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Wilson Snyder <[email protected]>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
=cut
|
||||
|
||||
######################################################################
|
||||
### Local Variables:
|
||||
### compile-command: "./dot_importer | tee ~/d/a.dot"
|
||||
### End:
|
||||
+44
-57
@@ -1,17 +1,5 @@
|
||||
#!/usr/bin/perl -w
|
||||
# $Id$
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2005-2007 by Wilson Snyder <[email protected]>. This
|
||||
# program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of either the GNU Lesser General Public License or the Perl
|
||||
# Artistic License.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
require 5.006_001;
|
||||
@@ -20,7 +8,7 @@ use IO::File;
|
||||
use Pod::Usage;
|
||||
use Data::Dumper; $Data::Dumper::Indent=1;
|
||||
use strict;
|
||||
use vars qw ($Debug);
|
||||
use vars qw($Debug);
|
||||
|
||||
#======================================================================
|
||||
|
||||
@@ -38,16 +26,16 @@ my $opt_filename;
|
||||
my $opt_circle;
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
if (! GetOptions (
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
"circle=s" => \$opt_circle,
|
||||
)) {
|
||||
if (! GetOptions(
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
"circle=s" => \$opt_circle,
|
||||
)) {
|
||||
usage();
|
||||
}
|
||||
|
||||
dotread ($opt_filename);
|
||||
dotread($opt_filename);
|
||||
circle($opt_circle) if $opt_circle;
|
||||
simplify();
|
||||
dotwrite();
|
||||
@@ -55,9 +43,8 @@ dotwrite();
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
print '$Id$ ', "\n";
|
||||
pod2usage(-verbose=>2, -exitval => 2);
|
||||
exit (1);
|
||||
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sub debug {
|
||||
@@ -67,9 +54,9 @@ sub debug {
|
||||
sub parameter {
|
||||
my $param = shift;
|
||||
if (!$opt_filename) {
|
||||
$opt_filename = $param;
|
||||
$opt_filename = $param;
|
||||
} else {
|
||||
die "%Error: Unknown parameter: $param\n";
|
||||
die "%Error: Unknown parameter: $param\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,16 +68,16 @@ sub dotread {
|
||||
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
|
||||
my $header = 1;
|
||||
while (defined (my $line = $fh->getline)) {
|
||||
if ($line =~ /^\t([a-zA-Z0-9_]+)\t(.*)$/) {
|
||||
$header = 0;
|
||||
$Vertexes{$1} = $2;
|
||||
}
|
||||
elsif ($line =~ /^\t([a-zA-Z0-9_]+)\s+->\s+([a-zA-Z0-9_]+)\s+(.*)$/) {
|
||||
$Edges{$1}{$2} = $3;
|
||||
}
|
||||
elsif ($header) {
|
||||
push @Header, $line;
|
||||
}
|
||||
if ($line =~ /^\t([a-zA-Z0-9_]+)\t(.*)$/) {
|
||||
$header = 0;
|
||||
$Vertexes{$1} = $2;
|
||||
}
|
||||
elsif ($line =~ /^\t([a-zA-Z0-9_]+)\s+->\s+([a-zA-Z0-9_]+)\s+(.*)$/) {
|
||||
$Edges{$1}{$2} = $3;
|
||||
}
|
||||
elsif ($header) {
|
||||
push @Header, $line;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,12 +85,12 @@ sub dotread {
|
||||
|
||||
sub simplify {
|
||||
foreach my $ver (sort (keys %Vertexes)) {
|
||||
$Vertexes{$ver} = _simplify($Vertexes{$ver});
|
||||
$Vertexes{$ver} = _simplify($Vertexes{$ver});
|
||||
}
|
||||
foreach my $v1 (sort (keys %Edges)) {
|
||||
foreach my $v2 (sort (keys %{$Edges{$v1}})) {
|
||||
$Edges{$v1}{$v2} = _simplify($Edges{$v1}{$v2});
|
||||
}
|
||||
foreach my $v2 (sort (keys %{$Edges{$v1}})) {
|
||||
$Edges{$v1}{$v2} = _simplify($Edges{$v1}{$v2});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,15 +103,15 @@ sub _simplify {
|
||||
|
||||
sub dotwrite {
|
||||
foreach my $line (@Header) {
|
||||
print "$line";
|
||||
print "$line";
|
||||
}
|
||||
foreach my $ver (sort (keys %Vertexes)) {
|
||||
print "\t$ver\t$Vertexes{$ver}\n";
|
||||
print "\t$ver\t$Vertexes{$ver}\n";
|
||||
}
|
||||
foreach my $v1 (sort (keys %Edges)) {
|
||||
foreach my $v2 (sort (keys %{$Edges{$v1}})) {
|
||||
print "\t$v1 -> $v2\t$Edges{$v1}{$v2}\n";
|
||||
}
|
||||
foreach my $v2 (sort (keys %{$Edges{$v1}})) {
|
||||
print "\t$v1 -> $v2\t$Edges{$v1}{$v2}\n";
|
||||
}
|
||||
}
|
||||
print "}\n";
|
||||
}
|
||||
@@ -138,15 +125,15 @@ sub circle {
|
||||
_circle_recurse($node, 1);
|
||||
|
||||
foreach my $ver (keys %Vertexes) {
|
||||
if (!$User{$ver}) {
|
||||
delete $Vertexes{$ver};
|
||||
delete $Edges{$ver};
|
||||
}
|
||||
if (!$User{$ver}) {
|
||||
delete $Vertexes{$ver};
|
||||
delete $Edges{$ver};
|
||||
}
|
||||
}
|
||||
foreach my $v1 (sort (keys %Edges)) {
|
||||
foreach my $v2 (sort (keys %{$Edges{$v1}})) {
|
||||
if (!$Vertexes{$v2}) { delete $Edges{$v1}{$v2}; }
|
||||
}
|
||||
foreach my $v2 (sort (keys %{$Edges{$v1}})) {
|
||||
if (!$Vertexes{$v2}) { delete $Edges{$v1}{$v2}; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +148,7 @@ sub _circle_recurse {
|
||||
$User2{$node} = 1;
|
||||
my $r = 0;
|
||||
foreach my $v2 (keys %{$Edges{$node}}) {
|
||||
$r |= _circle_recurse($v2,$level++)||0;
|
||||
$r |= _circle_recurse($v2,$level++)||0;
|
||||
}
|
||||
$User{$node} = 1 if $r;
|
||||
$User2{$node} = 2;
|
||||
@@ -175,7 +162,7 @@ __END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
dot_pruner -
|
||||
dot_pruner -
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
@@ -197,9 +184,9 @@ Displays this message and program version and exits.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2007 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 or the Perl Artistic License.
|
||||
Copyright 2005-2019 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
|
||||
Executable
+64
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/perl -w
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2007-2019 by Wilson Snyder. This package is free software; you
|
||||
# can redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
######################################################################
|
||||
|
||||
# DESCRIPTION: Diff flex files
|
||||
|
||||
use IO::File;
|
||||
use strict;
|
||||
|
||||
my $Debug;
|
||||
|
||||
diff($ARGV[0],$ARGV[1]);
|
||||
|
||||
sub diff {
|
||||
my $a=shift;
|
||||
my $b=shift;
|
||||
|
||||
my $ta = "/tmp/flexdiff.$$.a";
|
||||
my $tb = "/tmp/flexdiff.$$.b";
|
||||
|
||||
prep($a,$ta);
|
||||
prep($b,$tb);
|
||||
|
||||
system("diff -u -w $ta $tb");
|
||||
}
|
||||
|
||||
sub prep {
|
||||
my $filename = shift;
|
||||
my $wfilename = shift;
|
||||
|
||||
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename";
|
||||
my $fho = IO::File->new(">$wfilename") or die "%Error: $! writing $wfilename";
|
||||
|
||||
my %declared;
|
||||
my %used;
|
||||
my @lines;
|
||||
|
||||
while (defined(my $line = $fh->getline)) {
|
||||
# Productions
|
||||
#$line =~ s/[ \t]{[^}]*?}/\t{}/g;
|
||||
$line =~ s/StashPrefix;//g;
|
||||
$line =~ s/VALTEXT;//g;
|
||||
$line =~ s/CALLBACK\([^)]*\);//g;
|
||||
push @lines, $line;
|
||||
}
|
||||
|
||||
#@lines = sort @lines;
|
||||
$fho->print(@lines);
|
||||
}
|
||||
|
||||
# Local Variables:
|
||||
# compile-command: "./flexdiff $VP/Parser/VParseLex.l ../src/verilog.l"
|
||||
# End:
|
||||
Executable
+249
@@ -0,0 +1,249 @@
|
||||
#!/usr/bin/perl -w
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
use Getopt::Long;
|
||||
#use Data::Dumper; $Data::Dumper::Indent=1; $Data::Dumper::Sortkeys=1; #Debug
|
||||
use IO::File;
|
||||
use IO::Dir;
|
||||
use Pod::Usage;
|
||||
use strict;
|
||||
use vars qw($Debug);
|
||||
|
||||
our $VERSION = '0.001';
|
||||
our $Opt_Widen = 1;
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
Getopt::Long::config("no_auto_abbrev");
|
||||
if (! GetOptions (
|
||||
"debug" => sub { $Debug = 1; },
|
||||
"help" => sub { print "Version $VERSION\n";
|
||||
pod2usage(-verbose=>2, -exitval => 2, output=>\*STDOUT, -noperldoc=>1); },
|
||||
"narrow!" => sub { $Opt_Widen = 0; },
|
||||
"version" => sub { print "Version $VERSION\n"; exit(0); },
|
||||
"widen!" => sub { $Opt_Widen = 1; }, # Default, undocumented
|
||||
"<>" => sub { die "%Error: Unknown parameter: $_[0]\n"; },
|
||||
)) {
|
||||
die "%Error: Bad usage, try 'git_untabify --help'\n";
|
||||
}
|
||||
|
||||
read_patch();
|
||||
|
||||
#######################################################################
|
||||
|
||||
sub read_patch {
|
||||
my $filename = undef;
|
||||
my $lineno = 0;
|
||||
my $hunk = 0;
|
||||
my $editlines = {};
|
||||
while (defined(my $line = <STDIN>)) {
|
||||
chomp $line;
|
||||
if ($line =~ m!^\+\+\+ b/(.*)!) {
|
||||
find_edits($editlines);
|
||||
edit_file($filename, $editlines);
|
||||
$filename = $1;
|
||||
$lineno = 0;
|
||||
$editlines = {};
|
||||
print "FILE $filename\n" if $Debug;
|
||||
}
|
||||
elsif ($line =~ m!^@@ -?[0-9]+,?[0-9]* \+?([0-9]+)!) {
|
||||
$lineno = $1 - 1;
|
||||
++$hunk;
|
||||
print " LINE $1 $line" if $Debug;
|
||||
}
|
||||
elsif ($line =~ m!^ !) {
|
||||
++$lineno;
|
||||
$editlines->{$lineno} = {line => $line,
|
||||
hunk => $hunk,
|
||||
user_edit => 0, };
|
||||
}
|
||||
elsif ($line =~ m!^\+!) {
|
||||
++$lineno;
|
||||
print " $lineno: $line" if $Debug;
|
||||
$editlines->{$lineno} = {line => $line,
|
||||
hunk => $hunk,
|
||||
user_edit => 1, };
|
||||
}
|
||||
}
|
||||
find_edits($editlines);
|
||||
edit_file($filename, $editlines);
|
||||
}
|
||||
|
||||
sub find_edits {
|
||||
my $editlines = shift;
|
||||
# Expand edit regions so if have edited line, non-edited line, edited
|
||||
# line, we will tab expand the middle ones.
|
||||
my %hunk_firstlines;
|
||||
foreach my $lineno (sort {$a <=> $b} keys %$editlines) {
|
||||
my $hunk = $editlines->{$lineno}{hunk};
|
||||
$hunk_firstlines{$hunk} ||= $lineno if $editlines->{$lineno}{user_edit};
|
||||
}
|
||||
my %hunk_lastlines;
|
||||
foreach my $lineno (sort {$b <=> $a} keys %$editlines) {
|
||||
my $hunk = $editlines->{$lineno}{hunk};
|
||||
$hunk_lastlines{$hunk} ||= $lineno if $editlines->{$lineno}{user_edit};
|
||||
}
|
||||
# Expand to include }'s that finish basic block
|
||||
foreach my $hunk (keys %hunk_lastlines) {
|
||||
while (my $lineno = $hunk_lastlines{$hunk}) {
|
||||
++$lineno;
|
||||
if (($editlines->{$lineno}{line} || "")
|
||||
=~ /^[+ ]\s+}[ \t};]*$/) {
|
||||
$hunk_lastlines{$hunk} = $lineno;
|
||||
} else {
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
# Expand to always untabify at least 3 lines (so that future diff will
|
||||
# have non-tabs within a edit hunk distance
|
||||
foreach my $hunk (keys %hunk_firstlines) {
|
||||
if ($hunk_firstlines{$hunk} == $hunk_lastlines{$hunk}) {
|
||||
--$hunk_firstlines{$hunk};
|
||||
++$hunk_lastlines{$hunk};
|
||||
}
|
||||
elsif ($hunk_firstlines{$hunk}+1 == $hunk_lastlines{$hunk}) {
|
||||
++$hunk_lastlines{$hunk};
|
||||
}
|
||||
}
|
||||
|
||||
foreach my $lineno (sort {$a <=> $b} keys %$editlines) {
|
||||
if (($editlines->{$lineno}{line}||"") =~ /\t/) {
|
||||
my $hunk = $editlines->{$lineno}{hunk};
|
||||
if ($hunk_firstlines{$hunk} <= $lineno && $hunk_lastlines{$hunk} >= $lineno) {
|
||||
$editlines->{$lineno}{editit} = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub edit_file {
|
||||
my $filename = shift;
|
||||
my $editlines = shift;
|
||||
|
||||
my @editits;
|
||||
foreach my $lineno (sort {$a <=> $b} keys %$editlines) {
|
||||
push @editits, $lineno if $editlines->{$lineno}{editit};
|
||||
}
|
||||
|
||||
return if $#editits < 0;
|
||||
if (ignore($filename)) {
|
||||
print "%Warning: Ignoring $filename\n";
|
||||
return;
|
||||
}
|
||||
print "Edit $filename ",join(",",@editits),"\n";
|
||||
|
||||
my $lineno = 0;
|
||||
my @out;
|
||||
{
|
||||
my $fh = IO::File->new("<$filename") or die "%Error: $! $filename\n";
|
||||
while (defined(my $line = $fh->getline)) {
|
||||
++$lineno;
|
||||
if ($editlines->{$lineno}{editit}) {
|
||||
print $line;
|
||||
push @out, untabify($line);
|
||||
} else {
|
||||
push @out, $line;
|
||||
}
|
||||
}
|
||||
$fh->close;
|
||||
}
|
||||
{
|
||||
my $fh = IO::File->new(">${filename}.untab") or die "%Error: $! ${filename}.untab,";
|
||||
$fh->print(join('',@out));
|
||||
$fh->close;
|
||||
|
||||
my ($dev,$ino,$mode) = stat($filename);
|
||||
chmod $mode, "${filename}.untab";
|
||||
}
|
||||
|
||||
rename("${filename}.untab", $filename) or die "%Error: $! ${filename}.untab,";
|
||||
}
|
||||
|
||||
sub ignore {
|
||||
my $filename = shift;
|
||||
return 1 if ($filename =~ /(Makefile|\.mk)/);
|
||||
return 1 if ($filename =~ /\.(y|l|out|vcd)$/);
|
||||
return 1 if ($filename =~ /gtkwave/);
|
||||
#
|
||||
return 0 if ($filename =~ /\.(sv|v|vh|svh|h|vc|cpp|pl)$/);
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub untabify {
|
||||
my $line = shift;
|
||||
my $out = "";
|
||||
my $col = 0;
|
||||
foreach my $c (split //, $line) {
|
||||
if ($c eq "\t") {
|
||||
my $destcol = int(($col+8)/8)*8;
|
||||
while ($col < $destcol) { ++$col; $out .= " "; }
|
||||
} else {
|
||||
$out .= $c;
|
||||
$col++;
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
git_untabify - Pipe a git diff report and untabify differences
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
git diff a..b | git_untabify
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Take a patch file, and edit the files in the destination patch list to
|
||||
untabify the related patch lines.
|
||||
|
||||
=head1 ARGUMENTS
|
||||
|
||||
=over 4
|
||||
|
||||
=item --help
|
||||
|
||||
Displays this message and program version and exits.
|
||||
|
||||
=item --narrow
|
||||
|
||||
Only edit lines which the user edited.
|
||||
|
||||
If not provided, also edit other lines within at least a 3 line area around
|
||||
the edit, and between any edits within the same hunk.
|
||||
|
||||
=item --version
|
||||
|
||||
Displays program version and exits.
|
||||
|
||||
=back
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2019 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Wilson Snyder <[email protected]>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
=cut
|
||||
|
||||
######################################################################
|
||||
### Local Variables:
|
||||
### compile-command: "./git_untabify "
|
||||
### End:
|
||||
Executable
+208
@@ -0,0 +1,208 @@
|
||||
#!/usr/bin/perl -w
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
use Getopt::Long;
|
||||
use Cwd;
|
||||
use IO::File;
|
||||
use Pod::Usage;
|
||||
use strict;
|
||||
use vars qw($Debug);
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
our $Opt_Stage = 0;
|
||||
our $Opt_Jobs = calc_jobs();
|
||||
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
Getopt::Long::config("no_auto_abbrev");
|
||||
if (! GetOptions(
|
||||
"debug" => sub { $Debug = 1; },
|
||||
"<>" => sub { die "%Error: Unknown parameter: $_[0]\n"; },
|
||||
"stage=i" => \$Opt_Stage,
|
||||
"j=i" => \$Opt_Jobs,
|
||||
)) {
|
||||
die "%Error: Bad usage, try 'install_test --help'\n";
|
||||
}
|
||||
|
||||
test();
|
||||
exit(0);
|
||||
|
||||
#######################################################################
|
||||
|
||||
sub test {
|
||||
-r "nodist/install_test" or die "%Error: Run from the top of the verilator kit,";
|
||||
|
||||
cleanenv();
|
||||
run("make distclean") if -r "Makefile";
|
||||
|
||||
# Try building from a scratch area
|
||||
my $srcdir = getcwd();
|
||||
my $blddir = $srcdir."/test_regress/obj_dir/install_test_bld";
|
||||
my $prefix = $srcdir."/test_regress/obj_dir/install_test_prefix";
|
||||
my $testdirp= $srcdir."/test_regress/obj_dir/install_test_testp";
|
||||
my $testdirn= $srcdir."/test_regress/obj_dir/install_test_testn";
|
||||
|
||||
if ($Opt_Stage <= 0) {
|
||||
run("/bin/rm -rf $blddir");
|
||||
run("/bin/mkdir -p $blddir");
|
||||
run("cd $blddir && $srcdir/configure --prefix $prefix");
|
||||
run("cd $blddir && make -j $Opt_Jobs");
|
||||
}
|
||||
|
||||
# Install it under the prefix
|
||||
if ($Opt_Stage <= 1) {
|
||||
run("/bin/rm -rf $prefix");
|
||||
run("/bin/mkdir -p $prefix");
|
||||
run("cd $blddir && make install");
|
||||
run("test -e $prefix/share/man/man1/verilator.1");
|
||||
run("test -e $prefix/share/verilator/examples/tracing_c/Makefile");
|
||||
run("test -e $prefix/share/verilator/include/verilated.h");
|
||||
run("test -e $prefix/bin/verilator");
|
||||
run("test -e $prefix/bin/verilator_bin");
|
||||
run("test -e $prefix/bin/verilator_bin_dbg");
|
||||
run("test -e $prefix/bin/verilator_gantt");
|
||||
run("test -e $prefix/bin/verilator_profcfunc");
|
||||
}
|
||||
|
||||
# Run a test using just the path
|
||||
if ($Opt_Stage <= 2) {
|
||||
my $dir = $testdirp;
|
||||
run("/bin/rm -rf $dir");
|
||||
run("/bin/mkdir -p $dir");
|
||||
my $bin1 = $prefix."/bin";
|
||||
my $bin2 = $prefix."/share/bin";
|
||||
write_verilog($dir);
|
||||
run("cd $dir && PATH=$bin1:$bin2:\$PATH verilator --cc foo.v --exe foo.cpp");
|
||||
run("cd $dir/obj_dir && PATH=$bin1:$bin2:\$PATH make -f Vfoo.mk");
|
||||
run("cd $dir && PATH=$bin1:$bin2:\$PATH obj_dir/Vfoo");
|
||||
}
|
||||
|
||||
# Run a test using exact path to binary
|
||||
if ($Opt_Stage <= 3) {
|
||||
my $dir = $testdirn;
|
||||
run("/bin/rm -rf $dir");
|
||||
run("/bin/mkdir -p $dir");
|
||||
write_verilog($dir);
|
||||
my $bin1 = $prefix."/bin";
|
||||
my $bin2 = $prefix."/share/bin";
|
||||
run("cd $dir && $bin1/verilator --cc foo.v --exe foo.cpp");
|
||||
run("cd $dir/obj_dir && make -f Vfoo.mk");
|
||||
run("cd $dir/obj_dir && ./Vfoo");
|
||||
}
|
||||
|
||||
if ($Opt_Stage <= 9) {
|
||||
print "*-* All Finished *-*\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub write_verilog {
|
||||
my $dir = shift;
|
||||
IO::File->new(">$dir/foo.v")->print('module t; initial begin $display("HELLO WORLD"); $finish; end endmodule'."\n");
|
||||
my $fh = IO::File->new(">$dir/foo.cpp");
|
||||
$fh->print('#include "Vfoo.h"' ,"\n");
|
||||
$fh->print('unsigned int main_time = 0;' ,"\n");
|
||||
$fh->print('double sc_time_stamp() {' ,"\n");
|
||||
$fh->print(' return main_time;' ,"\n");
|
||||
$fh->print('}' ,"\n");
|
||||
$fh->print('int main() {' ,"\n");
|
||||
$fh->print(' Vfoo *top = new Vfoo;' ,"\n");
|
||||
$fh->print(' while (!Verilated::gotFinish()) {',"\n");
|
||||
$fh->print(' top->eval();' ,"\n");
|
||||
$fh->print(' main_time++;' ,"\n");
|
||||
$fh->print(' }' ,"\n");
|
||||
$fh->print(' top->final();' ,"\n");
|
||||
$fh->print('}' ,"\n");
|
||||
}
|
||||
|
||||
sub cleanenv {
|
||||
foreach my $var (keys %ENV) {
|
||||
if ($var eq "VERILATOR_ROOT"
|
||||
|| $var eq "VERILATOR_INCLUDE"
|
||||
|| $var eq "VERILATOR_NO_OPT_BUILD") {
|
||||
print "unset $var # Was '$ENV{$var}'\n";
|
||||
delete $ENV{$var}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
|
||||
sub calc_jobs {
|
||||
my $ok = eval "
|
||||
use Unix::Processors;
|
||||
return Unix::Processors->new->max_online;
|
||||
";
|
||||
$ok && !$@ or return 1;
|
||||
print "driver.pl: Found $ok cores, using -j ",$ok+1,"\n" if $Debug;
|
||||
return $ok + 1;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
install_test - Build and install Verilator several ways
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
install_test
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
install_test performs several make-and-install iterations to verify the
|
||||
kit. It isn't part of the normal "make test" due to the number of builds
|
||||
required.
|
||||
|
||||
=head1 ARGUMENTS
|
||||
|
||||
=over 4
|
||||
|
||||
=item --help
|
||||
|
||||
Displays this message and program version and exits.
|
||||
|
||||
=item -j I<jobs>
|
||||
|
||||
Specify make -j flag. Defaults to number of cores + 1 if Perl's
|
||||
Unix::Processors is installed, else 1.
|
||||
|
||||
=item -stage I<stage>
|
||||
|
||||
Runs a specific test stage (see the script).
|
||||
|
||||
=back
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2009-2019 by Wilson Snyder. This package is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Wilson Snyder <[email protected]>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
=cut
|
||||
|
||||
######################################################################
|
||||
### Local Variables:
|
||||
### compile-command: "cd .. ; nodist/install_test "
|
||||
### End:
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/perl -w
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
require 5.006_001;
|
||||
use strict;
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
eval `modulecmd perl add axiom-athdl`;
|
||||
exec('atsim',@ARGV);
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
invoke_atsim - Invoke tool under "modules" command
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
invoke_atsim {ncv arguments}
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2019 by Wilson Snyder. This package is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Wilson Snyder <[email protected]>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
=cut
|
||||
|
||||
######################################################################
|
||||
### Local Variables:
|
||||
### compile-command: "./invoke_atsim -help"
|
||||
### End:
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/perl -w
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
require 5.006_001;
|
||||
use strict;
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
eval `modulecmd perl add cds-ius`;
|
||||
exec('iccr',@ARGV);
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
invoke_iccr - Invoke tool under "modules" command
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
invoke_iccr {ncv arguments}
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2007-2019 by Wilson Snyder. This package is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Wilson Snyder <[email protected]>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
=cut
|
||||
|
||||
######################################################################
|
||||
### Local Variables:
|
||||
### compile-command: "./invoke_iccr -help"
|
||||
### End:
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/perl -w
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
require 5.006_001;
|
||||
use strict;
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
eval `modulecmd perl add cds-ius/latest`;
|
||||
exec('ncverilog',@ARGV);
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
invoke_ncverilog - Invoke tool under "modules" command
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
invoke_ncverilog {ncv arguments}
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2019 by Wilson Snyder. This package is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Wilson Snyder <[email protected]>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
=cut
|
||||
|
||||
######################################################################
|
||||
### Local Variables:
|
||||
### compile-command: "./invoke_ncverilog -help"
|
||||
### End:
|
||||
Executable
+47
@@ -0,0 +1,47 @@
|
||||
#!/usr/bin/perl -w
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
require 5.006_001;
|
||||
use strict;
|
||||
|
||||
#======================================================================
|
||||
# main
|
||||
|
||||
eval `modulecmd perl add synopsys-sim/latest`;
|
||||
exec('vcs',@ARGV);
|
||||
|
||||
#######################################################################
|
||||
__END__
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
invoke_vcs - Invoke tool under "modules" command
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
invoke_vcs {ncv arguments}
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2019 by Wilson Snyder. This package is free software; you
|
||||
can redistribute it and/or modify it under the terms of either the GNU
|
||||
Lesser General Public License Version 3 or the Perl Artistic License
|
||||
Version 2.0.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
Wilson Snyder <[email protected]>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
=cut
|
||||
|
||||
######################################################################
|
||||
### Local Variables:
|
||||
### compile-command: "./invoke_vcs -help"
|
||||
### End:
|
||||
@@ -0,0 +1,4 @@
|
||||
export GLIBCPP_FORCE_NEW=1
|
||||
compile with -DVL_LEAK_CHECKS
|
||||
valgrind --tool=memcheck --leak-check=yes $VERILATOR_ROOT/verilator_bin_dbg -MMD --bin $VERILATOR_ROOT/verilator_bin_dbg --cc -f $VERILATOR_ROOT/test_c/../test_v/input.vc top.v --no-skip-identical 2>&1 | tee ~/d/aa
|
||||
valgrind --tool=memcheck --leak-check=yes $VERILATOR_ROOT/verilator_bin_dbg -MMD --bin $VERILATOR_ROOT/verilator_bin_dbg --cc $VERILATOR_ROOT/test_regress/t/t_case_huge.v --no-skip-identical -I$VERILATOR_ROOT/test_regress/t 2>&1 | tee ~/d/aa
|
||||
+152
-165
@@ -1,17 +1,5 @@
|
||||
#!/usr/bin/perl -w
|
||||
# $Id$
|
||||
######################################################################
|
||||
#
|
||||
# Copyright 2005-2007 by Wilson Snyder <[email protected]>. This
|
||||
# program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of either the GNU Lesser General Public License or the Perl
|
||||
# Artistic License.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# See copyright, etc in below POD section.
|
||||
######################################################################
|
||||
|
||||
require 5.006_001;
|
||||
@@ -20,7 +8,7 @@ use IO::File;
|
||||
use Pod::Usage;
|
||||
use Data::Dumper; $Data::Dumper::Indent=1;
|
||||
use strict;
|
||||
use vars qw ($Debug);
|
||||
use vars qw($Debug);
|
||||
|
||||
#======================================================================
|
||||
|
||||
@@ -35,15 +23,15 @@ $Debug = 0;
|
||||
my $opt_filename;
|
||||
autoflush STDOUT 1;
|
||||
autoflush STDERR 1;
|
||||
if (! GetOptions (
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
if (! GetOptions(
|
||||
"help" => \&usage,
|
||||
"debug" => \&debug,
|
||||
"<>" => \¶meter,
|
||||
)) {
|
||||
usage();
|
||||
}
|
||||
|
||||
vread ($opt_filename);
|
||||
vread($opt_filename);
|
||||
#print Dumper($Tree);
|
||||
vwrite();
|
||||
|
||||
@@ -52,9 +40,8 @@ print '(query-replace-regexp "(\\([0-9a-z_]+\\))" "\\1" nil nil nil)',"\n";
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub usage {
|
||||
print '$Id$ ', "\n";
|
||||
pod2usage(-verbose=>2, -exitval => 2);
|
||||
exit (1);
|
||||
pod2usage(-verbose=>2, -exitval=>2, -output=>\*STDOUT);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sub debug {
|
||||
@@ -64,9 +51,9 @@ sub debug {
|
||||
sub parameter {
|
||||
my $param = shift;
|
||||
if (!$opt_filename) {
|
||||
$opt_filename = $param;
|
||||
$opt_filename = $param;
|
||||
} else {
|
||||
die "%Error: Unknown parameter: $param\n";
|
||||
die "%Error: Unknown parameter: $param\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,45 +64,45 @@ sub vread {
|
||||
my $fh = IO::File->new($filename) or die "%Error: $! $filename,";
|
||||
my $lasthier="";
|
||||
$Tree = {
|
||||
op => 'NETLIST',
|
||||
t => [[],[],[],[],[],],
|
||||
op => 'NETLIST',
|
||||
t => [[],[],[],[],[],],
|
||||
};
|
||||
my @stack;
|
||||
$stack[1] = $Tree;
|
||||
while (defined (my $line = $fh->getline)) {
|
||||
if ($line =~ /^\s+(\S+):\s+(\S+)\s+0x\S+\s+{(\d+)}\s+w(\d+)\s+(.*)$/) {
|
||||
my $hier = $1;
|
||||
my $op = $2;
|
||||
my $lineno = $3;
|
||||
my $width = $4;
|
||||
my $etc = $5;
|
||||
if ($line =~ /^\s+(\S+):\s+(\S+)\s+0x\S+\s+{(\d+)}\s+w(\d+)\s+(.*)$/) {
|
||||
my $hier = $1;
|
||||
my $op = $2;
|
||||
my $lineno = $3;
|
||||
my $width = $4;
|
||||
my $etc = $5;
|
||||
|
||||
$etc =~ s/__DOT__/./g;
|
||||
$etc =~ s/__PVT__//g;
|
||||
$etc =~ s/__DOT__/./g;
|
||||
$etc =~ s/__PVT__//g;
|
||||
|
||||
my $self = {
|
||||
op => $op,
|
||||
#width => $width,
|
||||
#lineno => $lineno,
|
||||
#line => $line,
|
||||
etc => $etc,
|
||||
args => [split(/[ \t]+/,$etc)],
|
||||
t => [[],[],[],[],[],],
|
||||
};
|
||||
my $self = {
|
||||
op => $op,
|
||||
#width => $width,
|
||||
#lineno => $lineno,
|
||||
#line => $line,
|
||||
etc => $etc,
|
||||
args => [split(/[ \t]+/,$etc)],
|
||||
t => [[],[],[],[],[],],
|
||||
};
|
||||
|
||||
my @hiers = (1,split(/:/,$hier));
|
||||
my $depth = $#hiers+1;
|
||||
my $newchild = $hiers[$#hiers];
|
||||
my @hiers = (1,split(/:/,$hier));
|
||||
my $depth = $#hiers+1;
|
||||
my $newchild = $hiers[$#hiers];
|
||||
|
||||
#print "DD $depth $newchild $op\n";
|
||||
#print "DD $depth $newchild $op\n";
|
||||
|
||||
push @{$stack[$depth-1]->{t}[$newchild]}, $self;
|
||||
$stack[$depth] = $self;
|
||||
push @{$stack[$depth-1]->{t}[$newchild]}, $self;
|
||||
$stack[$depth] = $self;
|
||||
|
||||
$lasthier = $hier;
|
||||
#print " $lasthier\n";
|
||||
#print Dumper($Tree);
|
||||
}
|
||||
$lasthier = $hier;
|
||||
#print " $lasthier\n";
|
||||
#print Dumper($Tree);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,125 +168,125 @@ sub nl { p "\n"," "x$Indent; }
|
||||
|
||||
sub gentree {
|
||||
%OpMap = (
|
||||
'NULLNODE' => sub { "" },
|
||||
'NETLIST' => sub { nl;t1;t2;t3;t4;t5; },
|
||||
'ACTIVE' => sub { p "always_act @(";t1;p ") begin";indentInc;nl;t2;t3;t4;t5;indentDec;p "end";nl; },
|
||||
'ADD' => sub { p1;p " + ";p2; },
|
||||
'ALWAYS' => sub { p "always @(";t1;p ") begin";indentInc;nl;t2;t3;t4;t5;indentDec;p "end";nl; },
|
||||
'ALWAYSPOST' => sub { p "ALWAYSPOST what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'AND' => sub { p1;p " & ";p2; },
|
||||
'ARRAYSEL' => sub { t1;p "[";t2;p "]"; },
|
||||
'ASSIGN' => sub { t2;p " = ";t1;p ";";nl; },
|
||||
'ASSIGNDLY' => sub { t2;p " <= ";t1;p ";";nl; },
|
||||
'ASSIGNPOST' => sub { p "ASSIGNPOST what{";t1;p " = ";t2;p ";";nl; },
|
||||
'ASSIGNPRE' => sub { p "ASSIGNPRE what{";t1;p " = ";t2;p ";";nl; },
|
||||
'ASSIGNW' => sub { p "assign ";t2;p " = ";t1;p ";";nl; },
|
||||
'ATTROF' => sub { p "ATTROF what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'BEGIN' => sub { p "begin";indentInc;nl;t1;t2;t3;t4;t5;indentDec;p "end";nl; },
|
||||
'BITSEL' => sub { t1;local $Avoid_Hex=1; p "[";t2;p "]"; },
|
||||
'CASE' => sub { p "CASE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CASEITEM' => sub { p "CASEITEM what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CAST' => sub { p "CAST what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CCALL' => sub { p "CCALL what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CELL' => sub { a1;p " ";a7;p " (/*CELL*/);"; nl; },
|
||||
'CFUNC' => sub { p "CFUNC what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CHANGEDET' => sub { p "CHANGEDET what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CINCLUDE' => sub { p "CINCLUDE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'COMMENT' => sub { p "//COMMENT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl;nl; },
|
||||
'CONCAT' => sub { p "{";p1;p ",";p2;p "}"; },
|
||||
'CONDITIONAL' => sub { p1;p " ? ";p2;p " : ";p3; },
|
||||
'CONST' => sub { p_const(); },
|
||||
'COVER' => sub { p "COVER what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CRETURN' => sub { p "CRETURN what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CSTMT' => sub { p "CSTMT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'DEFPARAM' => sub { p "defparam ";p1;p " = ";p2;p ";";nl; },
|
||||
'DISPLAY' => sub { p '$write("';p1;p "\",";p2;p3;p4;p5;p ");";nl; },
|
||||
'DIV' => sub { p1;p " / ";p2; },
|
||||
'EQ' => sub { p1;p " == ";p2; },
|
||||
'EQCASE' => sub { p1;p " === ";p2; },
|
||||
'EXTEND' => sub { t1; },
|
||||
'EXTRACT' => sub { t1;local $Avoid_Hex=1; p "[";t2;p ":";t3;p "]"; },
|
||||
'FINISH' => sub { p '$finish;';nl },
|
||||
'FOR' => sub { p "for (";p1;p ",";p2;p ",";p3;p ") begin";indentInc;nl;p4;p5;indentDec;p "end";nl; },
|
||||
'FUNC' => sub { p "FUNC what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'FUNCREF' => sub { p "FUNCREF what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'GT' => sub { p1;p " > ";p2; },
|
||||
'GTE' => sub { p1;p " >= ";p2; },
|
||||
'IF' => sub { p "if (";p1;p ") begin";indentInc;nl;t2;indentDec;if (exists3) {p "end else begin";indentInc;nl;t3;indentDec;} p "end"; nl; },
|
||||
'INITARRAY' => sub { p "INITARRAY what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'INITIAL' => sub { p "initial begin";indentInc;nl;t1;t2;t3;t4;t5;indentDec;p "end";nl; },
|
||||
'LOGAND' => sub { p1;p " && ";p2; },
|
||||
'LOGNOT' => sub { p1;p " || ";p2; },
|
||||
'LOGOR' => sub { p "!";p1; },
|
||||
'LT' => sub { p1;p " < ";p2; },
|
||||
'LTE' => sub { p1;p " <= ";p2; },
|
||||
'MODDIV' => sub { p1;p " % ";p2; },
|
||||
'MODULE' => sub { p "module ";a1;p " (/*AUTOARG*/);";indentInc;nl;t1;t2;t3;t4;t5;indentDec;nl;p "endmodule";nl; },
|
||||
'MUL' => sub { p1;p " * ";p2; },
|
||||
'NEQ' => sub { p1;p " != ";p2; },
|
||||
'NEQCASE' => sub { p1;p " !== ";p2; },
|
||||
'NOT' => sub { p " ~";p1; },
|
||||
'OR' => sub { p1;p " | ";p2; },
|
||||
'PIN' => sub { p ";p ";p1;p " (";p2;p "),";nl; },
|
||||
'PORT' => sub { p ""; },
|
||||
'PRAGMA' => sub { p "PRAGMA what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'RAND' => sub { p '$rand'; },
|
||||
'RANGE' => sub { t1; local $Avoid_Hex=1; p "[";t2;p ":";t3;p "]"; },
|
||||
'REDAND' => sub { p "&(";p1;p ")"; },
|
||||
'REDOR' => sub { p "|(";p1;p ")"; },
|
||||
'REDXNOR' => sub { p "~|(";p1;p ")"; },
|
||||
'REDXOR' => sub { p "~^(";p1;p ")"; },
|
||||
'REPLICATE' => sub { p "{";p1;p "{";p2;p "}}"; },
|
||||
'SCCTOR' => sub { p "SCCTOR what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'SCHDR' => sub { p "SCHDR what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'SCIMP' => sub { p "SCIMP what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'SCINT' => sub { p "SCINT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'SCOPE' => sub { t1;t2;t3;t4;t5; },
|
||||
'SENITEM' => sub { a1;p " ";t1; },
|
||||
'SENTREE' => sub { t1;t2;t3;t4;t5; },
|
||||
'SHIFTL' => sub { p1;p " << ";p2; },
|
||||
'SHIFTR' => sub { p1;p " >> ";p2; },
|
||||
'STOP' => sub { p '$stop;';nl; },
|
||||
'SUB' => sub { p1;p " - ";p2; },
|
||||
'TASK' => sub { p "TASK what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'TASKREF' => sub { p "TASKREF what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'TEXT' => sub { p "TEXT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'TIME' => sub { p '$time'; },
|
||||
'TOPSCOPE' => sub { t1;t2;t3;t4;t5; },
|
||||
'TRACE' => sub { p "TRACE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'UCFUNC' => sub { p '$c(';p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p ")"; },
|
||||
'UCSTMT' => sub { p '$c(';p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p ");";nl; },
|
||||
'UNARYMIN' => sub { p " -";p1; },
|
||||
'VAR' => sub { p_var(); },
|
||||
'VARPIN' => sub { p "VARPIN what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'VARREF' => sub { a1; },
|
||||
'VARSCOPE' => sub { },
|
||||
'WHILE' => sub { t1; p "while (";t2;p ") begin";indentInc;nl;t3;t4;indentDec;p "end";nl; },
|
||||
'WORDSEL' => sub { p1;p "[";p2;p ":";p3;p "]"; },
|
||||
'XNOR' => sub { p1;p " ~^ ";p2; },
|
||||
'XOR' => sub { p1;p " ^";p2; },
|
||||
'NULLNODE' => sub { "" },
|
||||
'NETLIST' => sub { nl;t1;t2;t3;t4;t5; },
|
||||
'ACTIVE' => sub { p "always_act @(";t1;p ") begin";indentInc;nl;t2;t3;t4;t5;indentDec;p "end";nl; },
|
||||
'ADD' => sub { p1;p " + ";p2; },
|
||||
'ALWAYS' => sub { p "always @(";t1;p ") begin";indentInc;nl;t2;t3;t4;t5;indentDec;p "end";nl; },
|
||||
'ALWAYSPOST' => sub { p "ALWAYSPOST what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'AND' => sub { p1;p " & ";p2; },
|
||||
'ARRAYSEL' => sub { t1;p "[";t2;p "]"; },
|
||||
'ASSIGN' => sub { t2;p " = ";t1;p ";";nl; },
|
||||
'ASSIGNDLY' => sub { t2;p " <= ";t1;p ";";nl; },
|
||||
'ASSIGNPOST' => sub { p "ASSIGNPOST what{";t1;p " = ";t2;p ";";nl; },
|
||||
'ASSIGNPRE' => sub { p "ASSIGNPRE what{";t1;p " = ";t2;p ";";nl; },
|
||||
'ASSIGNW' => sub { p "assign ";t2;p " = ";t1;p ";";nl; },
|
||||
'ATTROF' => sub { p "ATTROF what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'BEGIN' => sub { p "begin";indentInc;nl;t1;t2;t3;t4;t5;indentDec;p "end";nl; },
|
||||
'BITSEL' => sub { t1;local $Avoid_Hex=1; p "[";t2;p "]"; },
|
||||
'CASE' => sub { p "CASE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CASEITEM' => sub { p "CASEITEM what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CAST' => sub { p "CAST what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CCALL' => sub { p "CCALL what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CELL' => sub { a1;p " ";a7;p " (/*CELL*/);"; nl; },
|
||||
'CFUNC' => sub { p "CFUNC what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CHANGEDET' => sub { p "CHANGEDET what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CINCLUDE' => sub { p "CINCLUDE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'COMMENT' => sub { p "//COMMENT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl;nl; },
|
||||
'CONCAT' => sub { p "{";p1;p ",";p2;p "}"; },
|
||||
'CONDITIONAL' => sub { p1;p " ? ";p2;p " : ";p3; },
|
||||
'CONST' => sub { p_const(); },
|
||||
'COVER' => sub { p "COVER what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CRETURN' => sub { p "CRETURN what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'CSTMT' => sub { p "CSTMT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'DEFPARAM' => sub { p "defparam ";p1;p " = ";p2;p ";";nl; },
|
||||
'DISPLAY' => sub { p '$write("';p1;p "\",";p2;p3;p4;p5;p ");";nl; },
|
||||
'DIV' => sub { p1;p " / ";p2; },
|
||||
'EQ' => sub { p1;p " == ";p2; },
|
||||
'EQCASE' => sub { p1;p " === ";p2; },
|
||||
'EXTEND' => sub { t1; },
|
||||
'EXTRACT' => sub { t1;local $Avoid_Hex=1; p "[";t2;p ":";t3;p "]"; },
|
||||
'FINISH' => sub { p '$finish;';nl },
|
||||
'FOR' => sub { p "for (";p1;p ",";p2;p ",";p3;p ") begin";indentInc;nl;p4;p5;indentDec;p "end";nl; },
|
||||
'FUNC' => sub { p "FUNC what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'FUNCREF' => sub { p "FUNCREF what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'GT' => sub { p1;p " > ";p2; },
|
||||
'GTE' => sub { p1;p " >= ";p2; },
|
||||
'IF' => sub { p "if (";p1;p ") begin";indentInc;nl;t2;indentDec;if (exists3) {p "end else begin";indentInc;nl;t3;indentDec;} p "end"; nl; },
|
||||
'INITARRAY' => sub { p "INITARRAY what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'INITIAL' => sub { p "initial begin";indentInc;nl;t1;t2;t3;t4;t5;indentDec;p "end";nl; },
|
||||
'LOGAND' => sub { p1;p " && ";p2; },
|
||||
'LOGNOT' => sub { p1;p " || ";p2; },
|
||||
'LOGOR' => sub { p "!";p1; },
|
||||
'LT' => sub { p1;p " < ";p2; },
|
||||
'LTE' => sub { p1;p " <= ";p2; },
|
||||
'MODDIV' => sub { p1;p " % ";p2; },
|
||||
'MODULE' => sub { p "module ";a1;p " (/*AUTOARG*/);";indentInc;nl;t1;t2;t3;t4;t5;indentDec;nl;p "endmodule";nl; },
|
||||
'MUL' => sub { p1;p " * ";p2; },
|
||||
'NEQ' => sub { p1;p " != ";p2; },
|
||||
'NEQCASE' => sub { p1;p " !== ";p2; },
|
||||
'NOT' => sub { p " ~";p1; },
|
||||
'OR' => sub { p1;p " | ";p2; },
|
||||
'PIN' => sub { p ";p ";p1;p " (";p2;p "),";nl; },
|
||||
'PORT' => sub { p ""; },
|
||||
'PRAGMA' => sub { p "PRAGMA what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'RAND' => sub { p '$rand'; },
|
||||
'RANGE' => sub { t1; local $Avoid_Hex=1; p "[";t2;p ":";t3;p "]"; },
|
||||
'REDAND' => sub { p "&(";p1;p ")"; },
|
||||
'REDOR' => sub { p "|(";p1;p ")"; },
|
||||
'REDXNOR' => sub { p "~|(";p1;p ")"; },
|
||||
'REDXOR' => sub { p "~^(";p1;p ")"; },
|
||||
'REPLICATE' => sub { p "{";p1;p "{";p2;p "}}"; },
|
||||
'SCCTOR' => sub { p "SCCTOR what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'SCHDR' => sub { p "SCHDR what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'SCIMP' => sub { p "SCIMP what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'SCINT' => sub { p "SCINT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'SCOPE' => sub { t1;t2;t3;t4;t5; },
|
||||
'SENITEM' => sub { a1;p " ";t1; },
|
||||
'SENTREE' => sub { t1;t2;t3;t4;t5; },
|
||||
'SHIFTL' => sub { p1;p " << ";p2; },
|
||||
'SHIFTR' => sub { p1;p " >> ";p2; },
|
||||
'STOP' => sub { p '$stop;';nl; },
|
||||
'SUB' => sub { p1;p " - ";p2; },
|
||||
'TASK' => sub { p "TASK what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'TASKREF' => sub { p "TASKREF what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'TEXT' => sub { p "TEXT what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'TIME' => sub { p '$time'; },
|
||||
'TOPSCOPE' => sub { t1;t2;t3;t4;t5; },
|
||||
'TRACE' => sub { p "TRACE what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'UCFUNC' => sub { p '$c(';p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p ")"; },
|
||||
'UCSTMT' => sub { p '$c(';p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p ");";nl; },
|
||||
'NEGATE' => sub { p " -";p1; },
|
||||
'VAR' => sub { p_var(); },
|
||||
'VARPIN' => sub { p "VARPIN what{";p1;p ",";p2;p ",";p3;p ",";p4;p ",";p5;p "}";nl; },
|
||||
'VARREF' => sub { a1; },
|
||||
'VARSCOPE' => sub { },
|
||||
'WHILE' => sub { t1; p "while (";t2;p ") begin";indentInc;nl;t3;t4;indentDec;p "end";nl; },
|
||||
'WORDSEL' => sub { p1;p "[";p2;p ":";p3;p "]"; },
|
||||
'XNOR' => sub { p1;p " ~^ ";p2; },
|
||||
'XOR' => sub { p1;p " ^";p2; },
|
||||
);
|
||||
}
|
||||
|
||||
sub p_var {
|
||||
my $self = $Code_Self;
|
||||
if ($self->{etc} =~ /\[I\]/) {
|
||||
print "input";
|
||||
print "input";
|
||||
} elsif ($self->{etc} =~ /\[O\]/) {
|
||||
print "output";
|
||||
print "output";
|
||||
} else {
|
||||
print "reg";
|
||||
print "reg";
|
||||
}
|
||||
p "\t";
|
||||
{
|
||||
local $Avoid_Hex=1;
|
||||
t1;
|
||||
local $Avoid_Hex=1;
|
||||
t1;
|
||||
}
|
||||
p "\t";
|
||||
a1;
|
||||
if (exists2()) {
|
||||
p " = ";
|
||||
t2;
|
||||
p " = ";
|
||||
t2;
|
||||
}
|
||||
p ";";
|
||||
nl;
|
||||
@@ -308,10 +295,10 @@ sub p_var {
|
||||
sub p_const {
|
||||
my $v = $Code_Self->{args}[0];
|
||||
if ($v =~ /\?32\?h(.*)$/
|
||||
|| ($Avoid_Hex && $v =~ /^[0-9?]*h(.*)$/)) {
|
||||
print hex $1;
|
||||
|| ($Avoid_Hex && $v =~ /^[0-9?]*h(.*)$/)) {
|
||||
print hex $1;
|
||||
} else {
|
||||
print $v;
|
||||
print $v;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -322,7 +309,7 @@ __END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
vtree_importer -
|
||||
vtree_importer -
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
@@ -344,9 +331,9 @@ Displays this message and program version and exits.
|
||||
|
||||
=head1 DISTRIBUTION
|
||||
|
||||
Copyright 2005-2007 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 or the Perl Artistic License.
|
||||
Copyright 2005-2019 by Wilson Snyder. Verilator is free software; you can
|
||||
redistribute it and/or modify it under the terms of either the GNU Lesser
|
||||
General Public License Version 3 or the Perl Artistic License Version 2.0.
|
||||
|
||||
=head1 AUTHORS
|
||||
|
||||
|
||||
-188
@@ -1,188 +0,0 @@
|
||||
\input texinfo @c -*-texinfo-*-
|
||||
@c %**start of header
|
||||
$c $Id$
|
||||
@setfilename readme.info
|
||||
@settitle Verilator Installation
|
||||
@c %**end of header
|
||||
|
||||
@c DESCRIPTION: TexInfo: DOCUMENT source run through texinfo to produce README file
|
||||
@c Use 'make README' to produce the output file
|
||||
@c Before release, run C-u C-c C-u C-a (texinfo-all-menus-update)
|
||||
|
||||
@node Top, Copyright, (dir), (dir)
|
||||
@chapter Verilator
|
||||
|
||||
This is the Verilator Package.
|
||||
|
||||
@menu
|
||||
* Copyright::
|
||||
* Description::
|
||||
* Obtaining Distribution::
|
||||
* Directory Structure::
|
||||
* Supported Systems::
|
||||
* Installation::
|
||||
* Limitations::
|
||||
@end menu
|
||||
|
||||
@node Copyright, Description, Top, Top
|
||||
@section Copyright
|
||||
|
||||
This package is Copyright 2003-2007 by Wilson Snyder @email{wsnyder@@wsnyder.org}.
|
||||
|
||||
You may distribute under the terms of either the GNU General Public License
|
||||
or the Artistic License, as specified in the Perl README file.
|
||||
|
||||
This code is provided with no warranty of any kind, and is used entirely at
|
||||
your own risk.
|
||||
|
||||
@node Description, Obtaining Distribution, Copyright, Top
|
||||
@section Description
|
||||
|
||||
Verilator converts synthesizable (not behavioral) Verilog code into C++ or
|
||||
SystemC code. It is not a complete simulator, just a translator.
|
||||
|
||||
Verilator is invoked with parameters similar to GCC or Synopsys's VCS. It
|
||||
reads the specified Verilog code, lints it, and optionally adds coverage
|
||||
code. For C++ format, it outputs .cpp and .h files. For SystemC format,
|
||||
it outputs .sp files for the SystemPerl preprocessor available at
|
||||
http://veripool.com.
|
||||
|
||||
The resulting files are then compiled with C++. The user writes a little
|
||||
C++ wrapper file, which instantiates the top level module. This is
|
||||
compiled in C++, and linked with the Verilated files.
|
||||
|
||||
The resulting executable will perform the actual simulation.
|
||||
|
||||
@node Obtaining Distribution, Directory Structure, Description, Top
|
||||
@section Obtaining Distribution
|
||||
|
||||
The latest version is available at
|
||||
@uref{http://veripool.com/verilator.htm}
|
||||
|
||||
Download the latest package from that site, and decompress.
|
||||
@samp{gunzip verilator_version.tar.gz ; tar xvf verilator_version.tar}
|
||||
|
||||
@node Directory Structure, Supported Systems, Obtaining Distribution, Top
|
||||
@section Directory Structure
|
||||
|
||||
The directories after de-taring are as follows:
|
||||
|
||||
@itemize @bullet
|
||||
@item bin/verilator => Compiler Wrapper invoked on user Verilog code
|
||||
@item include/ => Files that should be in your -I compiler path
|
||||
@item include/verilated.cpp => Global routines to link into your simulator
|
||||
@item include/verilated.h => Global headers
|
||||
@item include/verilated.v => Stub defines for linting
|
||||
@item include/verilated.mk => Common makefile
|
||||
@item src/ => Translator source code
|
||||
@item test_v => Example Verilog code for other test dirs
|
||||
@item test_c => Example Verilog->C++ conversion
|
||||
@item test_sc => Example Verilog->SystemC conversion
|
||||
@item test_sp => Example Verilog->SystemPerl conversion
|
||||
@item test_vcs => Example Verilog->VCS conversion (test the test)
|
||||
@item test_verilated => Internal tests
|
||||
@item test_regress => Internal tests
|
||||
@end itemize
|
||||
|
||||
@node Supported Systems, Installation, Directory Structure, Top
|
||||
@section Supported Systems
|
||||
|
||||
This version of verilator has been built and tested on:
|
||||
|
||||
@itemize @bullet
|
||||
@item SuSE AMD64 i686-linux-2.6.5
|
||||
@end itemize
|
||||
|
||||
Other users report success with Redhat Linux 2.4, Windows under
|
||||
Cygwin, HPUX and Solaris. It should run with minor porting on any
|
||||
Unix system.
|
||||
|
||||
@node Installation, Limitations, Supported Systems, Top
|
||||
@section Installation
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
If you will be using SystemC (vs straight C++ output), download
|
||||
SystemC 2.0.1 from @url{http://www.systemc.org}. Follow their
|
||||
installation instructions. As described in the System-Perl README,
|
||||
you will need to set SYSTEMC and/or SYSTEMC_KIT to point to this
|
||||
download. Also, set SYSTEMC_ARCH to the architecture name you used
|
||||
with SystemC, generally 'linux' or 'cygwin'.
|
||||
|
||||
@item
|
||||
If you will be using SystemC, download and install Verilog-Perl,
|
||||
@url{http://search.cpan.org/search?module=Verilog::Language}.
|
||||
|
||||
@item
|
||||
If you will be using SystemC, download and install System-Perl,
|
||||
@url{http://search.cpan.org/search?module=SystemC::Netlist}. Note
|
||||
you'll need to set a @samp{SYSTEMPERL} environment variable to point
|
||||
to the downloaded kit (not the installed files.) Also, make sure to
|
||||
do a @code{make sc_patch}.
|
||||
|
||||
@item
|
||||
@code{cd} to the Verilator directory containing this README.
|
||||
|
||||
@item
|
||||
Type @samp{./configure} to configure Verilator for your system.
|
||||
|
||||
@item
|
||||
Type @samp{make} to compile Verilator.
|
||||
|
||||
On Cygwin (Windows) you may get a error about libperl.a not being
|
||||
found. You need to copy your perl libraries as follows.
|
||||
|
||||
@enumerate
|
||||
@item
|
||||
Type @samp{perl -MExtUtils::Embed -e ldopts}
|
||||
@item
|
||||
It will show a directory name ending in /CORE. cd to that directory.
|
||||
@item
|
||||
@samp{cp libperl5_6_1.a libperl.a}
|
||||
@item
|
||||
@samp{cp libperl5_6_1.dll libperl.dll}
|
||||
@item
|
||||
@samp{cp libperl5_6_1.def libperl.def}
|
||||
@end enumerate
|
||||
|
||||
@item
|
||||
Type @samp{make test} to check the compilation.
|
||||
|
||||
You may get a error about the Bit::Vector perl package. You will need to install
|
||||
it if you want the tests to pass. (Try @samp{make test_c} for a smaller test that
|
||||
doesn't require it.)
|
||||
|
||||
You may get a error about a typedef conflict for uint32_t. Edit verilated.h to change
|
||||
the typedef to work, probably to @samp{typedef unsigned long uint32_t;}.
|
||||
|
||||
If you get warnings, you might want to edit @samp{include/verilated.mk} to delete the
|
||||
lines that define VK_CPPFLAGS_WALL.
|
||||
|
||||
@item
|
||||
|
||||
There is no installation at present; this package runs from the
|
||||
distribution directory. Programs should set the environment variable
|
||||
VERILATOR_ROOT to point to this distribution, then execute
|
||||
$VERILATOR_ROOT/bin/verilator, which will find the path to all needed
|
||||
files.
|
||||
|
||||
Verilator assumes you did a make in the SystemC kit directory. If not, you will need
|
||||
to populate @samp{$SYSTEMC/include} and @samp{$SYSTEMC/lib-linux} appropriately.
|
||||
|
||||
If you will be modifying Verilator, you will probably want a second
|
||||
stable copy of this kit for others to use while you experiment.
|
||||
|
||||
@item
|
||||
Detailed documentation and the man page can be seen by running:
|
||||
|
||||
bin/verilator --help
|
||||
|
||||
or reading verilator.txt in the same directory as this README.
|
||||
|
||||
@end enumerate
|
||||
|
||||
@node Limitations, , Installation, Top
|
||||
@section Limitations
|
||||
|
||||
See verilator.txt (or execute @samp{bin/verilator --help}) for limitations.
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
# DESCRIPTION: Verilator: GDB startup file with useful defines
|
||||
#
|
||||
# Copyright 2012-2019 by Wilson Snyder. This program is free software; you can
|
||||
# redistribute it and/or modify it under the terms of either the GNU
|
||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||
# Version 2.0.
|
||||
|
||||
define pn
|
||||
call $arg0->dumpGdb()
|
||||
end
|
||||
document pn
|
||||
Verilator: Print single AstNode NODEP
|
||||
end
|
||||
|
||||
define pnt
|
||||
call $arg0->dumpTreeGdb()
|
||||
end
|
||||
document pnt
|
||||
Verilator: Print AstNode NODEP's tree
|
||||
end
|
||||
|
||||
define dtf
|
||||
call AstNode::dumpTreeFileGdb(0)
|
||||
end
|
||||
document dtf
|
||||
Verilator: Dump AstNode tree to file
|
||||
end
|
||||
|
||||
define watchedit
|
||||
watch AstNode::s_editCntGbl==$arg0
|
||||
end
|
||||
document watchedit
|
||||
Verilator: Create watch on where a edit number is made
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user