mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-25 07:16:52 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
64f13540a6 | ||
|
|
4d06b81f10 | ||
|
|
e14ae1ca5f | ||
|
|
5a5146e4bd | ||
|
|
4fab4ca04d | ||
|
|
b8c54059e1 | ||
|
|
f91cca3494 | ||
|
|
65b943b009 | ||
|
|
5726589cac | ||
|
|
502ba94a07 | ||
|
|
b5fdf06475 | ||
|
|
bea0fdeb3c | ||
|
|
506eaa5415 | ||
|
|
21bfe06b33 | ||
|
|
db90f0ef06 | ||
|
|
a7e258fad1 | ||
|
|
9a2106a439 | ||
|
|
c5ab989dc7 | ||
|
|
3ed306bab8 | ||
|
|
6e8c05eda8 | ||
|
|
b3d0677d08 | ||
|
|
7c5c1acf02 | ||
|
|
e5f2975a97 | ||
|
|
9d7e8e67ab | ||
|
|
f35515ac65 | ||
|
|
4e425289bb | ||
|
|
6155d56482 | ||
|
|
cf6f70e03b | ||
|
|
1d2aa1b6fa | ||
|
|
7752cb8ec1 | ||
|
|
2efe188b52 | ||
|
|
cb3bf494f2 | ||
|
|
008b76eae6 | ||
|
|
04c21e1982 | ||
|
|
72998c5415 | ||
|
|
d1e0fa7da0 | ||
|
|
aa8f928ffa | ||
|
|
4ffeb748f4 | ||
|
|
b883f7713c | ||
|
|
14066871e5 | ||
|
|
bfc0121fb9 | ||
|
|
6e2c7f352e | ||
|
|
f493076882 | ||
|
|
b4d92f7bb9 | ||
|
|
c71709d75d | ||
|
|
9a06cf5483 | ||
|
|
8e420f56ff | ||
|
|
f6f7f9d6d7 | ||
|
|
591d2c2473 | ||
|
|
8cd52ac5be | ||
|
|
101bf5f841 | ||
|
|
e4d29bb1c1 | ||
|
|
da0adf6614 | ||
|
|
431b3ba1a2 | ||
|
|
e393487126 | ||
|
|
19772cfe07 | ||
|
|
c5dbdddf7b | ||
|
|
dd403e7ea0 | ||
|
|
2556b5f073 | ||
|
|
d05b13b604 | ||
|
|
b1635c21cc | ||
|
|
b8b6e225fc | ||
|
|
3679d25e4b | ||
|
|
eda9fdcd13 | ||
|
|
41f4ff0fbc | ||
|
|
8df804c273 | ||
|
|
8997c01d6f | ||
|
|
5f479cbad4 | ||
|
|
beaf44895a | ||
|
|
a4989d023d | ||
|
|
9378bbf337 | ||
|
|
f796a59367 | ||
|
|
afe849249c | ||
|
|
f0b6d3addc | ||
|
|
e628e6c8c5 | ||
|
|
31d1850bc8 | ||
|
|
402c96583f | ||
|
|
f5e496b032 | ||
|
|
9c56f0172d | ||
|
|
fd902d1501 | ||
|
|
dcc8e93d7e | ||
|
|
1cf8133420 | ||
|
|
78aa852bf1 | ||
|
|
243dccc368 | ||
|
|
713ad762af | ||
|
|
a0e5240109 | ||
|
|
11af9fb3b3 | ||
|
|
173f6af729 | ||
|
|
36f013f97f | ||
|
|
97928cfb15 | ||
|
|
7792b5ab8a | ||
|
|
3c3f46099d | ||
|
|
60f366790b | ||
|
|
35a809d55b | ||
|
|
9740f7bc76 | ||
|
|
e3222e77ad | ||
|
|
614607c135 | ||
|
|
dec4e939f4 | ||
|
|
e367080276 | ||
|
|
e4bede3c76 | ||
|
|
812c1cedcb | ||
|
|
67d39803e6 | ||
|
|
55250457ed | ||
|
|
29a8a4d052 | ||
|
|
4a505546a1 | ||
|
|
15689210c1 | ||
|
|
e5482b89b1 | ||
|
|
d376375020 | ||
|
|
d15f24ff49 | ||
|
|
2ff0be6bfd | ||
|
|
e7233856c8 | ||
|
|
9a7178fef0 | ||
|
|
82350c4866 | ||
|
|
4d07a8466c | ||
|
|
0e3ac8685c | ||
|
|
1d623a67d1 | ||
|
|
a540a7a163 | ||
|
|
9ec8f8e2dd | ||
|
|
36a79568b7 | ||
|
|
ee14022127 | ||
|
|
0723d9a477 | ||
|
|
f8069416f2 | ||
|
|
c0cf842eb2 | ||
|
|
20a34d33c6 | ||
|
|
f870c755fa | ||
|
|
3e0c298b25 | ||
|
|
6844ed4194 | ||
|
|
9880fb8d5e | ||
|
|
e02a0bc2ec | ||
|
|
abfb4e83bc | ||
|
|
17ca0948f4 | ||
|
|
f6848300b7 | ||
|
|
06740d0dda | ||
|
|
15277c9fa4 | ||
|
|
ca5c6fc59f | ||
|
|
2cef311be2 | ||
|
|
ff0b4a3154 | ||
|
|
2b67d9f754 | ||
|
|
56c42dcf37 | ||
|
|
c8568998af | ||
|
|
8d4faf2744 | ||
|
|
025cbcc81f | ||
|
|
b6829ab504 | ||
|
|
43817251f4 | ||
|
|
0c7341be37 | ||
|
|
21b0107bae | ||
|
|
24743af7d5 | ||
|
|
60a81493cd | ||
|
|
bc6d421ff2 | ||
|
|
e56c93a2be | ||
|
|
98d10727f2 | ||
|
|
50b477bc1f | ||
|
|
5364f11d16 | ||
|
|
dc66f2fe7e | ||
|
|
e2ab464656 | ||
|
|
d01efc910b | ||
|
|
158d7b76f2 | ||
|
|
823aa224db | ||
|
|
5a99d0e449 | ||
|
|
9bbdb0da0e | ||
|
|
9bff2399df | ||
|
|
f358b3fa8f | ||
|
|
be298d1cca | ||
|
|
89b2c8bd80 | ||
|
|
7cffbf440d | ||
|
|
a1c333ea6e | ||
|
|
d5306085c5 | ||
|
|
77fdcfd800 | ||
|
|
d2a97663b9 | ||
|
|
d246979d26 | ||
|
|
55d78cf1a8 | ||
|
|
78750c51d0 | ||
|
|
0e7c62d579 | ||
|
|
5311c0cd38 | ||
|
|
8c7f8f3f7b | ||
|
|
1babbc0c92 | ||
|
|
e9bc3488fb | ||
|
|
f472a77e3a | ||
|
|
8c27786a27 | ||
|
|
e31c441dbe | ||
|
|
ff0b269ce9 | ||
|
|
c53e4245b9 | ||
|
|
3c7250eb51 | ||
|
|
9fb607d98e | ||
|
|
eaa7197602 | ||
|
|
9004d10df4 | ||
|
|
4e168a4d1f | ||
|
|
e75b0d7968 | ||
|
|
167a6bbcdb | ||
|
|
a5bf5e145f | ||
|
|
a615ee03e7 | ||
|
|
bb8b05bb5d | ||
|
|
7934ab9eeb | ||
|
|
daadc38f18 | ||
|
|
a5b9879ada | ||
|
|
72833b9570 | ||
|
|
449abb6bda | ||
|
|
0637afd284 | ||
|
|
c124abaa3e | ||
|
|
03f1bbdd37 | ||
|
|
e9d3fe4ea3 | ||
|
|
10349287a0 | ||
|
|
9bc86af284 | ||
|
|
593a97bede | ||
|
|
d5a16b31a1 | ||
|
|
20a969bf38 | ||
|
|
4b9675abd7 | ||
|
|
8caa3af689 | ||
|
|
6326c5b1ba | ||
|
|
128c621e85 | ||
|
|
f963322076 | ||
|
|
de415b2f03 | ||
|
|
5b512e4f1e | ||
|
|
c5c0b09ef6 | ||
|
|
aa3d804b72 | ||
|
|
2fc9d27190 | ||
|
|
1e6e69ee7f | ||
|
|
c7530dbcc1 | ||
|
|
e47160c6a8 | ||
|
|
311c22e4de | ||
|
|
2d3502f4b7 | ||
|
|
e54b404700 | ||
|
|
297dbe94c2 | ||
|
|
7b2c050457 | ||
|
|
6a6ff90197 | ||
|
|
aafda65b99 | ||
|
|
129a5c980f | ||
|
|
da42011b97 | ||
|
|
e35c857a24 | ||
|
|
7e7d0ae94b | ||
|
|
0d74d5b211 | ||
|
|
2e50fb2f06 | ||
|
|
8b861b4171 | ||
|
|
ecb8a70bed | ||
|
|
635bdd8eb8 | ||
|
|
ab6a0e0799 | ||
|
|
85c58d0a7a | ||
|
|
cc86f69a89 | ||
|
|
28e121c040 | ||
|
|
02fa1a9978 | ||
|
|
3495889112 | ||
|
|
e7934d5e66 | ||
|
|
86546b5960 | ||
|
|
ca3a00a51a | ||
|
|
e6cfb08dd6 | ||
|
|
74491cfe9f | ||
|
|
dea82c5a91 | ||
|
|
8229ce1b49 | ||
|
|
08479888b1 | ||
|
|
46c0526dab | ||
|
|
0f75156d37 | ||
|
|
f8e9384689 | ||
|
|
fb3be420b4 | ||
|
|
eb45fb6eec | ||
|
|
1f5c7c888a | ||
|
|
3f0d02350f | ||
|
|
0a6fa449de | ||
|
|
eadb1d24ae | ||
|
|
00325f3efb | ||
|
|
b605f42a1e | ||
|
|
9f3f35e451 | ||
|
|
73cee3b3e0 | ||
|
|
9ff4a42171 | ||
|
|
84dc4ec99f | ||
|
|
1751f4ed0b | ||
|
|
96cea271ba | ||
|
|
b8eac7fc19 | ||
|
|
f9ab26b3d9 | ||
|
|
208078838e | ||
|
|
73ae5bd1db | ||
|
|
5b62f32ad6 | ||
|
|
a6ba0eef5e | ||
|
|
d84f1b9843 | ||
|
|
f1c71eff5c | ||
|
|
5fac9fae4d | ||
|
|
a042847b38 | ||
|
|
2f1987bded | ||
|
|
a1299f7ca8 | ||
|
|
00bb35a0ce | ||
|
|
9d3101fd19 | ||
|
|
4014db47e0 | ||
|
|
3e7135aabb | ||
|
|
38a24e71b5 | ||
|
|
214324db8c | ||
|
|
6b1878c1b5 | ||
|
|
1476f36ff3 | ||
|
|
89740e6f0e | ||
|
|
2449ee2054 | ||
|
|
e4afd6dc25 | ||
|
|
cdb9bc2c21 | ||
|
|
a8eda65859 | ||
|
|
33584ec6f1 | ||
|
|
46a329f16f | ||
|
|
49ee58c356 | ||
|
|
5b51ed9aa5 | ||
|
|
ba3f46722c | ||
|
|
265272a962 | ||
|
|
56afcb6e75 | ||
|
|
a52bef20ed | ||
|
|
f696064af1 | ||
|
|
1ea5f72496 | ||
|
|
377881b723 | ||
|
|
bcc3a66657 | ||
|
|
ea57b6dd9a | ||
|
|
ba74c7b5ad | ||
|
|
fb6dfebcec | ||
|
|
13d5155e88 | ||
|
|
fde4ef85c1 | ||
|
|
8c7f3452c5 | ||
|
|
5240790480 | ||
|
|
417ab54445 | ||
|
|
2228e31a6a | ||
|
|
39072cd452 | ||
|
|
c963809709 | ||
|
|
71ce460caa | ||
|
|
e212ea1a1c | ||
|
|
3d8f906bdd | ||
|
|
3986804264 | ||
|
|
e0e4a2af48 | ||
|
|
81222402c7 | ||
|
|
c2b63e69a4 | ||
|
|
48242818b3 | ||
|
|
e4c4247266 | ||
|
|
d8e7cd4037 | ||
|
|
f559a05672 | ||
|
|
99c7a9f940 | ||
|
|
33a6d58258 | ||
|
|
6ffb4b9a3a | ||
|
|
e9cffe506b | ||
|
|
e02eb2a4d8 | ||
|
|
68244563ca | ||
|
|
0f454ff548 | ||
|
|
cf53479ba2 | ||
|
|
41c3423209 | ||
|
|
f8e20f5a09 | ||
|
|
d59e2c97ba | ||
|
|
272cf91eae | ||
|
|
8519a30354 | ||
|
|
d39e81e1d1 | ||
|
|
be3be03fec | ||
|
|
11c619e265 | ||
|
|
181cb7b2ed | ||
|
|
9b42bf0df6 | ||
|
|
0846198602 | ||
|
|
6c52271afa | ||
|
|
ed7240b392 | ||
|
|
c14c73dd9a | ||
|
|
03cac78504 | ||
|
|
49eaafe886 | ||
|
|
731891b58f | ||
|
|
92d345ddb2 | ||
|
|
10b5f70e71 | ||
|
|
68f461f5a9 | ||
|
|
6f3beca5fb | ||
|
|
15989f3d62 | ||
|
|
db06b37243 | ||
|
|
047974bdb6 | ||
|
|
e8a4cc7c9e | ||
|
|
804e06cce9 | ||
|
|
ca756322a7 | ||
|
|
eed88fc61f | ||
|
|
9b0d46b4bf | ||
|
|
1248394a5d | ||
|
|
fa518a3409 | ||
|
|
aa417d7575 | ||
|
|
f20865a5ea | ||
|
|
ac3ef217c3 | ||
|
|
6767a07956 | ||
|
|
42d0c3fd4a | ||
|
|
5da8894590 | ||
|
|
4c315b32d4 | ||
|
|
dc0d162fa9 | ||
|
|
29e128ed94 | ||
|
|
475f098cab | ||
|
|
7d438b66c8 | ||
|
|
54f17a2cb1 | ||
|
|
42f7d3a922 | ||
|
|
1f8991e382 | ||
|
|
ab74cafa20 | ||
|
|
ff2f4c6864 | ||
|
|
d3bda52d69 | ||
|
|
d64bf0b0b3 | ||
|
|
c836236b28 | ||
|
|
462a15dcbb | ||
|
|
57385f9ac6 | ||
|
|
f9a0542a49 | ||
|
|
14a25bfe92 | ||
|
|
4dfac864ce | ||
|
|
3f936d2d8b | ||
|
|
b8de0499a9 | ||
|
|
98391b56bc | ||
|
|
aec9fe98ab | ||
|
|
9d0f6fc995 | ||
|
|
68ba79eb7a | ||
|
|
42d591d296 | ||
|
|
f3506a8c92 | ||
|
|
9a7d852782 | ||
|
|
5d8fcdd7bc | ||
|
|
9d3cd045ef | ||
|
|
5beeeee3fa | ||
|
|
d736cffc11 | ||
|
|
2302fa37d5 | ||
|
|
15d6e83f8d | ||
|
|
4af84bfaad | ||
|
|
9b44d55e9a | ||
|
|
935f92da05 | ||
|
|
71c8963922 | ||
|
|
8385b13356 | ||
|
|
b46fbe0892 | ||
|
|
5e1f1055e1 | ||
|
|
de3e50e486 | ||
|
|
7786fb67c3 | ||
|
|
f071957736 | ||
|
|
a838d5143d | ||
|
|
4cc6ae35dd | ||
|
|
911a20c134 | ||
|
|
9da5c1868f | ||
|
|
827e08f8d3 | ||
|
|
826672705e | ||
|
|
e9f26a2f11 | ||
|
|
8f7b2a23eb | ||
|
|
9df3cc3126 | ||
|
|
26ba3f62e3 | ||
|
|
dc1763bbf5 | ||
|
|
5b0ce2c6ca | ||
|
|
2f05c831c0 | ||
|
|
8014c5cee2 | ||
|
|
ebf2dc1685 | ||
|
|
49fc24a798 | ||
|
|
33e28df834 | ||
|
|
7916ae3c49 | ||
|
|
67e48188a9 | ||
|
|
60b13d020c | ||
|
|
f040d513a5 | ||
|
|
dfa824c03e | ||
|
|
6b276fa316 | ||
|
|
128d970d60 | ||
|
|
068f33b35a | ||
|
|
e51ce2a8e9 | ||
|
|
c3d550e03e | ||
|
|
2345c51478 | ||
|
|
964878382d | ||
|
|
78fa7a5a10 | ||
|
|
4d0a277f3b | ||
|
|
951ede0922 | ||
|
|
6651df6f2c | ||
|
|
385a0fb46a | ||
|
|
7dbaa67a02 | ||
|
|
918976651a | ||
|
|
c3abb84ce6 | ||
|
|
5708010a5c | ||
|
|
c172a0d3a7 | ||
|
|
e5943047da | ||
|
|
aad14df3d7 | ||
|
|
eff75f8209 | ||
|
|
44611f8301 | ||
|
|
2b45f4c399 | ||
|
|
95ffc97f5f | ||
|
|
4f31fec5c8 | ||
|
|
d87dbb08cf | ||
|
|
1c6f0e768a | ||
|
|
1b1def7f79 | ||
|
|
f5708a0322 | ||
|
|
28717b4de7 | ||
|
|
3b209301e2 | ||
|
|
87d9d0ac74 | ||
|
|
a7502173d3 | ||
|
|
d697312cf8 | ||
|
|
efb0ea2ec7 | ||
|
|
70094ce564 | ||
|
|
e32584f228 | ||
|
|
9bf45a85e2 | ||
|
|
97da696b5a | ||
|
|
d392dcf07f | ||
|
|
e4b3f1bc69 | ||
|
|
b69cb8efda | ||
|
|
d766248bc1 | ||
|
|
587d87bb96 | ||
|
|
da853622e9 | ||
|
|
cc496c3cf3 | ||
|
|
3d4f1eb94b | ||
|
|
702189a948 | ||
|
|
b7292e0179 | ||
|
|
0b7bd36960 | ||
|
|
860761f9c6 | ||
|
|
08c8ee081a | ||
|
|
929fbf3507 | ||
|
|
5f651d944b | ||
|
|
6210c307fa | ||
|
|
935910c3c9 | ||
|
|
cf66c64e32 | ||
|
|
8e2d543304 | ||
|
|
10770c9129 | ||
|
|
884349caab | ||
|
|
94dcd658c8 | ||
|
|
fcb543d6e5 | ||
|
|
d79e49a372 | ||
|
|
9c62154924 | ||
|
|
4372560290 | ||
|
|
3e7cc4eac2 | ||
|
|
cc1ead51c7 | ||
|
|
12b87da742 | ||
|
|
fede5239ba | ||
|
|
23b6f955d4 | ||
|
|
a4c90fb5f0 | ||
|
|
936f92ebe6 | ||
|
|
1fdeb7b982 | ||
|
|
753a52b56c | ||
|
|
8de5e68e83 | ||
|
|
d67d3323ad | ||
|
|
d400fa21bd | ||
|
|
dad78d5258 | ||
|
|
1be953cfa6 | ||
|
|
fa5fc0eca0 | ||
|
|
c0e44b4849 | ||
|
|
db82380cec | ||
|
|
8bd9cb14e7 | ||
|
|
5a4cb616d1 | ||
|
|
b979441de2 | ||
|
|
c7d37bcc21 | ||
|
|
eceb48e5d6 | ||
|
|
e55d9454da | ||
|
|
30f1de9062 | ||
|
|
cfb8ec17d2 | ||
|
|
60e4023e6f | ||
|
|
a883f2afe6 | ||
|
|
7161dc0ab1 | ||
|
|
afc1b2a51b | ||
|
|
fd7029a299 | ||
|
|
dd714d78c4 | ||
|
|
aec91c7754 | ||
|
|
0ecb71625b | ||
|
|
f82c6c7b3a | ||
|
|
66d57628bf | ||
|
|
a05da1ca08 | ||
|
|
46a5078a68 | ||
|
|
6426afc8d0 | ||
|
|
a2ffbc307a | ||
|
|
adcb9f4e0d | ||
|
|
26c01e7f0a | ||
|
|
7c60005d1a | ||
|
|
ea26587b5e | ||
|
|
1aec31ac27 | ||
|
|
b11749e04c | ||
|
|
b7f9be9370 | ||
|
|
2b01cf335c | ||
|
|
7e238e7ca5 | ||
|
|
4138fcf6c4 | ||
|
|
f5decd471d | ||
|
|
7e95dfff5a | ||
|
|
bf45073359 | ||
|
|
b0c57ab177 | ||
|
|
60f5026ae4 | ||
|
|
25104ca2a8 | ||
|
|
9afaf6f136 | ||
|
|
cfa4a289ec | ||
|
|
99580cd051 | ||
|
|
6088a26d78 | ||
|
|
1b729831b7 | ||
|
|
0ca26c95d8 | ||
|
|
7f4ff37ad0 | ||
|
|
14375567c7 | ||
|
|
eb90bcf313 | ||
|
|
4c03ac5b36 | ||
|
|
30123f8945 | ||
|
|
27bae7eab1 | ||
|
|
e2008c9c0e | ||
|
|
60b6435653 | ||
|
|
b794b9cc26 | ||
|
|
9f8a8959a7 | ||
|
|
7c970e91b9 | ||
|
|
43c138fdd3 | ||
|
|
867c7d18b4 | ||
|
|
d0327c5eda | ||
|
|
c22b375c86 | ||
|
|
4854de06ca | ||
|
|
4471961ed4 | ||
|
|
23a7c80dde | ||
|
|
e3a5567ceb | ||
|
|
9e60be2946 | ||
|
|
1e9cfc34c0 |
@@ -1,16 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
echo "Using the bundled ivtest to run regression tests."
|
||||
echo " pwd = $(pwd)"
|
||||
|
||||
cd ivtest
|
||||
|
||||
status=0
|
||||
|
||||
perl vvp_reg.pl || status=1
|
||||
|
||||
perl vpi_reg.pl || status=1
|
||||
|
||||
python3 vvp_reg.py || status=1
|
||||
|
||||
exit $status
|
||||
@@ -19,10 +19,15 @@ jobs:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt update -qq
|
||||
sudo apt install -y make autoconf python3-sphinx
|
||||
sudo apt install -y make autoconf python3-venv
|
||||
python3 -m venv .venv
|
||||
. .venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install -r Documentation/requirements.txt
|
||||
|
||||
- name: Make Documentation
|
||||
run: |
|
||||
. .venv/bin/activate
|
||||
cd Documentation
|
||||
make html
|
||||
|
||||
|
||||
+62
-27
@@ -14,61 +14,82 @@ jobs:
|
||||
mac:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
runs-on: macos-13
|
||||
name: '🍏 macOS'
|
||||
matrix:
|
||||
libvvp: [true]
|
||||
suffix: [true]
|
||||
runs-on: macos-15-intel
|
||||
name: 🍏 macOS${{ matrix.libvvp && ' +libvvp' || '' }}${{ matrix.suffix && ' +suffix' || '' }}
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
brew install bison
|
||||
pip3 install --break-system-packages docopt
|
||||
|
||||
- name: Build, check and install
|
||||
run: |
|
||||
export PATH="/usr/local/opt/bison/bin:$PATH"
|
||||
CONFIG_OPTS="--enable-libveriuser"
|
||||
if [ "${{ matrix.libvvp }}" = "true" ]; then
|
||||
CONFIG_OPTS="$CONFIG_OPTS --enable-libvvp"
|
||||
fi
|
||||
if [ "${{ matrix.suffix }}" = "true" ]; then
|
||||
CONFIG_OPTS="$CONFIG_OPTS --enable-suffix"
|
||||
fi
|
||||
autoconf
|
||||
./configure
|
||||
./configure $CONFIG_OPTS
|
||||
make -j$(nproc) check
|
||||
sudo make install
|
||||
|
||||
- name: Test
|
||||
run: ./.github/test.sh
|
||||
run: |
|
||||
make check-installed
|
||||
|
||||
|
||||
lin:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [
|
||||
'20.04',
|
||||
'22.04',
|
||||
'24.04'
|
||||
]
|
||||
os: ['22.04', '24.04']
|
||||
# libvvp: [false, true]
|
||||
# suffix: [false, true]
|
||||
runs-on: ubuntu-${{ matrix.os }}
|
||||
name: '🐧 Ubuntu ${{ matrix.os }}'
|
||||
name: 🐧 Ubuntu ${{ matrix.os }}${{ matrix.libvvp && ' +libvvp' || '' }}${{ matrix.suffix && ' +suffix' || '' }}
|
||||
steps:
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt update -qq
|
||||
sudo apt install -y make g++ git bison flex gperf libreadline-dev libbz2-dev autoconf python3-sphinx python3-docopt
|
||||
sudo apt install -y make g++ git bison flex gperf libreadline-dev libbz2-dev autoconf python3-venv
|
||||
python3 -m venv .venv
|
||||
. .venv/bin/activate
|
||||
pip install --upgrade pip
|
||||
pip install -r Documentation/requirements.txt
|
||||
|
||||
- name: Build, check and install
|
||||
run: |
|
||||
CONFIG_OPTS="--enable-libveriuser"
|
||||
if [ "${{ matrix.libvvp }}" = "true" ]; then
|
||||
CONFIG_OPTS="$CONFIG_OPTS --enable-libvvp"
|
||||
fi
|
||||
if [ "${{ matrix.suffix }}" = "true" ]; then
|
||||
CONFIG_OPTS="$CONFIG_OPTS --enable-suffix"
|
||||
fi
|
||||
autoconf
|
||||
./configure
|
||||
./configure $CONFIG_OPTS
|
||||
make -j$(nproc) check
|
||||
sudo make install
|
||||
|
||||
- name: Test
|
||||
run: ./.github/test.sh
|
||||
run:
|
||||
make check-installed
|
||||
|
||||
- name: Documentation
|
||||
run: |
|
||||
. .venv/bin/activate
|
||||
cd Documentation
|
||||
make html
|
||||
|
||||
@@ -77,10 +98,14 @@ jobs:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include: [
|
||||
{ msystem: MINGW64, arch: x86_64 }
|
||||
]
|
||||
name: 🟪 ${{ matrix.msystem}} · ${{ matrix.arch }}
|
||||
msystem: [MINGW64, UCRT64, CLANG64]
|
||||
# libvvp: [false, true]
|
||||
# suffix: [false, true]
|
||||
include:
|
||||
- { msystem: MINGW64, env: x86_64 }
|
||||
- { msystem: UCRT64, env: ucrt-x86_64 }
|
||||
- { msystem: CLANG64, env: clang-x86_64 }
|
||||
name: 🟪 ${{ matrix.msystem }}${{ matrix.libvvp && ' +libvvp' || '' }}${{ matrix.suffix && ' +suffix' || '' }}
|
||||
defaults:
|
||||
run:
|
||||
shell: msys2 {0}
|
||||
@@ -91,7 +116,7 @@ jobs:
|
||||
- run: git config --global core.autocrlf input
|
||||
shell: bash
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
@@ -100,17 +125,27 @@ jobs:
|
||||
install: >
|
||||
git
|
||||
base-devel
|
||||
gperf
|
||||
python-pip
|
||||
mingw-w64-${{ matrix.arch }}-toolchain
|
||||
mingw-w64-${{ matrix.env }}-perl
|
||||
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v6
|
||||
with:
|
||||
python-version: '>=3.5'
|
||||
|
||||
- name: Build and check
|
||||
run: |
|
||||
cd msys2
|
||||
CONFIG_OPTS=""
|
||||
if [ ${{ matrix.msystem }} != "CLANG64" ] ; then
|
||||
CONFIG_OPTS="$CONFIG_OPTS --enable-libveriuser"
|
||||
fi
|
||||
if [ "${{ matrix.libvvp }}" = "true" ] ; then
|
||||
CONFIG_OPTS="$CONFIG_OPTS --enable-libvvp"
|
||||
fi
|
||||
if [ "${{ matrix.suffix }}" = "true" ]; then
|
||||
CONFIG_OPTS="$CONFIG_OPTS --enable-suffix"
|
||||
fi
|
||||
export IVL_CONFIG_OPTIONS="$CONFIG_OPTS"
|
||||
makepkg-mingw --noconfirm --noprogressbar -sCLf
|
||||
|
||||
- name: Install
|
||||
@@ -118,9 +153,9 @@ jobs:
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
./.github/test.sh
|
||||
make check-installed
|
||||
|
||||
- uses: actions/upload-artifact@v4
|
||||
- uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: ${{ matrix.msystem }}-${{ matrix.arch }}
|
||||
name: 🟪 ${{ matrix.msystem }}${{ matrix.libvvp && ' +libvvp' || '' }}
|
||||
path: msys2/*.zst
|
||||
|
||||
+26
-21
@@ -8,6 +8,10 @@
|
||||
*.swp
|
||||
*~
|
||||
|
||||
# Virtual environments
|
||||
.conda/
|
||||
.venv/
|
||||
|
||||
# Top level generic files
|
||||
tags
|
||||
TAGS
|
||||
@@ -31,16 +35,19 @@ Makefile
|
||||
/_pli_types.h
|
||||
config.h
|
||||
/tgt-pcb/pcb_config.h
|
||||
/tgt-pcb/fp.cc
|
||||
/tgt-pcb/fp.h
|
||||
/tgt-pcb/fp.output
|
||||
/tgt-pcb/fp_lex.cc
|
||||
/tgt-vvp/vvp_config.h
|
||||
/tgt-vhdl/vhdl_config.h
|
||||
/vhdlpp/vhdlpp_config.h
|
||||
/vpi/vpi_config.h
|
||||
stamp-*-h
|
||||
/version.h
|
||||
/version_tag.h
|
||||
/version_base.h
|
||||
|
||||
/driver-vpi/iverilog-vpi.man
|
||||
/driver-vpi/res.rc
|
||||
/driver/iverilog.man
|
||||
/vvp/libvvp.pc
|
||||
/vvp/vvp.man
|
||||
|
||||
# Directories
|
||||
autom4te.cache
|
||||
@@ -52,8 +59,6 @@ dep
|
||||
*.vpi
|
||||
/cadpli/cadpli.vpl
|
||||
|
||||
/tgt-blif/Makefile
|
||||
|
||||
# lex, yacc and gperf output
|
||||
/driver/cflexor.c
|
||||
/driver/cfparse.c
|
||||
@@ -62,14 +67,6 @@ dep
|
||||
|
||||
/ivlpp/lexor.c
|
||||
|
||||
/vhdlpp/lexor.cc
|
||||
/vhdlpp/lexor_keyword.cc
|
||||
/vhdlpp/parse.cc
|
||||
/vhdlpp/parse.h
|
||||
/vhdlpp/parse.output
|
||||
/vhdlpp/vhdlpp_config.h
|
||||
/vhdlpp/vhdlpp
|
||||
|
||||
/lexor.cc
|
||||
/lexor_keyword.cc
|
||||
/parse.cc
|
||||
@@ -78,6 +75,17 @@ dep
|
||||
/syn-rules.cc
|
||||
/syn-rules.output
|
||||
|
||||
/tgt-pcb/fp.cc
|
||||
/tgt-pcb/fp.h
|
||||
/tgt-pcb/fp.output
|
||||
/tgt-pcb/fp_lex.cc
|
||||
|
||||
/vhdlpp/lexor.cc
|
||||
/vhdlpp/lexor_keyword.cc
|
||||
/vhdlpp/parse.cc
|
||||
/vhdlpp/parse.h
|
||||
/vhdlpp/parse.output
|
||||
|
||||
/vpi/sdf_lexor.c
|
||||
/vpi/sdf_parse.c
|
||||
/vpi/sdf_parse.h
|
||||
@@ -97,17 +105,13 @@ dep
|
||||
# Program created files
|
||||
/vvp/tables.cc
|
||||
|
||||
/iverilog-vpi.man
|
||||
/driver-vpi/res.rc
|
||||
/driver/iverilog.man
|
||||
/vvp/vvp.man
|
||||
|
||||
# The executables.
|
||||
*.exe
|
||||
/driver/iverilog
|
||||
/iverilog-vpi
|
||||
/driver-vpi/iverilog-vpi
|
||||
/ivl
|
||||
/ivlpp/ivlpp
|
||||
/vhdlpp/vhdlpp
|
||||
/vvp/vvp
|
||||
|
||||
/ivl.exp
|
||||
@@ -115,3 +119,4 @@ dep
|
||||
|
||||
# Check output
|
||||
/check.vvp
|
||||
/driver/top.vvp
|
||||
|
||||
+8
-5
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_AStatement_H
|
||||
#define IVL_AStatement_H
|
||||
/*
|
||||
* Copyright (c) 2008-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2008-2026 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -40,10 +40,13 @@ class AContrib : public Statement {
|
||||
|
||||
public:
|
||||
AContrib(PExpr*lval, PExpr*rval);
|
||||
~AContrib();
|
||||
~AContrib() override;
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
AContrib(const AContrib&) = delete;
|
||||
AContrib& operator=(const AContrib&) = delete;
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
|
||||
private:
|
||||
PExpr*lval_;
|
||||
@@ -61,7 +64,7 @@ class AProcess : public LineInfo {
|
||||
AProcess(ivl_process_type_t t, Statement*st)
|
||||
: type_(t), statement_(st) { }
|
||||
|
||||
~AProcess();
|
||||
~AProcess() override;
|
||||
|
||||
bool elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
|
||||
+20
-6
@@ -20,7 +20,7 @@
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'Icarus Verilog'
|
||||
copyright = '2024, Stephen Williams'
|
||||
copyright = '2024-2026, Stephen Williams'
|
||||
author = 'Stephen Williams'
|
||||
|
||||
# The short X.Y version
|
||||
@@ -58,7 +58,7 @@ master_doc = 'index'
|
||||
#
|
||||
# This is also used if you do content translation via gettext catalogs.
|
||||
# Usually you set "language" from the command line for these cases.
|
||||
language = None
|
||||
language = 'en'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
@@ -73,21 +73,35 @@ highlight_language = 'none'
|
||||
|
||||
# -- Options for HTML output -------------------------------------------------
|
||||
|
||||
# A dictionary of values to pass into the template engine's context for all pages.
|
||||
#
|
||||
html_context = {
|
||||
# Edit this page
|
||||
"source_type": "github",
|
||||
"source_user": "steveicarus",
|
||||
"source_repo": "iverilog",
|
||||
"source_version": "master",
|
||||
"source_docs_path": "/Documentation/",
|
||||
}
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
#
|
||||
html_theme = 'alabaster'
|
||||
html_theme = 'shibuya'
|
||||
|
||||
# Theme options are theme-specific and customize the look and feel of a theme
|
||||
# further. For a list of options available for each theme, see the
|
||||
# documentation.
|
||||
#
|
||||
# html_theme_options = {}
|
||||
html_theme_options = {
|
||||
"github_url": "https://github.com/steveicarus/iverilog",
|
||||
}
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
#html_static_path = ['_static']
|
||||
html_static_path = []
|
||||
|
||||
# Custom sidebar templates, must be a dictionary that maps document names
|
||||
# to template names.
|
||||
@@ -141,7 +155,7 @@ latex_documents = [
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
man_pages = [
|
||||
(master_doc, 'icarusverilog', 'Icarus Verilog Documentation',
|
||||
(master_doc, 'iverilog-docs', 'Icarus Verilog Documentation',
|
||||
[author], 1)
|
||||
]
|
||||
|
||||
|
||||
@@ -103,6 +103,22 @@ reference the correct run time files and directories. The run time will check
|
||||
that it is running a file with a compatible version e.g.(you can not run a
|
||||
V0.9 file with the V0.8 run time).
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
--enable-libvvp
|
||||
|
||||
The vvp program is built as a small stub linked to a shared library,
|
||||
libvvp.so, that may be linked with other programs so that they can host
|
||||
a vvp simulation.
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
--enable-libveriuser
|
||||
|
||||
PLI version 1 (the ACC and TF routines) were deprecated in IEEE 1364-2005.
|
||||
These are supported in Icarus Verilog by the libveriuser library and cadpli
|
||||
module. Starting with v13, these will only be built if this option is used.
|
||||
|
||||
A debug options is:
|
||||
|
||||
.. code-block:: none
|
||||
@@ -111,7 +127,7 @@ A debug options is:
|
||||
|
||||
This option adds extra memory cleanup code and pool management code to allow
|
||||
better memory leak checking when valgrind is available. This option is not
|
||||
need when checking for basic errors with valgrind.
|
||||
needed when checking for basic errors with valgrind.
|
||||
|
||||
Compiling on Linux
|
||||
------------------
|
||||
@@ -163,13 +179,21 @@ example:
|
||||
.. code-block:: console
|
||||
|
||||
% cd ivtest
|
||||
% ./vvp_reg.pl --strict
|
||||
% ./vvp_reg.pl
|
||||
% ./vvp_reg.py
|
||||
% ./vpi_reg.pl
|
||||
|
||||
will run all the regression tests for the simulation engine. (This is what
|
||||
most people will want to do.) You should rerun this test before submitting
|
||||
most people will want to do.) You should rerun these tests before submitting
|
||||
patches to the developers. Also, if you are adding a new feature, you should
|
||||
add test programs to the regression test suite to validate your new feature
|
||||
(or bug fix.)
|
||||
(or bug fix.). The python script is the preferred method to add new tests.
|
||||
|
||||
All of these scripts take other options to test various configurations. What
|
||||
options are supported can be found by using the ``-h/--help`` argument. There
|
||||
is also a separate ``vlog95_reg.pl`` script for testing the vlog95 translation
|
||||
of the original tests. This is integrated into the existing Python test script
|
||||
for the new tests.
|
||||
|
||||
Note that pull requests will be required to pass these regression tests before
|
||||
being merged.
|
||||
@@ -222,4 +246,3 @@ or the version branch that you are working on. Your pull request will be run
|
||||
through continuous integration, and reviewed by one of the main
|
||||
authors. Feedback may be offered to your PR, and once accepted, an approved
|
||||
individual will merge it for you. Then you are done.
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ source code itself, so that you can find the global parts where you
|
||||
can look for even better detail.
|
||||
|
||||
The documentation for getting, building and installing Icarus Verilog
|
||||
is kept and maintained at :doc:`Getting Started as a Contributer <../getting_started>`
|
||||
is kept and maintained at :doc:`Getting Started as a Contributor <../getting_started>`
|
||||
|
||||
See the Installation Guide for getting the current source from the git
|
||||
repository (and how to use the git repository) and see the Developer Guide
|
||||
|
||||
@@ -812,6 +812,10 @@ result is pushed back on the vec4 stack.
|
||||
|
||||
This opcode multiplies two real words together.
|
||||
|
||||
* %neg/wr
|
||||
|
||||
This opcode negates the real value on top of the real stack.
|
||||
|
||||
* %nand
|
||||
|
||||
Perform the bitwise NAND of two vec4 vectors, and push the result. Each
|
||||
|
||||
@@ -54,11 +54,6 @@ This describes the kind of test to run. The valid values are:
|
||||
that succeeds execute it using the vvp command. If there is no gold file
|
||||
specified, then look for an output line with the "PASSED" string.
|
||||
|
||||
* **normal-vlog95** - This is similar to the normal case, but uses
|
||||
the -tvlog95 target in a first pass to generate simplified verilog, then a
|
||||
regular iverilog command with the -tvvp target to generate the actual
|
||||
executable. This tests the -tvlog95 target.
|
||||
|
||||
* **NI** - Mark the test as not implemented. The test will be skipped without
|
||||
running or reporting an error.
|
||||
|
||||
@@ -68,6 +63,9 @@ This describes the kind of test to run. The valid values are:
|
||||
* **EF** - Compile and run, but expect the run time to fail. This means the
|
||||
run time program must return an error exit.
|
||||
|
||||
* **TE** - This is specific to testing the vlog95 conversion and indicates the
|
||||
translated code failed to compile.
|
||||
|
||||
gold (optional)
|
||||
^^^^^^^^^^^^^^^
|
||||
|
||||
@@ -123,3 +121,9 @@ vvp-args-extended (optional)
|
||||
If this is specified, it is a lost of strings that are passed as arguments to
|
||||
the vvp command. These are extended arguments, and are placed after the vvp
|
||||
input file that is being run. This is where you place things like plusargs.
|
||||
|
||||
strict, force-sv or vlog95 (optional)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Any of these can be used to create overrides for the type, gold or
|
||||
iverilog-args when the given test type is run.
|
||||
|
||||
@@ -17,7 +17,7 @@ the "make version" target, or automatically if the version_tag.h
|
||||
file doesn't exist at all. This implies that a "make version" is
|
||||
something worth doing when you do a "git pull" or create commits.
|
||||
|
||||
The files below are now edited by the makefile and the version.exe program:
|
||||
The files below are now edited by the Makefile:
|
||||
|
||||
* iverilog-vpi.man -- The .TH tag has a version string
|
||||
* driver/iverilog.man -- The .TH tag has a version string
|
||||
@@ -28,10 +28,5 @@ This now includes version_base.h to get the version:
|
||||
|
||||
* vpi/vams_simparam.c -- Hard coded result to simulatorVersion query
|
||||
|
||||
This is actually a test file list that is specific to a major version.
|
||||
The regression test scripts query the version of the compiler to infer
|
||||
that it must include this list of tests. For example, for version 12.x
|
||||
of the compiler, the needs to be an ivltest/regress-v12.list file that
|
||||
lists the tests that are specific to that version.
|
||||
|
||||
* ivltests/regress-XXX.list -- Version specific regression tests
|
||||
The test suite no longer has version specific files since it tracks along with
|
||||
the code/branch.
|
||||
|
||||
@@ -12,6 +12,7 @@ Welcome to the documentation for Icarus Verilog.
|
||||
:maxdepth: 2
|
||||
:caption: Contents:
|
||||
|
||||
releases/index
|
||||
usage/index
|
||||
targets/index
|
||||
developer/index
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
Icarus Verilog Release Notes
|
||||
============================
|
||||
|
||||
This section contains the release notes for all releases after and including
|
||||
V13.0. Older release notes can be found here: `<https://iverilog.fandom.com/wiki/User_Guide>`__
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
v13-0-release-note
|
||||
@@ -0,0 +1,98 @@
|
||||
🎉 Release V13.0
|
||||
================
|
||||
|
||||
The Icarus Verilog development team is pleased to announce **Release V13** of Icarus Verilog.
|
||||
|
||||
Release V13 builds on the V12 series with a focus on correctness, runtime stability, improved
|
||||
diagnostics, and incremental standard conformance improvements.
|
||||
|
||||
----
|
||||
|
||||
🐞 Bug Fix Summary
|
||||
------------------
|
||||
|
||||
Release V13 resolves numerous issues reported against V12, including:
|
||||
|
||||
* Incorrect signed constant handling.
|
||||
* Generate block naming collisions.
|
||||
* Elaboration-time assertion failures.
|
||||
* Runtime crashes in malformed corner cases.
|
||||
* Memory management issues during elaboration and simulation.
|
||||
|
||||
|
||||
----
|
||||
|
||||
🔄 Major Changes in V13
|
||||
=======================
|
||||
|
||||
🧠 Language & Elaboration Fixes
|
||||
-------------------------------
|
||||
|
||||
Release V13 includes multiple fixes to elaboration and expression handling:
|
||||
|
||||
* Resolved generate block scope resolution issues affecting nested and conditional generate constructs.
|
||||
* Corrected signed arithmetic corner cases, including shift and width propagation behavior.
|
||||
* Fixed constant expression evaluation inconsistencies during parameter elaboration.
|
||||
* Improved handling of packed and unpacked arrays in assignments and port binding corner cases.
|
||||
* Addressed elaboration-time assertion failures triggered by malformed or ambiguous constructs.
|
||||
* Corrected several source-location reporting issues for elaboration errors.
|
||||
|
||||
These changes improve standards conformance and eliminate behavioral inconsistencies observed in the V12 series.
|
||||
|
||||
----
|
||||
|
||||
⚙️ Simulator (vvp) Improvements
|
||||
-------------------------------
|
||||
|
||||
The `vvp` runtime engine has received internal stability and correctness updates:
|
||||
|
||||
* Improved event scheduling behavior in zero-delay and non-blocking assignment scenarios.
|
||||
* Fixed race-condition corner cases uncovered by expanded regression testing.
|
||||
* Eliminated memory leaks affecting long-running or large simulations.
|
||||
* Resolved crash conditions caused by invalid internal state transitions.
|
||||
* Improved robustness of `$dumpvars` handling in large hierarchical designs.
|
||||
* General runtime consistency and determinism improvements.
|
||||
|
||||
`vvp` continues to enforce version matching between the runtime and generated bytecode. Designs
|
||||
must be recompiled after upgrading.
|
||||
|
||||
----
|
||||
|
||||
🔌 VPI Updates
|
||||
--------------
|
||||
|
||||
Fixes improve VPI reliability and conformance:
|
||||
|
||||
* Corrected hierarchical object lookup behavior in specific corner cases.
|
||||
* Improved stability of callback registration during startup and shutdown.
|
||||
* Fixed invalid handle dereference scenarios that could result in segmentation faults.
|
||||
* Addressed inconsistencies in VPI object property reporting.
|
||||
|
||||
----
|
||||
|
||||
🛠 Diagnostics & Toolchain
|
||||
--------------------------
|
||||
|
||||
* Improved clarity and consistency of error and warning messages.
|
||||
* Better reporting of width mismatches and implicit net declarations.
|
||||
* More accurate diagnostic source locations.
|
||||
* Build system updates for compatibility with modern compiler toolchains.
|
||||
* Regression suite expansion and CI validation improvements.
|
||||
|
||||
----
|
||||
|
||||
📦 Upgrade Notes
|
||||
----------------
|
||||
|
||||
* Recompile all designs when upgrading from V12 or any other prior version.
|
||||
* Review warnings carefully; improved diagnostics may expose previously silent issues.
|
||||
* The only known breaking change is that wires must now be declared before use; which is required in the standard (see `gh1287 <https://github.com/steveicarus/iverilog/issues/1287>`__).
|
||||
|
||||
----
|
||||
|
||||
🙏 Acknowledgments
|
||||
------------------
|
||||
|
||||
We thank all contributors who reported issues, submitted patches, expanded regression coverage, and
|
||||
improved documentation. Release 13 reflects continued community effort toward improving correctness,
|
||||
stability, and maintainability.
|
||||
@@ -0,0 +1,2 @@
|
||||
sphinx==8.1.3
|
||||
shibuya==2026.1.9
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
The sizer Code Analyzer (-tvvp)
|
||||
===============================
|
||||
The sizer Code Analyzer (-tsizer)
|
||||
=================================
|
||||
|
||||
The sizer target does not generate any code. Instead it will print statistics about the Verilog code.
|
||||
|
||||
|
||||
@@ -68,6 +68,16 @@ These flags affect the general behavior of the compiler.
|
||||
This flag enables the IEEE1800-2012 standard, which includes
|
||||
SystemVerilog.
|
||||
|
||||
* 2017
|
||||
|
||||
This flag enables the IEEE1800-2017 standard, which includes
|
||||
SystemVerilog.
|
||||
|
||||
* 2023
|
||||
|
||||
This flag enables the IEEE1800-2023 standard, which includes
|
||||
SystemVerilog.
|
||||
|
||||
* verilog-ams
|
||||
|
||||
This flag enables Verilog-AMS features that are supported by Icarus
|
||||
@@ -131,6 +141,18 @@ These flags affect the general behavior of the compiler.
|
||||
containing an unsized constant number, and unsized constant numbers are
|
||||
not truncated to integer width.
|
||||
|
||||
* strict-declaration/no-strict-declaration
|
||||
|
||||
* strict-net-var-declaration/no-strict-net-var-declaration
|
||||
|
||||
* strict-parameter-declaration/no-strict-parameter-declaration
|
||||
|
||||
The standards require that nets, variables, and parameters must be
|
||||
declared lexically before they are used. Using -gno-strict-declaration
|
||||
will allow using a data object before declaration, with a warning. The
|
||||
warning can be suppressed with -Wno-declaration-after-use. The option
|
||||
can be applied for nets and variables and for parameters separately.
|
||||
|
||||
* shared-loop-index/no-shared-loop-index
|
||||
|
||||
Enable or disable the exclusion of for-loop control variables from
|
||||
@@ -260,6 +282,7 @@ These flags affect the general behavior of the compiler.
|
||||
-Wanachronisms
|
||||
-Wimplicit
|
||||
-Wimplicit-dimensions
|
||||
-Wdeclaration-after-use
|
||||
-Wmacro-replacement
|
||||
-Wportbind
|
||||
-Wselect-range
|
||||
@@ -288,6 +311,15 @@ These flags affect the general behavior of the compiler.
|
||||
This flag is supported in release 10.1 or master branch snapshots after
|
||||
2016-02-06.
|
||||
|
||||
* declaration-after-use
|
||||
|
||||
This enables warnings for declarations after use, when those are not
|
||||
flagged as errors (enabled by default). Use no-declaration-after-use
|
||||
to disable this.
|
||||
|
||||
This flag was added in version 14.0 or later (and is in the master branch
|
||||
as of 2026-03-21).
|
||||
|
||||
* macro-redefinition
|
||||
|
||||
This enables warnings when a macro is redefined, even if the macro text
|
||||
|
||||
@@ -7,8 +7,91 @@ standard. Some of these are picked from extended variants of the
|
||||
language, such as SystemVerilog, and some are expressions of internal
|
||||
behavior of Icarus Verilog, made available as a tool debugging aid.
|
||||
|
||||
Built-in System Functions
|
||||
-------------------------
|
||||
Don't use any of these extensions if you want to keep your code portable
|
||||
across other Verilog compilers.
|
||||
|
||||
System Functions
|
||||
----------------
|
||||
|
||||
``$is_signed(<expr>)``
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This function returns 1 if the expression contained is signed, or 0 otherwise.
|
||||
This is mostly of use for compiler regression tests.
|
||||
|
||||
``$bits(<expr>)``, ``$sizeof(<expr>)``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``$bits`` system function returns the size in bits of the expression that
|
||||
is its argument. The result of this function is undefined if the argument
|
||||
doesn't have a self-determined size.
|
||||
|
||||
The ``$sizeof`` system function is deprecated in favour of ``$bits``, which is
|
||||
the same thing, but included in the SystemVerilog definition.
|
||||
|
||||
``$simtime()``
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
This returns as a 64bit value the simulation time, unscaled by the time units
|
||||
of the local scope. This is different from the ``$time`` and ``$stime``
|
||||
functions which return the scaled times. This function is added for regression
|
||||
testing of the compiler and run time, but can be used by applications who
|
||||
really want the simulation time.
|
||||
|
||||
Note that the simulation time can be confusing if there are lots of different
|
||||
```timescales`` within a design. It is not in general possible to predict
|
||||
what the simulation precision will turn out to be.
|
||||
|
||||
``$mti_random()``, ``$mti_dist_uniform``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
These functions are similar to the IEEE 1364 standard ``$random`` functions,
|
||||
but they use the Mersenne Twister (MT19937) algorithm. This is considered an
|
||||
excellent random number generator, but does not generate the same sequence as
|
||||
the standardized ``$random``.
|
||||
|
||||
System Tasks
|
||||
------------
|
||||
|
||||
``$readmempath``
|
||||
^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``$readmemb`` and ``$readmemh`` system tasks read text files that contain
|
||||
data values to populate memories. Normally, those files are found in a current
|
||||
working directory. The ``$readmempath()`` system task can be used to create a
|
||||
search path for those files. For example:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
reg [7:0] mem [0:7];
|
||||
initial begin
|
||||
$readmemh("datafile.txt", mem);
|
||||
end
|
||||
|
||||
This assumes that "datafile.txt" is in the current working directory where
|
||||
the ``vvp`` command is running. But with the ``$readmempath``, one can specify
|
||||
a search path:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
reg [7:0] mem [0:7];
|
||||
initial begin
|
||||
$readmempath(".:alternative:/global/defaults");
|
||||
$readmemh("datafile.txt", mem);
|
||||
end
|
||||
|
||||
In this example, "datafile.txt" is searched for in each of the directories
|
||||
in the above list (separated by ":" characters). The first located instance
|
||||
is the one that is used. So for example, if "./datafile.txt" exists, then it
|
||||
is read instead of "/global/defaults/datafile.txt" even if the latter exists.
|
||||
|
||||
``$finish_and_return(code)``
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
This task operates the same as the ``$finish`` system task, but adds the
|
||||
feature of specifying an exit code for the interpreter. This can be useful in
|
||||
automated test environments to indicate whether the simulation finished with
|
||||
or without errors.
|
||||
|
||||
Extended Verilog Data Types
|
||||
---------------------------
|
||||
|
||||
@@ -9,39 +9,430 @@ standard, or from other implementations.
|
||||
This is NOT AN EXHAUSTIVE LIST. If something is missing from this list, let us
|
||||
know and we can add documentation.
|
||||
|
||||
System Tasks - Unique to Icarus Verilog
|
||||
---------------------------------------
|
||||
Unsized Numeric Constants are Not Limited to 32 Bits
|
||||
----------------------------------------------------
|
||||
|
||||
These are system tasks that are unique to Icarus Verilog. Don't use any of
|
||||
these if you want to keep your code portable across other Verilog compilers.
|
||||
The Verilog standard allows Verilog implementations to limit the size of
|
||||
unsized constants to a bit width of at least 32. That means that a constant
|
||||
17179869183 (``36'h3_ffff_ffff``) may overflow some compilers. In fact, it
|
||||
is common to limit these values to 32 bits. However, a compiler may just as
|
||||
easily choose another width limit, for example 64 bits. That value is
|
||||
equally good.
|
||||
|
||||
$readmempath
|
||||
^^^^^^^^^^^^
|
||||
The "$readmemb" and "$readmemh" system tasks read text files that contain data
|
||||
values to populate memories. Normally, those files are found in a current work
|
||||
directory. The "$readmempath()" system task can be used to create a search
|
||||
path for those files. For example:
|
||||
However, it is not required that an implementation truncate at 32 bits, and
|
||||
in fact Icarus Verilog does not truncate at all. It will make the unsized
|
||||
constant as big as it needs to be to hold the value accurately. This is
|
||||
especially useful in situations like this;
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
reg [7:0] mem [0:7];
|
||||
initial begin
|
||||
$readmemh("datafile.txt", mem);
|
||||
end
|
||||
reg [width-1:0] foo = 17179869183;
|
||||
|
||||
This assumes that the "datafile.txt" is in the current working directory where
|
||||
the vvp command is running. But with the "$readmempath", one can specify a
|
||||
search path:
|
||||
The programmer wants the constant to take on the width of the reg, which in
|
||||
this example is parameterized. Since constant sizes cannot be parameterized,
|
||||
the programmer ideally gives an unsized constant, which the compiler then
|
||||
expands/contracts to match the l-value.
|
||||
|
||||
Also, by choosing to not ever truncate, Icarus Verilog can handle code written
|
||||
for a 64 bit compiler as easily as for a 32 bit compiler. In particular, any
|
||||
constants that the user does not expect to be arbitrarily truncated by their
|
||||
compiler will also not be truncated by Icarus Verilog, no matter what that
|
||||
other compiler chooses as a truncation point.
|
||||
|
||||
Unsized Expressions
|
||||
-------------------
|
||||
|
||||
Icarus Verilog classes any expression containing an unsized numeric constant
|
||||
or unsized parameter value that is not part of a self-determined operand as
|
||||
an unsized expression. When calculating the bit width of an unsized expression,
|
||||
it extends the width of the expression to avoid arithmetic overflow or
|
||||
underflow; in other words, the expression width will be made large enough to
|
||||
represent any possible arithmetic result of the expression. If the expression
|
||||
contains operations that do not follow the normal rules of arithmetic (e.g. an
|
||||
explicit or implicit cast between signed and unsigned values), the expression
|
||||
width will be extended to at least the width of an integer.
|
||||
|
||||
An exception to the above is made if the expression contains a shift or power
|
||||
operator with a right hand operand that is a non-constant unsized expression.
|
||||
In this case any expansion of the expression width due to that operation is
|
||||
limited to the width of an integer, to avoid excessive expression widths
|
||||
(without this, an expression such as ``2**(i-1)``, where ``i`` is an integer,
|
||||
would be expanded to 2\**33 bits).
|
||||
|
||||
The above behaviour is a deviation from the Verilog standard, which states
|
||||
that when calculating an expression width, the width of an unsized constant
|
||||
number is the same as the width of an integer. If you need strict standard
|
||||
compliance (for compatibility with other EDA tools), then the compiler has
|
||||
a command line option, ``-gstrict-expr-width``, which disables the special
|
||||
treatment of unsized expressions. With this option, the compiler will output
|
||||
a warning message if an unsized numeric constant is encountered that cannot
|
||||
be represented in integer-width bits and will truncate the value.
|
||||
|
||||
If you are simulating synthesisable code, it is recommended that the
|
||||
``-gstrict-expr-width`` option is used, as this eliminates a potential
|
||||
source of synthesis vs. simulation mismatches.
|
||||
|
||||
Unsized Parameters
|
||||
------------------
|
||||
|
||||
Icarus Verilog classes any parameter declaration that has no explicit or
|
||||
implicit range specification as an unsized parameter declaration. When
|
||||
calculating the bit width of the final value expression for the parameter,
|
||||
it follows the same rules as it does for unsized expressions, regardless of
|
||||
whether or not the expression contains any unsized numeric constants.
|
||||
|
||||
If the final value expression for an unsized parameter is an unsized
|
||||
expression (i.e. does contain unsized numeric constants), any subsequent use
|
||||
of that parameter will be treated as if it was an unsized numeric constant.
|
||||
If not, it will be treated as if it was a numeric constant of the appropriate
|
||||
size. For example, with the declarations:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
reg [7:0] mem [0:7];
|
||||
initial begin
|
||||
$readmempath(".:alternative:/global/defaults");
|
||||
$readmemh("datafile.txt", mem);
|
||||
end
|
||||
localparam Value1 = 'd3 + 'd2;
|
||||
localparam Value2 = 2'd3 + 2'd2;
|
||||
|
||||
In this example, the "datafile.txt" is searched for in each of the directories
|
||||
in the above list (separated by ":" characters). The first located instance
|
||||
is the one that is used. So for example, if "./datafile.txt" exists, then it
|
||||
is read instead of "/global/defaults/datafile.txt" even if the latter exists.
|
||||
any subsequent use of ``Value1`` will be treated as if the programmer had
|
||||
written ``'d5`` and any subsequent use of ``Value2`` will be treated as if
|
||||
the programmer had written ``3'd5``. In particular, note that ``Value2`` can
|
||||
be used as a concatenation operand, but ``Value1`` cannot.
|
||||
|
||||
The above behaviour is a deviation from the Verilog standard. As for
|
||||
unsized expressions, if you need strict standard compliance. use the
|
||||
``-gstrict-expr-width`` compiler option.
|
||||
|
||||
Unsized Expressions as Arguments to Concatenation
|
||||
-------------------------------------------------
|
||||
|
||||
The Verilog standard clearly states in 4.1.14:
|
||||
|
||||
"Unsized constant numbers shall not be allowed in concatenations. This
|
||||
is because the size of each operand in the concatenation is needed to
|
||||
calculate the complete size of the concatenation."
|
||||
|
||||
So for example the expression ``{1'b0, 16}`` is clearly illegal. It also stands
|
||||
to reason that ``{1'b0, 15+1}`` is illegal, for exactly the same justification.
|
||||
What is the size of the expression (15+1)? Furthermore, it is reasonable to
|
||||
expect that (16) and (15+1) are exactly the same so far as the compiler is
|
||||
concerned.
|
||||
|
||||
Unfortunately, Cadence seems to feel otherwise. In particular, it has been
|
||||
reported that although ``{1'b0, 16}`` causes an error, ``{1'b0, 15+1}`` is
|
||||
accepted. Further testing shows that any expression other than a simple
|
||||
unsized constant is accepted there, even if all the operands of all the
|
||||
operators that make up the expression are unsized integers.
|
||||
|
||||
This is a semantic problem. Icarus Verilog doesn't limit the size of integer
|
||||
constants. This is valid as stated in 2.5.1 Note 3:
|
||||
|
||||
"The number of bits that make up an unsized number (which is a simple
|
||||
decimal number or a number without the size specification) shall be
|
||||
**at least** 32." [emphasis added]
|
||||
|
||||
Icarus Verilog will hold any integer constant, so the size will be as large as
|
||||
it needs to be, whether that is 64 bits, 128 bits, or more. With this in mind,
|
||||
what is the value of these expressions?
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
{'h1_00_00_00_00}
|
||||
{'h1 << 32}
|
||||
{'h0_00_00_00_01 << 32}
|
||||
{'h5_00_00_00_00 + 1}
|
||||
|
||||
These examples show that the standard is justified in requiring that the
|
||||
operands of concatenation have size. The dispute is what it takes to cause
|
||||
an expression to have a size, and what that size is. Verilog-XL claims that
|
||||
(16) does not have a size, but (15+1) does. The size of the expression (15+1)
|
||||
is the size of the adder that is created, but how wide is the adder when
|
||||
adding unsized constants?
|
||||
|
||||
One might note that the quote from section 4.1.14 says "Unsized constant
|
||||
numbers shall not be allowed." It does not say "Unsized expressions...", so
|
||||
arguably accepting (15+1) or even (16+0) as an operand to a concatenation is
|
||||
not a violation of the letter of the law. However, the very next sentence of
|
||||
the quote expresses the intent, and accepting (15+1) as having a more defined
|
||||
size then (16) seems to be a violation of that intent.
|
||||
|
||||
Whatever a compiler decides the size is, the user has no way to predict it,
|
||||
and the compiler should not have the right to treat (15+1) any differently
|
||||
then (16). Therefore, Icarus Verilog takes the position that such expressions
|
||||
are unsized and are not allowed as operands to concatenations. Icarus Verilog
|
||||
will in general assume that operations on unsized numbers produce unsized
|
||||
results. There are exceptions when the operator itself does define a size,
|
||||
such as the comparison operators or the reduction operators. Icarus Verilog
|
||||
will generate appropriate error messages.
|
||||
|
||||
Scope of Macro Defines Doesn't Extend into Libraries
|
||||
----------------------------------------------------
|
||||
|
||||
Icarus Verilog does preprocess modules that are loaded from libraries via the
|
||||
``-y`` mechanism to substitute macros and load includes. However, the only
|
||||
macros defined during compilation of an automatically loaded library module
|
||||
file are those that it defines itself (or includes) or that are defined on the
|
||||
command line or in the command file. Specifically, macros defined in the non-
|
||||
library source files are not remembered when the library module is loaded, and
|
||||
macros defined in a library module do not escape into the rest of the design.
|
||||
This is intentional. If it were otherwise, then compilation results might vary
|
||||
depending on the order that libraries are loaded, and that is unacceptable.
|
||||
|
||||
For example, given sample library module ``a.v``:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
`define MACRO_A 1
|
||||
module a(input x);
|
||||
always @(x) $display("x=",x);
|
||||
endmodule
|
||||
|
||||
and sample library module ``b.v``:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
module b(input y);
|
||||
`ifdef MACRO_A
|
||||
always @(y) $display("MACRO_A is defined",,y);
|
||||
`else
|
||||
always @(y) $display("MACRO_A is NOT defined",,y);
|
||||
`endif
|
||||
endmodule
|
||||
|
||||
If a program instantiates both of these modules, there is no way to know
|
||||
which will be loaded first by the compiler, so if the definition of
|
||||
``MACRO_A`` in ``a.v`` were to escape, then there is no way to predict or
|
||||
control whether ``MACRO_A`` is defined when ``b.v`` is processed. So the
|
||||
preprocessor processes automatic library module files as if they are in
|
||||
their own compilation unit, and you can know that ``MACRO_A`` will not be
|
||||
defined in ``b.v`` unless it is defined on the command line (a ``-D`` flag)
|
||||
or in the command file (a ``+define+`` record.)
|
||||
|
||||
Of course if ``a.v`` and ``b.v`` were listed in the command file or on the
|
||||
command line, then the situation is different; the order is clear. The files
|
||||
are processed as if they were concatenated in the order that they are listed
|
||||
on the command line. The non-library modules are all together in a main
|
||||
compilation unit, and they are all processed before any library modules are
|
||||
loaded.
|
||||
|
||||
It is said that some commercial compilers do allow macro definitions to span
|
||||
library modules. That's just plain weird. However, there is a special case
|
||||
that Icarus Verilog does handle. Preprocessor definitions that are made in
|
||||
files explicitly listed on the command line or in the command file, do pass
|
||||
into implicitly loaded library files. For example, given the source file
|
||||
``x.v``:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
module main;
|
||||
reg foo;
|
||||
b dut(foo);
|
||||
endmodule
|
||||
`define MACRO_A
|
||||
|
||||
and the library module file ``b.v`` described above, the situation is well
|
||||
defined, assuming the ``x.v`` file is listed on the command line or in the
|
||||
command file. The library module will receive the ``MACRO_A`` definition
|
||||
from the last explicitly loaded source file. The position of the define of
|
||||
``MACRO_A`` in the explicitly loaded source files does not matter, as all
|
||||
explicitly loaded source files are preprocessed before any library files
|
||||
are loaded.
|
||||
|
||||
Continuous Assign L-Values Can Implicit-Define Wires
|
||||
----------------------------------------------------
|
||||
|
||||
The IEEE 1364-2001 standard, Section 3.5, lists the cases where nets may be
|
||||
implicitly created. These include:
|
||||
|
||||
- identifier is a module port
|
||||
- identifier is passed as a port to a primitive or module
|
||||
|
||||
This does not seem to include continuous assignment l-values (or r-values)
|
||||
so the standard does not justify allowing implicit declarations of nets by
|
||||
continuous assignment.
|
||||
|
||||
However, it has been reported that many Verilog compilers, including the big
|
||||
name tools, do allow this. So, Icarus Verilog will allow it as well, as an
|
||||
extension. If ``-gxtypes`` (the default) is used, this extension is enabled.
|
||||
To turn off this behavior, use the ``-gno-xtypes`` flag.
|
||||
|
||||
Dumping Array Words (``$dumpvars``)
|
||||
-----------------------------------
|
||||
|
||||
Icarus has the ability to dump individual array words. They are only dumped
|
||||
when explicitly passed to $dumpvars. They are not dumped by default. For
|
||||
example given the following:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
module top;
|
||||
reg [7:0] array [2:0];
|
||||
initial begin
|
||||
$dumpvars(0, array[0], array[1]);
|
||||
...
|
||||
end
|
||||
endmodule
|
||||
|
||||
``array[0]`` and ``array[1]`` will be dumped whenever they change value. They
|
||||
will be displayed as an escaped identifier and GTKWave fully supports this.
|
||||
Note that this is an implicitly created escaped identifier that could conflict
|
||||
with an explicitly created escaped identifier. You can automate adding the
|
||||
array word by adding an index definition
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
integer idx;
|
||||
|
||||
and replacing the previous $dumpvars statement with
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
for (idx = 0; idx < 2; idx = idx + 1) $dumpvars(0, array[idx]);
|
||||
|
||||
This will produce the same results as the previous example, but it is much
|
||||
easier to specify/change which elements are to be dumped. One important note
|
||||
regarding this syntax. Most system tasks/functions keep the variable selection
|
||||
(for this case it is a variable array word selection) context. If ``$dumpvars``
|
||||
did this then all callback created would point to this element and would use
|
||||
the same index which for the example above would have the value 2. This is
|
||||
certainly not what is desired and for this special case when ``$dumpvars``
|
||||
executes it uses the current index value to create a constant array selection
|
||||
and that is monitored instead of the original variable selection.
|
||||
|
||||
Referencing Declarations Within an Unnamed Generate Block
|
||||
---------------------------------------------------------
|
||||
|
||||
The IEEE 1364-2005 standard permits generate blocks to be unnamed, but states:
|
||||
|
||||
"If the generate block selected for instantiation is not named, it still
|
||||
creates a scope; but the declarations within it cannot be referenced using
|
||||
hierarchical names other than from within the hierarchy instantiated by the
|
||||
generate block itself."
|
||||
|
||||
The standard later defines a scheme for automatically naming the unnamed
|
||||
scopes for use with external interfaces.
|
||||
|
||||
Icarus Verilog implements the defined automatic naming scheme, but does not
|
||||
prevent the automatically generated names being used in a hierarchical
|
||||
reference. This behaviour is harmless - the automatically generated names are
|
||||
guaranteed to be unique within the enclosing scope, so there is no possibility
|
||||
of confusion with explicit scope names. However, to maintain code portability,
|
||||
it is recommended that this behavior is not exploited.
|
||||
|
||||
``%g/%G`` Format Specifiers
|
||||
---------------------------
|
||||
|
||||
In the IEEE 1364-2001 standard there is a general statement that the real
|
||||
number format specifiers will use the full formatting capabilities of C.
|
||||
This is then followed by an example that describes ``%10.3g``. The example
|
||||
description would be correct for the ``%e`` format specifier which should
|
||||
always have three fractional digits, but the ``%g`` format specifier does
|
||||
not work that way. For it the ``.3`` specifies that there will be three
|
||||
significant digits. What this means is that ``%g`` will always produce one
|
||||
less significant digit than ``%e`` and will only match the output from ``%f``
|
||||
for certain values. For example:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
module top_level;
|
||||
real rval;
|
||||
initial begin
|
||||
rval = 1234567890;
|
||||
$display("This is g and e: %10.3g, %10.3e.", rval, rval);
|
||||
rval = 0.1234567890;
|
||||
$display("This is g and f: %10.3g, %10.3f.", rval, rval);
|
||||
rval = 1.234567890;
|
||||
$display("This is more g and f: %10.3g, %10.3f.", rval, rval);
|
||||
end
|
||||
endmodule // top_level
|
||||
|
||||
will produce the following output:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
This is g and e: 1.23e+09, 1.235e+09.
|
||||
This is g and f: 0.123, 0.123.
|
||||
This is more g and f: 1.23, 1.235.
|
||||
|
||||
``%t`` Time Format Specifier Can Specify Width
|
||||
----------------------------------------------
|
||||
|
||||
Standard Verilog does not allow width fields in the ``%t`` formats of display
|
||||
strings. For example, this is illegal:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
$display("Time is %0t", $time);
|
||||
|
||||
Standard Verilog instead relies on the ``$timeformat`` to completely specify
|
||||
the format.
|
||||
|
||||
Icarus Verilog allows the programmer to specify the field width. The ``%t``
|
||||
format in Icarus Verilog works exactly as it does in standard Verilog.
|
||||
However, if the programmer chooses to specify a minimum width (i.e., ``%5t``),
|
||||
then for that display Icarus Verilog will override the ``$timeformat`` minimum
|
||||
width and use the explicit minimum width.
|
||||
|
||||
``%v`` Format Specifier Can Display Vectors
|
||||
-------------------------------------------
|
||||
|
||||
The IEEE 1364-2005 standard limits the ``%v`` specifier in display strings to
|
||||
work only with a single bit. Icarus Verilog extends that to support displaying
|
||||
the strength of vectors. The output is a strength specifier for each bit of the
|
||||
vector, with underscore characters separating each bit, e.g. ``St0_St1_Pu1_HiZ``.
|
||||
Most other tools will just print the strength of the least significant bit of
|
||||
a vector, so this may give different output results for code that otherwise
|
||||
works fine.
|
||||
|
||||
Assign/Deassign and Force/Release of Bit/Part Selects
|
||||
-----------------------------------------------------
|
||||
|
||||
Icarus Verilog allows as an extension the assign/deassign and force/release
|
||||
of variable bit and part selects in certain cases. This allows the Verilog
|
||||
test bench writer to assign/deassign for example single bits of a variable
|
||||
(register, etc.). Other tools will report this as an error.
|
||||
|
||||
``repeat`` Statement is Sign Aware
|
||||
----------------------------------
|
||||
|
||||
The standard does not specify what to do for this case, but it does say what
|
||||
a repeat event control should do. In Icarus Verilog the ``repeat`` statement
|
||||
is consistent with the repeat event control definition. If the argument is
|
||||
signed and is a negative value this will be treated the same as an argument
|
||||
value of 0.
|
||||
|
||||
Built-in System Functions May Be Evaluated at Compile Time
|
||||
----------------------------------------------------------
|
||||
|
||||
Certain of the system functions have well-defined meanings, so can
|
||||
theoretically be evaluated at compile-time, instead of using runtime VPI
|
||||
code. Doing so means that VPI cannot override the definitions of functions
|
||||
handled in this manner. On the other hand, this makes them synthesizable,
|
||||
and also allows for more aggressive constant propagation. The functions
|
||||
handled in this manner are:
|
||||
|
||||
- ``$bits``
|
||||
- ``$signed``
|
||||
- ``$sizeof``
|
||||
- ``$unsigned``
|
||||
|
||||
Implementations of these system functions in VPI modules will be ignored.
|
||||
|
||||
``vpiScope`` Iterator on ``vpiScope`` Objects
|
||||
---------------------------------------------
|
||||
|
||||
In the VPI, the normal way to iterate over ``vpiScope`` objects contained
|
||||
within a ``vpiScope`` object, is the ``vpiInternalScope`` iterator. Icarus
|
||||
Verilog adds support for the ``vpiScope`` iterator of a ``vpiScope`` object,
|
||||
that iterates over *everything* that is contained in the current scope. This
|
||||
is useful in cases where one wants to iterate over all the objects in a scope
|
||||
without iterating over all the contained types explicitly.
|
||||
|
||||
Time 0 Race Resolution
|
||||
----------------------
|
||||
|
||||
Combinational logic is routinely modelled using always blocks. However, this
|
||||
can lead to race conditions if the inputs to the combinational block are
|
||||
initialized in initial statements. Icarus Verilog slightly modifies time 0
|
||||
scheduling by arranging for always statements with ANYEDGE sensitivity lists
|
||||
to be scheduled before any other threads. This causes combinational always
|
||||
blocks to be triggered when the values in the sensitivity list are initialized
|
||||
by initial threads.
|
||||
|
||||
@@ -18,7 +18,7 @@ This section contains documents to help support Icarus Verilog users.
|
||||
vvp_debug
|
||||
vvp_library
|
||||
vhdlpp_flags
|
||||
gtkwave
|
||||
waveform_viewer
|
||||
vpi
|
||||
icarus_verilog_extensions
|
||||
icarus_verilog_quirks
|
||||
|
||||
@@ -2,24 +2,26 @@
|
||||
Installation Guide
|
||||
==================
|
||||
|
||||
Icarus Verilog may be installed from source code, or from pre-packaged binary
|
||||
distributions. If you don't have need for the very latest, and prepackaged
|
||||
binaries are available, that would be the best place to start.
|
||||
Icarus Verilog may be installed from source code (either from ``git`` or a
|
||||
released `tar/zip` file), or from pre-packaged binary distributions. If you
|
||||
don't have a need for the very latest, and prepackaged binaries are available,
|
||||
that is the easiest place to start.
|
||||
|
||||
Installation From Source
|
||||
------------------------
|
||||
|
||||
Icarus is developed for Unix-like environments but can also be compiled on
|
||||
Windows systems using the Cygwin environment or MinGW compilers. The following
|
||||
instructions are the common steps for obtaining the Icarus Verilog source,
|
||||
compiling and installing. Note that there are precompiled and/or prepackaged
|
||||
versions for a variety of systems, so if you find an appropriate packaged
|
||||
version, then that is the easiest way to install.
|
||||
Windows systems using the `Cygwin/MSYS2` environments or `MinGW` compilers. The
|
||||
following instructions are the common steps for obtaining the Icarus Verilog
|
||||
source code, compiling, installing, and checking the compiled code is working
|
||||
properly. Note that there are pre-compiled and/or prepackaged versions for a
|
||||
variety of systems, so if you find an appropriate packaged version, then that
|
||||
is the easiest way to install.
|
||||
|
||||
The source code for Icarus is stored under the git source code control
|
||||
system. You can use git to get the latest development head or the latest of a
|
||||
specific branch. Stable releases are placed on branches, and in particular v11
|
||||
stable releases are on the branch "v11-branch" To get the development version
|
||||
The source code for Icarus is stored under the `git` source code control
|
||||
system. You can use ``git`` to get the latest development head or the latest of
|
||||
a specific branch. Stable releases are placed on branches, and in particular V12
|
||||
stable releases are on the branch "v12-branch" To get the development version
|
||||
of the code follow these steps::
|
||||
|
||||
% git config --global user.name "Your Name Goes Here"
|
||||
@@ -29,7 +31,7 @@ of the code follow these steps::
|
||||
The first two lines are optional and are used to tell git who you are. This
|
||||
information is important if/when you submit a patch. We suggest that you add
|
||||
this information now so you don't forget to do it later. The clone will create
|
||||
a directory, named iverilog, containing the source tree, and will populate
|
||||
a directory, named `iverilog`, containing the source tree, and will populate
|
||||
that directory with the most current source from the HEAD of the repository.
|
||||
|
||||
Change into this directory using::
|
||||
@@ -37,19 +39,26 @@ Change into this directory using::
|
||||
% cd iverilog
|
||||
|
||||
Normally, this is enough as you are now pointing at the most current
|
||||
development code, and you have implicitly created a branch "master" that
|
||||
development code, and you have implicitly created a branch `master` that
|
||||
tracks the development head. However, If you want to actually be working on
|
||||
the v11-branch (the branch where the latest v11 patches are) then you checkout
|
||||
that branch with the command::
|
||||
the `v12-branch` (the branch where the latest V12 patches are) then you
|
||||
checkout that branch with the command::
|
||||
|
||||
% git checkout --track -b v11-branch origin/v11-branch
|
||||
% git checkout --track -b v12-branch origin/v12-branch
|
||||
|
||||
This creates a local branch that tracks the v11-branch in the repository, and
|
||||
switches you over to your new v11-branch. The tracking is important as it
|
||||
This creates a local branch that tracks the `v12-branch` in the repository, and
|
||||
switches you over to your new `v12-branch`. The tracking is important as it
|
||||
causes pulls from the repository to re-merge your local branch with the remote
|
||||
v11-branch. You always work on a local branch, then merge only when you
|
||||
`v12-branch`. You always work on a local branch, then merge only when you
|
||||
push/pull from the remote repository.
|
||||
|
||||
The choice between the development branch and the latest released branch
|
||||
depends on your stability requirements. The released branch will only get bug
|
||||
fixes. It will not get any enhancements or changes in the compiler output
|
||||
format. Unlike many project the development branch is fairly stable with only
|
||||
occasional periods of instability. We do most of our big changes in side
|
||||
branches and only merge them into the development branch when they are clean.
|
||||
|
||||
Now that you've cloned the repository and optionally selected the branch you
|
||||
want to work on, your local source tree may later be synced up with the
|
||||
development source by using the git command::
|
||||
@@ -59,22 +68,33 @@ development source by using the git command::
|
||||
The git system remembers the repository that it was cloned from, so you don't
|
||||
need to re-enter it when you pull.
|
||||
|
||||
Finally, configuration files are built by the extra step::
|
||||
To build the `configure` script and hash files you need to run the
|
||||
following::
|
||||
|
||||
% sh autoconf.sh
|
||||
% cd ..
|
||||
|
||||
The source is then compiled as appropriate for your system. See the specific
|
||||
build instructions below for your operation system for what to do next.
|
||||
|
||||
You will need autoconf and gperf installed in order for the script to work.
|
||||
If you get errors such as::
|
||||
This is not need for the released `tar/zip` files since they already contain
|
||||
these files. You only need to run this once after cloning. If you are missing
|
||||
``autoconf`` or ``gperf`` then the script will fail::
|
||||
|
||||
Autoconf in root...
|
||||
autoconf.sh: 10: autoconf: not found
|
||||
Precompiling lexor_keyword.gperf
|
||||
autoconf.sh: 13: gperf: not found.
|
||||
|
||||
You will need to install download and install the autoconf and gperf tools.
|
||||
You will need to install the ``autoconf`` and ``gperf`` tools before you can
|
||||
continue.
|
||||
|
||||
The other way to get the source code is to download a released `tar/zip` file::
|
||||
|
||||
% tar -xvzf v13_0.tar.gz
|
||||
or
|
||||
% unzip v13_0.zip
|
||||
|
||||
See the build instructions for your operation system below to know what to do
|
||||
next. Though first determine if there are any extra configuration option you
|
||||
may need.
|
||||
|
||||
Icarus Specific Configuration Options
|
||||
-------------------------------------
|
||||
@@ -93,43 +113,215 @@ All programs or directories are tagged with this suffix. e.g.(iverilog-0.8,
|
||||
vvp-0.8, etc.). The output of iverilog will reference the correct run time
|
||||
files and directories. The run time will check that it is running a file with
|
||||
a compatible version e.g.(you can not run a V0.9 file with the V0.8 run
|
||||
time). ::
|
||||
time).::
|
||||
|
||||
--with-valgrind
|
||||
|
||||
This option adds extra memory cleanup code and pool management code to allow
|
||||
better memory leak checking when valgrind is available. This option is not
|
||||
need when checking for basic errors with valgrind. ::
|
||||
needed when checking for basic errors with valgrind and should not be used if
|
||||
you just intend to use ``iverilog`` as a simulator. ::
|
||||
|
||||
--enable-libvvp
|
||||
|
||||
The vvp progam is built as a small stub linked to a shared library,
|
||||
The vvp program is built as a small stub linked to a shared library,
|
||||
libvvp.so, that may be linked with other programs so that they can host
|
||||
a vvp simulation.
|
||||
a vvp simulation. ::
|
||||
|
||||
--enable-libveriuser
|
||||
|
||||
PLI version 1 (the ACC and TF routines) were deprecated in IEEE 1364-2005.
|
||||
These are supported in Icarus Verilog by the libveriuser library and cadpli
|
||||
module. Starting with V13, these will only be built if this option is used.
|
||||
|
||||
Compiling on Linux/Unix
|
||||
-----------------------
|
||||
|
||||
(Note: You will need to install bison, flex, g++ and gcc) This is probably the
|
||||
easiest case. Given that you have the source tree from the above instructions,
|
||||
the compile and install is generally as simple as::
|
||||
Note: For a gcc compile you will need to install ``bison``, ``flex``, ``g++``,
|
||||
``gcc`` and preferably `bz2`, `zlib` and `readline` development packages. The
|
||||
`bz2` and `zlib` development packages are required for the non-VCD waveform
|
||||
dumpers and the `readline` development package is needed to enable better
|
||||
terminal control in the ``vvp`` interactive mode.
|
||||
|
||||
% ./configure
|
||||
% make
|
||||
(su to root)
|
||||
# make install
|
||||
If you are only compiling one variant then you can compile directly in the
|
||||
source tree. If you need multiple variants (optimized, debugging, multiple
|
||||
compilers) then it is recommended you compile each in their own directory.
|
||||
|
||||
The "make install" typically needs to be done as root so that it can install
|
||||
in directories such as "/usr/local/bin" etc. You can change where you want to
|
||||
install by passing a prefix to the "configure" command::
|
||||
For multiple variants create a directory for each of the variants you intend
|
||||
to create and in each run the following steps, adjusting the options in the
|
||||
configure stage to get the functionality you want. For a single build you can
|
||||
either build it with the source or in a separate build directory.
|
||||
|
||||
% ./configure --prefix=/my/special/directory
|
||||
The following is from a Ubuntu 22.04 machine using gcc (version 11.4)::
|
||||
|
||||
This will configure the source for eventual installation in the directory that
|
||||
you specify. Note that "rpm" packages of binaries for Linux are typically
|
||||
configured with "--prefix=/usr" per the Linux File System Standard.
|
||||
% mkdir gcc
|
||||
% cd gcc
|
||||
or
|
||||
% cd iverilog
|
||||
|
||||
Make sure you have the latest version of flex otherwise you will get an error
|
||||
You can also use ``clang/clang++``. I usual build optimized version for
|
||||
normal use and reserve debugging options for a valgrind or a separate
|
||||
debugging build. Make sure you have `sudo` permission if you are using a
|
||||
system prefix area, otherwise you need to use some place you have
|
||||
permission to install (e.g. ~/).::
|
||||
|
||||
% env CFLAGS=-O2 CXXFLAGS=-O2 LDFLAGS=-s CC=gcc CXX=g++ ../iverilog/configure --enable-suffix=-gcc --prefix=/usr/local
|
||||
|
||||
This will generate the following (with some inline comments)::
|
||||
|
||||
checking build system type... x86_64-pc-linux-gnu
|
||||
checking host system type... x86_64-pc-linux-gnu
|
||||
checking for gcc... gcc
|
||||
checking whether the C compiler works... yes
|
||||
...
|
||||
checking for gperf... gperf # required for git builds
|
||||
checking for man... man # you likely want manual pages
|
||||
checking for ps2pdf... ps2pdf
|
||||
checking for groff... groff
|
||||
checking for git... git # required for git builds
|
||||
checking for flex... flex # required
|
||||
checking for bison... bison # required
|
||||
...
|
||||
checking for tputs in -ltermcap... yes
|
||||
checking for readline in -lreadline... yes
|
||||
checking for add_history in -lreadline... yes
|
||||
checking for readline/readline.h... yes
|
||||
checking for readline/history.h... yes # you likely want this
|
||||
...
|
||||
checking for pthread_create in -lpthread... yes
|
||||
checking for gzwrite in -lz... yes
|
||||
checking for gzwrite in -lz... (cached) yes
|
||||
checking for BZ2_bzdopen in -lbz2... yes
|
||||
checking for BZ2_bzdopen in -lbz2... (cached) yes # you want these for fst dumping
|
||||
...
|
||||
<Create all the parameterized Makefile and header files>
|
||||
|
||||
Usually if ``configure`` fails there is some required dependency missing. I
|
||||
usually review all the output to make sure it makes sense (e.g. I requested
|
||||
``gcc`` and that's what is being used, other things match my expectation). If
|
||||
all the waveform dumpers are not enabled there could be a few test failures.
|
||||
|
||||
Next we need to compile the code. Note: make sure you are using GNU make.
|
||||
It may be named gmake (e.g. GhostBSD)::
|
||||
|
||||
% make check >& make.log
|
||||
|
||||
This is for a tcsh/csh shell. Bash/fish/zsh use ``&>`` instead of ``>&``.
|
||||
Once this has completed check the make.log for any errors. There should not
|
||||
be any! I also check for warnings. There are often some related to the
|
||||
output from bison. For example::
|
||||
|
||||
From: ./parse.cc
|
||||
parse.cc:9462:18: warning: missing initializer for member ‘vlltype::lexical_pos’ [-Wmissing-field-initializers]
|
||||
9462 | = { 1, 1, 1, 1 }
|
||||
| ^
|
||||
parse.cc:9462:18: warning: missing initializer for member ‘vlltype::text’ [-Wmissing-field-initializers]
|
||||
|
||||
and::
|
||||
|
||||
From: ./vvp/parse.cc
|
||||
parse.cc:3242: warning: suspicious sequence in the output: m4_type [-Wother]
|
||||
parse.cc:3248: warning: suspicious sequence in the output: m4_type [-Wother]
|
||||
|
||||
Are common, but benign warnings. Different compilers or compiler versions may
|
||||
have other warnings.
|
||||
|
||||
The expected last few lines of the make.log file and these indicate everything
|
||||
should be working as expected are::
|
||||
|
||||
...
|
||||
driver/iverilog -B. -BMvpi -BPivlpp -tcheck -ocheck.vvp ../iverilog/examples/hello.vl
|
||||
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
Hello, World
|
||||
|
||||
If everything is good to this point and you are installing into a system
|
||||
prefix; install using ``sudo`` as shown below. If you are installing into a
|
||||
personal location skip the ``sudo``::
|
||||
|
||||
% sudo make install
|
||||
|
||||
Now you should verify the regression test suite is working as expected::
|
||||
|
||||
% cd ../iverilog/ivtest
|
||||
% ./vvp_reg.pl --suffix=-gcc
|
||||
|
||||
This is the original test script and should give no failures::
|
||||
|
||||
Running compiler/VVP tests for Icarus Verilog version: 13, suffix: -gcc.
|
||||
----------------------------------------------------------------------------
|
||||
macro_with_args: Passed.
|
||||
mcl1: Passed.
|
||||
pr622: Passed.
|
||||
pr639: Passed.
|
||||
...
|
||||
ssetclr2: Passed.
|
||||
ssetclr3: Passed.
|
||||
synth_if_no_else: Passed.
|
||||
ufuncsynth1: Passed.
|
||||
============================================================================
|
||||
Test results:
|
||||
Total=3018, Passed=3013, Failed=0, Not Implemented=2, Expected Fail=3
|
||||
|
||||
Next run the new test script::
|
||||
|
||||
% ./vvp_reg.py --suffix=-gcc
|
||||
|
||||
This should also give no failures::
|
||||
|
||||
Running compiler/VVP tests for Icarus Verilog version: 13, suffix: -gcc
|
||||
Using list(s): regress-vvp.list
|
||||
----------------------------------------------------------------------------
|
||||
always4A: Passed - CE.
|
||||
always4B: Passed - CE.
|
||||
analog1: Not Implemented.
|
||||
analog2: Not Implemented.
|
||||
...
|
||||
vvp_quiet_mode: Passed.
|
||||
warn_opt_sys_tf: Passed - EF.
|
||||
wreal: Passed.
|
||||
writemem-invalid: Passed - EF.
|
||||
============================================================================
|
||||
Test results: Ran 284, Failed 0.
|
||||
|
||||
Finally you can check that the VPI is working properly using::
|
||||
|
||||
% ./vpi_reg.pl --suffix=-gcc
|
||||
|
||||
The output for this should have no failures::
|
||||
|
||||
Running VPI tests for Icarus Verilog version: 13, suffix: -gcc.
|
||||
----------------------------------------------------------------------------
|
||||
br_gh59: Passed.
|
||||
br_gh73a: Passed.
|
||||
br_gh73b: Passed.
|
||||
br_gh117: Passed.
|
||||
...
|
||||
value_change_cb2: Passed.
|
||||
value_change_cb3: Passed.
|
||||
value_change_cb4: Passed.
|
||||
vpi_control: Passed.
|
||||
============================================================================
|
||||
Test results: Total=77, Passed=77, Failed=0, Not Implemented=0
|
||||
|
||||
You can uninstall everything using the following. If needed skip the ``sudo``
|
||||
as described in the install description above.::
|
||||
|
||||
% sudo make uninstall
|
||||
|
||||
You can cleanup the compile directory using::
|
||||
|
||||
% make clean
|
||||
or
|
||||
% make distclean
|
||||
|
||||
The first just cleans up just the compiled files, etc. The later cleans up
|
||||
the compiled file along with all the files generated in the ``configure``
|
||||
phase.
|
||||
|
||||
Note that "rpm" packages of binaries for Linux are typically configured with
|
||||
"--prefix=/usr" per the Linux File System Standard.
|
||||
|
||||
Make sure you have a recent version of flex otherwise you will get an error
|
||||
when parsing lexor.lex.
|
||||
|
||||
Compiling on Macintosh OS X
|
||||
@@ -151,10 +343,16 @@ be updated to version 3. ::
|
||||
Icarus Verilog is also available through the Homebrew package manager: "brew
|
||||
install icarus-verilog".
|
||||
|
||||
Compiling for Windows
|
||||
---------------------
|
||||
Cross-Compiling for Windows
|
||||
---------------------------
|
||||
|
||||
These are instructions for building Icarus Verilog binaries for
|
||||
The `Cygwin` and `MSYS2` environments can compile Icarus Verilog as described
|
||||
above for `Linux/Unix`. There is a `MSYS2` build recipe which can be found in
|
||||
the `msys2/` directory. The accompanying README file provides further details.
|
||||
`MSYS2` is typically preferred over `Cygwin` since ``GTKWave`` and Icarus
|
||||
Verilog are both provided as pre-compiled packages.
|
||||
|
||||
What follows are older instructions for building Icarus Verilog binaries for
|
||||
Windows using mingw cross compiler tools on Linux.
|
||||
|
||||
To start with, you need the mingw64-cross-* packages for your linux
|
||||
@@ -175,9 +373,5 @@ Next, compile with the command::
|
||||
|
||||
$ make
|
||||
|
||||
The configure generated the cross compiler flags, but there are a few
|
||||
bits that need to be compiled with the native compiler. (version.exe
|
||||
for example is used by the build process but is not installed.) The
|
||||
The configure generated the cross compiler flags. The
|
||||
configure script should have gotten all that right.
|
||||
|
||||
There is also a MSYS2 build recipe which you can find under `msys2/` in the repository.
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
Reporting Issues
|
||||
================
|
||||
|
||||
The developers of and contributers to Icarus Verilog use github to track
|
||||
The developers of and contributors to Icarus Verilog use github to track
|
||||
issues and to create patches for the product. If you believe you have found a
|
||||
problem, use the Issues tracker at the
|
||||
`Icarus Verilog github page <https://github.com/steveicarus/iverilog>`_.
|
||||
`Icarus Verilog github page <https://github.com/steveicarus/iverilog>`__.
|
||||
|
||||
You may browse the bugs database for existing
|
||||
bugs that may be related to yours. You might find that your bug has
|
||||
@@ -13,7 +13,7 @@ already been fixed in a later release or snapshot. If that's the case,
|
||||
then you are set.
|
||||
|
||||
On the main page, you will find a row of selections near the top. Click the
|
||||
`Issues <https://github.com/steveicarus/iverilog/issues>`_ link to get to the
|
||||
`Issues <https://github.com/steveicarus/iverilog/issues>`__ link to get to the
|
||||
list of issues, open and closed. You will find a friendly green button where
|
||||
you can create a new issue. You will be asked to create a title for your
|
||||
issue, and to write a detailed description of your issue. Please include
|
||||
@@ -60,7 +60,7 @@ Bug reports with patches/PRs are very welcome. Please also add a new test case i
|
||||
|
||||
If you are editing the source, you should be using the latest
|
||||
version from git. Please see the developer documentation for more
|
||||
detailed instructions -- :doc:`Getting Started as a Contributer <getting_started>` .
|
||||
detailed instructions -- :doc:`Getting Started as a Contributor <getting_started>` .
|
||||
|
||||
COPYRIGHT ISSUES
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ module, is a null terminated table of function pointers. The simulator calls
|
||||
each of the functions in the table in order. The following simple C definition
|
||||
defines a sample table::
|
||||
|
||||
void (*vlog_startup_routines[])() = {
|
||||
void (*vlog_startup_routines[])(void) = {
|
||||
hello_register,
|
||||
0
|
||||
};
|
||||
@@ -89,16 +89,18 @@ file hello.c::
|
||||
|
||||
static int hello_compiletf(char*user_data)
|
||||
{
|
||||
(void)user_data; // Avoid a warning since user_data is not used.
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hello_calltf(char*user_data)
|
||||
{
|
||||
(void)user_data; // Avoid a warning since user_data is not used.
|
||||
vpi_printf("Hello, World!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
void hello_register()
|
||||
void hello_register(void)
|
||||
{
|
||||
s_vpi_systf_data tf_data;
|
||||
|
||||
@@ -111,7 +113,7 @@ file hello.c::
|
||||
vpi_register_systf(&tf_data);
|
||||
}
|
||||
|
||||
void (*vlog_startup_routines[])() = {
|
||||
void (*vlog_startup_routines[])(void) = {
|
||||
hello_register,
|
||||
0
|
||||
};
|
||||
|
||||
@@ -105,7 +105,7 @@ behavior.
|
||||
* -fst
|
||||
|
||||
Generate FST format outputs instead of VCD format waveform dumps. This is
|
||||
the preferred output format if using GTKWave for viewing waveforms.
|
||||
the preferred output format if using GTKWave or Surfer for viewing waveforms.
|
||||
|
||||
* -lxt/-lxt2
|
||||
|
||||
|
||||
@@ -1,22 +1,32 @@
|
||||
Viewing Waveforms
|
||||
=================
|
||||
|
||||
Waveforms With GTKWave
|
||||
======================
|
||||
To view waveforms, either GTKWave or Surfer can be used.
|
||||
|
||||
GTKWave is a VCD waveform viewer based on the GTK library. This viewer support
|
||||
VCD and LXT formats for signal dumps. GTKWAVE is available on github
|
||||
`here <https://github.com/gtkwave/gtkwave>`_. Most Linux distributions already
|
||||
include gtkwave prepackaged.
|
||||
GTKWave is a waveform viewer based on the GTK library. This viewer supports
|
||||
VCD, FST, LXT, and LXT2 formats for waveform dumps. GTKWave is available on GitHub
|
||||
`here <https://github.com/gtkwave/gtkwave>`__. Most Linux distributions already
|
||||
include gtkwave prepackaged and there are binaries for Windows available.
|
||||
|
||||
.. image:: GTKWave_Example2.png
|
||||
|
||||
Generating VCD/FST files for GTKWAVE ------------------------------------
|
||||
Surfer is a waveform viewer based on the Rust egui library. This viewer supports
|
||||
VCD and FST formats for waveform dumps. Surfer is available on GitLab
|
||||
`here <https://gitlab.com/surfer-project/surfer>`__. It runs on Windows, Linux,
|
||||
and MacOS, but can also run in a `web browser <https://app.surfer-project.org/>`__
|
||||
and there is a VS Code
|
||||
`extension <https://marketplace.visualstudio.com/items?itemName=surfer-project.surfer>`__.
|
||||
|
||||
Generating waveform dump files for viewing
|
||||
------------------------------------------
|
||||
|
||||
Waveform dumps are written by the Icarus Verilog runtime program vvp. The user
|
||||
uses $dumpfile and $dumpvars system tasks to enable waveform dumping, then the
|
||||
vvp runtime takes care of the rest. The output is written into the file
|
||||
specified by the $dumpfile system task. If the $dumpfile call is absent, the
|
||||
compiler will choose the file name dump.vcd or dump.lxt or dump.fst, depending
|
||||
on runtime flags. The example below dumps everything in and below the test
|
||||
module:
|
||||
compiler will choose the file name dump.vcd, dump.lxt, dump.lxt2, or dump.fst,
|
||||
depending on runtime flags. The example below dumps everything in and below
|
||||
the test module:
|
||||
|
||||
.. code-block:: verilog
|
||||
|
||||
@@ -30,9 +40,9 @@ module:
|
||||
|
||||
By default, the vvp runtime will generate VCD dump output. This is the default
|
||||
because it is the most portable. However, when using gtkwave, the FST output
|
||||
format is faster and most compact. Use the "-fst" extended argument to
|
||||
activate LXT output. For example, if your compiled output is written into the
|
||||
file "foo.vvp", the command:
|
||||
format is faster and most compact. Use the "-fst", "-lxt", or "-lxt2" extended
|
||||
argument to activate FST, LXT, or LXT2 output, respectively. For example, if
|
||||
your compiled output is written into the file "foo.vvp", the command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
@@ -40,7 +50,7 @@ file "foo.vvp", the command:
|
||||
|
||||
will cause the dumpfile output to be written in FST format. Absent any
|
||||
specific $dumpfile command, this file will be called dump.fst, which can be
|
||||
viewed with the command:
|
||||
viewed with GTKWave using the command:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
@@ -105,7 +115,7 @@ Then the simulation file:
|
||||
$time, value, value);
|
||||
endmodule // test
|
||||
|
||||
Compile, run, and view waveforms with these commands:
|
||||
Compile, run, and view waveforms with GTKWave using these commands:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
@@ -113,6 +123,6 @@ Compile, run, and view waveforms with these commands:
|
||||
% vvp dsn
|
||||
% gtkwave test.vcd &
|
||||
|
||||
Click on the 'test', then 'c1' in the top left box on GTKWAVE, then drag the
|
||||
Click on the 'test', then 'c1' in the top left box of GTKWave, then drag the
|
||||
signals to the Signals box. You will be able to add signals to display,
|
||||
scanning by scope.
|
||||
+64
-124
@@ -36,18 +36,23 @@ prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
srcdir = @srcdir@
|
||||
datarootdir = @datarootdir@
|
||||
VERSION_MAJOR = @VERSION_MAJOR@
|
||||
VERSION_MINOR = @VERSION_MINOR@
|
||||
|
||||
SUBDIRS = ivlpp vhdlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \
|
||||
tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif tgt-sizer driver
|
||||
SUBDIRS = ivlpp vhdlpp vvp vpi tgt-null tgt-stub tgt-vvp \
|
||||
tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif tgt-sizer driver \
|
||||
ivtest
|
||||
# Only run distclean for these directories.
|
||||
NOTUSED = tgt-fpga tgt-pal tgt-verilog
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
SUBDIRS += driver-vpi
|
||||
ifeq (@LIBVERIUSER@,yes)
|
||||
SUBDIRS += libveriuser cadpli
|
||||
else
|
||||
NOTUSED += driver-vpi
|
||||
NOTUSED += libveriuser cadpli
|
||||
endif
|
||||
|
||||
SUBDIRS += driver-vpi
|
||||
|
||||
# To get the version headers to build correctly we only want to look
|
||||
# for C++ files in the source directory. All other files will require
|
||||
# an explicit $(srcdir). The one exception to this is if we need to
|
||||
@@ -61,9 +66,7 @@ bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
# This is actually the directory where we install our own header files.
|
||||
# It is a little different from the generic includedir.
|
||||
includedir = @includedir@/iverilog$(suffix)
|
||||
mandir = @mandir@
|
||||
pdfdir = @docdir@
|
||||
ivl_includedir = @includedir@/iverilog$(suffix)
|
||||
|
||||
dllib=@DLLIB@
|
||||
|
||||
@@ -73,16 +76,19 @@ HOSTCFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
|
||||
BUILDCC = @CC_FOR_BUILD@
|
||||
BUILDEXT = @BUILD_EXEEXT@
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
DLLTOOL = @DLLTOOL@
|
||||
ENV_VVP=@ENV_VVP@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
YACC_CONFLICT_FLAGS = -Werror=conflicts-sr -Werror=conflicts-rr
|
||||
MAN = @MAN@
|
||||
PS2PDF = @PS2PDF@
|
||||
GROFF = @GROFF@
|
||||
GIT = @GIT@
|
||||
|
||||
ifeq (@srcdir@,.)
|
||||
@@ -124,7 +130,7 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
|
||||
PGate.o PGenerate.o PModport.o PNamedItem.o PPackage.o PScope.o PSpec.o PTimingCheck.o \
|
||||
PTask.o PUdp.o PWire.o Statement.o AStatement.o $M $(FF) $(TT)
|
||||
|
||||
all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vpi.man
|
||||
all: dep config.h _pli_types.h version_tag.h version_base.h ivl@EXEEXT@
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
|
||||
# In the windows world, the installer will need a dosify program to
|
||||
@@ -132,37 +138,29 @@ all: dep config.h _pli_types.h version_tag.h ivl@EXEEXT@ version.exe iverilog-vp
|
||||
ifeq (@MINGW32@,yes)
|
||||
all: dosify$(BUILDEXT)
|
||||
dosify$(BUILDEXT): $(srcdir)/dosify.c
|
||||
$(BUILDCC) $(CFLAGS) -o dosify$(BUILDEXT) $(srcdir)/dosify.c
|
||||
$(BUILDCC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o dosify$(BUILDEXT) $(srcdir)/dosify.c
|
||||
endif
|
||||
|
||||
# This rule rules the compiler in the trivial hello.vl program to make
|
||||
# sure the basics were compiled properly.
|
||||
# This rule runs the compiler using the trivial hello.vl program to make sure
|
||||
# the base programs are compiled properly.
|
||||
check: all
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
rm -f check.vvp
|
||||
test -r check.conf || cp $(srcdir)/check.conf .
|
||||
driver/iverilog -B. -BMvpi -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
|
||||
ifeq (@WIN32@,yes)
|
||||
ifeq (@install_suffix@,)
|
||||
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
else
|
||||
# On Windows if we have a suffix we must run the vvp part of
|
||||
# the test with a suffix since it was built/linked that way.
|
||||
ln vvp/vvp.exe vvp/vvp$(suffix).exe
|
||||
vvp/vvp$(suffix) -M- -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
rm vvp/vvp$(suffix).exe
|
||||
endif
|
||||
else
|
||||
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
endif
|
||||
driver/iverilog@EXEEXT@ -B. -BMvpi -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl && \
|
||||
$(ENV_VVP) vvp/vvp$(suffix)@EXEEXT@ -M- -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
|
||||
check-installed check-installed-vpi check-installed-vvp check-installed-vvp-py:
|
||||
$(MAKE) -C ivtest $@
|
||||
|
||||
clean:
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
rm -f *.o parse.cc parse.h lexor.cc
|
||||
rm -f ivl.exp iverilog-vpi.man iverilog-vpi.pdf iverilog-vpi.ps
|
||||
rm -f ivl.exp
|
||||
rm -f iverilog_man.ps iverilog_man.pdf iverilog_man_$(VERSION_MAJOR)_$(VERSION_MINOR).pdf
|
||||
rm -f parse.output syn-rules.output dosify$(BUILDEXT) ivl@EXEEXT@ check.vvp
|
||||
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc
|
||||
rm -f lexor_keyword.cc libivl.a libvpi.a syn-rules.cc
|
||||
rm -rf dep
|
||||
rm -f version.exe
|
||||
|
||||
distclean: clean
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
@@ -170,14 +168,17 @@ distclean: clean
|
||||
rm -f Makefile config.status config.log config.cache
|
||||
rm -f stamp-config-h config.h
|
||||
rm -f stamp-_pli_types-h _pli_types.h
|
||||
rm -f stamp-version_base-h version_base.h
|
||||
ifneq (@srcdir@,.)
|
||||
rm -f version_tag.h check.conf
|
||||
rmdir $(SUBDIRS) $(NOTUSED)
|
||||
endif
|
||||
rm -rf autom4te.cache
|
||||
|
||||
cppcheck: $(O:.o=.cc) $(srcdir)/dosify.c $(srcdir)/version.c
|
||||
cppcheck: $(O:.o=.cc) $(srcdir)/dosify.c
|
||||
cppcheck --enable=all --std=c99 --std=c++11 -f \
|
||||
--check-level=exhaustive \
|
||||
--suppressions-list=$(srcdir)/cppcheck-global.sup \
|
||||
--suppressions-list=$(srcdir)/cppcheck.sup \
|
||||
-UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \
|
||||
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \
|
||||
@@ -205,6 +206,11 @@ stamp-_pli_types-h: $(srcdir)/_pli_types.h.in config.status
|
||||
./config.status _pli_types.h
|
||||
_pli_types.h: stamp-_pli_types-h
|
||||
|
||||
stamp-version_base-h: $(srcdir)/version_base.h.in config.status
|
||||
@rm -f $@
|
||||
./config.status version_base.h
|
||||
version_base.h: stamp-version_base-h
|
||||
|
||||
$(srcdir)/configure: $(srcdir)/configure.ac $(srcdir)/aclocal.m4
|
||||
cd $(srcdir) && autoconf
|
||||
|
||||
@@ -213,40 +219,17 @@ config.status: $(srcdir)/configure
|
||||
./config.status
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
# Under Windows (mingw) I need to make the ivl.exe in two steps.
|
||||
# The first step makes an ivl.exe that dlltool can use to make an
|
||||
# export and import library, and the last link makes a, ivl.exe
|
||||
# that really exports the things that the import library imports.
|
||||
# Under Windows we need to create an import library to allow the target code
|
||||
# generators to access the items exported by ivl.exe. The .def file controls
|
||||
# what is visible in the import library.
|
||||
ivl@EXEEXT@: $O $(srcdir)/ivl.def
|
||||
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
|
||||
$(DLLTOOL) --dllname ivl@EXEEXT@ --def $(srcdir)/ivl.def \
|
||||
--output-lib libivl.a --output-exp ivl.exp
|
||||
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
|
||||
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ -Wl,--out-implib=libivl.a $(srcdir)/ivl.def $O $(dllib) @EXTRALIBS@
|
||||
else
|
||||
ivl@EXEEXT@: $O
|
||||
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
|
||||
endif
|
||||
|
||||
ifeq (@MINGW32@,no)
|
||||
all: iverilog-vpi
|
||||
|
||||
iverilog-vpi: $(srcdir)/iverilog-vpi.sh Makefile
|
||||
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
|
||||
-e 's;@SUFFIX@;$(suffix);' \
|
||||
-e 's;@IVCC@;$(CC);' \
|
||||
-e 's;@IVCXX@;$(CXX);' \
|
||||
-e 's;@IVCFLAGS@;$(CFLAGS);' \
|
||||
-e 's;@IVCXXFLAGS@;$(CXXFLAGS);' \
|
||||
-e 's;@IVCTARGETFLAGS@;$(CTARGETFLAGS);' \
|
||||
-e 's;@INCLUDEDIR@;$(includedir);' \
|
||||
-e 's;@LIBDIR@;@libdir@;' $< > $@
|
||||
chmod +x $@
|
||||
endif
|
||||
|
||||
version.exe: $(srcdir)/version.c $(srcdir)/version_base.h version_tag.h
|
||||
$(BUILDCC) $(CFLAGS) -o version.exe -I. -I$(srcdir) $(srcdir)/version.c
|
||||
|
||||
%.o: %.cc config.h
|
||||
%.o: %.cc config.h | dep
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||
mv $*.d dep/$*.d
|
||||
|
||||
@@ -259,10 +242,10 @@ parse.o: parse.cc
|
||||
|
||||
# Use pattern rules to avoid parallel build issues (see pr3462585)
|
||||
parse%cc parse%h: $(srcdir)/parse%y
|
||||
$(YACC) --verbose -t -p VL --defines=parse.h -o parse.cc $<
|
||||
$(YACC) --verbose $(YACC_CONFLICT_FLAGS) -t -p VL --defines=parse.h -o parse.cc $<
|
||||
|
||||
syn-rules.cc: $(srcdir)/syn-rules.y
|
||||
$(YACC) --verbose -t -p syn_ -o $@ $<
|
||||
$(YACC) --verbose $(YACC_CONFLICT_FLAGS) -t -p syn_ -o $@ $<
|
||||
|
||||
lexor.cc: $(srcdir)/lexor.lex
|
||||
$(LEX) -s -t $< > $@
|
||||
@@ -270,17 +253,14 @@ lexor.cc: $(srcdir)/lexor.lex
|
||||
lexor_keyword.o: lexor_keyword.cc parse.h
|
||||
|
||||
lexor_keyword.cc: $(srcdir)/lexor_keyword.gperf
|
||||
gperf -o -i 7 -C -k 1-4,6,9,$$ -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
|
||||
gperf -o -i 7 -C -k 1-4,6,9,$$ -H keyword_hash -N check_identifier -t $< > $@ || (rm -f $@ ; false)
|
||||
|
||||
iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in version.exe
|
||||
./version.exe `head -1 $(srcdir)/iverilog-vpi.man.in`'\n' > $@
|
||||
tail -n +2 $(srcdir)/iverilog-vpi.man.in >> $@
|
||||
iverilog_man.ps: driver/iverilog.man vvp/vvp.man driver-vpi/iverilog-vpi.man
|
||||
$(GROFF) -man -rC1 -rD1 -T ps $^ > $@
|
||||
|
||||
iverilog-vpi.ps: iverilog-vpi.man
|
||||
$(MAN) -t ./iverilog-vpi.man > iverilog-vpi.ps
|
||||
|
||||
iverilog-vpi.pdf: iverilog-vpi.ps
|
||||
$(PS2PDF) iverilog-vpi.ps iverilog-vpi.pdf
|
||||
iverilog_man.pdf: iverilog_man.ps
|
||||
$(PS2PDF) $< $@
|
||||
cp $@ iverilog_man_$(VERSION_MAJOR)_$(VERSION_MINOR).pdf
|
||||
|
||||
# For VERSION_TAG in driver/main.c, first try git-describe, then look for a
|
||||
# release_tag.h file in the source tree (included in snapshots and releases),
|
||||
@@ -306,33 +286,6 @@ version_tag.h version:
|
||||
echo '#define VERSION_TAG ""' > version_tag.h; \
|
||||
fi
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
ifeq ($(MAN),none)
|
||||
INSTALL_DOC = installman
|
||||
INSTALL_PDFDIR = $(prefix)
|
||||
else
|
||||
ifeq ($(PS2PDF),none)
|
||||
INSTALL_DOC = installman
|
||||
INSTALL_PDFDIR = $(prefix)
|
||||
else
|
||||
INSTALL_DOC = installpdf installman
|
||||
INSTALL_PDFDIR = $(pdfdir)
|
||||
all: dep iverilog-vpi.pdf
|
||||
endif
|
||||
endif
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
else
|
||||
INSTALL_DOC = installman
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
INSTALL_PDFDIR = $(prefix)
|
||||
endif
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
WIN32_INSTALL =
|
||||
else
|
||||
WIN32_INSTALL = installwin32
|
||||
endif
|
||||
|
||||
install: all installdirs installfiles
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
|
||||
@@ -344,37 +297,24 @@ F = ./ivl@EXEEXT@ \
|
||||
$(srcdir)/sv_vpi_user.h \
|
||||
$(srcdir)/vpi_user.h \
|
||||
$(srcdir)/acc_user.h \
|
||||
$(srcdir)/veriuser.h \
|
||||
$(INSTALL_DOC) \
|
||||
$(WIN32_INSTALL)
|
||||
|
||||
installwin32: ./iverilog-vpi installdirs
|
||||
$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"
|
||||
|
||||
installman: iverilog-vpi.man installdirs
|
||||
$(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1"
|
||||
|
||||
installpdf: iverilog-vpi.pdf installdirs
|
||||
$(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(pdfdir)/iverilog-vpi$(suffix).pdf"
|
||||
$(srcdir)/veriuser.h
|
||||
|
||||
installfiles: $(F) | installdirs
|
||||
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ "$(DESTDIR)$(libdir)/ivl$(suffix)/ivl@EXEEXT@"
|
||||
$(INSTALL_DATA) $(srcdir)/constants.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/constants.vams"
|
||||
$(INSTALL_DATA) $(srcdir)/disciplines.vams "$(DESTDIR)$(libdir)/ivl$(suffix)/include/disciplines.vams"
|
||||
$(INSTALL_DATA) $(srcdir)/ivl_target.h "$(DESTDIR)$(includedir)/ivl_target.h"
|
||||
$(INSTALL_DATA) ./_pli_types.h "$(DESTDIR)$(includedir)/_pli_types.h"
|
||||
$(INSTALL_DATA) $(srcdir)/sv_vpi_user.h "$(DESTDIR)$(includedir)/sv_vpi_user.h"
|
||||
$(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(includedir)/vpi_user.h"
|
||||
$(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(includedir)/acc_user.h"
|
||||
$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(includedir)/veriuser.h"
|
||||
$(INSTALL_DATA) $(srcdir)/ivl_target.h "$(DESTDIR)$(ivl_includedir)/ivl_target.h"
|
||||
$(INSTALL_DATA) ./_pli_types.h "$(DESTDIR)$(ivl_includedir)/_pli_types.h"
|
||||
$(INSTALL_DATA) $(srcdir)/sv_vpi_user.h "$(DESTDIR)$(ivl_includedir)/sv_vpi_user.h"
|
||||
$(INSTALL_DATA) $(srcdir)/vpi_user.h "$(DESTDIR)$(ivl_includedir)/vpi_user.h"
|
||||
$(INSTALL_DATA) $(srcdir)/acc_user.h "$(DESTDIR)$(ivl_includedir)/acc_user.h"
|
||||
$(INSTALL_DATA) $(srcdir)/veriuser.h "$(DESTDIR)$(ivl_includedir)/veriuser.h"
|
||||
|
||||
installdirs: $(srcdir)/mkinstalldirs
|
||||
$(srcdir)/mkinstalldirs "$(DESTDIR)$(bindir)" \
|
||||
"$(DESTDIR)$(includedir)" \
|
||||
"$(DESTDIR)$(ivl_includedir)" \
|
||||
"$(DESTDIR)$(libdir)/ivl$(suffix)" \
|
||||
"$(DESTDIR)$(libdir)/ivl$(suffix)/include" \
|
||||
"$(DESTDIR)$(INSTALL_DOCDIR)" \
|
||||
"$(DESTDIR)$(INSTALL_PDFDIR)"
|
||||
"$(DESTDIR)$(libdir)/ivl$(suffix)/include"
|
||||
|
||||
uninstall:
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
@@ -382,13 +322,13 @@ uninstall:
|
||||
do rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/$$f"; done
|
||||
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)/include"
|
||||
-rmdir "$(DESTDIR)$(libdir)/ivl$(suffix)"
|
||||
for f in verilog$(suffix) iverilog-vpi$(suffix) gverilog$(suffix)@EXEEXT@; \
|
||||
for f in verilog$(suffix) gverilog$(suffix)@EXEEXT@; \
|
||||
do rm -f "$(DESTDIR)$(bindir)/$$f"; done
|
||||
for f in ivl_target.h vpi_user.h _pli_types.h sv_vpi_user.h acc_user.h veriuser.h; \
|
||||
do rm -f "$(DESTDIR)$(includedir)/$$f"; done
|
||||
-test X$(suffix) = X || rmdir "$(DESTDIR)$(includedir)"
|
||||
rm -f "$(DESTDIR)$(mandir)/man1/iverilog-vpi$(suffix).1" \
|
||||
"$(DESTDIR)$(pdfdir)/iverilog-vpi$(suffix).pdf"
|
||||
do rm -f "$(DESTDIR)$(ivl_includedir)/$$f"; done
|
||||
-test X$(suffix) = X || rmdir "$(DESTDIR)$(ivl_includedir)"
|
||||
|
||||
|
||||
-include $(patsubst %.o, dep/%.d, $O)
|
||||
|
||||
.PHONY: check-installed check-installed-vpi check-installed-vvp check-installed-vvp-py
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2022 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2026 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -21,13 +21,65 @@
|
||||
|
||||
# include "Module.h"
|
||||
# include "PGate.h"
|
||||
# include "PModport.h"
|
||||
# include "PWire.h"
|
||||
# include "parse_api.h"
|
||||
# include "ivl_assert.h"
|
||||
# include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
list<Module::named_expr_t> Module::user_defparms;
|
||||
|
||||
Module::port_t::port_t()
|
||||
: port_kind(P_SIGNAL), default_value(0), interface_unpacked_dimensions(0), lexical_pos(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool resolve_interface_formal_port(const LineInfo*li, Design*des,
|
||||
const Module::port_t*port,
|
||||
interface_formal_port_t&res,
|
||||
bool emit_errors)
|
||||
{
|
||||
ivl_assert(*li, port);
|
||||
ivl_assert(*li, port->is_interface_port());
|
||||
|
||||
res = interface_formal_port_t();
|
||||
|
||||
map<perm_string,Module*>::const_iterator mod =
|
||||
pform_modules.find(port->interface_type);
|
||||
if (mod == pform_modules.end() || !mod->second->is_interface) {
|
||||
if (emit_errors) {
|
||||
cerr << li->get_fileline() << ": error: Interface port "
|
||||
<< port->name << " uses unknown interface type `"
|
||||
<< port->interface_type << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
res.module = mod->second;
|
||||
|
||||
if (port->modport_name.str()) {
|
||||
map<perm_string,PModport*>::const_iterator mp =
|
||||
mod->second->modports.find(port->modport_name);
|
||||
if (mp == mod->second->modports.end()) {
|
||||
if (emit_errors) {
|
||||
cerr << li->get_fileline() << ": error: Interface port "
|
||||
<< port->name << " uses unknown modport `"
|
||||
<< port->modport_name << "' of interface `"
|
||||
<< port->interface_type << "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
res.modport = mp->second;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* n is a permallocated string. */
|
||||
Module::Module(LexicalScope*parent, perm_string n)
|
||||
: PScopeExtra(n, parent)
|
||||
@@ -63,12 +115,18 @@ const vector<PEIdent*>& Module::get_port(unsigned idx) const
|
||||
ivl_assert(*this, idx < ports.size());
|
||||
static const vector<PEIdent*> zero;
|
||||
|
||||
if (ports[idx])
|
||||
if (ports[idx] && !ports[idx]->is_interface_port())
|
||||
return ports[idx]->expr;
|
||||
else
|
||||
return zero;
|
||||
}
|
||||
|
||||
const Module::port_t* Module::get_port_info(unsigned idx) const
|
||||
{
|
||||
ivl_assert(*this, idx < ports.size());
|
||||
return ports[idx];
|
||||
}
|
||||
|
||||
unsigned Module::find_port(const char*name) const
|
||||
{
|
||||
ivl_assert(*this, name != 0);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_Module_H
|
||||
#define IVL_Module_H
|
||||
/*
|
||||
* Copyright (c) 1998-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2026 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -43,6 +43,7 @@ class PFunction;
|
||||
class PWire;
|
||||
class PProcess;
|
||||
class Design;
|
||||
class LineInfo;
|
||||
class NetScope;
|
||||
|
||||
/*
|
||||
@@ -65,16 +66,32 @@ class Module : public PScopeExtra, public PNamedItem {
|
||||
default value. */
|
||||
public:
|
||||
struct port_t {
|
||||
enum port_kind_t { P_SIGNAL, P_INTERFACE };
|
||||
|
||||
port_t();
|
||||
|
||||
port_kind_t port_kind;
|
||||
perm_string name;
|
||||
std::vector<PEIdent*> expr;
|
||||
PExpr*default_value;
|
||||
|
||||
/* Interface formal port metadata. For signal ports these
|
||||
fields are empty/zero. The modport name is optional in the
|
||||
representation, although the parser initially only accepts
|
||||
the explicit interface_type.modport form. */
|
||||
perm_string interface_type;
|
||||
perm_string modport_name;
|
||||
std::list<pform_range_t>*interface_unpacked_dimensions;
|
||||
unsigned lexical_pos;
|
||||
|
||||
bool is_interface_port() const { return port_kind == P_INTERFACE; }
|
||||
};
|
||||
|
||||
public:
|
||||
/* The name passed here is the module name, not the instance
|
||||
name. This name must be a permallocated string. */
|
||||
explicit Module(LexicalScope*parent, perm_string name);
|
||||
~Module();
|
||||
~Module() override;
|
||||
|
||||
/* Initially false. This is set to true if the module has been
|
||||
declared as a library module. This makes the module
|
||||
@@ -148,6 +165,7 @@ class Module : public PScopeExtra, public PNamedItem {
|
||||
|
||||
unsigned port_count() const;
|
||||
const std::vector<PEIdent*>& get_port(unsigned idx) const;
|
||||
const port_t* get_port_info(unsigned idx) const;
|
||||
unsigned find_port(const char*name) const;
|
||||
|
||||
// Return port name ("" for undeclared port)
|
||||
@@ -167,7 +185,7 @@ class Module : public PScopeExtra, public PNamedItem {
|
||||
|
||||
bool elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
SymbolType symbol_type() const override;
|
||||
|
||||
bool can_be_toplevel() const;
|
||||
|
||||
@@ -181,4 +199,16 @@ class Module : public PScopeExtra, public PNamedItem {
|
||||
Module& operator= (const Module&);
|
||||
};
|
||||
|
||||
struct interface_formal_port_t {
|
||||
interface_formal_port_t() : module(0), modport(0) { }
|
||||
|
||||
const Module*module;
|
||||
const PModport*modport;
|
||||
};
|
||||
|
||||
extern bool resolve_interface_formal_port(const LineInfo*li, Design*des,
|
||||
const Module::port_t*port,
|
||||
interface_formal_port_t&res,
|
||||
bool emit_errors);
|
||||
|
||||
#endif /* IVL_Module_H */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PClass_H
|
||||
#define IVL_PClass_H
|
||||
/*
|
||||
* Copyright (c) 2012-2019 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2012-2025 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -36,11 +36,11 @@ class PClass : public PScopeExtra, public PNamedItem {
|
||||
|
||||
public:
|
||||
explicit PClass (perm_string name, LexicalScope*parent);
|
||||
~PClass();
|
||||
~PClass() override;
|
||||
|
||||
void dump(std::ostream&out, unsigned indent) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
SymbolType symbol_type() const override;
|
||||
|
||||
public:
|
||||
class_type_t*type;
|
||||
|
||||
+22
-22
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2026 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -130,10 +130,11 @@ static NetExpr* make_delay_nets(Design*des, NetScope*scope, NetExpr*expr)
|
||||
return expr;
|
||||
}
|
||||
|
||||
static NetExpr* calc_decay_time(NetExpr *rise, NetExpr *fall)
|
||||
static const NetExpr *calc_decay_time(const NetExpr *rise,
|
||||
const NetExpr *fall)
|
||||
{
|
||||
NetEConst *c_rise = dynamic_cast<NetEConst*>(rise);
|
||||
NetEConst *c_fall = dynamic_cast<NetEConst*>(fall);
|
||||
const NetEConst *c_rise = dynamic_cast<const NetEConst*>(rise);
|
||||
const NetEConst *c_fall = dynamic_cast<const NetEConst*>(fall);
|
||||
if (c_rise && c_fall) {
|
||||
if (c_rise->value() < c_fall->value()) return rise;
|
||||
else return fall;
|
||||
@@ -142,44 +143,43 @@ static NetExpr* calc_decay_time(NetExpr *rise, NetExpr *fall)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||
NetExpr*&rise_time,
|
||||
NetExpr*&fall_time,
|
||||
NetExpr*&decay_time,
|
||||
void PDelays::eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays,
|
||||
bool as_nets_flag) const
|
||||
{
|
||||
assert(scope);
|
||||
|
||||
|
||||
if (delay_[0]) {
|
||||
rise_time = calculate_val(des, scope, delay_[0]);
|
||||
NetExpr *rise = calculate_val(des, scope, delay_[0]);
|
||||
if (as_nets_flag)
|
||||
rise_time = make_delay_nets(des, scope, rise_time);
|
||||
rise = make_delay_nets(des, scope, rise);
|
||||
delays.rise = rise;
|
||||
|
||||
if (delay_[1]) {
|
||||
fall_time = calculate_val(des, scope, delay_[1]);
|
||||
NetExpr *fall = calculate_val(des, scope, delay_[1]);
|
||||
if (as_nets_flag)
|
||||
fall_time = make_delay_nets(des, scope, fall_time);
|
||||
fall = make_delay_nets(des, scope, fall);
|
||||
delays.fall = fall;
|
||||
|
||||
if (delay_[2]) {
|
||||
decay_time = calculate_val(des, scope, delay_[2]);
|
||||
NetExpr *decay = calculate_val(des, scope, delay_[2]);
|
||||
if (as_nets_flag)
|
||||
decay_time = make_delay_nets(des, scope,
|
||||
decay_time);
|
||||
decay = make_delay_nets(des, scope, decay);
|
||||
delays.decay = decay;
|
||||
|
||||
} else {
|
||||
// If this is zero then we need to do the min()
|
||||
// at run time.
|
||||
decay_time = calc_decay_time(rise_time, fall_time);
|
||||
delays.decay = calc_decay_time(delays.rise,
|
||||
delays.fall);
|
||||
}
|
||||
} else {
|
||||
assert(delay_[2] == 0);
|
||||
fall_time = rise_time;
|
||||
decay_time = rise_time;
|
||||
delays.fall = delays.rise;
|
||||
delays.decay = delays.rise;
|
||||
}
|
||||
} else {
|
||||
rise_time = 0;
|
||||
fall_time = 0;
|
||||
decay_time = 0;
|
||||
delays.rise = nullptr;
|
||||
delays.fall = nullptr;
|
||||
delays.decay = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PDelays_H
|
||||
#define IVL_PDelays_H
|
||||
/*
|
||||
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2026 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -27,6 +27,7 @@ class Design;
|
||||
class NetScope;
|
||||
class NetExpr;
|
||||
class PExpr;
|
||||
struct delay_exprs_t;
|
||||
|
||||
/*
|
||||
* Various PForm objects can carry delays. These delays include rise,
|
||||
@@ -46,10 +47,7 @@ class PDelays {
|
||||
|
||||
unsigned delay_count() const;
|
||||
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
NetExpr*&rise_time,
|
||||
NetExpr*&fall_time,
|
||||
NetExpr*&decay_time,
|
||||
void eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays,
|
||||
bool as_nets_flag =false) const;
|
||||
|
||||
void dump_delays(std::ostream&out) const;
|
||||
|
||||
@@ -22,8 +22,9 @@
|
||||
# include "PEvent.h"
|
||||
|
||||
PEvent::PEvent(perm_string n, unsigned lexical_pos)
|
||||
: name_(n), lexical_pos_(lexical_pos)
|
||||
: name_(n)
|
||||
{
|
||||
LineInfo::lexical_pos(lexical_pos);
|
||||
}
|
||||
|
||||
PEvent::~PEvent()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PEvent_H
|
||||
#define IVL_PEvent_H
|
||||
/*
|
||||
* Copyright (c) 2000-2024 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000-2025 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -37,19 +37,16 @@ class PEvent : public PNamedItem {
|
||||
// The name is a perm-allocated string. It is the simple name
|
||||
// of the event, without any scope.
|
||||
explicit PEvent(perm_string name, unsigned lexical_pos);
|
||||
~PEvent();
|
||||
~PEvent() override;
|
||||
|
||||
perm_string name() const;
|
||||
|
||||
unsigned lexical_pos() const { return lexical_pos_; }
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
SymbolType symbol_type() const override;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
unsigned lexical_pos_;
|
||||
|
||||
private: // not implemented
|
||||
PEvent(const PEvent&);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2024 Stephen Williams <[email protected]>
|
||||
* Copyright (c) 1998-2026 Stephen Williams <[email protected]>
|
||||
* Copyright CERN 2013 / Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -20,10 +20,12 @@
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <algorithm>
|
||||
# include <iostream>
|
||||
|
||||
# include "compiler.h"
|
||||
# include "PExpr.h"
|
||||
# include "PPackage.h"
|
||||
# include "PWire.h"
|
||||
# include "Module.h"
|
||||
# include "ivl_assert.h"
|
||||
@@ -54,7 +56,7 @@ bool PExpr::has_aa_term(Design*, NetScope*) const
|
||||
return false;
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_lnet(Design*, NetScope*) const
|
||||
NetNet* PExpr::elaborate_lnet(Design*, NetScope*, bool) const
|
||||
{
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "expression not valid in assign l-value: "
|
||||
@@ -62,7 +64,7 @@ NetNet* PExpr::elaborate_lnet(Design*, NetScope*) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_bi_net(Design*, NetScope*) const
|
||||
NetNet* PExpr::elaborate_bi_net(Design*, NetScope*, bool) const
|
||||
{
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "expression not valid as argument to inout port: "
|
||||
@@ -107,6 +109,16 @@ PEAssignPattern::~PEAssignPattern()
|
||||
{
|
||||
}
|
||||
|
||||
bool PEAssignPattern::has_aa_term(Design*des, NetScope*scope) const
|
||||
{
|
||||
bool flag = false;
|
||||
for (const auto *parm : parms_) {
|
||||
if (parm)
|
||||
flag = parm->has_aa_term(des, scope) || flag;
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
|
||||
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
|
||||
: op_(op), left_(l), right_(r)
|
||||
{
|
||||
@@ -128,30 +140,12 @@ bool PEBinary::has_aa_term(Design*des, NetScope*scope) const
|
||||
return left_->has_aa_term(des, scope) || right_->has_aa_term(des, scope);
|
||||
}
|
||||
|
||||
PECastSize::PECastSize(PExpr*si, PExpr*b)
|
||||
: size_(si), base_(b)
|
||||
PECast::PECast(PExpr *target, PExpr *base)
|
||||
: target_(target), base_(base)
|
||||
{
|
||||
}
|
||||
|
||||
PECastSize::~PECastSize()
|
||||
{
|
||||
}
|
||||
|
||||
bool PECastSize::has_aa_term(Design *des, NetScope *scope) const
|
||||
{
|
||||
return base_->has_aa_term(des, scope);
|
||||
}
|
||||
|
||||
PECastType::PECastType(data_type_t*t, PExpr*b)
|
||||
: target_(t), base_(b)
|
||||
{
|
||||
}
|
||||
|
||||
PECastType::~PECastType()
|
||||
{
|
||||
}
|
||||
|
||||
bool PECastType::has_aa_term(Design *des, NetScope *scope) const
|
||||
bool PECast::has_aa_term(Design *des, NetScope *scope) const
|
||||
{
|
||||
return base_->has_aa_term(des, scope);
|
||||
}
|
||||
@@ -259,26 +253,60 @@ PECallFunction::PECallFunction(perm_string n, const list<named_pexpr_t> &parms)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
|
||||
const vector<named_pexpr_t> &parms)
|
||||
: path_(method), parms_(parms), chain_prefix_(chain_prefix), is_overridden_(false)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
|
||||
const list<named_pexpr_t> &parms)
|
||||
: path_(method), parms_(parms.begin(), parms.end()),
|
||||
chain_prefix_(chain_prefix), is_overridden_(false)
|
||||
{
|
||||
}
|
||||
|
||||
void PECallFunction::set_with_clause(PExpr* with_expr)
|
||||
{
|
||||
delete with_expr_;
|
||||
with_expr_ = with_expr;
|
||||
}
|
||||
|
||||
PECallFunction::~PECallFunction()
|
||||
{
|
||||
delete chain_prefix_;
|
||||
delete with_expr_;
|
||||
}
|
||||
|
||||
void PECallFunction::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
{
|
||||
if (chain_prefix_) {
|
||||
chain_prefix_->declare_implicit_nets(scope, type);
|
||||
}
|
||||
if (with_expr_) {
|
||||
with_expr_->declare_implicit_nets(scope, type);
|
||||
}
|
||||
for (const auto &parm : parms_) {
|
||||
if (parm.parm)
|
||||
if (parm.parm) {
|
||||
parm.parm->declare_implicit_nets(scope, type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PECallFunction::has_aa_term(Design*des, NetScope*scope) const
|
||||
{
|
||||
bool flag = false;
|
||||
for (const auto &parm : parms_) {
|
||||
if (parm.parm)
|
||||
flag |= parm.parm->has_aa_term(des, scope);
|
||||
if (chain_prefix_ && chain_prefix_->has_aa_term(des, scope)) {
|
||||
return true;
|
||||
}
|
||||
return flag;
|
||||
if (with_expr_ && with_expr_->has_aa_term(des, scope)) {
|
||||
return true;
|
||||
}
|
||||
for (const auto &parm : parms_) {
|
||||
if (parm.parm && parm.parm->has_aa_term(des, scope)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
PEConcat::PEConcat(const list<PExpr*>&p, PExpr*r)
|
||||
@@ -360,19 +388,22 @@ const verireal& PEFNumber::value() const
|
||||
return *value_;
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(const pform_name_t&that, unsigned lexical_pos)
|
||||
: path_(that), lexical_pos_(lexical_pos), no_implicit_sig_(false)
|
||||
PEIdent::PEIdent(const pform_name_t&that, unsigned lexical_pos,
|
||||
bool no_implicit_sig)
|
||||
: path_(that), no_implicit_sig_(no_implicit_sig)
|
||||
{
|
||||
LineInfo::lexical_pos(lexical_pos);
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(perm_string s, unsigned lexical_pos, bool no_implicit_sig)
|
||||
: lexical_pos_(lexical_pos), no_implicit_sig_(no_implicit_sig)
|
||||
: no_implicit_sig_(no_implicit_sig)
|
||||
{
|
||||
LineInfo::lexical_pos(lexical_pos);
|
||||
path_.name.push_back(name_component_t(s));
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that, unsigned lexical_pos)
|
||||
: path_(pkg, that), lexical_pos_(lexical_pos), no_implicit_sig_(true)
|
||||
PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that)
|
||||
: path_(pkg, that), no_implicit_sig_(true)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -382,13 +413,33 @@ PEIdent::~PEIdent()
|
||||
|
||||
static bool find_enum_constant(LexicalScope*scope, perm_string name)
|
||||
{
|
||||
for (vector<enum_type_t*>::const_iterator cur = scope->enum_sets.begin() ;
|
||||
cur != scope->enum_sets.end() ; ++ cur) {
|
||||
for (list<named_pexpr_t>::const_iterator idx = (*cur)->names->begin() ;
|
||||
idx != (*cur)->names->end() ; ++ idx) {
|
||||
if (idx->name == name) return true;
|
||||
return std::any_of(scope->enum_sets.cbegin(), scope->enum_sets.cend(),
|
||||
[name](const enum_type_t *cur) {
|
||||
return std::any_of(cur->names->cbegin(), cur->names->cend(),
|
||||
[name](const named_pexpr_t&idx){return idx.name == name;});
|
||||
});
|
||||
}
|
||||
|
||||
static bool is_typedef_identifier(LexicalScope *scope, perm_string name)
|
||||
{
|
||||
while (scope) {
|
||||
auto import = scope->explicit_imports.find(name);
|
||||
if (import != scope->explicit_imports.end()) {
|
||||
// An explicit import shadows declarations in outer scopes.
|
||||
const auto &typedefs = import->second.package->typedefs;
|
||||
return typedefs.find(name) != typedefs.end();
|
||||
}
|
||||
|
||||
if (scope->typedefs.find(name) != scope->typedefs.end())
|
||||
return true;
|
||||
|
||||
// A local non-type declaration also hides outer typedefs.
|
||||
if (scope->local_symbols.find(name) != scope->local_symbols.end())
|
||||
return false;
|
||||
|
||||
scope = scope->parent_scope();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -405,6 +456,9 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
return;
|
||||
if (path_.name.size() == 1 && path_.name.front().index.empty()) {
|
||||
perm_string name = path_.name.front().name;
|
||||
if (is_typedef_identifier(scope, name))
|
||||
return;
|
||||
|
||||
LexicalScope*ss = scope;
|
||||
while (ss) {
|
||||
if (ss->wires.find(name) != ss->wires.end())
|
||||
@@ -426,9 +480,8 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
|
||||
ss = ss->parent_scope();
|
||||
}
|
||||
PWire*net = new PWire(name, lexical_pos_, type, NetNet::NOT_A_PORT);
|
||||
net->set_file(get_file());
|
||||
net->set_lineno(get_lineno());
|
||||
PWire*net = new PWire(name, lexical_pos(), type, NetNet::NOT_A_PORT);
|
||||
net->set_line(*this);
|
||||
scope->wires[name] = net;
|
||||
if (warn_implicit) {
|
||||
cerr << get_fileline() << ": warning: implicit "
|
||||
@@ -440,7 +493,10 @@ void PEIdent::declare_implicit_nets(LexicalScope*scope, NetNet::Type type)
|
||||
bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
|
||||
{
|
||||
symbol_search_results sr;
|
||||
if (!symbol_search(this, des, scope, path_, lexical_pos_, &sr))
|
||||
if (!symbol_search(this, des, scope, path_, lexical_pos(), &sr))
|
||||
return false;
|
||||
|
||||
if (sr.type_def)
|
||||
return false;
|
||||
|
||||
// Class properties are not considered automatic since a non-blocking
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PExpr_H
|
||||
#define IVL_PExpr_H
|
||||
/*
|
||||
* Copyright (c) 1998-2024 Stephen Williams <[email protected]>
|
||||
* Copyright (c) 1998-2026 Stephen Williams <[email protected]>
|
||||
* Copyright CERN 2013 / Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -37,6 +37,7 @@ class NetExpr;
|
||||
class NetScope;
|
||||
class PPackage;
|
||||
struct symbol_search_results;
|
||||
class netclass_t;
|
||||
|
||||
/*
|
||||
* The PExpr class hierarchy supports the description of
|
||||
@@ -50,6 +51,11 @@ class PExpr : public LineInfo {
|
||||
// Mode values used by test_width() (see below for description).
|
||||
enum width_mode_t { SIZED, UNSIZED, EXPAND, LOSSLESS, UPSIZE };
|
||||
|
||||
enum class type_elaboration_context_t {
|
||||
DEFAULT,
|
||||
CAST_TARGET
|
||||
};
|
||||
|
||||
// Flag values that can be passed to elaborate_expr().
|
||||
static const unsigned NO_FLAGS = 0x0;
|
||||
static const unsigned NEED_CONST = 0x1;
|
||||
@@ -60,7 +66,7 @@ class PExpr : public LineInfo {
|
||||
static const char*width_mode_name(width_mode_t mode);
|
||||
|
||||
PExpr();
|
||||
virtual ~PExpr();
|
||||
virtual ~PExpr() override;
|
||||
|
||||
virtual void dump(std::ostream&) const;
|
||||
|
||||
@@ -127,6 +133,17 @@ class PExpr : public LineInfo {
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
|
||||
// Return true if this expression represents a type in this scope. This
|
||||
// may cache lookup state for a subsequent elaborate_type() call.
|
||||
virtual bool test_type(Design *des, NetScope *scope);
|
||||
|
||||
// Elaborate this expression as a type in a specific context. Return
|
||||
// null if the expression is not a type or elaboration fails.
|
||||
virtual ivl_type_t elaborate_type(
|
||||
Design *des, NetScope *scope,
|
||||
type_elaboration_context_t context =
|
||||
type_elaboration_context_t::DEFAULT) const;
|
||||
|
||||
// After the test_width method is complete, these methods
|
||||
// return valid results.
|
||||
ivl_variable_type_t expr_type() const { return expr_type_; }
|
||||
@@ -156,13 +173,15 @@ class PExpr : public LineInfo {
|
||||
|
||||
// This method elaborates the expression as gates, but
|
||||
// restricted for use as l-values of continuous assignments.
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
||||
bool var_allowed_in_sv) const;
|
||||
|
||||
// This is similar to elaborate_lnet, except that the
|
||||
// expression is evaluated to be bi-directional. This is
|
||||
// useful for arguments to inout ports of module instances and
|
||||
// ports of tran primitives.
|
||||
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
|
||||
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope,
|
||||
bool var_allowed_in_sv) const;
|
||||
|
||||
// Expressions that can be in the l-value of procedural
|
||||
// assignments can be elaborated with this method. If the
|
||||
@@ -202,17 +221,19 @@ class PEAssignPattern : public PExpr {
|
||||
public:
|
||||
explicit PEAssignPattern();
|
||||
explicit PEAssignPattern(const std::list<PExpr*>&p);
|
||||
~PEAssignPattern();
|
||||
~PEAssignPattern() override;
|
||||
|
||||
void dump(std::ostream&) const;
|
||||
void dump(std::ostream&) const override;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode);
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const override;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode) override;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
ivl_type_t type, unsigned flags) const override;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
unsigned flags) const override;
|
||||
private:
|
||||
NetExpr* elaborate_expr_packed_(Design *des, NetScope *scope,
|
||||
ivl_variable_type_t base_type,
|
||||
@@ -240,36 +261,39 @@ class PEConcat : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEConcat(const std::list<PExpr*>&p, PExpr*r =0);
|
||||
~PEConcat();
|
||||
~PEConcat() override;
|
||||
|
||||
virtual void dump(std::ostream&) const;
|
||||
virtual void dump(std::ostream&) const override;
|
||||
|
||||
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
|
||||
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override;
|
||||
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const override;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
|
||||
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
||||
bool var_allowed_in_sv) const override;
|
||||
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope,
|
||||
bool var_allowed_in_sv) const override;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
ivl_type_t type, unsigned flags) const override;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
unsigned flags) const override;
|
||||
virtual NetAssign_* elaborate_lval(Design*des,
|
||||
NetScope*scope,
|
||||
bool is_cassign,
|
||||
bool is_force,
|
||||
bool is_init = false) const;
|
||||
bool is_init = false) const override;
|
||||
virtual bool is_collapsible_net(Design*des, NetScope*scope,
|
||||
NetNet::PortType port_type) const;
|
||||
NetNet::PortType port_type) const override;
|
||||
private:
|
||||
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
bool bidirectional_flag) const;
|
||||
bool bidirectional_flag,
|
||||
bool var_allowed_in_sv) const;
|
||||
private:
|
||||
std::vector<PExpr*>parms_;
|
||||
std::valarray<width_mode_t>width_modes_;
|
||||
@@ -294,14 +318,14 @@ class PEEvent : public PExpr {
|
||||
// Use this constructor to create events based on edges or levels.
|
||||
PEEvent(edge_t t, PExpr*e);
|
||||
|
||||
~PEEvent();
|
||||
~PEEvent() override;
|
||||
|
||||
edge_t type() const;
|
||||
PExpr* expr() const;
|
||||
|
||||
virtual void dump(std::ostream&) const;
|
||||
virtual void dump(std::ostream&) const override;
|
||||
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const override;
|
||||
|
||||
private:
|
||||
edge_t type_;
|
||||
@@ -315,19 +339,19 @@ class PEFNumber : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEFNumber(verireal*vp);
|
||||
~PEFNumber();
|
||||
~PEFNumber() override;
|
||||
|
||||
const verireal& value() const;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
ivl_type_t type, unsigned flags) const override;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
unsigned flags) const override;
|
||||
|
||||
virtual void dump(std::ostream&) const;
|
||||
virtual void dump(std::ostream&) const override;
|
||||
|
||||
private:
|
||||
verireal*value_;
|
||||
@@ -337,40 +361,46 @@ class PEIdent : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEIdent(perm_string, unsigned lexical_pos, bool no_implicit_sig=false);
|
||||
explicit PEIdent(PPackage*pkg, const pform_name_t&name, unsigned lexical_pos);
|
||||
explicit PEIdent(const pform_name_t&, unsigned lexical_pos);
|
||||
~PEIdent();
|
||||
explicit PEIdent(PPackage*pkg, const pform_name_t&name);
|
||||
explicit PEIdent(const pform_name_t&, unsigned lexical_pos,
|
||||
bool no_implicit_sig = false);
|
||||
~PEIdent() override;
|
||||
|
||||
// Add another name to the string of hierarchy that is the
|
||||
// current identifier.
|
||||
void append_name(perm_string);
|
||||
|
||||
virtual void dump(std::ostream&) const;
|
||||
virtual void dump(std::ostream&) const override;
|
||||
|
||||
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
|
||||
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override;
|
||||
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const override;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
|
||||
// Identifiers are allowed (with restrictions) is assign l-values.
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope, bool var_allowed_in_sv) const override;
|
||||
|
||||
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
|
||||
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope, bool var_allowed_in_sv) const override;
|
||||
|
||||
// Identifiers are also allowed as procedural assignment l-values.
|
||||
virtual NetAssign_* elaborate_lval(Design*des,
|
||||
NetScope*scope,
|
||||
bool is_cassign,
|
||||
bool is_force,
|
||||
bool is_init = false) const;
|
||||
bool is_init = false) const override;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
ivl_type_t type, unsigned flags) const override;
|
||||
bool test_type(Design *des, NetScope *scope) override;
|
||||
ivl_type_t elaborate_type(
|
||||
Design *des, NetScope *scope,
|
||||
type_elaboration_context_t context =
|
||||
type_elaboration_context_t::DEFAULT) const override;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
unsigned flags) const override;
|
||||
|
||||
// Elaborate the PEIdent as a port to a module. This method
|
||||
// only applies to Ident expressions.
|
||||
@@ -382,18 +412,27 @@ class PEIdent : public PExpr {
|
||||
NetNet* elaborate_unpacked_net(Design*des, NetScope*sc) const;
|
||||
|
||||
virtual bool is_collapsible_net(Design*des, NetScope*scope,
|
||||
NetNet::PortType port_type) const;
|
||||
NetNet::PortType port_type) const override;
|
||||
|
||||
const pform_scoped_name_t& path() const { return path_; }
|
||||
|
||||
unsigned lexical_pos() const { return lexical_pos_; }
|
||||
|
||||
private:
|
||||
// Type testing and elaboration normally happen as a pair. Preserve the
|
||||
// lookup result between them, but only reuse it in the same scope.
|
||||
struct type_lookup_t {
|
||||
const NetScope *lookup_scope = nullptr;
|
||||
NetScope *declaration_scope = nullptr;
|
||||
typedef_t *type_def = nullptr;
|
||||
bool valid = false;
|
||||
};
|
||||
|
||||
pform_scoped_name_t path_;
|
||||
unsigned lexical_pos_;
|
||||
bool no_implicit_sig_;
|
||||
type_lookup_t type_lookup_;
|
||||
|
||||
bool find_type_(Design *des, NetScope *scope,
|
||||
struct symbol_search_results &search_results) const;
|
||||
|
||||
private:
|
||||
// Common functions to calculate parts of part/bit
|
||||
// selects. These methods return true if the expressions
|
||||
// elaborate/calculate, or false if there is some sort of
|
||||
@@ -407,7 +446,7 @@ class PEIdent : public PExpr {
|
||||
// the values written to the msb/lsb arguments. If there are
|
||||
// invalid bits (xz) in either expression, then the defined
|
||||
// flag is set to *false*.
|
||||
bool calculate_parts_(Design*, NetScope*, long&msb, long&lsb, bool&defined) const;
|
||||
void calculate_parts_(Design*, NetScope*, long&msb, long&lsb, bool&defined) const;
|
||||
NetExpr* calculate_up_do_base_(Design*, NetScope*, bool need_const) const;
|
||||
|
||||
bool calculate_up_do_width_(Design*, NetScope*, unsigned long&wid) const;
|
||||
@@ -421,7 +460,7 @@ class PEIdent : public PExpr {
|
||||
// [2:0][x] - BAD
|
||||
// [y][x] - BAD
|
||||
// Leave the last index for special handling.
|
||||
bool calculate_packed_indices_(Design*des, NetScope*scope, NetNet*net,
|
||||
bool calculate_packed_indices_(Design*des, NetScope*scope, const NetNet*net,
|
||||
std::list<long>&prefix_indices) const;
|
||||
|
||||
private:
|
||||
@@ -483,18 +522,12 @@ class PEIdent : public PExpr {
|
||||
const NetScope*found_in,
|
||||
ivl_type_t par_type,
|
||||
unsigned expr_wid) const;
|
||||
NetExpr*elaborate_expr_param_idx_up_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
const NetScope*found_in,
|
||||
ivl_type_t par_type,
|
||||
bool need_const) const;
|
||||
NetExpr*elaborate_expr_param_idx_do_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
const NetScope*found_in,
|
||||
ivl_type_t par_type,
|
||||
bool need_const) const;
|
||||
NetExpr*elaborate_expr_param_idx_up_do_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
const NetScope*found_in,
|
||||
ivl_type_t par_type,
|
||||
bool up, bool need_const) const;
|
||||
NetExpr*elaborate_expr_net(Design*des,
|
||||
NetScope*scope,
|
||||
NetNet*net,
|
||||
@@ -512,16 +545,11 @@ class PEIdent : public PExpr {
|
||||
NetESignal*net,
|
||||
NetScope*found,
|
||||
unsigned expr_wid) const;
|
||||
NetExpr*elaborate_expr_net_idx_up_(Design*des,
|
||||
NetScope*scope,
|
||||
NetESignal*net,
|
||||
NetScope*found,
|
||||
bool need_const) const;
|
||||
NetExpr*elaborate_expr_net_idx_do_(Design*des,
|
||||
NetScope*scope,
|
||||
NetESignal*net,
|
||||
NetScope*found,
|
||||
bool need_const) const;
|
||||
NetExpr*elaborate_expr_net_idx_up_do_(Design*des,
|
||||
NetScope*scope,
|
||||
NetESignal*net,
|
||||
NetScope*found,
|
||||
bool up, bool need_const) const;
|
||||
NetExpr*elaborate_expr_net_bit_(Design*des,
|
||||
NetScope*scope,
|
||||
NetESignal*net,
|
||||
@@ -545,10 +573,11 @@ class PEIdent : public PExpr {
|
||||
|
||||
private:
|
||||
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
bool bidirectional_flag) const;
|
||||
bool bidirectional_flag,
|
||||
bool var_allowed_in_sv) const;
|
||||
|
||||
|
||||
bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||
bool eval_part_select_(Design*des, NetScope*scope, const NetNet*sig,
|
||||
long&midx, long&lidx) const;
|
||||
};
|
||||
|
||||
@@ -556,16 +585,16 @@ class PENewArray : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PENewArray (PExpr*s, PExpr*i);
|
||||
~PENewArray();
|
||||
~PENewArray() override;
|
||||
|
||||
virtual void dump(std::ostream&) const;
|
||||
virtual void dump(std::ostream&) const override;
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
ivl_type_t type, unsigned flags) const override;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
unsigned flags) const override;
|
||||
|
||||
private:
|
||||
PExpr*size_;
|
||||
@@ -581,18 +610,18 @@ class PENewClass : public PExpr {
|
||||
explicit PENewClass (const std::list<named_pexpr_t> &p,
|
||||
data_type_t *class_type = nullptr);
|
||||
|
||||
~PENewClass();
|
||||
~PENewClass() override;
|
||||
|
||||
virtual void dump(std::ostream&) const;
|
||||
virtual void dump(std::ostream&) const override;
|
||||
// Class objects don't have a useful width, but the expression
|
||||
// is IVL_VT_CLASS.
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
// Note that class (new) expressions only appear in context
|
||||
// that uses this form of the elaborate_expr method. In fact,
|
||||
// the type argument is going to be a netclass_t object.
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
ivl_type_t type, unsigned flags) const override;
|
||||
|
||||
private:
|
||||
NetExpr* elaborate_expr_constructor_(Design*des, NetScope*scope,
|
||||
@@ -607,18 +636,18 @@ class PENewClass : public PExpr {
|
||||
class PENewCopy : public PExpr {
|
||||
public:
|
||||
explicit PENewCopy(PExpr*src);
|
||||
~PENewCopy();
|
||||
~PENewCopy() override;
|
||||
|
||||
virtual void dump(std::ostream&) const;
|
||||
virtual void dump(std::ostream&) const override;
|
||||
// Class objects don't have a useful width, but the expression
|
||||
// is IVL_VT_CLASS.
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
// Note that class (new) expressions only appear in context
|
||||
// that uses this form of the elaborate_expr method. In fact,
|
||||
// the type argument is going to be a netclass_t object.
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
ivl_type_t type, unsigned flags) const override;
|
||||
|
||||
private:
|
||||
PExpr*src_;
|
||||
@@ -627,39 +656,45 @@ class PENewCopy : public PExpr {
|
||||
class PENull : public PExpr {
|
||||
public:
|
||||
explicit PENull();
|
||||
~PENull();
|
||||
~PENull() override;
|
||||
|
||||
virtual void dump(std::ostream&) const;
|
||||
virtual void dump(std::ostream&) const override;
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
ivl_type_t type, unsigned flags) const override;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
unsigned flags) const override;
|
||||
};
|
||||
|
||||
// Internal marker for the '$' in a queue dimension.
|
||||
class PEQueueDimension : public PExpr {
|
||||
public:
|
||||
void dump(std::ostream&) const override;
|
||||
};
|
||||
|
||||
class PENumber : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PENumber(verinum*vp);
|
||||
~PENumber();
|
||||
~PENumber() override;
|
||||
|
||||
const verinum& value() const;
|
||||
|
||||
virtual void dump(std::ostream&) const;
|
||||
virtual void dump(std::ostream&) const override;
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
|
||||
virtual NetExpr *elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
ivl_type_t type, unsigned flags) const override;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid, unsigned) const;
|
||||
unsigned expr_wid, unsigned) const override;
|
||||
virtual NetAssign_* elaborate_lval(Design*des,
|
||||
NetScope*scope,
|
||||
bool is_cassign,
|
||||
bool is_force,
|
||||
bool is_init = false) const;
|
||||
bool is_init = false) const override;
|
||||
|
||||
private:
|
||||
verinum*const value_;
|
||||
@@ -676,20 +711,24 @@ class PEString : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEString(char*s);
|
||||
~PEString();
|
||||
~PEString() override;
|
||||
|
||||
std::string value() const;
|
||||
virtual void dump(std::ostream&) const;
|
||||
virtual void dump(std::ostream&) const override;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const override;
|
||||
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid, unsigned) const;
|
||||
unsigned expr_wid, unsigned) const override;
|
||||
|
||||
NetExpr *elaborate_expr_uarray_(Design *des, NetScope *scope,
|
||||
const netuarray_t *uarray_type,
|
||||
const std::vector<netrange_t> &dims,
|
||||
unsigned int cur_dim) const;
|
||||
private:
|
||||
char*text_;
|
||||
};
|
||||
@@ -697,15 +736,18 @@ class PEString : public PExpr {
|
||||
class PETypename : public PExpr {
|
||||
public:
|
||||
explicit PETypename(data_type_t*data_type);
|
||||
~PETypename();
|
||||
~PETypename() override;
|
||||
|
||||
virtual void dump(std::ostream&) const;
|
||||
virtual void dump(std::ostream&) const override;
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
|
||||
inline data_type_t* get_type() const { return data_type_; }
|
||||
ivl_type_t type, unsigned flags) const override;
|
||||
bool test_type(Design *des, NetScope *scope) override;
|
||||
ivl_type_t elaborate_type(
|
||||
Design *des, NetScope *scope,
|
||||
type_elaboration_context_t context =
|
||||
type_elaboration_context_t::DEFAULT) const override;
|
||||
|
||||
private:
|
||||
data_type_t*data_type_;
|
||||
@@ -715,20 +757,20 @@ class PEUnary : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEUnary(char op, PExpr*ex);
|
||||
~PEUnary();
|
||||
~PEUnary() override;
|
||||
|
||||
virtual void dump(std::ostream&out) const;
|
||||
virtual void dump(std::ostream&out) const override;
|
||||
|
||||
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
|
||||
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override;
|
||||
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const override;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
unsigned flags) const override;
|
||||
|
||||
public:
|
||||
inline char get_op() const { return op_; }
|
||||
@@ -746,20 +788,20 @@ class PEBinary : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEBinary(char op, PExpr*l, PExpr*r);
|
||||
~PEBinary();
|
||||
~PEBinary() override;
|
||||
|
||||
virtual void dump(std::ostream&out) const;
|
||||
virtual void dump(std::ostream&out) const override;
|
||||
|
||||
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
|
||||
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override;
|
||||
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const override;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
unsigned flags) const override;
|
||||
|
||||
protected:
|
||||
char op_;
|
||||
@@ -790,13 +832,13 @@ class PEBComp : public PEBinary {
|
||||
|
||||
public:
|
||||
explicit PEBComp(char op, PExpr*l, PExpr*r);
|
||||
~PEBComp();
|
||||
~PEBComp() override;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
|
||||
NetExpr* elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid, unsigned flags) const;
|
||||
unsigned expr_wid, unsigned flags) const override;
|
||||
|
||||
private:
|
||||
unsigned l_width_;
|
||||
@@ -810,13 +852,13 @@ class PEBLogic : public PEBinary {
|
||||
|
||||
public:
|
||||
explicit PEBLogic(char op, PExpr*l, PExpr*r);
|
||||
~PEBLogic();
|
||||
~PEBLogic() override;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
|
||||
NetExpr* elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid, unsigned flags) const;
|
||||
unsigned expr_wid, unsigned flags) const override;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -828,38 +870,38 @@ class PEBLeftWidth : public PEBinary {
|
||||
|
||||
public:
|
||||
explicit PEBLeftWidth(char op, PExpr*l, PExpr*r);
|
||||
~PEBLeftWidth() =0;
|
||||
~PEBLeftWidth() override =0;
|
||||
|
||||
virtual NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
|
||||
unsigned expr_wid) const =0;
|
||||
|
||||
protected:
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
unsigned flags) const override;
|
||||
};
|
||||
|
||||
class PEBPower : public PEBLeftWidth {
|
||||
|
||||
public:
|
||||
explicit PEBPower(char op, PExpr*l, PExpr*r);
|
||||
~PEBPower();
|
||||
~PEBPower() override;
|
||||
|
||||
NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
|
||||
unsigned expr_wid) const;
|
||||
unsigned expr_wid) const override;
|
||||
};
|
||||
|
||||
class PEBShift : public PEBLeftWidth {
|
||||
|
||||
public:
|
||||
explicit PEBShift(char op, PExpr*l, PExpr*r);
|
||||
~PEBShift();
|
||||
~PEBShift() override;
|
||||
|
||||
NetExpr*elaborate_expr_leaf(Design*des, NetExpr*lp, NetExpr*rp,
|
||||
unsigned expr_wid) const;
|
||||
unsigned expr_wid) const override;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -870,20 +912,20 @@ class PETernary : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PETernary(PExpr*e, PExpr*t, PExpr*f);
|
||||
~PETernary();
|
||||
~PETernary() override;
|
||||
|
||||
virtual void dump(std::ostream&out) const;
|
||||
virtual void dump(std::ostream&out) const override;
|
||||
|
||||
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
|
||||
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override;
|
||||
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const override;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
unsigned flags) const override;
|
||||
|
||||
private:
|
||||
NetExpr* elab_and_eval_alternative_(Design*des, NetScope*scope,
|
||||
@@ -918,26 +960,43 @@ class PECallFunction : public PExpr {
|
||||
explicit PECallFunction(const pform_name_t &n, const std::list<named_pexpr_t> &parms);
|
||||
explicit PECallFunction(perm_string n, const std::list<named_pexpr_t> &parms);
|
||||
|
||||
~PECallFunction();
|
||||
// SystemVerilog: prefix().method(args) — prefix elaborates to a class handle.
|
||||
explicit PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
|
||||
const std::vector<named_pexpr_t> &parms);
|
||||
explicit PECallFunction(PExpr* chain_prefix, const pform_name_t &method,
|
||||
const std::list<named_pexpr_t> &parms);
|
||||
|
||||
virtual void dump(std::ostream &) const;
|
||||
// SystemVerilog: q.find with (expr) — iterator "item"/"index" in expr.
|
||||
void set_with_clause(PExpr* with_expr);
|
||||
const PExpr* peek_with_clause(void) const { return with_expr_; }
|
||||
|
||||
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type);
|
||||
~PECallFunction() override;
|
||||
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
||||
// For chained-call resolution (path is only the final method name).
|
||||
const pform_scoped_name_t& peek_path(void) const { return path_; }
|
||||
const PExpr* peek_chain_prefix(void) const { return chain_prefix_; }
|
||||
|
||||
virtual void dump(std::ostream &) const override;
|
||||
|
||||
virtual void declare_implicit_nets(LexicalScope*scope, NetNet::Type type) override;
|
||||
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const override;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
ivl_type_t type, unsigned flags) const override;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid, unsigned flags) const;
|
||||
unsigned expr_wid, unsigned flags) const override;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
width_mode_t&mode) override;
|
||||
|
||||
private:
|
||||
pform_scoped_name_t path_;
|
||||
std::vector<named_pexpr_t> parms_;
|
||||
// If non-null, this call is prefix().tail_name(...) (SV method chain).
|
||||
PExpr* chain_prefix_ = nullptr;
|
||||
PExpr* with_expr_ = nullptr;
|
||||
|
||||
// For system functions.
|
||||
bool is_overridden_;
|
||||
@@ -953,8 +1012,8 @@ class PECallFunction : public PExpr {
|
||||
NetExpr* elaborate_expr_method_(Design*des, NetScope*scope,
|
||||
symbol_search_results&search_results)
|
||||
const;
|
||||
NetExpr* elaborate_expr_method_par_(Design*des, NetScope*scope,
|
||||
symbol_search_results&search_results)
|
||||
NetExpr* elaborate_expr_method_par_(Design*des, const NetScope*scope,
|
||||
const symbol_search_results&search_results)
|
||||
const;
|
||||
|
||||
|
||||
@@ -966,69 +1025,95 @@ class PECallFunction : public PExpr {
|
||||
unsigned test_width_sfunc_(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
unsigned test_width_method_(Design*des, NetScope*scope,
|
||||
symbol_search_results&search_results,
|
||||
const symbol_search_results&search_results,
|
||||
width_mode_t&mode);
|
||||
|
||||
NetExpr*elaborate_base_(Design*des, NetScope*scope, NetScope*dscope,
|
||||
unsigned flags) const;
|
||||
|
||||
unsigned elaborate_arguments_(Design*des, NetScope*scope,
|
||||
NetFuncDef*def, bool need_const,
|
||||
std::vector<NetExpr*>&parms,
|
||||
unsigned parm_off) const;
|
||||
const NetFuncDef*def, bool need_const,
|
||||
std::vector<NetExpr*>&parms,
|
||||
unsigned parm_off,
|
||||
const std::vector<named_pexpr_t>*src_parms = nullptr) const;
|
||||
|
||||
NetExpr* elaborate_class_method_net_(Design*des, NetScope*scope,
|
||||
NetNet*net, const netclass_t*class_type,
|
||||
perm_string method_name,
|
||||
const std::vector<named_pexpr_t>*src_parms) const;
|
||||
|
||||
NetExpr* elaborate_class_method_net_this_(Design*des, NetScope*scope,
|
||||
NetExpr* this_expr,
|
||||
const netclass_t*class_type,
|
||||
perm_string method_name,
|
||||
const std::vector<named_pexpr_t>*src_parms) const;
|
||||
|
||||
NetExpr* elaborate_expr_method_chained_(Design*des, NetScope*scope,
|
||||
symbol_search_results&search_results) const;
|
||||
|
||||
NetExpr* elaborate_expr_chain_(Design*des, NetScope*scope, unsigned flags) const;
|
||||
|
||||
unsigned test_width_chain_(Design*des, NetScope*scope, width_mode_t&mode);
|
||||
};
|
||||
|
||||
/*
|
||||
* Support the SystemVerilog cast to size.
|
||||
*/
|
||||
class PECastSize : public PExpr {
|
||||
/* Support SystemVerilog size and type casts. */
|
||||
class PECast : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PECastSize(PExpr*size, PExpr*base);
|
||||
~PECastSize();
|
||||
explicit PECast(PExpr *target, PExpr *base);
|
||||
~PECast() override = default;
|
||||
|
||||
void dump(std::ostream &out) const;
|
||||
void dump(std::ostream &out) const override;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
NetExpr *elaborate_expr(Design *des, NetScope *scope,
|
||||
ivl_type_t type, unsigned int flags) const override;
|
||||
|
||||
virtual bool has_aa_term(Design *des, NetScope *scope) const;
|
||||
NetExpr *elaborate_expr(Design *des, NetScope *scope,
|
||||
unsigned int expr_wid,
|
||||
unsigned int flags) const override;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
bool has_aa_term(Design *des, NetScope *scope) const override;
|
||||
|
||||
unsigned int test_width(Design *des, NetScope *scope,
|
||||
width_mode_t &mode) override;
|
||||
|
||||
private:
|
||||
PExpr* size_;
|
||||
PExpr* base_;
|
||||
};
|
||||
NetExpr *elaborate_size_cast_(Design *des, NetScope *scope,
|
||||
unsigned int expr_wid,
|
||||
unsigned int target_width,
|
||||
bool signed_flag,
|
||||
unsigned int flags) const;
|
||||
NetExpr *elaborate_type_cast_(Design *des, NetScope *scope,
|
||||
unsigned int expr_wid,
|
||||
ivl_type_t target_type,
|
||||
unsigned int target_width,
|
||||
bool signed_flag,
|
||||
unsigned int flags) const;
|
||||
|
||||
/*
|
||||
* Support the SystemVerilog cast to a different type.
|
||||
*/
|
||||
class PECastType : public PExpr {
|
||||
enum class target_kind_t {
|
||||
ERROR,
|
||||
SIZE,
|
||||
TYPE
|
||||
};
|
||||
|
||||
public:
|
||||
explicit PECastType(data_type_t*target, PExpr*base);
|
||||
~PECastType();
|
||||
struct target_info_t {
|
||||
target_kind_t kind = target_kind_t::ERROR;
|
||||
ivl_type_t type = nullptr;
|
||||
unsigned int width = 0;
|
||||
};
|
||||
|
||||
void dump(std::ostream &out) const;
|
||||
target_info_t resolve_target_(Design *des, NetScope *scope) const;
|
||||
target_info_t target_for_scope_(Design *des, NetScope *scope) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
std::unique_ptr<PExpr> target_;
|
||||
std::unique_ptr<PExpr> base_;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid, unsigned flags) const;
|
||||
|
||||
virtual bool has_aa_term(Design *des, NetScope *scope) const;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
|
||||
private:
|
||||
data_type_t* target_;
|
||||
ivl_type_t target_type_;
|
||||
PExpr* base_;
|
||||
// Cast targets can depend on parameters in the instance scope. Width
|
||||
// testing and expression elaboration run sequentially for one scope, so
|
||||
// retain only the most recent result.
|
||||
const NetScope *target_scope_ = nullptr;
|
||||
target_info_t target_info_;
|
||||
bool target_resolved_ = false;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1038,16 +1123,16 @@ class PECastSign : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PECastSign(bool signed_flag, PExpr *base);
|
||||
~PECastSign() = default;
|
||||
~PECastSign() override = default;
|
||||
|
||||
void dump(std::ostream &out) const;
|
||||
void dump(std::ostream &out) const override;
|
||||
|
||||
NetExpr* elaborate_expr(Design *des, NetScope *scope,
|
||||
unsigned expr_wid, unsigned flags) const;
|
||||
unsigned expr_wid, unsigned flags) const override;
|
||||
|
||||
virtual bool has_aa_term(Design *des, NetScope *scope) const;
|
||||
virtual bool has_aa_term(Design *des, NetScope *scope) const override;
|
||||
|
||||
unsigned test_width(Design *des, NetScope *scope, width_mode_t &mode);
|
||||
unsigned test_width(Design *des, NetScope *scope, width_mode_t &mode) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<PExpr> base_;
|
||||
@@ -1061,11 +1146,11 @@ class PEVoid : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEVoid();
|
||||
~PEVoid();
|
||||
~PEVoid() override;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
unsigned flags) const override;
|
||||
};
|
||||
|
||||
#endif /* IVL_PExpr_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2026 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -41,29 +41,23 @@ void PGate::set_pins_(list<PExpr*>*pins)
|
||||
}
|
||||
|
||||
PGate::PGate(perm_string name, list<PExpr*>*pins, const list<PExpr*>*del)
|
||||
: name_(name), pins_(pins? pins->size() : 0), ranges_(0)
|
||||
: name_(name), pins_(pins? pins->size() : 0), ranges_(nullptr)
|
||||
{
|
||||
if (pins) set_pins_(pins);
|
||||
if (del) delay_.set_delays(del);
|
||||
str0_ = IVL_DR_STRONG;
|
||||
str1_ = IVL_DR_STRONG;
|
||||
}
|
||||
|
||||
PGate::PGate(perm_string name, list<PExpr*>*pins, PExpr*del)
|
||||
: name_(name), pins_(pins? pins->size() : 0), ranges_(0)
|
||||
: name_(name), pins_(pins? pins->size() : 0), ranges_(nullptr)
|
||||
{
|
||||
if (pins) set_pins_(pins);
|
||||
if (del) delay_.set_delay(del);
|
||||
str0_ = IVL_DR_STRONG;
|
||||
str1_ = IVL_DR_STRONG;
|
||||
}
|
||||
|
||||
PGate::PGate(perm_string name, list<PExpr*>*pins)
|
||||
: name_(name), pins_(pins? pins->size() : 0), ranges_(0)
|
||||
: name_(name), pins_(pins? pins->size() : 0), ranges_(nullptr)
|
||||
{
|
||||
if (pins) set_pins_(pins);
|
||||
str0_ = IVL_DR_STRONG;
|
||||
str1_ = IVL_DR_STRONG;
|
||||
}
|
||||
|
||||
PGate::~PGate()
|
||||
@@ -76,24 +70,14 @@ void PGate::set_ranges(list<pform_range_t>*ranges)
|
||||
ranges_ = ranges;
|
||||
}
|
||||
|
||||
ivl_drive_t PGate::strength0() const
|
||||
drive_strength_t PGate::strength() const
|
||||
{
|
||||
return str0_;
|
||||
return strength_;
|
||||
}
|
||||
|
||||
void PGate::strength0(ivl_drive_t s)
|
||||
void PGate::strength(const drive_strength_t &str)
|
||||
{
|
||||
str0_ = s;
|
||||
}
|
||||
|
||||
ivl_drive_t PGate::strength1() const
|
||||
{
|
||||
return str1_;
|
||||
}
|
||||
|
||||
void PGate::strength1(ivl_drive_t s)
|
||||
{
|
||||
str1_ = s;
|
||||
strength_ = str;
|
||||
}
|
||||
|
||||
void PGate::elaborate_scope(Design*, NetScope*) const
|
||||
@@ -109,15 +93,10 @@ void PGate::elaborate_scope(Design*, NetScope*) const
|
||||
* numbers of expressions.
|
||||
*/
|
||||
|
||||
void PGate::eval_delays(Design*des, NetScope*scope,
|
||||
NetExpr*&rise_expr,
|
||||
NetExpr*&fall_expr,
|
||||
NetExpr*&decay_expr,
|
||||
void PGate::eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays,
|
||||
bool as_net_flag) const
|
||||
{
|
||||
delay_.eval_delays(des, scope,
|
||||
rise_expr, fall_expr, decay_expr,
|
||||
as_net_flag);
|
||||
delay_.eval_delays(des, scope, delays, as_net_flag);
|
||||
}
|
||||
|
||||
unsigned PGate::delay_count() const
|
||||
@@ -148,7 +127,7 @@ PGAssign::~PGAssign()
|
||||
|
||||
PGBuiltin::PGBuiltin(Type t, perm_string name,
|
||||
list<PExpr*>*pins,
|
||||
list<PExpr*>*del)
|
||||
const list<PExpr*>*del)
|
||||
: PGate(name, pins, del), type_(t)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PGate_H
|
||||
#define IVL_PGate_H
|
||||
/*
|
||||
* Copyright (c) 1998-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2026 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -31,6 +31,8 @@
|
||||
class PExpr;
|
||||
class PUdp;
|
||||
class Module;
|
||||
struct delay_exprs_t;
|
||||
struct drive_strength_t;
|
||||
|
||||
/*
|
||||
* A PGate represents a Verilog gate. The gate has a name and other
|
||||
@@ -57,7 +59,7 @@ class PGate : public PNamedItem {
|
||||
|
||||
explicit PGate(perm_string name, std::list<PExpr*>*pins);
|
||||
|
||||
virtual ~PGate();
|
||||
virtual ~PGate() override;
|
||||
|
||||
void set_ranges(std::list<pform_range_t>*ranges);
|
||||
bool is_array() const { return ranges_ != 0; }
|
||||
@@ -66,10 +68,7 @@ class PGate : public PNamedItem {
|
||||
|
||||
// This evaluates the delays as far as possible, but returns
|
||||
// an expression, and do not signal errors.
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
NetExpr*&rise_time,
|
||||
NetExpr*&fall_time,
|
||||
NetExpr*&decay_time,
|
||||
void eval_delays(Design*des, NetScope*scope, delay_exprs_t &delays,
|
||||
bool as_net_flag =false) const;
|
||||
|
||||
unsigned delay_count() const;
|
||||
@@ -77,11 +76,9 @@ class PGate : public PNamedItem {
|
||||
unsigned pin_count() const { return pins_.size(); }
|
||||
PExpr*pin(unsigned idx) const { return pins_[idx]; }
|
||||
|
||||
ivl_drive_t strength0() const;
|
||||
ivl_drive_t strength1() const;
|
||||
drive_strength_t strength() const;
|
||||
|
||||
void strength0(ivl_drive_t);
|
||||
void strength1(ivl_drive_t);
|
||||
void strength(const drive_strength_t &str);
|
||||
|
||||
std::map<perm_string,PExpr*> attributes;
|
||||
|
||||
@@ -90,7 +87,7 @@ class PGate : public PNamedItem {
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
SymbolType symbol_type() const override;
|
||||
|
||||
protected:
|
||||
const std::vector<PExpr*>& get_pins() const { return pins_; }
|
||||
@@ -109,7 +106,7 @@ class PGate : public PNamedItem {
|
||||
|
||||
std::list<pform_range_t>*ranges_;
|
||||
|
||||
ivl_drive_t str0_, str1_;
|
||||
drive_strength_t strength_;
|
||||
|
||||
void set_pins_(std::list<PExpr*>*pins);
|
||||
|
||||
@@ -127,14 +124,15 @@ class PGAssign : public PGate {
|
||||
public:
|
||||
explicit PGAssign(std::list<PExpr*>*pins);
|
||||
explicit PGAssign(std::list<PExpr*>*pins, std::list<PExpr*>*dels);
|
||||
~PGAssign();
|
||||
~PGAssign() override;
|
||||
|
||||
void dump(std::ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
void dump(std::ostream&out, unsigned ind =4) const override;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const override;
|
||||
|
||||
private:
|
||||
void elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval) const;
|
||||
void elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval,
|
||||
const drive_strength_t &drive,
|
||||
const delay_exprs_t &delays) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -159,18 +157,17 @@ class PGBuiltin : public PGate {
|
||||
public:
|
||||
explicit PGBuiltin(Type t, perm_string name,
|
||||
std::list<PExpr*>*pins,
|
||||
std::list<PExpr*>*del);
|
||||
const std::list<PExpr*>*del);
|
||||
explicit PGBuiltin(Type t, perm_string name,
|
||||
std::list<PExpr*>*pins,
|
||||
PExpr*del);
|
||||
~PGBuiltin();
|
||||
~PGBuiltin() override;
|
||||
|
||||
Type type() const { return type_; }
|
||||
const char * gate_name() const;
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind =4) const override;
|
||||
virtual void elaborate(Design*, NetScope*scope) const override;
|
||||
|
||||
private:
|
||||
void calculate_gate_and_lval_count_(unsigned&gate_count,
|
||||
@@ -210,19 +207,17 @@ class PGModule : public PGate {
|
||||
// constructor.
|
||||
explicit PGModule(Module*type, perm_string name);
|
||||
|
||||
~PGModule();
|
||||
~PGModule() override;
|
||||
|
||||
// Parameter overrides can come as an ordered list, or a set
|
||||
// of named expressions.
|
||||
void set_parameters(std::list<PExpr*>*o);
|
||||
void set_parameters(named_pexpr_t *pa, unsigned npa);
|
||||
|
||||
std::map<perm_string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind =4) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind =4) const override;
|
||||
virtual void elaborate(Design*, NetScope*scope) const override;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const override;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const override;
|
||||
|
||||
// This returns the module name of this module. It is a
|
||||
// permallocated string.
|
||||
@@ -240,11 +235,20 @@ class PGModule : public PGate {
|
||||
unsigned nparms_;
|
||||
|
||||
friend class delayed_elaborate_scope_mod_instances;
|
||||
void elaborate_mod_(Design*, Module*mod, NetScope*scope) const;
|
||||
void elaborate_mod_(Design*, const Module*mod, NetScope*scope) const;
|
||||
void elaborate_udp_(Design*, PUdp *udp, NetScope*scope) const;
|
||||
void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const;
|
||||
void elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*sc) const;
|
||||
bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const;
|
||||
bool elaborate_sig_mod_(Design*des, NetScope*scope, const Module*mod) const;
|
||||
bool bind_interface_ports_(Design*des, const Module*mod,
|
||||
NetScope*parent_scope, NetScope*instance_scope,
|
||||
const std::vector<PExpr*>&pins,
|
||||
const std::vector<bool>&pins_fromwc) const;
|
||||
bool match_module_ports_(Design*des, const Module*mod,
|
||||
NetScope*scope,
|
||||
std::vector<PExpr*>&pins,
|
||||
std::vector<bool>&pins_fromwc,
|
||||
std::vector<bool>&pins_is_explicitly_not_connected) const;
|
||||
// Not currently used.
|
||||
#if 0
|
||||
bool elaborate_sig_udp_(Design*des, NetScope*scope, PUdp*udp) const;
|
||||
|
||||
+8
-4
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PGenerate_H
|
||||
#define IVL_PGenerate_H
|
||||
/*
|
||||
* Copyright (c) 2006-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2006-2025 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -26,10 +26,12 @@
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include <valarray>
|
||||
# include <vector>
|
||||
# include "pform_types.h"
|
||||
|
||||
class Design;
|
||||
class NetScope;
|
||||
class PClass;
|
||||
class PExpr;
|
||||
class PFunction;
|
||||
class PProcess;
|
||||
@@ -54,7 +56,7 @@ class PGenerate : public PNamedItem, public LexicalScope {
|
||||
|
||||
public:
|
||||
explicit PGenerate(LexicalScope*parent, unsigned id_number);
|
||||
~PGenerate();
|
||||
~PGenerate() override;
|
||||
|
||||
// Generate schemes have an ID number, for when the scope is
|
||||
// implicit.
|
||||
@@ -92,9 +94,11 @@ class PGenerate : public PNamedItem, public LexicalScope {
|
||||
std::list<PGate*> gates;
|
||||
void add_gate(PGate*);
|
||||
|
||||
// Tasks instantiated within this scheme.
|
||||
// Definitions instantiated within this scheme.
|
||||
std::map<perm_string,PTask*> tasks;
|
||||
std::map<perm_string,PFunction*>funcs;
|
||||
std::map<perm_string,PClass*> classes;
|
||||
std::vector<PClass*> classes_lexical;
|
||||
|
||||
// Generate schemes can contain further generate schemes.
|
||||
std::list<PGenerate*> generate_schemes;
|
||||
@@ -112,7 +116,7 @@ class PGenerate : public PNamedItem, public LexicalScope {
|
||||
|
||||
void dump(std::ostream&out, unsigned indent) const;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
SymbolType symbol_type() const override;
|
||||
|
||||
private:
|
||||
void check_for_valid_genvar_value_(long value);
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PModport_H
|
||||
#define IVL_PModport_H
|
||||
/*
|
||||
* Copyright (c) 2015-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2015-2025 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -34,14 +34,14 @@ class PModport : public PNamedItem {
|
||||
// The name is a perm-allocated string. It is the simple name
|
||||
// of the modport, without any scope.
|
||||
explicit PModport(perm_string name);
|
||||
~PModport();
|
||||
~PModport() override;
|
||||
|
||||
perm_string name() const { return name_; }
|
||||
|
||||
typedef std::pair <NetNet::PortType,PExpr*> simple_port_t;
|
||||
std::map<perm_string,simple_port_t> simple_ports;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
SymbolType symbol_type() const override;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
|
||||
@@ -48,6 +48,9 @@ std::ostream& operator << (std::ostream&o, PNamedItem::SymbolType st)
|
||||
case PNamedItem::VAR:
|
||||
o << "a variable";
|
||||
break;
|
||||
case PNamedItem::CLASS_PROPERTY:
|
||||
o << "a class property";
|
||||
break;
|
||||
case PNamedItem::GENVAR:
|
||||
o << "a genvar";
|
||||
break;
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PNamedItem_H
|
||||
#define IVL_PNamedItem_H
|
||||
/*
|
||||
* Copyright (c) 2019 Martin Whitaker ([email protected])
|
||||
* Copyright (c) 2019-2025 Martin Whitaker ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -31,10 +31,10 @@ class PNamedItem : virtual public LineInfo {
|
||||
enum SymbolType { ANY, PARAM, NET, VAR, GENVAR, EVENT, TYPE, ENUM,
|
||||
CLASS, FUNCTION, TASK, BLOCK, GENBLOCK, MODPORT,
|
||||
PACKAGE, MODULE, PROGRAM, INTERFACE, PRIMITIVE,
|
||||
INSTANCE };
|
||||
INSTANCE, CLASS_PROPERTY };
|
||||
|
||||
explicit PNamedItem();
|
||||
virtual ~PNamedItem();
|
||||
virtual ~PNamedItem() override;
|
||||
|
||||
virtual SymbolType symbol_type() const;
|
||||
};
|
||||
@@ -49,9 +49,9 @@ class PGenvar : public PNamedItem {
|
||||
|
||||
public:
|
||||
explicit PGenvar();
|
||||
virtual ~PGenvar();
|
||||
virtual ~PGenvar() override;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
SymbolType symbol_type() const override;
|
||||
};
|
||||
|
||||
#endif /* IVL_PNamedItem_H */
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PPackage_H
|
||||
#define IVL_PPackage_H
|
||||
/*
|
||||
* Copyright (c) 2012-2014 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2012-2025 Stephen Williams ([email protected])
|
||||
* Copyright CERN 2013 / Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -36,7 +36,7 @@ class PPackage : public PScopeExtra, public LineInfo {
|
||||
|
||||
public:
|
||||
explicit PPackage (perm_string name, LexicalScope*parent);
|
||||
~PPackage();
|
||||
~PPackage() override;
|
||||
|
||||
bool elaborate_scope(Design*des, NetScope*scope);
|
||||
bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PScope_H
|
||||
#define IVL_PScope_H
|
||||
/*
|
||||
* Copyright (c) 2008-2024 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2008-2026 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -43,6 +43,16 @@ class PCallTask;
|
||||
class Design;
|
||||
class NetScope;
|
||||
|
||||
struct package_import_t : public LineInfo {
|
||||
package_import_t() = default;
|
||||
explicit package_import_t(PPackage *pkg) : package(pkg) { }
|
||||
|
||||
PPackage *package = nullptr;
|
||||
// LineInfo records where the imported name became locally visible.
|
||||
};
|
||||
|
||||
using package_import_map_t = std::map<perm_string, package_import_t>;
|
||||
|
||||
/*
|
||||
* The PScope class is a base representation of an object that
|
||||
* represents lexical scope. For example, a module, a function/task, a
|
||||
@@ -71,7 +81,7 @@ class LexicalScope {
|
||||
// Symbols that are explicitly imported. This contains the package where
|
||||
// the symbol has been decelared. When using exports, this might not be
|
||||
// the same as the package where it has been imported from.
|
||||
std::map<perm_string,PPackage*>explicit_imports;
|
||||
package_import_map_t explicit_imports;
|
||||
// Symbols that are explicitly imported. This contains the set of
|
||||
// packages from which the symbol has been imported. When using exports
|
||||
// the same identifier can be imported via multiple packages.
|
||||
@@ -86,7 +96,7 @@ class LexicalScope {
|
||||
// later in the scope. So here we stash the potential imports for
|
||||
// task and function calls. They will be added to the explicit
|
||||
// imports if we don't find a local definition.
|
||||
std::map<perm_string,PPackage*>possible_imports;
|
||||
package_import_map_t possible_imports;
|
||||
|
||||
struct range_t {
|
||||
// True if this is an exclude
|
||||
@@ -121,6 +131,8 @@ class LexicalScope {
|
||||
bool overridable;
|
||||
// Whether the parameter is a type parameter
|
||||
bool type_flag = false;
|
||||
// Type restriction for a type parameter
|
||||
type_restrict_t type_restrict;
|
||||
// The lexical position of the declaration
|
||||
unsigned lexical_pos = 0;
|
||||
|
||||
@@ -164,6 +176,7 @@ class LexicalScope {
|
||||
unsigned generate_counter;
|
||||
|
||||
LexicalScope* parent_scope() const { return parent_; }
|
||||
void set_parent_scope(LexicalScope *parent) { parent_ = parent; }
|
||||
|
||||
virtual bool var_init_needs_explicit_lifetime() const;
|
||||
|
||||
@@ -198,7 +211,7 @@ class PScope : public LexicalScope {
|
||||
// modules. Scopes for tasks and functions point to their
|
||||
// containing module.
|
||||
explicit PScope(perm_string name, LexicalScope*parent =0);
|
||||
virtual ~PScope();
|
||||
virtual ~PScope() override;
|
||||
|
||||
perm_string pscope_name() const { return name_; }
|
||||
|
||||
@@ -233,7 +246,7 @@ class PScopeExtra : public PScope {
|
||||
|
||||
public:
|
||||
explicit PScopeExtra(perm_string, LexicalScope*parent =0);
|
||||
~PScopeExtra();
|
||||
~PScopeExtra() override;
|
||||
|
||||
/* Task definitions within this module */
|
||||
std::map<perm_string,PTask*> tasks;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PSpec_H
|
||||
#define IVL_PSpec_H
|
||||
/*
|
||||
* Copyright (c) 2006-2014 Stephen Williams <[email protected]>
|
||||
* Copyright (c) 2006-2025 Stephen Williams <[email protected]>
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -60,7 +60,7 @@ class PSpecPath : public LineInfo {
|
||||
PSpecPath(const std::list<perm_string> &src_list,
|
||||
const std::list<perm_string> &dst_list,
|
||||
char polarity, bool full_flag);
|
||||
~PSpecPath();
|
||||
~PSpecPath() override;
|
||||
|
||||
void elaborate(class Design*des, class NetScope*scope) const;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PTask_H
|
||||
#define IVL_PTask_H
|
||||
/*
|
||||
* Copyright (c) 1999-2021 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2025 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -39,9 +39,9 @@ class PTaskFunc : public PScope, public PNamedItem {
|
||||
|
||||
public:
|
||||
PTaskFunc(perm_string name, LexicalScope*parent);
|
||||
~PTaskFunc();
|
||||
~PTaskFunc() override;
|
||||
|
||||
bool var_init_needs_explicit_lifetime() const;
|
||||
bool var_init_needs_explicit_lifetime() const override;
|
||||
|
||||
void set_ports(std::vector<pform_tf_port_t>*p);
|
||||
|
||||
@@ -80,7 +80,7 @@ class PTask : public PTaskFunc {
|
||||
|
||||
public:
|
||||
explicit PTask(perm_string name, LexicalScope*parent, bool is_auto);
|
||||
~PTask();
|
||||
~PTask() override;
|
||||
|
||||
void set_statement(Statement *s);
|
||||
|
||||
@@ -91,16 +91,16 @@ class PTask : public PTaskFunc {
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
// Bind the ports to the regs that are the ports.
|
||||
void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
void elaborate_sig(Design*des, NetScope*scope) const override;
|
||||
|
||||
// Elaborate the statement to finish off the task definition.
|
||||
void elaborate(Design*des, NetScope*scope) const;
|
||||
void elaborate(Design*des, NetScope*scope) const override;
|
||||
|
||||
bool is_auto() const { return is_auto_; };
|
||||
|
||||
void dump(std::ostream&, unsigned) const;
|
||||
void dump(std::ostream&, unsigned) const override;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
SymbolType symbol_type() const override;
|
||||
|
||||
private:
|
||||
Statement*statement_;
|
||||
@@ -122,7 +122,7 @@ class PFunction : public PTaskFunc {
|
||||
|
||||
public:
|
||||
explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto);
|
||||
~PFunction();
|
||||
~PFunction() override;
|
||||
|
||||
void set_statement(Statement *s);
|
||||
void set_return(data_type_t*t);
|
||||
@@ -142,16 +142,16 @@ class PFunction : public PTaskFunc {
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
/* elaborate the ports and return value. */
|
||||
void elaborate_sig(Design *des, NetScope*) const;
|
||||
void elaborate_sig(Design *des, NetScope*) const override;
|
||||
|
||||
/* Elaborate the behavioral statement. */
|
||||
void elaborate(Design *des, NetScope*) const;
|
||||
void elaborate(Design *des, NetScope*) const override;
|
||||
|
||||
bool is_auto() const { return is_auto_; };
|
||||
|
||||
void dump(std::ostream&, unsigned) const;
|
||||
void dump(std::ostream&, unsigned) const override;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
SymbolType symbol_type() const override;
|
||||
|
||||
private:
|
||||
data_type_t* return_type_;
|
||||
@@ -174,12 +174,12 @@ class PLet : public PTaskFunc {
|
||||
// FIXME: Should the port list be a vector. Check once implemented completely
|
||||
explicit PLet(perm_string name, LexicalScope*parent,
|
||||
std::list<let_port_t*>*ports, PExpr*expr);
|
||||
~PLet();
|
||||
~PLet() override;
|
||||
|
||||
void elaborate_sig(Design*des, NetScope*scope) const { (void)des; (void)scope; }
|
||||
void elaborate(Design*des, NetScope*scope) const { (void)des; (void)scope; }
|
||||
void elaborate_sig(Design*des, NetScope*scope) const override { (void)des; (void)scope; }
|
||||
void elaborate(Design*des, NetScope*scope) const override { (void)des; (void)scope; }
|
||||
|
||||
void dump(std::ostream&, unsigned) const;
|
||||
void dump(std::ostream&, unsigned) const override;
|
||||
|
||||
private:
|
||||
std::list<let_port_t*>*ports_;
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PTimingCheck_H
|
||||
#define IVL_PTimingCheck_H
|
||||
/*
|
||||
* Copyright (c) 2006-2023 Stephen Williams <[email protected]>
|
||||
* Copyright (c) 2006-2025 Stephen Williams <[email protected]>
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -52,7 +52,7 @@ class PTimingCheck : public LineInfo {
|
||||
};
|
||||
|
||||
PTimingCheck() { }
|
||||
virtual ~PTimingCheck() { }
|
||||
virtual ~PTimingCheck() override { }
|
||||
|
||||
virtual void elaborate(class Design*des, class NetScope*scope) const = 0;
|
||||
|
||||
@@ -76,7 +76,7 @@ class PRecRem : public PTimingCheck {
|
||||
pform_name_t* delayed_reference,
|
||||
pform_name_t* delayed_data);
|
||||
|
||||
~PRecRem();
|
||||
~PRecRem() override;
|
||||
|
||||
void elaborate(class Design*des, class NetScope*scope) const override;
|
||||
|
||||
@@ -114,7 +114,7 @@ class PSetupHold : public PTimingCheck {
|
||||
pform_name_t* delayed_reference,
|
||||
pform_name_t* delayed_data);
|
||||
|
||||
~PSetupHold();
|
||||
~PSetupHold() override;
|
||||
|
||||
void elaborate(class Design*des, class NetScope*scope) const override;
|
||||
|
||||
|
||||
@@ -29,10 +29,12 @@ PWire::PWire(perm_string n,
|
||||
NetNet::Type t,
|
||||
NetNet::PortType pt,
|
||||
PWSRType rt)
|
||||
: name_(n), lexical_pos_(lp), type_(t), port_type_(pt), signed_(false),
|
||||
: name_(n), type_(t), port_type_(pt), signed_(false),
|
||||
port_set_(false), net_set_(false), is_scalar_(false),
|
||||
error_cnt_(0), discipline_(0)
|
||||
{
|
||||
lexical_pos(lp);
|
||||
|
||||
switch (rt) {
|
||||
case SR_PORT:
|
||||
port_set_ = true;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_PWire_H
|
||||
#define IVL_PWire_H
|
||||
/*
|
||||
* Copyright (c) 1998-2024 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2025 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -63,8 +63,6 @@ class PWire : public PNamedItem {
|
||||
// Return a hierarchical name.
|
||||
perm_string basename() const;
|
||||
|
||||
unsigned lexical_pos() const { return lexical_pos_; }
|
||||
|
||||
NetNet::Type get_wire_type() const;
|
||||
bool set_wire_type(NetNet::Type);
|
||||
|
||||
@@ -93,7 +91,7 @@ class PWire : public PNamedItem {
|
||||
|
||||
NetNet* elaborate_sig(Design*, NetScope*scope);
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
SymbolType symbol_type() const override;
|
||||
|
||||
bool is_net() const { return net_set_; };
|
||||
bool is_port() const { return port_set_; };
|
||||
@@ -102,7 +100,6 @@ class PWire : public PNamedItem {
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
unsigned lexical_pos_;
|
||||
NetNet::Type type_;
|
||||
NetNet::PortType port_type_;
|
||||
bool signed_;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# The ICARUS Verilog Compilation System
|
||||
|
||||
Copyright 2000-2019 Stephen Williams
|
||||
Copyright 2000-2026 Stephen Williams
|
||||
|
||||
<details>
|
||||
<summary><h2>Table of Contents</h2></summary>
|
||||
@@ -35,10 +35,11 @@ Copyright 2000-2019 Stephen Williams
|
||||
## What is ICARUS Verilog?
|
||||
|
||||
Icarus Verilog is intended to compile ALL of the Verilog HDL, as
|
||||
described in the IEEE-1364 standard. Of course, it's not quite there
|
||||
yet. It does currently handle a mix of structural and behavioural
|
||||
constructs. For a view of the current state of Icarus Verilog, see its
|
||||
home page at https://steveicarus.github.io/iverilog/.
|
||||
described in the IEEE 1364 standard. Of course, it's not quite there
|
||||
yet. It also compiles a (slowly growing) subset of the SystemVerilog
|
||||
language, as described in the IEEE 1800 standard. For a view of the
|
||||
current state of Icarus Verilog, see its home page at
|
||||
https://steveicarus.github.io/iverilog/.
|
||||
|
||||
Icarus Verilog is not aimed at being a simulator in the traditional
|
||||
sense, but a compiler that generates code employed by back-end
|
||||
@@ -55,8 +56,6 @@ system and C/C++ compilation should be able to build the source
|
||||
distribution with little effort. Some actual programming skills are
|
||||
not required, but helpful in case of problems.
|
||||
|
||||
> If you are building on Windows, see the mingw.txt file.
|
||||
|
||||
### Compile Time Prerequisites
|
||||
|
||||
You can use:
|
||||
@@ -83,7 +82,7 @@ on a UNIX-like system:
|
||||
OSX note: bison 2.3 shipped with MacOS including Catalina generates
|
||||
broken code, but bison 3+ works. We recommend using the Fink
|
||||
project version of bison and flex (finkproject.org), brew version
|
||||
works fine either.
|
||||
works fine too.
|
||||
|
||||
- gperf 3.0 or later
|
||||
The lexical analyzer doesn't recognize keywords directly,
|
||||
@@ -392,161 +391,26 @@ Verilog web page for the current state of support for Verilog, and in
|
||||
particular, browse the bug report database for reported unsupported
|
||||
constructs.
|
||||
|
||||
- System functions are supported, but the return value is a little
|
||||
tricky. See SYSTEM FUNCTION TABLE FILES in the iverilog man page.
|
||||
|
||||
- Specify blocks are parsed but ignored in general.
|
||||
- Specify blocks are parsed but ignored by default. When enabled
|
||||
by the `-gspecify` compiler option, a subset of specify block
|
||||
constructs are supported.
|
||||
|
||||
- `trireg` is not supported. `tri0` and `tri1` are supported.
|
||||
|
||||
- tran primitives, i.e. `tran`, `tranif1`, `tranif0`, `rtran`, `rtranif1`,
|
||||
and `rtranif0` are not supported.
|
||||
|
||||
- Net delays, of the form `wire #N foo;` do not work. Delays in
|
||||
every other context do work properly, including the V2001 form
|
||||
`wire #5 foo = bar;`
|
||||
|
||||
- Event controls inside non-blocking assignments are not supported.
|
||||
i.e.: `a <= @(posedge clk) b;`
|
||||
The list of unsupported SystemVerilog constructs is too large to
|
||||
enumerate here.
|
||||
|
||||
- Macro arguments are not supported. `` `define `` macros are supported,
|
||||
but they cannot take arguments.
|
||||
|
||||
## Nonstandard Constructs or Behaviors
|
||||
|
||||
Icarus Verilog includes some features that are not part of the
|
||||
IEEE1364 standard, but have well-defined meaning, and also sometimes
|
||||
gives nonstandard (but extended) meanings to some features of the
|
||||
language that are defined. See the "extensions.txt" documentation for
|
||||
more details.
|
||||
|
||||
* `$is_signed(<expr>)`
|
||||
|
||||
This system function returns 1 if the expression contained is
|
||||
signed, or 0 otherwise. This is mostly of use for compiler
|
||||
regression tests.
|
||||
|
||||
* `$sizeof(<expr>)`, `$bits(<expr>)`
|
||||
|
||||
The `$bits` system function returns the size in bits of the
|
||||
expression that is its argument. The result of this
|
||||
function is undefined if the argument doesn't have a
|
||||
self-determined size.
|
||||
|
||||
The `$sizeof` function is deprecated in favour of `$bits`, which is
|
||||
the same thing, but included in the SystemVerilog definition.
|
||||
|
||||
* `$simtime`
|
||||
|
||||
The `$simtime` system function returns as a 64bit value the
|
||||
simulation time, unscaled by the time units of local
|
||||
scope. This is different from the $time and $stime functions
|
||||
which return the scaled times. This function is added for
|
||||
regression testing of the compiler and run time, but can be
|
||||
used by applications who really want the simulation time.
|
||||
|
||||
Note that the simulation time can be confusing if there are
|
||||
lots of different `` `timescales`` within a design. It is not in
|
||||
general possible to predict what the simulation precision will
|
||||
turn out to be.
|
||||
|
||||
* `$mti_random()`, `$mti_dist_uniform`
|
||||
|
||||
These functions are similar to the IEEE1364 standard $random
|
||||
functions, but they use the Mersenne Twister (MT19937)
|
||||
algorithm. This is considered an excellent random number
|
||||
generator, but does not generate the same sequence as the
|
||||
standardized $random.
|
||||
|
||||
### Builtin system functions
|
||||
|
||||
Certain of the system functions have well-defined meanings, so
|
||||
can theoretically be evaluated at compile-time, instead of
|
||||
using runtime VPI code. Doing so means that VPI cannot
|
||||
override the definitions of functions handled in this
|
||||
manner. On the other hand, this makes them synthesizable, and
|
||||
also allows for more aggressive constant propagation. The
|
||||
functions handled in this manner are:
|
||||
|
||||
* `$bits`
|
||||
* `$signed`
|
||||
* `$sizeof`
|
||||
* `$unsigned`
|
||||
|
||||
Implementations of these system functions in VPI modules will be ignored.
|
||||
|
||||
### Preprocessing Library Modules
|
||||
|
||||
Icarus Verilog does preprocess modules that are loaded from
|
||||
libraries via the -y mechanism. However, the only macros
|
||||
defined during the compilation of that file are those that it
|
||||
defines itself (or includes) or that are defined in the
|
||||
command line or command file.
|
||||
|
||||
Specifically, macros defined in the non-library source files
|
||||
are not remembered when the library module is loaded. This is
|
||||
intentional. If it were otherwise, then compilation results
|
||||
might vary depending on the order that libraries are loaded,
|
||||
and that is too unpredictable.
|
||||
|
||||
It is said that some commercial compilers do allow macro
|
||||
definitions to span library modules. That's just plain weird.
|
||||
|
||||
### Width in `%t` Time Formats
|
||||
|
||||
Standard Verilog does not allow width fields in the %t formats
|
||||
of display strings. For example, this is illegal:
|
||||
|
||||
```
|
||||
$display("Time is %0t", $time);
|
||||
```
|
||||
|
||||
Standard Verilog instead relies on the $timeformat to
|
||||
completely specify the format.
|
||||
|
||||
Icarus Verilog allows the programmer to specify the field
|
||||
width. The `%t` format in Icarus Verilog works exactly as it
|
||||
does in standard Verilog. However, if the programmer chooses
|
||||
to specify a minimum width (i.e., `%5t`), then for that display
|
||||
Icarus Verilog will override the `$timeformat` minimum width and
|
||||
use the explicit minimum width.
|
||||
|
||||
### vpiScope Iterator on vpiScope Objects
|
||||
|
||||
In the VPI, the normal way to iterate over vpiScope objects
|
||||
contained within a vpiScope object, is the vpiInternalScope
|
||||
iterator. Icarus Verilog adds support for the vpiScope
|
||||
iterator of a vpiScope object, that iterates over *everything*
|
||||
the is contained in the current scope. This is useful in cases
|
||||
where one wants to iterate over all the objects in a scope
|
||||
without iterating over all the contained types explicitly.
|
||||
|
||||
### Time 0 Race Resolution
|
||||
|
||||
Combinational logic is routinely modelled using always
|
||||
blocks. However, this can lead to race conditions if the
|
||||
inputs to the combinational block are initialized in initial
|
||||
statements. Icarus Verilog slightly modifies time 0 scheduling
|
||||
by arranging for always statements with ANYEDGE sensitivity
|
||||
lists to be scheduled before any other threads. This causes
|
||||
combinational always blocks to be triggered when the values in
|
||||
the sensitivity list are initialized by initial threads.
|
||||
|
||||
### Nets with Types
|
||||
|
||||
Icarus Verilog supports an extended syntax that allows nets
|
||||
and regs to be explicitly typed. The currently supported types
|
||||
are logic, bool and real. This implies that `logic` and `bool`
|
||||
are new keywords. Typical syntax is:
|
||||
|
||||
```verilog
|
||||
wire real foo = 1.0;
|
||||
reg logic bar, bat;
|
||||
```
|
||||
... and so forth. The syntax can be turned off by using the
|
||||
`-g2` flag to iverilog, and turned on explicitly with the `-g2x`
|
||||
flag to iverilog.
|
||||
## Nonstandard Constructs and Behaviors
|
||||
|
||||
Icarus Verilog includes some features that are not part of the IEEE 1364
|
||||
standard, but have well-defined meaning, and also sometimes gives nonstandard
|
||||
(but extended) meanings to some features of the language that are defined.
|
||||
See the "Icarus Verilog Extensions" and "Icarus Verilog Quirks" sections at
|
||||
https://steveicarus.github.io/iverilog/ for more details.
|
||||
|
||||
## Credits
|
||||
|
||||
|
||||
+4
-4
@@ -396,8 +396,8 @@ PReturn::~PReturn()
|
||||
delete expr_;
|
||||
}
|
||||
|
||||
PTrigger::PTrigger(PPackage*pkg, const pform_name_t&ev, unsigned lexical_pos)
|
||||
: event_(pkg, ev), lexical_pos_(lexical_pos)
|
||||
PTrigger::PTrigger(PPackage*pkg, const pform_name_t&ev)
|
||||
: event_(pkg, ev)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -405,8 +405,8 @@ PTrigger::~PTrigger()
|
||||
{
|
||||
}
|
||||
|
||||
PNBTrigger::PNBTrigger(const pform_name_t&ev, unsigned lexical_pos, PExpr*dly)
|
||||
: event_(ev), lexical_pos_(lexical_pos), dly_(dly)
|
||||
PNBTrigger::PNBTrigger(const pform_name_t&ev, PExpr*dly)
|
||||
: event_(ev), dly_(dly)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+174
-110
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_Statement_H
|
||||
#define IVL_Statement_H
|
||||
/*
|
||||
* Copyright (c) 1998-2024 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2026 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -40,6 +40,8 @@ class NetCAssign;
|
||||
class NetDeassign;
|
||||
class NetForce;
|
||||
class NetScope;
|
||||
class NetNet;
|
||||
class netdarray_t;
|
||||
|
||||
/*
|
||||
* The PProcess is the root of a behavioral process. Each process gets
|
||||
@@ -53,7 +55,10 @@ class PProcess : public LineInfo {
|
||||
PProcess(ivl_process_type_t t, Statement*st)
|
||||
: type_(t), statement_(st) { }
|
||||
|
||||
virtual ~PProcess();
|
||||
virtual ~PProcess() override;
|
||||
|
||||
PProcess(const PProcess&) = delete;
|
||||
PProcess& operator=(const PProcess&) = delete;
|
||||
|
||||
bool elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
@@ -78,7 +83,7 @@ class Statement : virtual public LineInfo {
|
||||
|
||||
public:
|
||||
Statement() { }
|
||||
virtual ~Statement() =0;
|
||||
virtual ~Statement() override =0;
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
@@ -99,7 +104,10 @@ class PAssign_ : public Statement {
|
||||
bool is_init = false);
|
||||
explicit PAssign_(PExpr*lval, PExpr*de, PExpr*ex);
|
||||
explicit PAssign_(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex);
|
||||
virtual ~PAssign_() =0;
|
||||
virtual ~PAssign_() override =0;
|
||||
|
||||
PAssign_(const PAssign_&) = delete;
|
||||
PAssign_& operator=(const PAssign_&) = delete;
|
||||
|
||||
const PExpr* lval() const { return lval_; }
|
||||
PExpr* rval() const { return rval_; }
|
||||
@@ -139,10 +147,10 @@ class PAssign : public PAssign_ {
|
||||
explicit PAssign(PExpr*lval, PExpr*de, PExpr*ex);
|
||||
explicit PAssign(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex);
|
||||
explicit PAssign(PExpr*lval, PExpr*ex, bool is_constant, bool is_init);
|
||||
~PAssign();
|
||||
~PAssign() override;
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
|
||||
private:
|
||||
NetProc* elaborate_compressed_(Design*des, NetScope*scope) const;
|
||||
@@ -155,10 +163,10 @@ class PAssignNB : public PAssign_ {
|
||||
explicit PAssignNB(PExpr*lval, PExpr*ex);
|
||||
explicit PAssignNB(PExpr*lval, PExpr*de, PExpr*ex);
|
||||
explicit PAssignNB(PExpr*lval, PExpr*cnt, PEventStatement*de, PExpr*ex);
|
||||
~PAssignNB();
|
||||
~PAssignNB() override;
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
|
||||
private:
|
||||
NetProc*assign_to_memory_(class NetMemory*, PExpr*,
|
||||
@@ -181,11 +189,11 @@ class PBlock : public PScope, public Statement, public PNamedItem {
|
||||
explicit PBlock(perm_string n, LexicalScope*parent, BL_TYPE t);
|
||||
// If it doesn't have a name, it's not a scope
|
||||
explicit PBlock(BL_TYPE t);
|
||||
~PBlock();
|
||||
~PBlock() override;
|
||||
|
||||
BL_TYPE bl_type() const { return bl_type_; }
|
||||
|
||||
bool var_init_needs_explicit_lifetime() const;
|
||||
bool var_init_needs_explicit_lifetime() const override;
|
||||
|
||||
// This is only used if this block is the statement list for a
|
||||
// constructor. We look for a PChainConstructor as the first
|
||||
@@ -202,12 +210,12 @@ class PBlock : public PScope, public Statement, public PNamedItem {
|
||||
// block.
|
||||
void push_statement_front(Statement*that);
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
|
||||
|
||||
SymbolType symbol_type() const;
|
||||
SymbolType symbol_type() const override;
|
||||
|
||||
private:
|
||||
BL_TYPE bl_type_;
|
||||
@@ -216,8 +224,8 @@ class PBlock : public PScope, public Statement, public PNamedItem {
|
||||
|
||||
class PBreak : public Statement {
|
||||
public:
|
||||
void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
void dump(std::ostream&out, unsigned ind) const override;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
};
|
||||
|
||||
class PCallTask : public Statement {
|
||||
@@ -226,12 +234,12 @@ class PCallTask : public Statement {
|
||||
explicit PCallTask(PPackage *pkg, const pform_name_t &n, const std::list<named_pexpr_t> &parms);
|
||||
explicit PCallTask(const pform_name_t &n, const std::list<named_pexpr_t> &parms);
|
||||
explicit PCallTask(perm_string n, const std::list<named_pexpr_t> &parms);
|
||||
~PCallTask();
|
||||
~PCallTask() override;
|
||||
|
||||
const pform_name_t& path() const;
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
|
||||
bool elaborate_elab(Design*des, NetScope*scope) const;
|
||||
|
||||
@@ -243,10 +251,12 @@ class PCallTask : public Statement {
|
||||
|
||||
NetProc*elaborate_method_(Design*des, NetScope*scope,
|
||||
bool add_this_flag = false) const;
|
||||
NetProc*elaborate_function_(Design*des, NetScope*scope) const;
|
||||
NetProc *elaborate_function_(
|
||||
Design *des, NetScope *scope, NetScope *func_scope) const;
|
||||
NetProc*elaborate_void_function_(Design*des, NetScope*scope,
|
||||
NetFuncDef*def) const;
|
||||
NetProc *elaborate_non_void_function_(Design *des, NetScope *scope) const;
|
||||
NetProc *elaborate_non_void_function_(Design *des, NetScope *scope,
|
||||
const pform_name_t &path) const;
|
||||
|
||||
NetProc*elaborate_build_call_(Design*des, NetScope*scope,
|
||||
NetScope*task, NetExpr*use_this) const;
|
||||
@@ -255,17 +265,43 @@ class PCallTask : public Statement {
|
||||
perm_string method_name,
|
||||
const char *sys_task_name,
|
||||
const std::vector<perm_string> &parm_names = {}) const;
|
||||
NetProc*elaborate_sys_task_property_method_(Design*des, NetScope*scope,
|
||||
NetNet*net, int property_idx,
|
||||
perm_string method_name,
|
||||
const char *sys_task_name,
|
||||
const std::vector<perm_string> &parm_names = {}) const;
|
||||
NetProc*elaborate_queue_method_(Design*des, NetScope*scope,
|
||||
NetNet*net,
|
||||
perm_string method_name,
|
||||
const char *sys_task_name,
|
||||
const std::vector<perm_string> &parm_names) const;
|
||||
NetProc*elaborate_queue_property_method_(Design*des, NetScope*scope,
|
||||
NetNet*net, int property_idx,
|
||||
perm_string method_name,
|
||||
const char *sys_task_name,
|
||||
const std::vector<perm_string> &parm_names) const;
|
||||
NetProc*elaborate_method_func_(NetScope*scope,
|
||||
NetNet*net,
|
||||
ivl_type_t type,
|
||||
perm_string method_name,
|
||||
const char*sys_task_name) const;
|
||||
bool test_task_calls_ok_(Design*des, NetScope*scope) const;
|
||||
NetProc*elaborate_method_property_func_(NetScope*scope,
|
||||
NetNet*net, int property_idx,
|
||||
ivl_type_t type,
|
||||
perm_string method_name,
|
||||
const char*sys_task_name) const;
|
||||
NetProc*elaborate_queue_method_expr_(Design*des, NetScope*scope,
|
||||
NetExpr*queue_base,
|
||||
const netdarray_t*use_darray,
|
||||
perm_string method_name,
|
||||
const char *sys_task_name,
|
||||
const std::vector<perm_string> &parm_names) const;
|
||||
NetProc*elaborate_method_func_expr_(NetScope*scope,
|
||||
NetExpr*queue_base,
|
||||
ivl_type_t type,
|
||||
perm_string method_name,
|
||||
const char*sys_task_name) const;
|
||||
bool test_task_calls_ok_(Design*des, const NetScope*scope) const;
|
||||
|
||||
PPackage*package_;
|
||||
pform_name_t path_;
|
||||
@@ -282,12 +318,12 @@ class PCase : public Statement {
|
||||
};
|
||||
|
||||
PCase(ivl_case_quality_t, NetCase::TYPE, PExpr*ex, std::vector<Item*>*);
|
||||
~PCase();
|
||||
~PCase() override;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
private:
|
||||
ivl_case_quality_t quality_;
|
||||
@@ -305,10 +341,13 @@ class PCAssign : public Statement {
|
||||
|
||||
public:
|
||||
explicit PCAssign(PExpr*l, PExpr*r);
|
||||
~PCAssign();
|
||||
~PCAssign() override;
|
||||
|
||||
virtual NetCAssign* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
PCAssign(const PCAssign&) = delete;
|
||||
PCAssign& operator=(const PCAssign&) = delete;
|
||||
|
||||
virtual NetCAssign* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
private:
|
||||
PExpr*lval_;
|
||||
@@ -324,10 +363,10 @@ class PChainConstructor : public Statement {
|
||||
public:
|
||||
explicit PChainConstructor(const std::list<named_pexpr_t> &parms);
|
||||
explicit PChainConstructor(const std::vector<named_pexpr_t> &parms);
|
||||
~PChainConstructor();
|
||||
~PChainConstructor() override;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
inline const std::vector<named_pexpr_t>& chain_args(void) const
|
||||
{ return parms_; }
|
||||
@@ -340,12 +379,12 @@ class PCondit : public Statement {
|
||||
|
||||
public:
|
||||
PCondit(PExpr*ex, Statement*i, Statement*e);
|
||||
~PCondit();
|
||||
~PCondit() override;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
private:
|
||||
PExpr*expr_;
|
||||
@@ -360,18 +399,21 @@ class PCondit : public Statement {
|
||||
class PContinue : public Statement {
|
||||
|
||||
public:
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
};
|
||||
|
||||
class PDeassign : public Statement {
|
||||
|
||||
public:
|
||||
explicit PDeassign(PExpr*l);
|
||||
~PDeassign();
|
||||
~PDeassign() override;
|
||||
|
||||
virtual NetDeassign* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
PDeassign(const PDeassign&) = delete;
|
||||
PDeassign& operator=(const PDeassign&) = delete;
|
||||
|
||||
virtual NetDeassign* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
private:
|
||||
PExpr*lval_;
|
||||
@@ -381,12 +423,12 @@ class PDelayStatement : public Statement {
|
||||
|
||||
public:
|
||||
PDelayStatement(PExpr*d, Statement*st);
|
||||
~PDelayStatement();
|
||||
~PDelayStatement() override;
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
|
||||
|
||||
private:
|
||||
PExpr*delay_;
|
||||
@@ -401,10 +443,10 @@ class PDisable : public Statement {
|
||||
|
||||
public:
|
||||
explicit PDisable(const pform_name_t&sc);
|
||||
~PDisable();
|
||||
~PDisable() override;
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
|
||||
private:
|
||||
pform_name_t scope_;
|
||||
@@ -414,12 +456,15 @@ class PDoWhile : public Statement {
|
||||
|
||||
public:
|
||||
PDoWhile(PExpr*ex, Statement*st);
|
||||
~PDoWhile();
|
||||
~PDoWhile() override;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
PDoWhile(const PDoWhile&) = delete;
|
||||
PDoWhile& operator=(const PDoWhile&) = delete;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
private:
|
||||
PExpr*cond_;
|
||||
@@ -444,17 +489,17 @@ class PEventStatement : public Statement {
|
||||
// from functions added and outputs removed for always_comb/latch.
|
||||
explicit PEventStatement(bool always_sens = false);
|
||||
|
||||
~PEventStatement();
|
||||
~PEventStatement() override;
|
||||
|
||||
void set_statement(Statement*st);
|
||||
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
// Call this with a NULL statement only. It is used to print
|
||||
// the event expression for inter-assignment event controls.
|
||||
virtual void dump_inline(std::ostream&out) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
|
||||
|
||||
bool has_aa_term(Design*des, NetScope*scope);
|
||||
|
||||
@@ -463,7 +508,7 @@ class PEventStatement : public Statement {
|
||||
NetProc* elaborate_st(Design*des, NetScope*scope, NetProc*st) const;
|
||||
|
||||
NetProc* elaborate_wait(Design*des, NetScope*scope, NetProc*st) const;
|
||||
NetProc* elaborate_wait_fork(Design*des, NetScope*scope) const;
|
||||
NetProc* elaborate_wait_fork(Design*des, const NetScope*scope) const;
|
||||
|
||||
private:
|
||||
std::vector<PEEvent*>expr_;
|
||||
@@ -477,10 +522,13 @@ class PForce : public Statement {
|
||||
|
||||
public:
|
||||
explicit PForce(PExpr*l, PExpr*r);
|
||||
~PForce();
|
||||
~PForce() override;
|
||||
|
||||
virtual NetForce* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
PForce(const PForce&) = delete;
|
||||
PForce& operator=(const PForce&) = delete;
|
||||
|
||||
virtual NetForce* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
private:
|
||||
PExpr*lval_;
|
||||
@@ -490,12 +538,15 @@ class PForce : public Statement {
|
||||
class PForeach : public Statement {
|
||||
public:
|
||||
explicit PForeach(perm_string var, const std::list<perm_string>&ix, Statement*stmt);
|
||||
~PForeach();
|
||||
~PForeach() override;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
PForeach(const PForeach&) = delete;
|
||||
PForeach& operator=(const PForeach&) = delete;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
private:
|
||||
NetProc* elaborate_static_array_(Design*des, NetScope*scope,
|
||||
@@ -510,12 +561,15 @@ class PForeach : public Statement {
|
||||
class PForever : public Statement {
|
||||
public:
|
||||
explicit PForever(Statement*s);
|
||||
~PForever();
|
||||
~PForever() override;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
PForever(const PForever&) = delete;
|
||||
PForever& operator=(const PForever&) = delete;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
private:
|
||||
Statement*statement_;
|
||||
@@ -526,12 +580,12 @@ class PForStatement : public Statement {
|
||||
public:
|
||||
PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
|
||||
Statement*step, Statement*body);
|
||||
~PForStatement();
|
||||
~PForStatement() override;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
private:
|
||||
PExpr* name1_;
|
||||
@@ -548,18 +602,21 @@ class PNoop : public Statement {
|
||||
|
||||
public:
|
||||
PNoop() { }
|
||||
~PNoop() { }
|
||||
~PNoop() override { }
|
||||
};
|
||||
|
||||
class PRepeat : public Statement {
|
||||
public:
|
||||
explicit PRepeat(PExpr*expr, Statement*s);
|
||||
~PRepeat();
|
||||
~PRepeat() override;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
PRepeat(const PRepeat&) = delete;
|
||||
PRepeat& operator=(const PRepeat&) = delete;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
private:
|
||||
PExpr*expr_;
|
||||
@@ -570,10 +627,13 @@ class PRelease : public Statement {
|
||||
|
||||
public:
|
||||
explicit PRelease(PExpr*l);
|
||||
~PRelease();
|
||||
~PRelease() override;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
PRelease(const PRelease&) = delete;
|
||||
PRelease& operator=(const PRelease&) = delete;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
private:
|
||||
PExpr*lval_;
|
||||
@@ -583,10 +643,13 @@ class PReturn : public Statement {
|
||||
|
||||
public:
|
||||
explicit PReturn(PExpr*e);
|
||||
~PReturn();
|
||||
~PReturn() override;
|
||||
|
||||
NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
PReturn(const PReturn&) = delete;
|
||||
PReturn& operator=(const PReturn&) = delete;
|
||||
|
||||
NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
private:
|
||||
PExpr*expr_;
|
||||
@@ -599,28 +662,26 @@ class PReturn : public Statement {
|
||||
class PTrigger : public Statement {
|
||||
|
||||
public:
|
||||
explicit PTrigger(PPackage*pkg, const pform_name_t&ev, unsigned lexical_pos);
|
||||
~PTrigger();
|
||||
explicit PTrigger(PPackage*pkg, const pform_name_t&ev);
|
||||
~PTrigger() override;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
private:
|
||||
pform_scoped_name_t event_;
|
||||
unsigned lexical_pos_;
|
||||
};
|
||||
|
||||
class PNBTrigger : public Statement {
|
||||
public:
|
||||
explicit PNBTrigger(const pform_name_t&ev, unsigned lexical_pos, PExpr*dly);
|
||||
~PNBTrigger();
|
||||
explicit PNBTrigger(const pform_name_t&ev, PExpr*dly);
|
||||
~PNBTrigger() override;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
private:
|
||||
pform_name_t event_;
|
||||
unsigned lexical_pos_;
|
||||
PExpr*dly_;
|
||||
};
|
||||
|
||||
@@ -628,12 +689,15 @@ class PWhile : public Statement {
|
||||
|
||||
public:
|
||||
PWhile(PExpr*ex, Statement*st);
|
||||
~PWhile();
|
||||
~PWhile() override;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
PWhile(const PWhile&) = delete;
|
||||
PWhile& operator=(const PWhile&) = delete;
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const override;
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const override;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const override;
|
||||
|
||||
private:
|
||||
PExpr*cond_;
|
||||
|
||||
Vendored
+23
-386
@@ -1,390 +1,27 @@
|
||||
# generated automatically by aclocal 1.18.1 -*- Autoconf -*-
|
||||
|
||||
# AX_ENABLE_SUFFIX
|
||||
# ----------------
|
||||
# Create the configure option --enable-suffix[=suffix] to generate suffix
|
||||
# strings for the installed commands. This allows for shared installs of
|
||||
# different builds. Remember to change the default suffix string to some
|
||||
# value appropriate for the current version.
|
||||
AC_DEFUN([AX_ENABLE_SUFFIX],
|
||||
[AC_ARG_ENABLE([suffix],[AS_HELP_STRING([--enable-suffix],
|
||||
[Use/set the installation command suffix])],
|
||||
[true],[enable_suffix=no])
|
||||
if test X$enable_suffix = Xyes; then
|
||||
install_suffix='-0.10'
|
||||
elif test X$enable_suffix = Xno; then
|
||||
install_suffix=''
|
||||
else
|
||||
install_suffix="$enable_suffix"
|
||||
fi
|
||||
AC_SUBST(install_suffix)
|
||||
])# AX_ENABLE_SUFFIX
|
||||
# Copyright (C) 1996-2025 Free Software Foundation, Inc.
|
||||
|
||||
# _AX_C_UNDERSCORES_MATCH_IFELSE(PATTERN, ACTION-IF-MATCH, ACTION-IF-NOMATCH)
|
||||
# ------------------------------
|
||||
# Sub-macro for AX_C_UNDERSCORES_LEADING and AX_C_UNDERSCORES_TRAILING.
|
||||
# Unwarranted assumptions:
|
||||
# - the object file produced by AC_COMPILE_IFELSE is called
|
||||
# "conftest.$ac_objext"
|
||||
# - the nm(1) utility or an equivalent is available, and its name
|
||||
# is defined by the $NM variable.
|
||||
AC_DEFUN([_AX_C_UNDERSCORES_MATCH_IF],
|
||||
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([void underscore(void){}])],
|
||||
[AS_IF([$NM conftest.$ac_objext|grep $1 >/dev/null 2>/dev/null],[$2],[$3])],
|
||||
[AC_MSG_ERROR([underscore test crashed])]
|
||||
)])
|
||||
# This file is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
# AX_C_UNDERSCORES_LEADING
|
||||
# ---------------------------------
|
||||
# Check if symbol names in object files produced by C compiler have
|
||||
# leading underscores. Define NEED_LU if so.
|
||||
AC_DEFUN([AX_C_UNDERSCORES_LEADING],
|
||||
[AC_CACHE_CHECK([for leading underscores], ax_cv_c_underscores_leading,
|
||||
[_AX_C_UNDERSCORES_MATCH_IF([_underscore],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_leading, yes)],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_leading, no)])])
|
||||
if test $ax_cv_c_underscores_leading = yes -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
|
||||
AC_DEFINE([NEED_LU], [1], [Symbol names in object files produced by C compiler have leading underscores.])
|
||||
fi
|
||||
])# AX_C_UNDERSCORES_LEADING
|
||||
|
||||
|
||||
# AX_C_UNDERSCORES_TRAILING
|
||||
# ---------------------------------
|
||||
# Check if symbol names in object files produced by C compiler have
|
||||
# trailing underscores. Define NEED_TU if so.
|
||||
AC_DEFUN([AX_C_UNDERSCORES_TRAILING],
|
||||
[AC_CACHE_CHECK([for trailing underscores], ax_cv_c_underscores_trailing,
|
||||
[_AX_C_UNDERSCORES_MATCH_IF([underscore_],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_trailing, yes)],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_trailing, no)])])
|
||||
if test $ax_cv_c_underscores_trailing = yes; then
|
||||
AC_DEFINE([NEED_TU], [1], [Symbol names in object files produced by C compiler have trailing underscores.])
|
||||
fi
|
||||
])# AX_C_UNDERSCORES_TRAILING
|
||||
|
||||
# AX_WIN32
|
||||
# --------
|
||||
# Combined check for several flavors of Microsoft Windows so
|
||||
# their "issues" can be dealt with
|
||||
AC_DEFUN([AX_WIN32],
|
||||
[AC_MSG_CHECKING([for Microsoft Windows])
|
||||
AC_REQUIRE([AC_CANONICAL_HOST]) []dnl
|
||||
case $host_os in
|
||||
*cygwin*) MINGW32=no; WIN32=yes;;
|
||||
|
||||
*mingw*) MINGW32=yes; WIN32=yes;;
|
||||
|
||||
*) MINGW32=no; WIN32=no;;
|
||||
esac
|
||||
AC_SUBST(MINGW32)
|
||||
AC_SUBST(WIN32)
|
||||
AC_MSG_RESULT($WIN32)
|
||||
if test $WIN32 = yes; then
|
||||
AC_MSG_CHECKING([for MinGW])
|
||||
AC_MSG_RESULT($MINGW32)
|
||||
fi
|
||||
])# AX_WIN32
|
||||
|
||||
# AX_LD_EXTRALIBS
|
||||
# ---------------
|
||||
# mingw needs to link with libiberty.a, but cygwin alone can't tolerate it
|
||||
AC_DEFUN([AX_LD_EXTRALIBS],
|
||||
[AC_MSG_CHECKING([for extra libs needed])
|
||||
EXTRALIBS=
|
||||
case "${host}" in
|
||||
*-*-cygwin* )
|
||||
if test "$MINGW32" = "yes"; then
|
||||
EXTRALIBS="-liberty"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(EXTRALIBS)
|
||||
AC_MSG_RESULT($EXTRALIBS)
|
||||
])# AX_LD_EXTRALIBS
|
||||
|
||||
# AX_LD_SHAREDLIB_OPTS
|
||||
# --------------------
|
||||
# linker options when building a shared library
|
||||
AC_DEFUN([AX_LD_SHAREDLIB_OPTS],
|
||||
[AC_MSG_CHECKING([for shared library link flag])
|
||||
shared=-shared
|
||||
case "${host}" in
|
||||
*-*-cygwin*)
|
||||
shared="-shared -Wl,--enable-auto-image-base"
|
||||
;;
|
||||
|
||||
*-*-mingw*)
|
||||
shared="-shared -Wl,--enable-auto-image-base"
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
shared="-b"
|
||||
;;
|
||||
|
||||
*-*-darwin1.[0123])
|
||||
shared="-bundle -undefined dynamic_lookup"
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
shared="-bundle -undefined dynamic_lookup -flat_namespace"
|
||||
;;
|
||||
|
||||
*-*-solaris*)
|
||||
if test ${using_sunpro_c} = 1
|
||||
then
|
||||
shared="-G"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(shared)
|
||||
AC_MSG_RESULT($shared)
|
||||
])# AX_LD_SHAREDLIB_OPTS
|
||||
|
||||
# AX_C_PICFLAG
|
||||
# ------------
|
||||
# The -fPIC flag is used to tell the compiler to make position
|
||||
# independent code. It is needed when making shared objects.
|
||||
AC_DEFUN([AX_C_PICFLAG],
|
||||
[AC_MSG_CHECKING([for flag to make position independent code])
|
||||
PICFLAG=-fPIC
|
||||
case "${host}" in
|
||||
|
||||
*-*-cygwin*)
|
||||
PICFLAG=
|
||||
;;
|
||||
|
||||
*-*-mingw*)
|
||||
PICFLAG=
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
PICFLAG=+z
|
||||
;;
|
||||
|
||||
*-*-solaris*)
|
||||
if test ${using_sunpro_c} = 1
|
||||
then
|
||||
PICFLAG=-G
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(PICFLAG)
|
||||
AC_MSG_RESULT($PICFLAG)
|
||||
])# AX_C_PICFLAG
|
||||
|
||||
# AX_LD_RDYNAMIC
|
||||
# --------------
|
||||
# The -rdynamic flag is used by iverilog when compiling the target,
|
||||
# to know how to export symbols of the main program to loadable modules
|
||||
# that are brought in by -ldl
|
||||
AC_DEFUN([AX_LD_RDYNAMIC],
|
||||
[AC_MSG_CHECKING([for -rdynamic compiler flag])
|
||||
rdynamic=-rdynamic
|
||||
case "${host}" in
|
||||
|
||||
*-*-netbsd*)
|
||||
rdynamic="-Wl,--export-dynamic"
|
||||
;;
|
||||
|
||||
*-*-openbsd*)
|
||||
rdynamic="-Wl,--export-dynamic"
|
||||
;;
|
||||
|
||||
*-*-solaris*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-cygwin*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-mingw*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
rdynamic="-E"
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
rdynamic="-Wl,-all_load"
|
||||
strip_dynamic="-SX"
|
||||
;;
|
||||
|
||||
esac
|
||||
AC_SUBST(rdynamic)
|
||||
AC_MSG_RESULT($rdynamic)
|
||||
AC_SUBST(strip_dynamic)
|
||||
# since we didn't tell them we're "checking", no good place to tell the answer
|
||||
# AC_MSG_RESULT($strip_dynamic)
|
||||
])# AX_LD_RDYNAMIC
|
||||
|
||||
|
||||
# AX_C99_STRTOD
|
||||
# -------------
|
||||
AC_DEFUN([AX_C99_STRTOD],
|
||||
[# On MinGW we need to jump through hoops to get a C99 compliant strtod().
|
||||
# mingw-w64 doesn't need this, and the 64-bit version doesn't support it.
|
||||
case "${host}" in
|
||||
x86_64-w64-mingw32)
|
||||
;;
|
||||
*-*-mingw32)
|
||||
LDFLAGS+=" -Wl,--undefined=___strtod,--wrap,strtod,--defsym,___wrap_strtod=___strtod"
|
||||
;;
|
||||
esac
|
||||
])# AX_C99_STRTOD
|
||||
|
||||
# When config.status generates a header, we must update the stamp-h file.
|
||||
# This file resides in the same directory as the config header
|
||||
# that is generated. The stamp file name are based on the header name.
|
||||
|
||||
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
|
||||
# loop where config.status creates the headers, so we can generate
|
||||
# our stamp files there.
|
||||
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
|
||||
[
|
||||
_config_header=$1
|
||||
_stamp_name=stamp-`expr //$_config_header : '.*/\([[^./]]*\)\.[[^./]]*$'`-h
|
||||
echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_stamp_name
|
||||
]) #_AC_AM_CONFIG_HEADER_HOOK
|
||||
|
||||
# ===========================================================================
|
||||
# https://www.gnu.org/software/autoconf-archive/ax_prog_cc_for_build.html
|
||||
# ===========================================================================
|
||||
#
|
||||
# SYNOPSIS
|
||||
#
|
||||
# AX_PROG_CC_FOR_BUILD
|
||||
#
|
||||
# DESCRIPTION
|
||||
#
|
||||
# This macro searches for a C compiler that generates native executables,
|
||||
# that is a C compiler that surely is not a cross-compiler. This can be
|
||||
# useful if you have to generate source code at compile-time like for
|
||||
# example GCC does.
|
||||
#
|
||||
# The macro sets the CC_FOR_BUILD and CPP_FOR_BUILD macros to anything
|
||||
# needed to compile or link (CC_FOR_BUILD) and preprocess (CPP_FOR_BUILD).
|
||||
# The value of these variables can be overridden by the user by specifying
|
||||
# a compiler with an environment variable (like you do for standard CC).
|
||||
#
|
||||
# It also sets BUILD_EXEEXT and BUILD_OBJEXT to the executable and object
|
||||
# file extensions for the build platform, and GCC_FOR_BUILD to `yes' if
|
||||
# the compiler we found is GCC. All these variables but GCC_FOR_BUILD are
|
||||
# substituted in the Makefile.
|
||||
#
|
||||
# LICENSE
|
||||
#
|
||||
# Copyright (c) 2008 Paolo Bonzini <[email protected]>
|
||||
#
|
||||
# Copying and distribution of this file, with or without modification, are
|
||||
# permitted in any medium without royalty provided the copyright notice
|
||||
# and this notice are preserved. This file is offered as-is, without any
|
||||
# warranty.
|
||||
|
||||
#serial 18
|
||||
|
||||
AU_ALIAS([AC_PROG_CC_FOR_BUILD], [AX_PROG_CC_FOR_BUILD])
|
||||
AC_DEFUN([AX_PROG_CC_FOR_BUILD], [dnl
|
||||
AC_REQUIRE([AC_PROG_CC])dnl
|
||||
AC_REQUIRE([AC_PROG_CPP])dnl
|
||||
AC_REQUIRE([AC_CANONICAL_BUILD])dnl
|
||||
|
||||
dnl Use the standard macros, but make them use other variable names
|
||||
dnl
|
||||
pushdef([ac_cv_prog_CPP], ac_cv_build_prog_CPP)dnl
|
||||
pushdef([ac_cv_prog_cc_c89], ac_cv_build_prog_cc_c89)dnl
|
||||
pushdef([ac_cv_prog_gcc], ac_cv_build_prog_gcc)dnl
|
||||
pushdef([ac_cv_prog_cc_works], ac_cv_build_prog_cc_works)dnl
|
||||
pushdef([ac_cv_prog_cc_cross], ac_cv_build_prog_cc_cross)dnl
|
||||
pushdef([ac_cv_prog_cc_g], ac_cv_build_prog_cc_g)dnl
|
||||
pushdef([ac_cv_c_compiler_gnu], ac_cv_build_c_compiler_gnu)dnl
|
||||
pushdef([ac_cv_exeext], ac_cv_build_exeext)dnl
|
||||
pushdef([ac_cv_objext], ac_cv_build_objext)dnl
|
||||
pushdef([ac_exeext], ac_build_exeext)dnl
|
||||
pushdef([ac_objext], ac_build_objext)dnl
|
||||
pushdef([CC], CC_FOR_BUILD)dnl
|
||||
pushdef([CPP], CPP_FOR_BUILD)dnl
|
||||
pushdef([GCC], GCC_FOR_BUILD)dnl
|
||||
pushdef([CFLAGS], CFLAGS_FOR_BUILD)dnl
|
||||
pushdef([CPPFLAGS], CPPFLAGS_FOR_BUILD)dnl
|
||||
pushdef([EXEEXT], BUILD_EXEEXT)dnl
|
||||
pushdef([LDFLAGS], LDFLAGS_FOR_BUILD)dnl
|
||||
pushdef([OBJEXT], BUILD_OBJEXT)dnl
|
||||
pushdef([host], build)dnl
|
||||
pushdef([host_alias], build_alias)dnl
|
||||
pushdef([host_cpu], build_cpu)dnl
|
||||
pushdef([host_vendor], build_vendor)dnl
|
||||
pushdef([host_os], build_os)dnl
|
||||
pushdef([ac_cv_host], ac_cv_build)dnl
|
||||
pushdef([ac_cv_host_alias], ac_cv_build_alias)dnl
|
||||
pushdef([ac_cv_host_cpu], ac_cv_build_cpu)dnl
|
||||
pushdef([ac_cv_host_vendor], ac_cv_build_vendor)dnl
|
||||
pushdef([ac_cv_host_os], ac_cv_build_os)dnl
|
||||
pushdef([ac_tool_prefix], ac_build_tool_prefix)dnl
|
||||
pushdef([am_cv_CC_dependencies_compiler_type], am_cv_build_CC_dependencies_compiler_type)dnl
|
||||
pushdef([am_cv_prog_cc_c_o], am_cv_build_prog_cc_c_o)dnl
|
||||
pushdef([cross_compiling], cross_compiling_build)dnl
|
||||
|
||||
cross_compiling_build=no
|
||||
|
||||
ac_build_tool_prefix=
|
||||
AS_IF([test -n "$build"], [ac_build_tool_prefix="$build-"],
|
||||
[test -n "$build_alias"],[ac_build_tool_prefix="$build_alias-"])
|
||||
|
||||
AC_LANG_PUSH([C])
|
||||
AC_PROG_CC
|
||||
_AC_COMPILER_EXEEXT
|
||||
_AC_COMPILER_OBJEXT
|
||||
AC_PROG_CPP
|
||||
|
||||
dnl Restore the old definitions
|
||||
dnl
|
||||
popdef([cross_compiling])dnl
|
||||
popdef([am_cv_prog_cc_c_o])dnl
|
||||
popdef([am_cv_CC_dependencies_compiler_type])dnl
|
||||
popdef([ac_tool_prefix])dnl
|
||||
popdef([ac_cv_host_os])dnl
|
||||
popdef([ac_cv_host_vendor])dnl
|
||||
popdef([ac_cv_host_cpu])dnl
|
||||
popdef([ac_cv_host_alias])dnl
|
||||
popdef([ac_cv_host])dnl
|
||||
popdef([host_os])dnl
|
||||
popdef([host_vendor])dnl
|
||||
popdef([host_cpu])dnl
|
||||
popdef([host_alias])dnl
|
||||
popdef([host])dnl
|
||||
popdef([OBJEXT])dnl
|
||||
popdef([LDFLAGS])dnl
|
||||
popdef([EXEEXT])dnl
|
||||
popdef([CPPFLAGS])dnl
|
||||
popdef([CFLAGS])dnl
|
||||
popdef([GCC])dnl
|
||||
popdef([CPP])dnl
|
||||
popdef([CC])dnl
|
||||
popdef([ac_objext])dnl
|
||||
popdef([ac_exeext])dnl
|
||||
popdef([ac_cv_objext])dnl
|
||||
popdef([ac_cv_exeext])dnl
|
||||
popdef([ac_cv_c_compiler_gnu])dnl
|
||||
popdef([ac_cv_prog_cc_g])dnl
|
||||
popdef([ac_cv_prog_cc_cross])dnl
|
||||
popdef([ac_cv_prog_cc_works])dnl
|
||||
popdef([ac_cv_prog_cc_c89])dnl
|
||||
popdef([ac_cv_prog_gcc])dnl
|
||||
popdef([ac_cv_prog_CPP])dnl
|
||||
|
||||
dnl restore global variables ac_ext, ac_cpp, ac_compile,
|
||||
dnl ac_link, ac_compiler_gnu (dependant on the current
|
||||
dnl language after popping):
|
||||
AC_LANG_POP([C])
|
||||
|
||||
dnl Finally, set Makefile variables
|
||||
dnl
|
||||
AC_SUBST(BUILD_EXEEXT)dnl
|
||||
AC_SUBST(BUILD_OBJEXT)dnl
|
||||
AC_SUBST([CFLAGS_FOR_BUILD])dnl
|
||||
AC_SUBST([CPPFLAGS_FOR_BUILD])dnl
|
||||
AC_SUBST([LDFLAGS_FOR_BUILD])dnl
|
||||
])
|
||||
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
|
||||
m4_include([m4/_ac_am_config_header_hook.m4])
|
||||
m4_include([m4/_ax_c_underscores_match_if.m4])
|
||||
m4_include([m4/ax_c99_strtod.m4])
|
||||
m4_include([m4/ax_c_picflag.m4])
|
||||
m4_include([m4/ax_c_underscores_leading.m4])
|
||||
m4_include([m4/ax_c_underscores_trailing.m4])
|
||||
m4_include([m4/ax_cxx_compile_stdcxx.m4])
|
||||
m4_include([m4/ax_enable_suffix.m4])
|
||||
m4_include([m4/ax_ld_extralibs.m4])
|
||||
m4_include([m4/ax_ld_rdynamic.m4])
|
||||
m4_include([m4/ax_ld_sharedlib_opts.m4])
|
||||
m4_include([m4/ax_prog_cc_for_build.m4])
|
||||
m4_include([m4/ax_win32.m4])
|
||||
|
||||
@@ -28,11 +28,6 @@ bool NetAssign::is_asynchronous()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetCondit::is_asynchronous()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* NetEvWait statements come from statements of the form @(...) in the
|
||||
* Verilog source. These event waits are considered asynchronous if
|
||||
|
||||
+6
-2
@@ -59,7 +59,11 @@ distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
||||
cppcheck: $(O:.o=.c)
|
||||
cppcheck --enable=all --std=c99 --std=c++11 -f $(INCLUDE_PATH) $^
|
||||
cppcheck --enable=all --std=c99 --std=c++11 -f \
|
||||
--check-level=exhaustive \
|
||||
--suppressions-list=$(srcdir)/../cppcheck-global.sup \
|
||||
--suppressions-list=$(srcdir)/cppcheck.sup \
|
||||
$(INCLUDE_PATH) $^
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
cd ..; ./config.status --file=cadpli/$@
|
||||
@@ -67,7 +71,7 @@ Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
dep:
|
||||
mkdir dep
|
||||
|
||||
%.o: %.c
|
||||
%.o: %.c | dep
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $<
|
||||
mv $*.d dep
|
||||
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2003-2026 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -53,7 +53,7 @@ static void thunker_register(void)
|
||||
strncpy(module, cp, bp-cp);
|
||||
module[bp-cp] = 0;
|
||||
|
||||
mod = ivl_dlopen(module);
|
||||
mod = ivl_dlopen(module, false);
|
||||
if (mod == 0) {
|
||||
vpi_printf("%s link: %s\n", vlog_info.argv[idx], dlerror());
|
||||
free(module);
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
// We use guarded memory allocation routines, but cppcheck is not
|
||||
// noticing this so it is complaining we could return a NULL value.
|
||||
nullPointerOutOfMemory:cadpli.c:53
|
||||
nullPointerOutOfMemory:cadpli.c:54
|
||||
|
||||
// Unused function
|
||||
unusedFunction:ivl_dlfcn.h:87
|
||||
@@ -1,94 +0,0 @@
|
||||
#ifndef IVL_ivl_dlfcn_H
|
||||
#define IVL_ivl_dlfcn_H
|
||||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
# include <windows.h>
|
||||
# include <stdio.h>
|
||||
typedef void * ivl_dll_t;
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
# include <dlfcn.h>
|
||||
typedef void* ivl_dll_t;
|
||||
#elif defined(HAVE_DL_H)
|
||||
# include <dl.h>
|
||||
typedef shl_t ivl_dll_t;
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
static __inline__ ivl_dll_t ivl_dlopen(const char *name)
|
||||
{ return (void *)LoadLibrary(name); }
|
||||
|
||||
static __inline__ void *ivl_dlsym(ivl_dll_t dll, const char *nm)
|
||||
{ return (void *)GetProcAddress((HINSTANCE)dll,nm);}
|
||||
|
||||
static __inline__ void ivl_dlclose(ivl_dll_t dll)
|
||||
{ (void)FreeLibrary((HINSTANCE)dll);}
|
||||
|
||||
static __inline__ const char *dlerror(void)
|
||||
{
|
||||
static char msg[256];
|
||||
unsigned long err = GetLastError();
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
err,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &msg,
|
||||
sizeof(msg) - 1,
|
||||
NULL
|
||||
);
|
||||
return msg;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
static __inline__ ivl_dll_t ivl_dlopen(const char*name)
|
||||
{ return dlopen(name,RTLD_LAZY); }
|
||||
|
||||
static __inline__ void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
{
|
||||
void*sym = dlsym(dll, nm);
|
||||
/* Not found? try without the leading _ */
|
||||
if (sym == 0 && nm[0] == '_')
|
||||
sym = dlsym(dll, nm+1);
|
||||
return sym;
|
||||
}
|
||||
|
||||
static __inline__ void ivl_dlclose(ivl_dll_t dll)
|
||||
{ dlclose(dll); }
|
||||
|
||||
#elif defined(HAVE_DL_H)
|
||||
static __inline__ ivl_dll_t ivl_dlopen(const char*name)
|
||||
{ return shl_load(name, BIND_IMMEDIATE, 0); }
|
||||
|
||||
static __inline__ void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
{
|
||||
void*sym;
|
||||
int rc = shl_findsym(&dll, nm, TYPE_PROCEDURE, &sym);
|
||||
return (rc == 0) ? sym : 0;
|
||||
}
|
||||
|
||||
static __inline__ void ivl_dlclose(ivl_dll_t dll)
|
||||
{ shl_unload(dll); }
|
||||
|
||||
static __inline__ const char*dlerror(void)
|
||||
{ return strerror( errno ); }
|
||||
#endif
|
||||
|
||||
#endif /* IVL_ivl_dlfcn_H */
|
||||
+20
-1
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_compiler_H
|
||||
#define IVL_compiler_H
|
||||
/*
|
||||
* Copyright (c) 1999-2021 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -104,6 +104,9 @@ extern bool warn_sens_entire_arr;
|
||||
/* Warn about level-appropriate anachronisms. */
|
||||
extern bool warn_anachronisms;
|
||||
|
||||
/* Warn about declaration after use (unless flaged as errors). */
|
||||
extern bool warn_decl_after_use;
|
||||
|
||||
/* Warn about nets that are references but not driven. */
|
||||
extern bool warn_floating_nets;
|
||||
|
||||
@@ -162,6 +165,8 @@ enum generation_t {
|
||||
GN_VER2005_SV = 5,
|
||||
GN_VER2009 = 6,
|
||||
GN_VER2012 = 7,
|
||||
GN_VER2017 = 8,
|
||||
GN_VER2023 = 9,
|
||||
GN_DEFAULT = 4
|
||||
};
|
||||
|
||||
@@ -210,6 +215,20 @@ extern bool gn_strict_expr_width_flag;
|
||||
loop. */
|
||||
extern bool gn_shared_loop_index_flag;
|
||||
|
||||
/* If this flag is true (default), then parameters must be declared before
|
||||
use. `-gno-strict[-parameter]-declaration` allows to use parameters before
|
||||
declaration, as prior to version 13.
|
||||
A warning is emited with -Wdeclaration-after-use (default).
|
||||
*/
|
||||
extern bool gn_strict_parameter_declaration;
|
||||
|
||||
/* If this flag is true (default), then nets and variablesmust be declared
|
||||
before use. `-gno-strict[-net-var]-declaration` allows to use nets and
|
||||
variables before declaration, as prior to version 13.
|
||||
A warning is emited with -Wdeclaration-after-use (default).
|
||||
*/
|
||||
extern bool gn_strict_net_var_declaration;
|
||||
|
||||
static inline bool gn_system_verilog(void)
|
||||
{
|
||||
if (generation_flag >= GN_VER2005_SV)
|
||||
|
||||
+16
-8
@@ -1,10 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright 1992-2024 Free Software Foundation, Inc.
|
||||
# Copyright 1992-2026 Free Software Foundation, Inc.
|
||||
|
||||
# shellcheck disable=SC2006,SC2268 # see below for rationale
|
||||
|
||||
timestamp='2024-07-27'
|
||||
timestamp='2026-05-17'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@@ -60,7 +60,7 @@ version="\
|
||||
GNU config.guess ($timestamp)
|
||||
|
||||
Originally written by Per Bothner.
|
||||
Copyright 1992-2024 Free Software Foundation, Inc.
|
||||
Copyright 1992-2026 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -150,7 +150,7 @@ UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
|
||||
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
||||
|
||||
case $UNAME_SYSTEM in
|
||||
Linux|GNU|GNU/*)
|
||||
Ironclad|Linux|GNU|GNU/*)
|
||||
LIBC=unknown
|
||||
|
||||
set_cc_for_build
|
||||
@@ -167,6 +167,8 @@ Linux|GNU|GNU/*)
|
||||
LIBC=gnu
|
||||
#elif defined(__LLVM_LIBC__)
|
||||
LIBC=llvm
|
||||
#elif defined(__mlibc__)
|
||||
LIBC=mlibc
|
||||
#else
|
||||
#include <stdarg.h>
|
||||
/* First heuristic to detect musl libc. */
|
||||
@@ -1186,6 +1188,9 @@ EOF
|
||||
sparc:Linux:*:* | sparc64:Linux:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
||||
;;
|
||||
sw_64:Linux:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
||||
;;
|
||||
tile*:Linux:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-linux-$LIBC
|
||||
;;
|
||||
@@ -1597,8 +1602,11 @@ EOF
|
||||
*:Unleashed:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE
|
||||
;;
|
||||
*:Ironclad:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-ironclad
|
||||
x86_64:[Ii]ronclad:*:*|i?86:[Ii]ronclad:*:*)
|
||||
GUESS=$UNAME_MACHINE-pc-ironclad-$LIBC
|
||||
;;
|
||||
*:[Ii]ronclad:*:*)
|
||||
GUESS=$UNAME_MACHINE-unknown-ironclad-$LIBC
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -1808,8 +1816,8 @@ fi
|
||||
exit 1
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp nil t)
|
||||
# time-stamp-start: "timestamp='"
|
||||
# time-stamp-format: "%:y-%02m-%02d"
|
||||
# time-stamp-format: "%Y-%02m-%02d"
|
||||
# time-stamp-end: "'"
|
||||
# End:
|
||||
|
||||
+20
-9
@@ -1,10 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright 1992-2024 Free Software Foundation, Inc.
|
||||
# Copyright 1992-2026 Free Software Foundation, Inc.
|
||||
|
||||
# shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale
|
||||
|
||||
timestamp='2024-05-27'
|
||||
timestamp='2026-05-17'
|
||||
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@@ -76,7 +76,7 @@ Report bugs and patches to <[email protected]>."
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright 1992-2024 Free Software Foundation, Inc.
|
||||
Copyright 1992-2026 Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
@@ -145,6 +145,7 @@ case $1 in
|
||||
| kfreebsd*-gnu* \
|
||||
| knetbsd*-gnu* \
|
||||
| kopensolaris*-gnu* \
|
||||
| ironclad-* \
|
||||
| linux-* \
|
||||
| managarm-* \
|
||||
| netbsd*-eabi* \
|
||||
@@ -242,7 +243,6 @@ case $1 in
|
||||
| rombug \
|
||||
| semi \
|
||||
| sequent* \
|
||||
| siemens \
|
||||
| sgi* \
|
||||
| siemens \
|
||||
| sim \
|
||||
@@ -261,7 +261,7 @@ case $1 in
|
||||
basic_machine=$field1-$field2
|
||||
basic_os=
|
||||
;;
|
||||
zephyr*)
|
||||
tock* | zephyr*)
|
||||
basic_machine=$field1-unknown
|
||||
basic_os=$field2
|
||||
;;
|
||||
@@ -1194,7 +1194,7 @@ case $cpu-$vendor in
|
||||
xscale-* | xscalee[bl]-*)
|
||||
cpu=`echo "$cpu" | sed 's/^xscale/arm/'`
|
||||
;;
|
||||
arm64-* | aarch64le-*)
|
||||
arm64-* | aarch64le-* | arm64_32-*)
|
||||
cpu=aarch64
|
||||
;;
|
||||
|
||||
@@ -1321,6 +1321,7 @@ case $cpu-$vendor in
|
||||
| i960 \
|
||||
| ia16 \
|
||||
| ia64 \
|
||||
| intelgt \
|
||||
| ip2k \
|
||||
| iq2000 \
|
||||
| javascript \
|
||||
@@ -1431,6 +1432,7 @@ case $cpu-$vendor in
|
||||
| sparcv9v \
|
||||
| spu \
|
||||
| sv1 \
|
||||
| sw_64 \
|
||||
| sx* \
|
||||
| tahoe \
|
||||
| thumbv7* \
|
||||
@@ -1522,6 +1524,10 @@ EOF
|
||||
kernel=nto
|
||||
os=`echo "$basic_os" | sed -e 's|nto|qnx|'`
|
||||
;;
|
||||
ironclad*)
|
||||
kernel=ironclad
|
||||
os=`echo "$basic_os" | sed -e 's|ironclad|gnu|'`
|
||||
;;
|
||||
linux*)
|
||||
kernel=linux
|
||||
os=`echo "$basic_os" | sed -e 's|linux|gnu|'`
|
||||
@@ -1976,6 +1982,7 @@ case $os in
|
||||
| atheos* \
|
||||
| auroraux* \
|
||||
| aux* \
|
||||
| banan_os* \
|
||||
| beos* \
|
||||
| bitrig* \
|
||||
| bme* \
|
||||
@@ -2022,7 +2029,6 @@ case $os in
|
||||
| ios* \
|
||||
| iris* \
|
||||
| irix* \
|
||||
| ironclad* \
|
||||
| isc* \
|
||||
| its* \
|
||||
| l4re* \
|
||||
@@ -2118,6 +2124,7 @@ case $os in
|
||||
| sysv* \
|
||||
| tenex* \
|
||||
| tirtos* \
|
||||
| tock* \
|
||||
| toppers* \
|
||||
| tops10* \
|
||||
| tops20* \
|
||||
@@ -2214,6 +2221,8 @@ case $kernel-$os-$obj in
|
||||
;;
|
||||
uclinux-uclibc*- | uclinux-gnu*- )
|
||||
;;
|
||||
ironclad-gnu*- | ironclad-mlibc*- )
|
||||
;;
|
||||
managarm-mlibc*- | managarm-kernel*- )
|
||||
;;
|
||||
windows*-msvc*-)
|
||||
@@ -2249,6 +2258,8 @@ case $kernel-$os-$obj in
|
||||
;;
|
||||
*-eabi*- | *-gnueabi*-)
|
||||
;;
|
||||
ios*-simulator- | tvos*-simulator- | watchos*-simulator- )
|
||||
;;
|
||||
none--*)
|
||||
# None (no kernel, i.e. freestanding / bare metal),
|
||||
# can be paired with an machine code file format
|
||||
@@ -2347,8 +2358,8 @@ echo "$cpu-$vendor${kernel:+-$kernel}${os:+-$os}${obj:+-$obj}"
|
||||
exit
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp)
|
||||
# eval: (add-hook 'before-save-hook 'time-stamp nil t)
|
||||
# time-stamp-start: "timestamp='"
|
||||
# time-stamp-format: "%:y-%02m-%02d"
|
||||
# time-stamp-format: "%Y-%02m-%02d"
|
||||
# time-stamp-end: "'"
|
||||
# End:
|
||||
|
||||
+124
-6
@@ -1,6 +1,35 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT
|
||||
|
||||
AC_CONFIG_MACRO_DIRS([m4])
|
||||
|
||||
dnl Define project version
|
||||
m4_define([VER_MAJOR], [14])
|
||||
m4_define([VER_MINOR], [0])
|
||||
m4_define([VER_EXTRA], [devel])
|
||||
|
||||
dnl define libvvp ABI version
|
||||
m4_define([LIBVVP_SOVERSION], [1])
|
||||
|
||||
AC_INIT([iverilog], [VER_MAJOR.VER_MINOR (VER_EXTRA)])
|
||||
AC_SUBST([VERSION_MAJOR], [VER_MAJOR])
|
||||
AC_SUBST([VERSION_MINOR], [VER_MINOR])
|
||||
AC_SUBST([VERSION_EXTRA], [" (VER_EXTRA)"])
|
||||
AC_SUBST([VERSION], ["VER_MAJOR.VER_MINOR (VER_EXTRA)"])
|
||||
# used in res.rc
|
||||
AC_SUBST([PRODUCTVERSION], ["VER_MAJOR,VER_MINOR,0,0"])
|
||||
|
||||
# setup libvvp soversion, which depends on abi not package version
|
||||
AC_SUBST([LIBVVP_SOVERSION], [LIBVVP_SOVERSION])
|
||||
# setup libvvp version
|
||||
AC_SUBST([LIBVVP_VERSION], [LIBVVP_SOVERSION.VER_MAJOR.VER_MINOR])
|
||||
|
||||
AC_CONFIG_SRCDIR([netlist.h])
|
||||
# Need a stamp file like the other header files
|
||||
AC_CONFIG_FILES([version_base.h],[
|
||||
_config_header=version_base.h
|
||||
_stamp_name=stamp-`expr //$_config_header : '.*/\([[^./]]*\)\.[[^./]]*$'`-h
|
||||
echo "timestamp for $_config_header" > `AS_DIRNAME(["$_config_header"])`/[]$_stamp_name
|
||||
])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AC_CONFIG_HEADERS([_pli_types.h])
|
||||
AC_CONFIG_HEADERS([vhdlpp/vhdlpp_config.h])
|
||||
@@ -18,15 +47,19 @@ AX_PROG_CC_FOR_BUILD
|
||||
AC_PREREQ([2.62])
|
||||
m4_version_prereq([2.70], [], [AC_PROG_CC_C99])
|
||||
AC_PROG_CXX
|
||||
|
||||
# Require C++11 (avoid newer defaults like C++23 from newer toolchains)
|
||||
AX_CXX_COMPILE_STDCXX(11, noext, mandatory)
|
||||
|
||||
AC_PROG_RANLIB
|
||||
AC_CHECK_TOOL(LD, ld, false)
|
||||
AC_CHECK_TOOL(AR, ar, false)
|
||||
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
|
||||
AC_CHECK_TOOL(STRIP, strip, true)
|
||||
AC_CHECK_TOOL(WINDRES,windres,false)
|
||||
AC_CHECK_PROGS(XGPERF,gperf,none)
|
||||
AC_CHECK_PROGS(MAN,man,none)
|
||||
AC_CHECK_PROGS(PS2PDF,ps2pdf,none)
|
||||
AC_CHECK_PROGS(GROFF,groff,none)
|
||||
AC_CHECK_PROGS(GIT,git,none)
|
||||
if test "$XGPERF" = "none"
|
||||
then
|
||||
@@ -65,6 +98,20 @@ AC_SUBST(EXEEXT)
|
||||
# Combined check for Microsoft-related bogosities; sets WIN32 if found
|
||||
AX_WIN32
|
||||
|
||||
# Detect which directory/file separator to use
|
||||
AC_MSG_CHECKING([for directory/file separator])
|
||||
|
||||
AS_CASE([$host_os:$MSYSTEM],
|
||||
[*mingw*:UCRT64|*mingw*:MINGW64|*mingw*:MINGW32|*mingw*:CLANG64|*mingw*:CLANGARM64], [
|
||||
PATH_SEP=\\\\
|
||||
],
|
||||
[
|
||||
PATH_SEP=/
|
||||
]
|
||||
)
|
||||
AC_MSG_RESULT([$PATH_SEP])
|
||||
AC_SUBST([PATH_SEP])
|
||||
|
||||
# Check to see if we are using the Sun compiler. If so then configure
|
||||
# some of the flags to match the Sun compiler syntax. This is also used
|
||||
# in the aclocal.m4 file to configure the flags used to build and link
|
||||
@@ -104,7 +151,15 @@ AS_IF( [test "x$with_m32" = xyes],
|
||||
[])
|
||||
|
||||
CFLAGS="$CTARGETFLAGS $CFLAGS"
|
||||
CXXFLAGS="$CTARGETFLAGS $CXXFLAGS -std=c++11"
|
||||
# Cygwin does not declare strdup() for C++ 11 by default so use gnu++11
|
||||
# to expose the declaration.
|
||||
decl_cxx_std="-std=c++11"
|
||||
case "${host}" in
|
||||
*-*-cygwin*)
|
||||
decl_cxx_std="-std=gnu++11"
|
||||
;;
|
||||
esac
|
||||
CXXFLAGS="$CTARGETFLAGS $CXXFLAGS $decl_cxx_std"
|
||||
LDFLAGS="$CTARGETFLAGS $LDFLAGS"
|
||||
|
||||
# Check that we are using either the GNU compilers or the Sun compilers
|
||||
@@ -170,13 +225,28 @@ AC_SUBST(HAVE_LIBBZ2)
|
||||
AC_FUNC_ALLOCA
|
||||
AC_FUNC_FSEEKO
|
||||
|
||||
# Package Options
|
||||
# Feature Options
|
||||
# ---------------
|
||||
|
||||
# Build VVP as a library and stub
|
||||
AC_ARG_ENABLE([libvvp],
|
||||
[AS_HELP_STRING([--enable-libvvp], [build VVP as a shared library])],
|
||||
[AC_SUBST(LIBVVP, yes)],[])
|
||||
[enable_libvvp=yes],
|
||||
[enable_libvvp=no])
|
||||
|
||||
AC_SUBST([LIBVVP], [$enable_libvvp])
|
||||
|
||||
AS_IF([test "x$enable_libvvp" = "xyes"],
|
||||
[AC_MSG_NOTICE([Building with libvvp support enabled])],
|
||||
[AC_MSG_NOTICE([Building with libvvp support disabled])])
|
||||
|
||||
AC_ARG_ENABLE([libveriuser],
|
||||
[AS_HELP_STRING([--enable-libveriuser], [include support for PLI 1 (deprecated)])],
|
||||
[AC_SUBST(LIBVERIUSER, yes)],
|
||||
[AC_SUBST(LIBVERIUSER, no)])
|
||||
|
||||
# Package Options
|
||||
# ---------------
|
||||
|
||||
# valgrind checks
|
||||
AC_ARG_WITH([valgrind], [AS_HELP_STRING([--with-valgrind],[Add valgrind hooks])],
|
||||
@@ -253,6 +323,27 @@ case "${host}" in
|
||||
;;
|
||||
esac
|
||||
|
||||
# Setup test environment for running vvp from build directory
|
||||
VVP_BUILDDIR="$(pwd)/vvp"
|
||||
case "$host_os" in
|
||||
linux*)
|
||||
ENV_VVP="LD_LIBRARY_PATH=$VVP_BUILDDIR"
|
||||
;;
|
||||
*bsd*)
|
||||
ENV_VVP="LD_LIBRARY_PATH=$VVP_BUILDDIR"
|
||||
;;
|
||||
darwin*)
|
||||
ENV_VVP="DYLD_LIBRARY_PATH=$VVP_BUILDDIR"
|
||||
;;
|
||||
*)
|
||||
# Since the libvvp DLL is located in the same directory as the
|
||||
# vvp executable, no action is required here
|
||||
ENV_VVP=""
|
||||
;;
|
||||
esac
|
||||
AC_SUBST([ENV_VVP])
|
||||
|
||||
|
||||
# Do some more operating system specific setup. We put the file64_support
|
||||
# define in a substitution instead of simply a define because there
|
||||
# are source files (namely lxt support files) that don't include any
|
||||
@@ -350,5 +441,32 @@ then
|
||||
AC_MSG_ERROR(cannot configure white space in libdir: $libdir)
|
||||
fi
|
||||
AC_MSG_RESULT(ok)
|
||||
AC_CONFIG_FILES([Makefile ivlpp/Makefile vhdlpp/Makefile vvp/Makefile vpi/Makefile driver/Makefile driver-vpi/Makefile cadpli/Makefile libveriuser/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-vvp/Makefile tgt-vhdl/Makefile tgt-fpga/Makefile tgt-verilog/Makefile tgt-pal/Makefile tgt-vlog95/Makefile tgt-pcb/Makefile tgt-blif/Makefile tgt-sizer/Makefile])
|
||||
AC_CONFIG_FILES([
|
||||
Makefile
|
||||
cadpli/Makefile
|
||||
driver-vpi/Makefile
|
||||
driver-vpi/iverilog-vpi.man
|
||||
driver-vpi/res.rc
|
||||
driver/Makefile
|
||||
driver/iverilog.man
|
||||
ivlpp/Makefile
|
||||
ivtest/Makefile
|
||||
libveriuser/Makefile
|
||||
tgt-blif/Makefile
|
||||
tgt-fpga/Makefile
|
||||
tgt-null/Makefile
|
||||
tgt-pal/Makefile
|
||||
tgt-pcb/Makefile
|
||||
tgt-sizer/Makefile
|
||||
tgt-stub/Makefile
|
||||
tgt-verilog/Makefile
|
||||
tgt-vhdl/Makefile
|
||||
tgt-vlog95/Makefile
|
||||
tgt-vvp/Makefile
|
||||
vhdlpp/Makefile
|
||||
vpi/Makefile
|
||||
vvp/Makefile
|
||||
vvp/libvvp.pc
|
||||
vvp/vvp.man
|
||||
])
|
||||
AC_OUTPUT
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
// Skip all messages about missing system include files
|
||||
missingIncludeSystem
|
||||
// Skip the active checker report message
|
||||
checkersReport
|
||||
+148
-3
@@ -1,10 +1,87 @@
|
||||
// Skip the use STL messages
|
||||
useStlAlgorithm
|
||||
|
||||
// Skip all memory issues since they should be handled by ivl_alloc.h
|
||||
ctunullpointerOutOfMemory
|
||||
nullPointerArithmeticOutOfMemory
|
||||
nullPointerOutOfMemory
|
||||
|
||||
// valgrind does not find any issues so cppcheck is wrong
|
||||
ctuuninitvar:parse_misc.cc:61
|
||||
|
||||
// Skip strdup() not constant.
|
||||
constVariablePointer:main.cc:421
|
||||
constVariablePointer:main.cc:425
|
||||
constVariablePointer:main.cc:675
|
||||
|
||||
// const auto should be const
|
||||
constVariablePointer:elab_expr.cc:628
|
||||
constVariablePointer:elab_expr.cc:631
|
||||
constVariablePointer:elab_expr.cc:700
|
||||
|
||||
// The reference cannot be const since it is updated in the calling function.
|
||||
constParameterReference:net_udp.cc:37
|
||||
|
||||
// These cannot be static since they access object data
|
||||
functionStatic:net_link.cc:178
|
||||
functionStatic:net_link.cc:184
|
||||
functionStatic:net_link.cc:189
|
||||
functionStatic:net_link.cc:194
|
||||
|
||||
// This cannot be static when checking with valgrind
|
||||
functionStatic:libmisc/StringHeap.cc
|
||||
|
||||
// Skip not initialized in the constructor for target scope
|
||||
uninitMemberVar:t-dll.cc:41
|
||||
uninitMemberVar:t-dll.cc:109
|
||||
|
||||
// By convention we put statics at the top scope.
|
||||
variableScope:pform.cc:3630
|
||||
|
||||
// These are correct and are used to find the base (zero) pin.
|
||||
thisSubtraction:netlist.h:5244
|
||||
thisSubtraction:netlist.h:5253
|
||||
thisSubtraction:netlist.h:5370
|
||||
thisSubtraction:netlist.h:5379
|
||||
|
||||
// This is used when running a debugger
|
||||
// debugger_release
|
||||
knownConditionTrueFalse:main.cc:921
|
||||
knownConditionTrueFalse:main.cc:955
|
||||
|
||||
// These should be checked, but are not real issues
|
||||
knownConditionTrueFalse:elaborate.cc:8165
|
||||
knownConditionTrueFalse:elab_sig.cc:272
|
||||
knownConditionTrueFalse:elab_sig.cc:345
|
||||
|
||||
// Yes, it's a duplicate
|
||||
duplicateCondition:elaborate.cc:8216
|
||||
|
||||
// To complicated to use std::find_if()
|
||||
useStlAlgorithm:map_named_args.cc:38
|
||||
|
||||
// The condition is always true at least once based on the previous assertion
|
||||
derefInvalidIterator:netmisc.cc:420
|
||||
|
||||
// By convention we put statics at the top scope.
|
||||
variableScope:t-dll.cc:2309
|
||||
|
||||
// We check memory allocation with valgrind
|
||||
unsafeClassCanLeak:libmisc/StringHeap.h:79
|
||||
|
||||
// We only use a StringHeap or a StringHepLex
|
||||
duplInheritedMember:libmisc/StringHeap.h:99
|
||||
duplInheritedMember:libmisc/StringHeap.h:100
|
||||
duplInheritedMember:libmisc/StringHeap.cc:160
|
||||
duplInheritedMember:libmisc/StringHeap.cc:182
|
||||
|
||||
// cppcheck is wrong this is correct usage
|
||||
redundantAssignment:syn-rules.y:230
|
||||
redundantAssignment:syn-rules.y:234
|
||||
redundantAssignment:syn-rules.y:243
|
||||
redundantAssignment:syn-rules.y:271
|
||||
redundantAssignment:syn-rules.y:274
|
||||
redundantAssignment:syn-rules.y:294
|
||||
|
||||
// Cannot define a constructor sine this is in the parser union
|
||||
noConstructor:property_qual.h:22
|
||||
|
||||
// This are just stubs
|
||||
// vpi_control()
|
||||
@@ -636,3 +713,71 @@ unusedFunction:t-dll-api.cc:1007
|
||||
unusedFunction:t-dll-api.cc:1016
|
||||
// ivl_udp_sequ()
|
||||
unusedFunction:t-dll-api.cc:980
|
||||
|
||||
// Unused routines
|
||||
// has_compat_attributes()
|
||||
unusedFunction:Attrib.cc:72
|
||||
// bl_type()
|
||||
unusedFunction:Statement.h:194
|
||||
// chain_args()
|
||||
unusedFunction:Statement.h:369
|
||||
// gn_modules_nest()
|
||||
unusedFunction:compiler.h:247
|
||||
// driven_mask()
|
||||
unusedFunction:link_const.cc:275
|
||||
// find_root_scope()
|
||||
unusedFunction:net_design.cc:121
|
||||
// assign_lval()
|
||||
unusedFunction:net_link.cc:283
|
||||
// intersect()
|
||||
unusedFunction:net_link.cc:687
|
||||
// get_def_fileline()
|
||||
unusedFunction:net_scope.cc:200
|
||||
// get_module_port_info()
|
||||
unusedFunction:net_scope.cc:631
|
||||
// find_link_signal()
|
||||
unusedFunction:netlist.cc:113
|
||||
// find_link()
|
||||
unusedFunction:netlist.cc:304
|
||||
// set_module_port_index()
|
||||
unusedFunction:netlist.cc:658
|
||||
// width_a()
|
||||
unusedFunction:netlist.cc:1685
|
||||
// width_b()
|
||||
unusedFunction:netlist.cc:1690
|
||||
// result_sig()
|
||||
unusedFunction:netlist.cc:2191
|
||||
// soft_union()
|
||||
unusedFunction:netstruct.h:93
|
||||
// test_protected()
|
||||
unusedFunction:property_qual.h:50
|
||||
// test_rand()
|
||||
unusedFunction:property_qual.h:52
|
||||
// test_randc()
|
||||
unusedFunction:property_qual.h:53
|
||||
// sub_off_from_expr_()
|
||||
unusedFunction:t-dll-expr.cc:55
|
||||
// mul_expr_by_const_()
|
||||
unusedFunction:t-dll-expr.cc:91
|
||||
// net_assign()
|
||||
unusedFunction:t-dll.cc:2300
|
||||
// is_before()
|
||||
unusedFunction:verinum.cc:588
|
||||
|
||||
// Errors/limitations in the generated yacc and lex files
|
||||
constVariablePointer:<stdout>
|
||||
cstyleCast:<stdout>
|
||||
duplicateBreak:<stdout>
|
||||
nullPointer:<stdout>
|
||||
redundantInitialization:<stdout>
|
||||
syntaxError:<stdout>
|
||||
unusedFunction:<stdout>
|
||||
duplicateBreak:lexor.lex
|
||||
allocaCalled:parse.cc
|
||||
constParameterPointer:parse.cc
|
||||
constVariablePointer:parse.cc
|
||||
knownConditionTrueFalse:parse.cc
|
||||
allocaCalled:syn-rules.cc
|
||||
constParameterPointer:syn-rules.cc
|
||||
knownConditionTrueFalse:syn-rules.cc
|
||||
constVariablePointer:syn-rules.cc
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2024 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -41,16 +41,16 @@ struct cprop_functor : public functor_t {
|
||||
|
||||
unsigned count;
|
||||
|
||||
virtual void signal(Design*des, NetNet*obj);
|
||||
virtual void lpm_add_sub(Design*des, NetAddSub*obj);
|
||||
virtual void lpm_compare(Design*des, const NetCompare*obj);
|
||||
virtual void lpm_concat(Design*des, NetConcat*obj);
|
||||
virtual void lpm_ff(Design*des, NetFF*obj);
|
||||
virtual void lpm_logic(Design*des, NetLogic*obj);
|
||||
virtual void lpm_mux(Design*des, NetMux*obj);
|
||||
virtual void lpm_part_select(Design*des, NetPartSelect*obj);
|
||||
virtual void signal(Design*des, NetNet*obj) override;
|
||||
virtual void lpm_add_sub(Design*des, NetAddSub*obj) override;
|
||||
virtual void lpm_compare(Design*des, const NetCompare*obj) override;
|
||||
virtual void lpm_concat(Design*des, NetConcat*obj) override;
|
||||
virtual void lpm_ff(Design*des, NetFF*obj) override;
|
||||
virtual void lpm_logic(Design*des, NetLogic*obj) override;
|
||||
virtual void lpm_mux(Design*des, NetMux*obj) override;
|
||||
virtual void lpm_part_select(Design*des, NetPartSelect*obj) override;
|
||||
|
||||
void lpm_compare_eq_(Design*des, const NetCompare*obj);
|
||||
static void lpm_compare_eq_(Design*des, const NetCompare*obj);
|
||||
};
|
||||
|
||||
void cprop_functor::signal(Design*, NetNet*)
|
||||
@@ -90,7 +90,7 @@ void cprop_functor::lpm_concat(Design*des, NetConcat*obj)
|
||||
unsigned off = 0;
|
||||
|
||||
for (unsigned idx = 1 ; idx < obj->pin_count() ; idx += 1) {
|
||||
Nexus*nex = obj->pin(idx).nexus();
|
||||
const Nexus*nex = obj->pin(idx).nexus();
|
||||
// If there are non-constant drivers, then give up.
|
||||
if (! nex->drivers_constant())
|
||||
return;
|
||||
@@ -156,7 +156,7 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
||||
if (obj->sel_width() != 1)
|
||||
return;
|
||||
|
||||
Nexus*sel_nex = obj->pin_Sel().nexus();
|
||||
const Nexus*sel_nex = obj->pin_Sel().nexus();
|
||||
|
||||
/* If the select input is constant, then replace with a BUFZ */
|
||||
|
||||
@@ -180,9 +180,7 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
||||
<< "Replace binary MUX with constant select=" << sel_val
|
||||
<< " with a BUFZ to the selected input." << endl;
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
tmp->delay_times(obj->delay_times());
|
||||
|
||||
connect(tmp->pin(0), obj->pin_Result());
|
||||
if (sel_val == verinum::V1)
|
||||
@@ -194,7 +192,7 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
||||
count += 1;
|
||||
}
|
||||
|
||||
static bool compare_base(NetPartSelect*a, NetPartSelect*b)
|
||||
static bool compare_base(const NetPartSelect*a, const NetPartSelect*b)
|
||||
{
|
||||
return a->base() < b->base();
|
||||
}
|
||||
@@ -226,7 +224,7 @@ void cprop_functor::lpm_part_select(Design*des, NetPartSelect*obj)
|
||||
NetPins*tmp_obj = cur->get_obj();
|
||||
|
||||
// Record if we are driving a 2-state net.
|
||||
NetNet*net_obj = dynamic_cast<NetNet*> (tmp_obj);
|
||||
const NetNet*net_obj = dynamic_cast<NetNet*> (tmp_obj);
|
||||
if (net_obj && (net_obj->data_type() == IVL_VT_BOOL))
|
||||
output_2_state = true;
|
||||
|
||||
@@ -355,7 +353,7 @@ void cprop_functor::lpm_part_select(Design*des, NetPartSelect*obj)
|
||||
*/
|
||||
struct cprop_dc_functor : public functor_t {
|
||||
|
||||
virtual void lpm_const(Design*des, NetConst*obj);
|
||||
virtual void lpm_const(Design*des, NetConst*obj) override;
|
||||
};
|
||||
|
||||
struct nexus_info_s {
|
||||
|
||||
+48
-61
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2026 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -90,6 +90,30 @@ ostream& operator << (ostream&o, ivl_drive_t str)
|
||||
return o;
|
||||
}
|
||||
|
||||
ostream &operator << (ostream &o, const drive_strength_t &strength)
|
||||
{
|
||||
o << strength.drive0 << "0 " << strength.drive1 << "1";
|
||||
return o;
|
||||
}
|
||||
|
||||
static void dump_delay_expr(ostream &o, const NetExpr *expr)
|
||||
{
|
||||
if (expr)
|
||||
o << *expr;
|
||||
else
|
||||
o << "0";
|
||||
}
|
||||
|
||||
ostream &operator << (ostream &o, const delay_exprs_t &delays)
|
||||
{
|
||||
dump_delay_expr(o, delays.rise);
|
||||
o << ",";
|
||||
dump_delay_expr(o, delays.fall);
|
||||
o << ",";
|
||||
dump_delay_expr(o, delays.decay);
|
||||
return o;
|
||||
}
|
||||
|
||||
ostream& operator << (ostream&o, ivl_variable_type_t val)
|
||||
{
|
||||
switch (val) {
|
||||
@@ -454,8 +478,7 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
||||
o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
|
||||
if (scope())
|
||||
o << " scope=" << scope_path(scope());
|
||||
o << " #(" << rise_time() << "," << fall_time() << ","
|
||||
<< decay_time() << ") vector_width=" << vector_width()
|
||||
o << " #(" << delay_times() << ") vector_width=" << vector_width()
|
||||
<< " pin_count=" << pin_count();
|
||||
if (pins_are_virtual()) {
|
||||
o << " pins_are_virtual" << endl;
|
||||
@@ -486,8 +509,7 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
||||
void NetNode::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "node: ";
|
||||
o << typeid(*this).name() << " #(" << rise_time()
|
||||
<< "," << fall_time() << "," << decay_time() << ") " << name()
|
||||
o << typeid(*this).name() << " #(" << delay_times() << ") " << name()
|
||||
<< endl;
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
@@ -518,8 +540,7 @@ void NetPins::dump_node_pins(ostream&o, unsigned ind, const char**pin_names) con
|
||||
break;
|
||||
}
|
||||
|
||||
o << " (" << pin(idx).drive0() << "0 "
|
||||
<< pin(idx).drive1() << "1): ";
|
||||
o << " (" << pin(idx).drive() << "): ";
|
||||
|
||||
if (pin(idx).is_linked()) {
|
||||
const Nexus*nex = pin(idx).nexus();
|
||||
@@ -622,11 +643,7 @@ void NetConcat::dump_node(ostream&o, unsigned ind) const
|
||||
o << setw(ind) << "" << "NetConcat: ";
|
||||
o << name();
|
||||
|
||||
if (rise_time())
|
||||
o << " #(" << *rise_time()
|
||||
<< "," << *fall_time() << "," << *decay_time() << ")";
|
||||
else
|
||||
o << " #(0,0,0)";
|
||||
o << " #(" << delay_times() << ")";
|
||||
o << " scope=" << scope_path(scope())
|
||||
<< " width=" << width_ << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
@@ -651,14 +668,7 @@ void NetPow::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "LPM_POW (NetPow): " << name()
|
||||
<< " scope=" << scope_path(scope())
|
||||
<< " delay=(";
|
||||
if (rise_time())
|
||||
o << *rise_time() << "," << *fall_time() << ","
|
||||
<< *decay_time();
|
||||
else
|
||||
o << "0,0,0";
|
||||
|
||||
o << ")" << endl;
|
||||
<< " delay=(" << delay_times() << ")" << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
@@ -676,8 +686,7 @@ void NetBUFZ::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "NetBUFZ: " << name()
|
||||
<< " scope=" << scope_path(scope())
|
||||
<< " delay=(" << rise_time() << "," << fall_time() << "," <<
|
||||
decay_time() << ") width=" << width()
|
||||
<< " delay=(" << delay_times() << ") width=" << width()
|
||||
<< (transparent()? " " : " non-") << "transparent" << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
}
|
||||
@@ -693,10 +702,8 @@ void NetConst::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "constant " << value_;
|
||||
o << ": " << name();
|
||||
if (rise_time())
|
||||
o << " #(" << *rise_time()
|
||||
<< "," << *fall_time()
|
||||
<< "," << *decay_time() << ")";
|
||||
if (delay_times().has_delay())
|
||||
o << " #(" << delay_times() << ")";
|
||||
else
|
||||
o << " #(.,.,.)";
|
||||
o << endl;
|
||||
@@ -729,10 +736,8 @@ void NetLiteral::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "constant real " << real_
|
||||
<< ": " << name();
|
||||
if (rise_time())
|
||||
o << " #(" << *rise_time()
|
||||
<< "," << *fall_time()
|
||||
<< "," << *decay_time() << ")";
|
||||
if (delay_times().has_delay())
|
||||
o << " #(" << delay_times() << ")";
|
||||
else
|
||||
o << " #(.,.,.)";
|
||||
o << endl;
|
||||
@@ -810,8 +815,7 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
|
||||
o << "xor";
|
||||
break;
|
||||
}
|
||||
o << " #(" << rise_time()
|
||||
<< "," << fall_time() << "," << decay_time() << ") " << name()
|
||||
o << " #(" << delay_times() << ") " << name()
|
||||
<< " scope=" << scope_path(scope())
|
||||
<< endl;
|
||||
|
||||
@@ -839,10 +843,8 @@ void NetPartSelect::dump_node(ostream&o, unsigned ind) const
|
||||
}
|
||||
o << setw(ind) << "" << "NetPartSelect(" << pt << "): "
|
||||
<< name();
|
||||
if (rise_time())
|
||||
o << " #(" << *rise_time()
|
||||
<< "," << *fall_time()
|
||||
<< "," << *decay_time() << ")";
|
||||
if (delay_times().has_delay())
|
||||
o << " #(" << delay_times() << ")";
|
||||
else
|
||||
o << " #(.,.,.)";
|
||||
o << " off=" << off_ << " wid=" << wid_ <<endl;
|
||||
@@ -854,10 +856,8 @@ void NetSubstitute::dump_node(ostream&fd, unsigned ind) const
|
||||
{
|
||||
fd << setw(ind) << "" << "NetSubstitute: "
|
||||
<< name();
|
||||
if (rise_time())
|
||||
fd << " #(" << *rise_time()
|
||||
<< "," << *fall_time()
|
||||
<< "," << *decay_time() << ")";
|
||||
if (delay_times().has_delay())
|
||||
fd << " #(" << delay_times() << ")";
|
||||
else
|
||||
fd << " #(.,.,.)";
|
||||
fd << " width=" << wid_ << " base=" << off_ <<endl;
|
||||
@@ -877,10 +877,8 @@ void NetReplicate::dump_node(ostream&o, unsigned ind) const
|
||||
void NetSignExtend::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "NetSignExtend: " << name();
|
||||
if (rise_time())
|
||||
o << " #(" << *rise_time()
|
||||
<< "," << *fall_time()
|
||||
<< "," << *decay_time() << ")";
|
||||
if (delay_times().has_delay())
|
||||
o << " #(" << delay_times() << ")";
|
||||
else
|
||||
o << " #(.,.,.)";
|
||||
o << " output width=" << width_ << endl;
|
||||
@@ -914,8 +912,7 @@ void NetUReduce::dump_node(ostream&o, unsigned ind) const
|
||||
o << "xnor";
|
||||
break;
|
||||
}
|
||||
o << " #(" << rise_time()
|
||||
<< "," << fall_time() << "," << decay_time() << ") " << name()
|
||||
o << " #(" << delay_times() << ") " << name()
|
||||
<< " scope=" << scope_path(scope())
|
||||
<< endl;
|
||||
|
||||
@@ -935,10 +932,8 @@ void NetUserFunc::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "USER FUNC: "
|
||||
<< scope_path(def_);
|
||||
if (rise_time())
|
||||
o << " #(" <<*rise_time()
|
||||
<<","<<*fall_time()
|
||||
<< "," <<*decay_time() << ")";
|
||||
if (delay_times().has_delay())
|
||||
o << " #(" << delay_times() << ")";
|
||||
o << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
@@ -986,14 +981,7 @@ void NetTran::dump_node(ostream&o, unsigned ind) const
|
||||
<< " part=" << part_width()
|
||||
<< " offset=" << part_offset();
|
||||
}
|
||||
o << " delay=(";
|
||||
if (rise_time())
|
||||
o << *rise_time() << "," << *fall_time() << ","
|
||||
<< *decay_time();
|
||||
else
|
||||
o << "0,0,0";
|
||||
|
||||
o << ")" << endl;
|
||||
o << " delay=(" << delay_times() << ")" << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
@@ -1001,8 +989,7 @@ void NetTran::dump_node(ostream&o, unsigned ind) const
|
||||
void NetUDP::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "UDP (" << udp_name() << "): ";
|
||||
o << " #(" << rise_time() << "," << fall_time() << "," << decay_time() <<
|
||||
") " << name() << endl;
|
||||
o << " #(" << delay_times() << ") " << name() << endl;
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
@@ -1151,7 +1138,7 @@ void NetAssignNB::dump(ostream&o, unsigned ind) const
|
||||
if (rval())
|
||||
o << *rval() << ";" << endl;
|
||||
else
|
||||
o << "rval elaboration error>;" << endl;
|
||||
o << "<rval elaboration error>;" << endl;
|
||||
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_discipline_H
|
||||
#define IVL_discipline_H
|
||||
/*
|
||||
* Copyright (c) 2008-2021 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2008-2025 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -36,7 +36,7 @@ extern std::ostream& operator << (std::ostream&, ivl_dis_domain_t);
|
||||
class ivl_nature_s : public LineInfo {
|
||||
public:
|
||||
explicit ivl_nature_s(perm_string name, perm_string access);
|
||||
~ivl_nature_s();
|
||||
~ivl_nature_s() override;
|
||||
|
||||
perm_string name() const { return name_; }
|
||||
// Identifier for the access function for this nature
|
||||
@@ -51,12 +51,12 @@ class ivl_discipline_s : public LineInfo {
|
||||
public:
|
||||
explicit ivl_discipline_s (perm_string name, ivl_dis_domain_t dom,
|
||||
ivl_nature_t pot, ivl_nature_t flow);
|
||||
~ivl_discipline_s();
|
||||
~ivl_discipline_s() override;
|
||||
|
||||
perm_string name() const { return name_; }
|
||||
ivl_dis_domain_t domain() const { return domain_; }
|
||||
ivl_nature_t potential() const { return potential_; }
|
||||
ivl_nature_t flow() const { return flow_; }
|
||||
perm_string name() const { return name_; }
|
||||
ivl_dis_domain_t domain() const { return domain_; }
|
||||
ivl_nature_t potential() const { return potential_; }
|
||||
ivl_nature_t flow() const { return flow_; }
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2009 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2025 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
# include <stdio.h>
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
int main(int argc, const char*argv[])
|
||||
{
|
||||
FILE*ifile;
|
||||
FILE*ofile;
|
||||
|
||||
+95
-11
@@ -31,7 +31,11 @@ suffix = @install_suffix@
|
||||
bindir = $(exec_prefix)/bin
|
||||
libdir = $(exec_prefix)/lib
|
||||
includedir = $(prefix)/include
|
||||
mandir = @mandir@
|
||||
# This is actually the directory where we install our own header files.
|
||||
# It is a little different from the generic includedir.
|
||||
ivl_includedir = @includedir@/iverilog$(suffix)
|
||||
man1dir = @mandir@/man1
|
||||
docdir = @docdir@
|
||||
|
||||
dllib=@DLLIB@
|
||||
|
||||
@@ -39,8 +43,11 @@ CC = @CC@
|
||||
HOSTCC := @CC@
|
||||
WINDRES = @WINDRES@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
MAN = @MAN@
|
||||
PS2PDF = @PS2PDF@
|
||||
|
||||
ifeq (@srcdir@,.)
|
||||
INCLUDE_PATH = -I. -I..
|
||||
@@ -48,31 +55,68 @@ else
|
||||
INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
|
||||
endif
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@
|
||||
CPPFLAGS = @DEFS@ $(INCLUDE_PATH) @CPPFLAGS@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
PICFLAGS = @PICFLAG@
|
||||
LDFLAGS = @rdynamic@ @LDFLAGS@
|
||||
|
||||
O = main.o res.o
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
all: iverilog-vpi@EXEEXT@
|
||||
else
|
||||
all: iverilog-vpi
|
||||
endif
|
||||
|
||||
INSTALL_DOC =
|
||||
ifneq ($(MAN),none)
|
||||
INSTALL_DOC += installman
|
||||
ifneq ($(PS2PDF),none)
|
||||
ifeq (@MINGW32@,yes)
|
||||
INSTALL_DOC += installpdf
|
||||
all: iverilog-vpi.pdf
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
check: all
|
||||
|
||||
clean:
|
||||
rm -f *.o config.h iverilog-vpi@EXEEXT@ res.rc
|
||||
rm -f *.o config.h iverilog-vpi@EXEEXT@ iverilog-vpi \
|
||||
iverilog-vpi.man iverilog-vpi.ps iverilog-vpi.pdf res.rc
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
||||
cppcheck: main.c
|
||||
cppcheck --enable=all --std=c99 --std=c++11 -f $(INCLUDE_PATH) $^
|
||||
cppcheck: main.c config.h
|
||||
cppcheck --enable=all --std=c99 --std=c++11 -f \
|
||||
--check-level=exhaustive \
|
||||
--suppressions-list=$(srcdir)/../cppcheck-global.sup \
|
||||
--suppressions-list=$(srcdir)/cppcheck.sup \
|
||||
$(INCLUDE_PATH) $^
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
cd ..; ./config.status --file=driver-vpi/$@
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
iverilog-vpi@EXEEXT@: $O
|
||||
$(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@
|
||||
endif
|
||||
ifeq (@MINGW32@,no)
|
||||
iverilog-vpi: $(srcdir)/iverilog-vpi.sh ../config.status
|
||||
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
|
||||
-e 's;@ENABLE_PLI1@;@LIBVERIUSER@;' \
|
||||
-e 's;@SUFFIX@;$(suffix);' \
|
||||
-e 's;@IVCC@;$(CC);' \
|
||||
-e 's;@IVCXX@;@CXX@;' \
|
||||
-e 's;@IVCFLAGS@;$(CFLAGS);' \
|
||||
-e 's;@IVCXXFLAGS@;$(CXXFLAGS);' \
|
||||
-e 's;@IVCTARGETFLAGS@;@CTARGETFLAGS@;' \
|
||||
-e 's;@INCLUDEDIR@;$(ivl_includedir);' \
|
||||
-e 's;@LIBDIR@;@libdir@;' $< > $@
|
||||
chmod +x $@
|
||||
endif
|
||||
|
||||
main.o: $(srcdir)/main.c config.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
|
||||
@@ -84,22 +128,46 @@ config.h: $(srcdir)/config.h.in Makefile
|
||||
-e 's;@IVLCFLAGS@;$(CFLAGS);' \
|
||||
-e 's;@IVLCXXFLAGS@;$(CXXFLAGS);' \
|
||||
-e 's;@SHARED@;@shared@;' $< > $@
|
||||
ifeq (@LIBVERIUSER@,yes)
|
||||
sed -i 's;@VPILIBS@;-lveriuser$(suffix) -lvpi$(suffix);' $@
|
||||
else
|
||||
sed -i 's;@VPILIBS@;-lvpi$(suffix);' $@
|
||||
endif
|
||||
|
||||
# Windows specific...
|
||||
res.rc: $(srcdir)/res.rc.in ../version.exe
|
||||
sed -e 's;@PRODUCTVERSION@;'`../version.exe '%M,%n,0,0'`';' \
|
||||
$(srcdir)/res.rc.in > $@
|
||||
res.rc: $(srcdir)/res.rc.in ../config.status
|
||||
cd ..; ./config.status --file=driver-vpi/$@
|
||||
|
||||
res.o: res.rc
|
||||
$(WINDRES) -i res.rc -o res.o
|
||||
#
|
||||
|
||||
iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in ../config.status
|
||||
cd ..; ./config.status --file=driver-vpi/$@
|
||||
|
||||
iverilog-vpi.ps: iverilog-vpi.man
|
||||
$(MAN) -t ./$< > $@
|
||||
|
||||
iverilog-vpi.pdf: iverilog-vpi.ps
|
||||
$(PS2PDF) $< $@
|
||||
|
||||
install: all installdirs installfiles
|
||||
|
||||
F = ./iverilog-vpi@EXEEXT@
|
||||
F = $(INSTALL_DOC)
|
||||
ifeq (@MINGW32@,yes)
|
||||
F += ./iverilog-vpi@EXEEXT@
|
||||
endif
|
||||
ifeq (@MINGW32@,no)
|
||||
F += ./iverilog-vpi
|
||||
endif
|
||||
|
||||
installfiles: $(F) | installdirs
|
||||
ifeq (@MINGW32@,yes)
|
||||
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)@EXEEXT@"
|
||||
endif
|
||||
ifeq (@MINGW32@,no)
|
||||
$(INSTALL_SCRIPT) ./iverilog-vpi "$(DESTDIR)$(bindir)/iverilog-vpi$(suffix)"
|
||||
endif
|
||||
ifeq (@WIN32@,yes)
|
||||
ifneq ($(HOSTCC),$(CC))
|
||||
$(INSTALL_PROGRAM) $(shell $(HOSTCC) --print-file-name=libwinpthread-1.dll) "$(DESTDIR)$(bindir)"
|
||||
@@ -108,8 +176,24 @@ ifneq ($(HOSTCC),$(CC))
|
||||
endif
|
||||
endif
|
||||
|
||||
installman: iverilog-vpi.man installdirs
|
||||
$(INSTALL_DATA) iverilog-vpi.man "$(DESTDIR)$(man1dir)/iverilog-vpi$(suffix).1"
|
||||
|
||||
installpdf: iverilog-vpi.pdf installdirs
|
||||
$(INSTALL_DATA) iverilog-vpi.pdf "$(DESTDIR)$(docdir)/iverilog-vpi$(suffix).pdf"
|
||||
|
||||
installdirs: $(srcdir)/../mkinstalldirs
|
||||
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)"
|
||||
$(srcdir)/../mkinstalldirs \
|
||||
"$(DESTDIR)$(bindir)" \
|
||||
"$(DESTDIR)$(docdir)" \
|
||||
"$(DESTDIR)$(man1dir)"
|
||||
|
||||
uninstall:
|
||||
ifeq (@MINGW32@,yes)
|
||||
rm -f $(DESTDIR)$(bindir)/iverilog-vpi$(suffix)@EXEEXT@
|
||||
endif
|
||||
ifeq (@MINGW32@,no)
|
||||
rm -f $(DESTDIR)$(bindir)/iverilog-vpi$(suffix)
|
||||
endif
|
||||
rm -f "$(DESTDIR)$(man1dir)/iverilog-vpi$(suffix).1" \
|
||||
"$(DESTDIR)$(docdir)/iverilog-vpi$(suffix).pdf"
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
#define IVERILOG_VPI_CFLAGS " @IVLCFLAGS@"
|
||||
#define IVERILOG_VPI_CXXFLAGS " @IVLCXXFLAGS@"
|
||||
#define IVERILOG_VPI_LDFLAGS "@SHARED@"
|
||||
#define IVERILOG_VPI_LDLIBS "-lveriuser@SUFFIX@ -lvpi@SUFFIX@"
|
||||
#define IVERILOG_VPI_LDLIBS "@VPILIBS@"
|
||||
#define IVERILOG_SUFFIX "@SUFFIX@"
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
// ptr is from strrchr() so the result does change
|
||||
redundantAssignment:main.c:525
|
||||
knownConditionTrueFalse:main.c:526
|
||||
@@ -1,4 +1,4 @@
|
||||
.TH iverilog-vpi 1 "Jan 20th, 2024" "" "Version %M.%n%E"
|
||||
.TH iverilog-vpi 1 "Jan 13th, 2026" "" "Version @VERSION@"
|
||||
.SH NAME
|
||||
iverilog-vpi - Compile front end for VPI modules
|
||||
|
||||
@@ -120,7 +120,7 @@ iverilog(1), vvp(1),
|
||||
|
||||
.SH COPYRIGHT
|
||||
.nf
|
||||
Copyright \(co 2002\-2024 Stephen Williams
|
||||
Copyright \(co 2002\-2026 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
@@ -1,5 +1,7 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright (c) 1998-2026 Stephen Williams ([email protected])
|
||||
#
|
||||
# This source code is free software; you can redistribute it
|
||||
# and/or modify it in source code form under the terms of the GNU
|
||||
# Library General Public License as published by the Free Software
|
||||
@@ -29,7 +31,11 @@ SUFFIX=@SUFFIX@
|
||||
# These are used for linking...
|
||||
LD=$CC
|
||||
LDFLAGS="@IVCTARGETFLAGS@ @SHARED@ -L@LIBDIR@"
|
||||
LDLIBS="-lveriuser$SUFFIX -lvpi$SUFFIX"
|
||||
if [ x@ENABLE_PLI1@ = xyes ] ; then
|
||||
LDLIBS="-lveriuser$SUFFIX -lvpi$SUFFIX"
|
||||
else
|
||||
LDLIBS="-lvpi$SUFFIX"
|
||||
fi
|
||||
|
||||
CCSRC=
|
||||
CXSRC=
|
||||
+10
-9
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2015-2022 Martin Whitaker
|
||||
* Copyright (c) 2015-2026 Martin Whitaker
|
||||
* Copyright (c) 2002 Gus Baldauf (gus@picturel.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -34,7 +34,7 @@
|
||||
#include <windows.h>
|
||||
|
||||
static void setup_ivl_environment(void);
|
||||
static void assign(char **ptr, char *str);
|
||||
static void assign(char **ptr, const char *str);
|
||||
|
||||
/* The compile options: compiler, flags, etc. are in here */
|
||||
#include "config.h"
|
||||
@@ -164,7 +164,7 @@ static int startsWith (char *prefix, char *str)
|
||||
/* append "app" to "ptr", allocating memory as needed */
|
||||
/* if count is zero, then copy all characters of "app" */
|
||||
|
||||
static void appendn (char **ptr, char *app, size_t count)
|
||||
static void appendn (char **ptr, const char *app, size_t count)
|
||||
{
|
||||
char *nptr = (char *) realloc(*ptr, strlen(*ptr) +
|
||||
(count ? count : strlen(app)) + 1);
|
||||
@@ -184,7 +184,7 @@ static void appendn (char **ptr, char *app, size_t count)
|
||||
|
||||
/* append "app" to "ptr", allocating memory as needed */
|
||||
|
||||
static void append (char **ptr, char *app)
|
||||
static void append (char **ptr, const char *app)
|
||||
{
|
||||
appendn(ptr, app, 0);
|
||||
}
|
||||
@@ -200,7 +200,7 @@ static void appendBackSlash(char **str)
|
||||
/* copy count characters of "str" to "ptr", allocating memory as needed */
|
||||
/* if count is zero, then copy all characters of "str" */
|
||||
|
||||
static void assignn (char **ptr, char *str, size_t count)
|
||||
static void assignn (char **ptr, const char *str, size_t count)
|
||||
{
|
||||
char *nptr = (char *) realloc(*ptr, (count ? count : strlen(str)) + 1);
|
||||
|
||||
@@ -221,7 +221,7 @@ static void assignn (char **ptr, char *str, size_t count)
|
||||
|
||||
/* copy count characters of "str" to "ptr", allocating memory as needed */
|
||||
|
||||
static void assign (char **ptr, char *str)
|
||||
static void assign (char **ptr, const char *str)
|
||||
{
|
||||
assignn(ptr, str, 0);
|
||||
}
|
||||
@@ -428,7 +428,7 @@ static int parse(int argc, char *argv[])
|
||||
|
||||
/* do minimal check that the MinGW root directory looks valid */
|
||||
|
||||
static void checkMingwDir(char *root)
|
||||
static void checkMingwDir(const char *root)
|
||||
{
|
||||
int irv;
|
||||
struct _stat stat_buf;
|
||||
@@ -551,9 +551,10 @@ static void setup_ivl_environment(void)
|
||||
|
||||
/* compile source modules */
|
||||
|
||||
static void compile(char *pSource, char *pFlags, char **pObject, int *compile_errors, char *compiler)
|
||||
static void compile(const char *pSource, const char *pFlags, char **pObject,
|
||||
int *compile_errors, const char *compiler)
|
||||
{
|
||||
char *ptr1 = pSource;
|
||||
const char *ptr1 = pSource;
|
||||
char *ptr2 = strchr(ptr1, ' ');
|
||||
char *buf=0, *src=0, *obj=0;
|
||||
|
||||
|
||||
+44
-35
@@ -17,20 +17,26 @@
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
EXEEXT = @EXEEXT@
|
||||
ENV_VVP=@ENV_VVP@
|
||||
PATH_SEP=@PATH_SEP@
|
||||
|
||||
suffix = @install_suffix@
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
srcdir = @srcdir@
|
||||
datarootdir = @datarootdir@
|
||||
builddir=@builddir@
|
||||
top_builddir=@top_builddir@
|
||||
|
||||
VPATH = $(srcdir)
|
||||
|
||||
bindir = $(exec_prefix)/bin
|
||||
libdir = $(exec_prefix)/lib
|
||||
includedir = $(prefix)/include
|
||||
mandir = @mandir@
|
||||
pdfdir = @docdir@
|
||||
man1dir = @mandir@/man1
|
||||
docdir = @docdir@
|
||||
|
||||
dllib=@DLLIB@
|
||||
|
||||
@@ -58,22 +64,34 @@ O = main.o substit.o cflexor.o cfparse.o
|
||||
all: dep iverilog@EXEEXT@ iverilog.man
|
||||
|
||||
check: all
|
||||
@echo "driver/iverilog: create a vvp file and then run it."
|
||||
@rm -f top.vvp
|
||||
@$(builddir)/iverilog@EXEEXT@ \
|
||||
-B$(top_builddir)$(PATH_SEP)tgt-vvp \
|
||||
-BI$(top_builddir) \
|
||||
-BM$(top_builddir)$(PATH_SEP)vpi \
|
||||
-BP$(top_builddir)$(PATH_SEP)ivlpp \
|
||||
-Bt$(top_builddir)$(PATH_SEP)tgt-vvp \
|
||||
$(verbose) -o top.vvp -s top $(srcdir)/hello_world.v && \
|
||||
$(ENV_VVP) $(top_builddir)/vvp/vvp$(suffix)@EXEEXT@ top.vvp
|
||||
|
||||
clean:
|
||||
rm -f *.o cflexor.c cfparse.c cfparse.h cfparse.output
|
||||
rm -f iverilog@EXEEXT@ iverilog.man iverilog.pdf iverilog.ps
|
||||
rm -rf dep
|
||||
rm -f top.vvp
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
||||
cppcheck: $(O:.o=.c)
|
||||
cppcheck --enable=all --std=c99 --std=c++11 -f \
|
||||
-UYY_USER_INIT \
|
||||
-UYYPARSE_PARAM -UYYPRINT -Ushort -Uyyoverflow \
|
||||
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \
|
||||
-UYYSTYPE -U__SIZE_TYPE__ -Umalloc -Usize_t -Ufree \
|
||||
$(INCLUDE_PATH) $^
|
||||
--check-level=exhaustive \
|
||||
--suppressions-list=$(srcdir)/../cppcheck-global.sup \
|
||||
--suppressions-list=$(srcdir)/cppcheck.sup \
|
||||
-Ushort -Usize_t -Uyyoverflow \
|
||||
-U__SIZE_TYPE__ -Umalloc -Ufree \
|
||||
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
cd ..; ./config.status --file=driver/$@
|
||||
@@ -91,45 +109,34 @@ cflexor.c: $(srcdir)/cflexor.lex
|
||||
cfparse%c cfparse%h: $(srcdir)/cfparse%y
|
||||
$(YACC) --verbose -t -p cf -d -o cfparse.c $<
|
||||
|
||||
%.o: %.c
|
||||
%.o: %.c | dep
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||
mv $*.d dep
|
||||
|
||||
main.o: main.c globals.h $(srcdir)/../version_base.h ../version_tag.h Makefile
|
||||
main.o: main.c globals.h ../version_base.h ../version_tag.h Makefile | dep
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c -DIVL_ROOT='"@libdir@/ivl$(suffix)"' -DIVL_SUFFIX='"$(suffix)"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' -DIVL_INCLUDE_INSTALL_DIR="\"$(realpath $(DESTDIR)/$(includedir))\"" $(srcdir)/main.c
|
||||
mv $*.d dep
|
||||
|
||||
cflexor.o: cflexor.c cfparse.h
|
||||
|
||||
iverilog.man: $(srcdir)/iverilog.man.in ../version.exe
|
||||
../version.exe `head -1 $(srcdir)/iverilog.man.in`'\n' > $@
|
||||
tail -n +2 $(srcdir)/iverilog.man.in >> $@
|
||||
iverilog.man: $(srcdir)/iverilog.man.in ../config.status
|
||||
cd ..; ./config.status --file=driver/$@
|
||||
|
||||
iverilog.ps: iverilog.man
|
||||
$(MAN) -t ./iverilog.man > iverilog.ps
|
||||
$(MAN) -t ./$< > $@
|
||||
|
||||
iverilog.pdf: iverilog.ps
|
||||
$(PS2PDF) iverilog.ps iverilog.pdf
|
||||
$(PS2PDF) $< $@
|
||||
|
||||
INSTALL_DOC =
|
||||
ifneq ($(MAN),none)
|
||||
INSTALL_DOC += installman
|
||||
ifneq ($(PS2PDF),none)
|
||||
ifeq (@MINGW32@,yes)
|
||||
ifeq ($(MAN),none)
|
||||
INSTALL_DOC = installman
|
||||
INSTALL_PDFDIR = $(prefix)
|
||||
else
|
||||
ifeq ($(PS2PDF),none)
|
||||
INSTALL_DOC = installman
|
||||
INSTALL_PDFDIR = $(prefix)
|
||||
else
|
||||
INSTALL_DOC = installpdf installman
|
||||
INSTALL_PDFDIR = $(pdfdir)
|
||||
INSTALL_DOC += installpdf
|
||||
all: iverilog.pdf
|
||||
endif
|
||||
endif
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
else
|
||||
INSTALL_DOC = installman
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
INSTALL_PDFDIR = $(prefix)
|
||||
endif
|
||||
|
||||
install: all installdirs installfiles
|
||||
@@ -138,21 +145,23 @@ F = ./iverilog@EXEEXT@ \
|
||||
$(INSTALL_DOC)
|
||||
|
||||
installman: iverilog.man installdirs
|
||||
$(INSTALL_DATA) iverilog.man "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1"
|
||||
$(INSTALL_DATA) iverilog.man "$(DESTDIR)$(man1dir)/iverilog$(suffix).1"
|
||||
|
||||
installpdf: iverilog.pdf installdirs
|
||||
$(INSTALL_DATA) iverilog.pdf "$(DESTDIR)$(pdfdir)/iverilog$(suffix).pdf"
|
||||
$(INSTALL_DATA) iverilog.pdf "$(DESTDIR)$(docdir)/iverilog$(suffix).pdf"
|
||||
|
||||
installfiles: $(F) | installdirs
|
||||
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@"
|
||||
|
||||
installdirs: $(srcdir)/../mkinstalldirs
|
||||
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(bindir)" \
|
||||
"$(DESTDIR)$(INSTALL_DOCDIR)" \
|
||||
"$(DESTDIR)$(INSTALL_PDFDIR)"
|
||||
$(srcdir)/../mkinstalldirs \
|
||||
"$(DESTDIR)$(bindir)" \
|
||||
"$(DESTDIR)$(docdir)" \
|
||||
"$(DESTDIR)$(man1dir)"
|
||||
|
||||
uninstall:
|
||||
rm -f "$(DESTDIR)$(bindir)/iverilog$(suffix)@EXEEXT@"
|
||||
rm -f "$(DESTDIR)$(mandir)/man1/iverilog$(suffix).1" "$(DESTDIR)$(pdfdir)/iverilog$(suffix).pdf"
|
||||
rm -f "$(DESTDIR)$(man1dir)/iverilog$(suffix).1" \
|
||||
"$(DESTDIR)$(docdir)/iverilog$(suffix).pdf"
|
||||
|
||||
-include $(patsubst %.o, dep/%.d, $O)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
// cppcheck is wrong this is correct usage
|
||||
syntaxError:main.c:415
|
||||
syntaxError:main.c:412
|
||||
|
||||
// cppcheck is missing the code adds a \0 at the previous location.
|
||||
knownConditionTrueFalse:main.c:1123
|
||||
redundantAssignment:main.c:1122
|
||||
|
||||
// Skip all memory issues since they should be handled by ivl_alloc.h
|
||||
memleakOnRealloc
|
||||
nullPointerArithmeticOutOfMemory
|
||||
nullPointerOutOfMemory
|
||||
|
||||
// Errors/limitations in the generated yacc and lex files
|
||||
duplicateBreak:cflexor.lex
|
||||
constVariablePointer:cfparse.y
|
||||
memleakOnRealloc:cfparse.y
|
||||
allocaCalled:cfparse.c
|
||||
constParameterPointer:cfparse.c
|
||||
constVariablePointer:cfparse.c
|
||||
invalidPrintfArgType_sint:cfparse.c
|
||||
knownConditionTrueFalse:cfparse.c
|
||||
sizeofwithnumericparameter:cfparse.c
|
||||
unsignedPositive:cfparse.c
|
||||
constVariablePointer:<stdout>
|
||||
duplicateBreak:<stdout>
|
||||
nullPointer:<stdout>
|
||||
redundantInitialization:<stdout>
|
||||
staticFunction:<stdout>
|
||||
syntaxError:<stdout>
|
||||
unusedFunction:<stdout>
|
||||
@@ -0,0 +1,3 @@
|
||||
module top;
|
||||
initial $display("Hello World!");
|
||||
endmodule
|
||||
+56
-15
@@ -1,12 +1,12 @@
|
||||
.TH iverilog 1 "Jan 20th, 2024" "" "Version %M.%n%E"
|
||||
.TH iverilog 1 "Jan 13th, 2026" "" "Version @VERSION@"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog
|
||||
[\-EiRSuVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]]
|
||||
[\-EiRSuVv] [\-B[IMPVt]path] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]]
|
||||
[\-Pparameter=value] [\-pflag=value] [\-dname]
|
||||
[\-g1995\:|\-g2001\:|\-g2005\:|\-g2005-sv\:|\-g2009\:|\-g2012\:|\-g<feature>]
|
||||
[\-g1995\:|\-g2001\:|\-g2005\:|\-g2005-sv\:|\-g2009\:|\-g2012\:|\-g2017\:|\-g2023\:|\-g<feature>]
|
||||
[\-Iincludedir] [\-Lmoduledir] [\-mmodule] [\-M[mode=]file] [\-Nfile]
|
||||
[\-ooutputfilename] [\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass]
|
||||
[\-ypath] [\-lfile]
|
||||
@@ -21,13 +21,36 @@ further processing. The main target is \fIvvp\fP for simulation.
|
||||
.SH OPTIONS
|
||||
\fIiverilog\fP accepts the following options:
|
||||
.TP 8
|
||||
.B -B\fIbase\fP
|
||||
.BI \-B path
|
||||
The \fIiverilog\fP program uses external programs and configuration
|
||||
files to preprocess and compile the Verilog source. Normally, the path
|
||||
used to locate these tools is built into the \fIiverilog\fP
|
||||
program. However, the \fB\-B\fP switch allows the user to select a
|
||||
different set of programs. The path given is used to locate
|
||||
\fIivlpp\fP, \fIivl\fP, code generators and the VPI modules.
|
||||
files to preprocess and compile Verilog source files. Normally, the
|
||||
paths used to locate these tools are built into the
|
||||
\fIiverilog\fP executable. The \fB\-B\fP option allows the user to
|
||||
override these paths.
|
||||
The specified path is used as the default base directory for locating
|
||||
\fIivlpp\fP, \fIivl\fP, code generators, configuration files, and
|
||||
VPI modules.
|
||||
Specialized forms of this option may be used to override individual
|
||||
tool paths:
|
||||
.RS
|
||||
.TP
|
||||
.BI \-BI path
|
||||
Directory for the \fIivl\fP parser.
|
||||
.TP
|
||||
.BI \-BM path
|
||||
Directory for VPI modules.
|
||||
.TP
|
||||
.BI \-BP path
|
||||
Directory for the \fIivlpp\fP preprocessor.
|
||||
.TP
|
||||
.BI \-BV path
|
||||
Directory for the \fIvhdlpp\fP VHDL preprocessor.
|
||||
.TP
|
||||
.BI \-Bt path
|
||||
Directory used to locate target configuration files for the
|
||||
\fB\-t\fP\fItarget\fP option. The configuration file name is
|
||||
\fItarget\fP.conf.
|
||||
.RE
|
||||
.TP 8
|
||||
.B -c\fIfile\fP -f\fIfile\fP
|
||||
These flags specify an input file that contains a list of Verilog
|
||||
@@ -47,7 +70,9 @@ Defines macro \fImacro\fP as \fIdefn\fP.
|
||||
Override (i.e. defparam) a parameter in a root module. This allows the
|
||||
user to override at compile time (defparam) a parameter in a root
|
||||
module instance. For example, \fB\-Pmain.foo=2\fP overrides the
|
||||
parameter foo in the root instance main with the value 2.
|
||||
parameter foo in the root instance main with the value 2 and
|
||||
\fB\-Pmain.foos='"New string value"'\fP will override the parameter
|
||||
foos in the root instance main with the value "New string value".
|
||||
.TP 8
|
||||
.B -d\fIname\fP
|
||||
Activate a class of compiler debugging messages. The \fB\-d\fP switch may
|
||||
@@ -61,11 +86,11 @@ is the Verilog input, but with file inclusions and macro references
|
||||
expanded and removed. This is useful, for example, to preprocess
|
||||
Verilog source for use by other compilers.
|
||||
.TP 8
|
||||
.B -g1995\fI|\fP-g2001\fI|\fP-g2001-noconfig\fI|\fP-g2005\fI|\fP-g2005-sv\fI|\fP-g2009\fI|\fP-g2012
|
||||
.B -g1995\fI|\fP-g2001\fI|\fP-g2001-noconfig\fI|\fP-g2005\fI|\fP-g2005-sv\fI|\fP-g2009\fI|\fP-g2012\fI|\fP-g2017\fI|\fP-g2023
|
||||
Select the Verilog language \fIgeneration\fP to support in the compiler.
|
||||
This selects between \fIIEEE1364\-1995\fP, \fIIEEE1364\-2001\fP,
|
||||
\fIIEEE1364\-2005\fP, \fIIEEE1800\-2005\fP, \fIIEEE1800\-2009\fP, or
|
||||
\fIIEEE1800\-2012\fP.
|
||||
\fIIEEE1364\-2005\fP, \fIIEEE1800\-2005\fP, \fIIEEE1800\-2009\fP,
|
||||
\fIIEEE1800\-2012\fP, \fIIEEE1800\-2017\fP, or \fIIEEE1800\-2023\fP.
|
||||
Icarus Verilog currently defaults to the \fIIEEE1364\-2005\fP generation
|
||||
of the language. This flag is used to restrict the language to a set of
|
||||
keywords/features, this allows simulation of older Verilog code that may
|
||||
@@ -122,7 +147,7 @@ to disable extended types if compiling code that clashes with the few
|
||||
new keywords used to implement the type system.
|
||||
.TP 8
|
||||
.B -gio-range-error\fI|\fP-gno-io-range-error
|
||||
The standards requires that a vectored port have matching ranges for its
|
||||
The standards require that a vectored port have matching ranges for its
|
||||
port declaration as well as any net/register declaration. It was common
|
||||
practice in the past to only specify the range for the net/register
|
||||
declaration and some tools still allow this. By default any mismatch is
|
||||
@@ -148,6 +173,17 @@ parameter assignment is evaluated as a lossless expression, as is any
|
||||
expression containing an unsized constant number, and unsized constant
|
||||
numbers are not truncated to integer width.
|
||||
.TP 8
|
||||
.B -gstrict-declaration\fI|\fP-gno-strict-declaration
|
||||
.TP 8
|
||||
.B -gstrict-net-var-declaration\fI|\fP-gno-strict-net-var-declaration
|
||||
.TP 8
|
||||
.B -gstrict-parameter-declaration\fI|\fP-gno-strict-parameter-declaration
|
||||
The standards require that nets, variables, and parameters are declared
|
||||
lexically before they are used. Using \fB\-gno\-strict\-declaration\fP
|
||||
will allow using a data object before declaration, with a warning. The
|
||||
warning can be suppressed with -Wno-declaration-after-use. The option
|
||||
can be applied for nets and variables and for parameters separately.
|
||||
.TP 8
|
||||
.B -gshared-loop-index\fI|\fP-gno-shared-loop-index
|
||||
Enable (default) or disable the exclusion of for-loop control variables
|
||||
from implicit event_expression lists. When enabled, if a for-loop control
|
||||
@@ -365,6 +401,11 @@ This enables warnings for creation of implicit declarations. For
|
||||
example, if a scalar wire X is used but not declared in the Verilog
|
||||
source, this will print a warning at its first use.
|
||||
|
||||
.TP 8
|
||||
.B declaration-after-use
|
||||
This enables warnings for declarations after use, when
|
||||
those are not flagged as errors (default).
|
||||
|
||||
.TP 8
|
||||
.B macro-redefinition\fI | \fPmacro-replacement
|
||||
This enables preprocessor warnings when a macro is being redefined.
|
||||
@@ -643,7 +684,7 @@ Tips on using, debugging, and developing the compiler can be found at
|
||||
|
||||
.SH COPYRIGHT
|
||||
.nf
|
||||
Copyright \(co 2002\-2024 Stephen Williams
|
||||
Copyright \(co 2002\-2026 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
|
||||
+75
-11
@@ -1,5 +1,5 @@
|
||||
const char COPYRIGHT[] =
|
||||
"Copyright (c) 2000-2024 Stephen Williams ([email protected])";
|
||||
"Copyright (c) 2000-2026 Stephen Williams ([email protected])";
|
||||
/*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -38,8 +38,8 @@ const char NOTICE[] =
|
||||
;
|
||||
|
||||
const char HELP[] =
|
||||
"Usage: iverilog [-EiRSuvV] [-B base] [-c cmdfile|-f cmdfile]\n"
|
||||
" [-g1995|-g2001|-g2005|-g2005-sv|-g2009|-g2012] [-g<feature>]\n"
|
||||
"Usage: iverilog [-EiRSuvV] [-B[IMPVt] base] [-c cmdfile|-f cmdfile]\n"
|
||||
" [-g1995|-g2001|-g2005|-g2005-sv|-g2009|-g2012|-g2017|-g2023] [-g<feature>]\n"
|
||||
" [-D macro[=defn]] [-I includedir] [-L moduledir]\n"
|
||||
" [-M [mode=]depfile] [-m module]\n"
|
||||
" [-N file] [-o filename] [-p flag=value]\n"
|
||||
@@ -69,6 +69,9 @@ const char HELP[] =
|
||||
# include <libiberty.h>
|
||||
#endif
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
# include <mach-o/dyld.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifdef HAVE_GETOPT_H
|
||||
@@ -109,6 +112,8 @@ extern void cfreset(FILE*fd, const char*path);
|
||||
|
||||
const char*base = 0;
|
||||
const char*vpi_dir = 0;
|
||||
const char*tconfig_dir = 0;
|
||||
const char*ivl_dir = 0;
|
||||
const char*ivlpp_dir = 0;
|
||||
const char*vhdlpp_dir= 0;
|
||||
const char*vhdlpp_work = 0;
|
||||
@@ -134,6 +139,8 @@ const char*gen_strict_ca_eval = "no-strict-ca-eval";
|
||||
const char*gen_strict_expr_width = "no-strict-expr-width";
|
||||
const char*gen_shared_loop_index = "shared-loop-index";
|
||||
const char*gen_verilog_ams = "no-verilog-ams";
|
||||
const char*gen_strict_net_var_declaration = "strict-net-var-declaration";
|
||||
const char*gen_strict_parameter_declaration = "strict-parameter-declaration";
|
||||
|
||||
/* Boolean: true means use a default include dir, false means don't */
|
||||
int gen_std_include = 1;
|
||||
@@ -142,7 +149,7 @@ int gen_std_include = 1;
|
||||
of the include list. */
|
||||
int gen_relative_include = 0;
|
||||
|
||||
char warning_flags[17] = "n";
|
||||
char warning_flags[18] = "nu";
|
||||
|
||||
int separate_compilation_flag = 0;
|
||||
|
||||
@@ -335,7 +342,7 @@ static int t_version_only(void)
|
||||
}
|
||||
|
||||
fflush(0);
|
||||
snprintf(tmp, sizeof tmp, "%s%civl -V -C\"%s\" -C\"%s\"", base, sep,
|
||||
snprintf(tmp, sizeof tmp, "%s%civl -V -C\"%s\" -C\"%s\"", ivl_dir, sep,
|
||||
iconfig_path, iconfig_common_path);
|
||||
rc = system(tmp);
|
||||
if (rc != 0) {
|
||||
@@ -442,7 +449,7 @@ static int t_compile(void)
|
||||
#endif
|
||||
|
||||
/* Build the ivl command. */
|
||||
snprintf(tmp, sizeof tmp, "%s%civl", base, sep);
|
||||
snprintf(tmp, sizeof tmp, "%s%civl", ivl_dir, sep);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
@@ -527,6 +534,7 @@ static void process_warning_switch(const char*name)
|
||||
{
|
||||
if (strcmp(name,"all") == 0) {
|
||||
process_warning_switch("anachronisms");
|
||||
process_warning_switch("declaration-after-use");
|
||||
process_warning_switch("implicit");
|
||||
process_warning_switch("implicit-dimensions");
|
||||
process_warning_switch("macro-replacement");
|
||||
@@ -537,6 +545,9 @@ static void process_warning_switch(const char*name)
|
||||
} else if (strcmp(name,"anachronisms") == 0) {
|
||||
if (! strchr(warning_flags, 'n'))
|
||||
strcat(warning_flags, "n");
|
||||
} else if (strcmp(name,"declaration-after-use") == 0) {
|
||||
if (! strchr(warning_flags, 'u'))
|
||||
strcat(warning_flags, "u");
|
||||
} else if (strcmp(name,"floating-nets") == 0) {
|
||||
if (! strchr(warning_flags, 'f'))
|
||||
strcat(warning_flags, "f");
|
||||
@@ -578,6 +589,12 @@ static void process_warning_switch(const char*name)
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-declaration-after-use") == 0) {
|
||||
char*cp = strchr(warning_flags, 'u');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-floating-nets") == 0) {
|
||||
char*cp = strchr(warning_flags, 'f');
|
||||
if (cp) while (*cp) {
|
||||
@@ -725,6 +742,12 @@ static int process_generation(const char*name)
|
||||
else if (strcmp(name,"2012") == 0)
|
||||
generation = "2012";
|
||||
|
||||
else if (strcmp(name,"2017") == 0)
|
||||
generation = "2017";
|
||||
|
||||
else if (strcmp(name,"2023") == 0)
|
||||
generation = "2023";
|
||||
|
||||
else if (strcmp(name,"1") == 0) { /* Deprecated: use 1995 */
|
||||
generation = "1995";
|
||||
gen_xtypes = "no-xtypes";
|
||||
@@ -815,6 +838,26 @@ static int process_generation(const char*name)
|
||||
else if (strcmp(name,"no-verilog-ams") == 0)
|
||||
gen_verilog_ams = "no-verilog-ams";
|
||||
|
||||
else if (strcmp(name,"strict-declaration") == 0) {
|
||||
gen_strict_net_var_declaration = "strict-net-var-declaration";
|
||||
gen_strict_parameter_declaration = "strict-parameter-declaration";
|
||||
}
|
||||
else if (strcmp(name,"no-strict-declaration") == 0) {
|
||||
gen_strict_net_var_declaration = "no-strict-net-var-declaration";
|
||||
gen_strict_parameter_declaration = "no-strict-parameter-declaration";
|
||||
}
|
||||
else if (strcmp(name,"strict-net-var-declaration") == 0)
|
||||
gen_strict_net_var_declaration = "strict-net-var-declaration";
|
||||
|
||||
else if (strcmp(name,"no-strict-net-var-declaration") == 0)
|
||||
gen_strict_net_var_declaration = "no-strict-net-var-declaration";
|
||||
|
||||
else if (strcmp(name,"strict-parameter-declaration") == 0)
|
||||
gen_strict_parameter_declaration = "strict-parameter-declaration";
|
||||
|
||||
else if (strcmp(name,"no-strict-parameter-declaration") == 0)
|
||||
gen_strict_parameter_declaration = "no-strict-parameter-declaration";
|
||||
|
||||
else {
|
||||
fprintf(stderr, "Unknown/Unsupported Language generation "
|
||||
"%s\n\n", name);
|
||||
@@ -825,6 +868,8 @@ static int process_generation(const char*name)
|
||||
" 2005-sv -- IEEE1800-2005\n"
|
||||
" 2009 -- IEEE1800-2009\n"
|
||||
" 2012 -- IEEE1800-2012\n"
|
||||
" 2017 -- IEEE1800-2017\n"
|
||||
" 2023 -- IEEE1800-2023\n"
|
||||
"Other generation flags:\n"
|
||||
" assertions | supported-assertions | no-assertions\n"
|
||||
" specify | no-specify\n"
|
||||
@@ -837,7 +882,9 @@ static int process_generation(const char*name)
|
||||
" io-range-error | no-io-range-error\n"
|
||||
" strict-ca-eval | no-strict-ca-eval\n"
|
||||
" strict-expr-width | no-strict-expr-width\n"
|
||||
" shared-loop-index | no-shared-loop-index\n");
|
||||
" shared-loop-index | no-shared-loop-index\n"
|
||||
" strict-declaration | no-strict-declaration\n"
|
||||
" [no-]strict-[net-var|parameter]-declaration\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -887,7 +934,8 @@ static void add_env_vpi_module_path(const char*path)
|
||||
static void get_env_vpi_module_paths(void)
|
||||
{
|
||||
char *var = getenv("IVERILOG_VPI_MODULE_PATH");
|
||||
char *ptr, *end;
|
||||
char *ptr;
|
||||
const char *end;
|
||||
|
||||
if (!var)
|
||||
return;
|
||||
@@ -1178,6 +1226,9 @@ int main(int argc, char **argv)
|
||||
character of the path indicates which path the
|
||||
user is specifying. */
|
||||
switch (optarg[0]) {
|
||||
case 'I': /* Path for the ivl parser */
|
||||
ivl_dir = optarg+1;
|
||||
break;
|
||||
case 'M': /* Path for the VPI modules */
|
||||
vpi_dir = optarg+1;
|
||||
break;
|
||||
@@ -1187,6 +1238,9 @@ int main(int argc, char **argv)
|
||||
case 'V': /* Path for the vhdlpp VHDL processor */
|
||||
vhdlpp_dir = optarg+1;
|
||||
break;
|
||||
case 't': /* Path to target.conf for the -ttarget option */
|
||||
tconfig_dir = optarg+1;
|
||||
break;
|
||||
default: /* Otherwise, this is a default base. */
|
||||
base=optarg;
|
||||
break;
|
||||
@@ -1329,8 +1383,12 @@ int main(int argc, char **argv)
|
||||
vpi_dir = base;
|
||||
if (ivlpp_dir == 0)
|
||||
ivlpp_dir = base;
|
||||
if (ivl_dir == 0)
|
||||
ivl_dir = base;
|
||||
if (vhdlpp_dir == 0)
|
||||
vhdlpp_dir = base;
|
||||
if (tconfig_dir == 0)
|
||||
tconfig_dir = base;
|
||||
|
||||
if (version_flag || verbose_flag) {
|
||||
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
|
||||
@@ -1340,7 +1398,7 @@ int main(int argc, char **argv)
|
||||
|
||||
/* Make a common conf file path to reflect the target. */
|
||||
snprintf(iconfig_common_path, sizeof iconfig_common_path, "%s%c%s%s.conf",
|
||||
base, sep, targ, synth_flag? "-s" : "");
|
||||
tconfig_dir, sep, targ, synth_flag? "-s" : "");
|
||||
|
||||
/* Write values to the iconfig file. */
|
||||
fprintf(iconfig_file, "basedir:%s\n", base);
|
||||
@@ -1350,11 +1408,13 @@ int main(int argc, char **argv)
|
||||
fprintf(iconfig_file, "module:%s%cvhdl_sys.vpi\n", vpi_dir, sep);
|
||||
fprintf(iconfig_file, "module:%s%cvhdl_textio.vpi\n", vpi_dir, sep);
|
||||
|
||||
/* If verilog-2005/09/12 is enabled or icarus-misc or verilog-ams,
|
||||
/* If verilog-2005/09/12/17/23 is enabled or icarus-misc or verilog-ams,
|
||||
* then include the v2005_math library. */
|
||||
if (strcmp(generation, "2005") == 0 ||
|
||||
strcmp(generation, "2009") == 0 ||
|
||||
strcmp(generation, "2012") == 0 ||
|
||||
strcmp(generation, "2017") == 0 ||
|
||||
strcmp(generation, "2023") == 0 ||
|
||||
strcmp(gen_icarus, "icarus-misc") == 0 ||
|
||||
strcmp(gen_verilog_ams, "verilog-ams") == 0) {
|
||||
fprintf(iconfig_file, "module:%s%cv2005_math.vpi\n", vpi_dir, sep);
|
||||
@@ -1369,7 +1429,9 @@ int main(int argc, char **argv)
|
||||
v2009 module. */
|
||||
if (strcmp(generation, "2005-sv") == 0 ||
|
||||
strcmp(generation, "2009") == 0 ||
|
||||
strcmp(generation, "2012") == 0) {
|
||||
strcmp(generation, "2012") == 0 ||
|
||||
strcmp(generation, "2017") == 0 ||
|
||||
strcmp(generation, "2023") == 0) {
|
||||
fprintf(iconfig_file, "module:%s%cv2009.vpi\n", vpi_dir, sep);
|
||||
}
|
||||
|
||||
@@ -1384,6 +1446,8 @@ int main(int argc, char **argv)
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_strict_expr_width);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_shared_loop_index);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_verilog_ams);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_strict_net_var_declaration);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_strict_parameter_declaration);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_icarus);
|
||||
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
|
||||
fprintf(iconfig_file, "ignore_missing_modules:%s\n", ignore_missing_modules ? "true" : "false");
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2026 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -37,7 +37,7 @@ char* substitutions(const char*str)
|
||||
it in the destination with the contents of the
|
||||
environment variable x. */
|
||||
char*name;
|
||||
char*value;
|
||||
const char*value;
|
||||
const char*ep = strchr(str, (str[1]=='(') ? ')' : '}');
|
||||
str += 2;
|
||||
|
||||
|
||||
+3
-1
@@ -235,7 +235,9 @@ NetESelect* NetESelect::dup_expr() const
|
||||
|
||||
NetESFunc* NetESFunc::dup_expr() const
|
||||
{
|
||||
NetESFunc*tmp = new NetESFunc(name_, type_, expr_width(), nparms(), is_overridden_);
|
||||
NetESFunc*tmp = net_type()
|
||||
? new NetESFunc(name_, net_type(), nparms())
|
||||
: new NetESFunc(name_, type_, expr_width(), nparms(), is_overridden_);
|
||||
ivl_assert(*this, tmp);
|
||||
|
||||
tmp->cast_signed(has_sign());
|
||||
|
||||
+1698
-738
File diff suppressed because it is too large
Load Diff
+46
-20
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2024 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2026 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2012-2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -133,11 +133,13 @@ NetAssign_* PEConcat::elaborate_lval(Design*des,
|
||||
the compiler catch more errors. */
|
||||
if (tmp == 0) continue;
|
||||
|
||||
if (tmp->expr_type() == IVL_VT_REAL) {
|
||||
ivl_type_t tmp_type = tmp->net_type();
|
||||
if (tmp_type && !tmp_type->packed()) {
|
||||
cerr << parms_[idx]->get_fileline() << ": error: "
|
||||
<< "concatenation operand can not be real: "
|
||||
<< "concatenation operand must be packed: "
|
||||
<< *parms_[idx] << endl;
|
||||
des->errors += 1;
|
||||
delete tmp;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -174,10 +176,13 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||
}
|
||||
|
||||
symbol_search_results sr;
|
||||
symbol_search(this, des, scope, path_, lexical_pos_, &sr);
|
||||
symbol_search(this, des, scope, path_, lexical_pos(), &sr);
|
||||
|
||||
if (!sr.require_non_type(this, des, "as a procedural l-value"))
|
||||
return nullptr;
|
||||
|
||||
NetNet *reg = sr.net;
|
||||
pform_name_t &member_path = sr.path_tail;
|
||||
const pform_name_t &member_path = sr.path_tail;
|
||||
|
||||
/* The l-value must be a variable. If not, then give up and
|
||||
print a useful error message. */
|
||||
@@ -254,7 +259,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des,
|
||||
NetAssign_*PEIdent::elaborate_lval_var_(Design *des, NetScope *scope,
|
||||
bool is_force, bool is_cassign,
|
||||
NetNet *reg, ivl_type_t data_type,
|
||||
pform_name_t tail_path) const
|
||||
const pform_name_t tail_path) const
|
||||
{
|
||||
// We are processing the tail of a string of names. For
|
||||
// example, the Verilog may be "a.b.c", so we are processing
|
||||
@@ -296,6 +301,15 @@ NetAssign_*PEIdent::elaborate_lval_var_(Design *des, NetScope *scope,
|
||||
// Past this point, we should have taken care of the cases
|
||||
// where the name is a member/method of a struct/class.
|
||||
// XXXX ivl_assert(*this, method_name.nil());
|
||||
if (!tail_path.empty()) {
|
||||
cerr << get_fileline() << ": error: Variable "
|
||||
<< reg->name()
|
||||
<< " does not have a field named: "
|
||||
<< tail_path << "." << endl;
|
||||
des->errors += 1;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ivl_assert(*this, tail_path.empty());
|
||||
|
||||
bool need_const_idx = is_cassign || is_force;
|
||||
@@ -475,7 +489,7 @@ NetAssign_* PEIdent::elaborate_lval_net_word_(Design*des,
|
||||
|
||||
if ((reg->type()==NetNet::UNRESOLVED_WIRE) && !is_force) {
|
||||
ivl_assert(*this, reg->coerced_to_uwire());
|
||||
NetEConst*canon_const = dynamic_cast<NetEConst*>(canon_index);
|
||||
const NetEConst*canon_const = dynamic_cast<NetEConst*>(canon_index);
|
||||
if (!canon_const || reg->test_part_driven(reg->vector_width() - 1, 0,
|
||||
canon_const->value().as_long())) {
|
||||
report_mixed_assignment_conflict_("array word");
|
||||
@@ -556,7 +570,7 @@ bool PEIdent::elaborate_lval_net_bit_(Design*des,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NetEConst*index_con = dynamic_cast<NetEConst*> (mux)) {
|
||||
if (const NetEConst*index_con = dynamic_cast<NetEConst*> (mux)) {
|
||||
// The index has a constant defined value.
|
||||
if (index_con->value().is_defined()) {
|
||||
lsb = index_con->value().as_long();
|
||||
@@ -761,8 +775,7 @@ bool PEIdent::elaborate_lval_net_part_(Design*des,
|
||||
// values into msb and lsb.
|
||||
long msb, lsb;
|
||||
bool parts_defined_flag;
|
||||
bool flag = calculate_parts_(des, scope, msb, lsb, parts_defined_flag);
|
||||
if (!flag) return false;
|
||||
calculate_parts_(des, scope, msb, lsb, parts_defined_flag);
|
||||
|
||||
NetNet*reg = lv->sig();
|
||||
ivl_assert(*this, reg);
|
||||
@@ -882,8 +895,10 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
||||
calculate_up_do_width_(des, scope, wid);
|
||||
|
||||
NetExpr*base = elab_and_eval(des, scope, index_tail.msb, -1);
|
||||
if (!base)
|
||||
return false;
|
||||
|
||||
if (base && base->expr_type() == IVL_VT_REAL) {
|
||||
if (base->expr_type() == IVL_VT_REAL) {
|
||||
cerr << get_fileline() << ": error: Indexed part select base "
|
||||
"expression for ";
|
||||
cerr << lv->sig()->name() << "[" << *base;
|
||||
@@ -901,7 +916,7 @@ bool PEIdent::elaborate_lval_net_idx_(Design*des,
|
||||
|
||||
// Handle the special case that the base is constant. For this
|
||||
// case we can reduce the expression.
|
||||
if (NetEConst*base_c = dynamic_cast<NetEConst*> (base)) {
|
||||
if (const NetEConst*base_c = dynamic_cast<NetEConst*> (base)) {
|
||||
// For the undefined case just let the constant pass and
|
||||
// we will handle it in the code generator.
|
||||
if (base_c->value().is_defined()) {
|
||||
@@ -1120,18 +1135,27 @@ NetAssign_* PEIdent::elaborate_lval_net_class_member_(Design*des, NetScope*scope
|
||||
// part of the sig, as the l-value.
|
||||
NetNet*psig = class_type->find_static_property(method_name);
|
||||
ivl_assert(*this, psig);
|
||||
if (psig->get_const()) {
|
||||
cerr << get_fileline() << ": error: Assignment to const signal `"
|
||||
<< psig->name() << "` is not allowed." << endl;
|
||||
des->errors++;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
lv = new NetAssign_(psig);
|
||||
return lv;
|
||||
|
||||
} else if (qual.test_const()) {
|
||||
auto method_scope = find_method_containing_scope(*this, scope);
|
||||
if (class_type->get_prop_initialized(pidx)) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Property " << class_type->get_prop_name(pidx)
|
||||
<< " is constant in this method."
|
||||
<< " (scope=" << scope_path(scope) << ")" << endl;
|
||||
des->errors++;
|
||||
} else if (scope->basename() != "new" && scope->basename() != "new@") {
|
||||
} else if (!method_scope ||
|
||||
(method_scope->basename() != "new" &&
|
||||
method_scope->basename() != "new@")) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Property " << class_type->get_prop_name(pidx)
|
||||
<< " is constant in this method."
|
||||
@@ -1445,14 +1469,18 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
|
||||
// possibly iterate through more of the member_path.
|
||||
|
||||
ivl_assert(*this, array->packed());
|
||||
ivl_assert(*this, !member_comp.index.empty());
|
||||
|
||||
if (member_comp.index.empty()) {
|
||||
struct_type = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
// These are the dimensions defined by the type
|
||||
const netranges_t&mem_packed_dims = array->static_dimensions();
|
||||
|
||||
if (member_comp.index.size() != mem_packed_dims.size()) {
|
||||
if (member_comp.index.size() > mem_packed_dims.size()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Incorrect number of index expressions for member "
|
||||
<< "Too many index expressions for member "
|
||||
<< member_name << "." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
@@ -1502,11 +1530,9 @@ bool PEIdent::elaborate_lval_net_packed_member_(Design*des, NetScope*scope,
|
||||
|
||||
// The width and offset calculated from the
|
||||
// indices is actually in elements, and not
|
||||
// bits. In fact, in this context, the lwid should
|
||||
// come down to 1 (one element).
|
||||
// bits.
|
||||
off += loff * element_width;
|
||||
ivl_assert(*this, lwid==1);
|
||||
use_width = element_width;
|
||||
use_width = lwid * element_width;
|
||||
|
||||
// To move on to the next component in the member
|
||||
// path, get the element type. For example, for
|
||||
|
||||
+89
-46
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2024 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -43,7 +43,8 @@ using namespace std;
|
||||
* make the l-value connections.
|
||||
*/
|
||||
NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
bool bidirectional_flag) const
|
||||
bool bidirectional_flag,
|
||||
bool var_allowed_in_sv) const
|
||||
{
|
||||
ivl_assert(*this, scope);
|
||||
|
||||
@@ -76,22 +77,28 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
}
|
||||
|
||||
if (bidirectional_flag) {
|
||||
nets[idx] = parms_[idx]->elaborate_bi_net(des, scope);
|
||||
nets[idx] = parms_[idx]->elaborate_bi_net(des, scope, var_allowed_in_sv);
|
||||
} else {
|
||||
nets[idx] = parms_[idx]->elaborate_lnet(des, scope);
|
||||
nets[idx] = parms_[idx]->elaborate_lnet(des, scope, var_allowed_in_sv);
|
||||
}
|
||||
|
||||
if (nets[idx] == 0) {
|
||||
errors += 1;
|
||||
} else if (nets[idx]->data_type() == IVL_VT_REAL) {
|
||||
cerr << parms_[idx]->get_fileline() << ": error: "
|
||||
<< "concatenation operand can no be real: "
|
||||
<< *parms_[idx] << endl;
|
||||
errors += 1;
|
||||
continue;
|
||||
} else {
|
||||
width += nets[idx]->vector_width();
|
||||
}
|
||||
ivl_type_t tmp_type = nets[idx]->array_type();
|
||||
if (!tmp_type)
|
||||
tmp_type = nets[idx]->net_type();
|
||||
|
||||
if (tmp_type && !tmp_type->packed()) {
|
||||
cerr << parms_[idx]->get_fileline() << ": error: "
|
||||
<< "concatenation operand must be packed: "
|
||||
<< *parms_[idx] << endl;
|
||||
errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
width += nets[idx]->vector_width();
|
||||
}
|
||||
}
|
||||
|
||||
if (errors) {
|
||||
@@ -104,7 +111,7 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
concat operator from most significant to least significant,
|
||||
which is the order they are given in the concat list. */
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(nets[0]->data_type(),width-1,0);
|
||||
const netvector_t*tmp2_vec = new netvector_t(nets[0]->data_type(),width-1,0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, tmp2_vec);
|
||||
|
||||
@@ -163,14 +170,16 @@ NetNet* PEConcat::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
return osig;
|
||||
}
|
||||
|
||||
NetNet* PEConcat::elaborate_lnet(Design*des, NetScope*scope) const
|
||||
NetNet* PEConcat::elaborate_lnet(Design*des, NetScope*scope,
|
||||
bool var_allowed_in_sv) const
|
||||
{
|
||||
return elaborate_lnet_common_(des, scope, false);
|
||||
return elaborate_lnet_common_(des, scope, false, var_allowed_in_sv);
|
||||
}
|
||||
|
||||
NetNet* PEConcat::elaborate_bi_net(Design*des, NetScope*scope) const
|
||||
NetNet* PEConcat::elaborate_bi_net(Design*des, NetScope*scope,
|
||||
bool var_allowed_in_sv) const
|
||||
{
|
||||
return elaborate_lnet_common_(des, scope, true);
|
||||
return elaborate_lnet_common_(des, scope, true, var_allowed_in_sv);
|
||||
}
|
||||
|
||||
bool PEConcat::is_collapsible_net(Design*des, NetScope*scope,
|
||||
@@ -203,7 +212,7 @@ bool PEConcat::is_collapsible_net(Design*des, NetScope*scope,
|
||||
* results, which may be the whole vector, or a single bit, or
|
||||
* anything in between. The values are in canonical indices.
|
||||
*/
|
||||
bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||
bool PEIdent::eval_part_select_(Design*des, NetScope*scope, const NetNet*sig,
|
||||
long&midx, long&lidx) const
|
||||
{
|
||||
list<long> prefix_indices;
|
||||
@@ -234,7 +243,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||
case index_component_t::SEL_IDX_DO:
|
||||
case index_component_t::SEL_IDX_UP: {
|
||||
NetExpr*tmp_ex = elab_and_eval(des, scope, index_tail.msb, -1, true);
|
||||
NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||
const NetEConst*tmp = dynamic_cast<NetEConst*>(tmp_ex);
|
||||
if (!tmp) {
|
||||
cerr << get_fileline() << ": error: Indexed part select "
|
||||
"base expression must be a constant integral value "
|
||||
@@ -518,12 +527,17 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||
* so most of the work for both is done here.
|
||||
*/
|
||||
NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
bool bidirectional_flag) const
|
||||
bool bidirectional_flag,
|
||||
bool var_allowed_in_sv) const
|
||||
{
|
||||
ivl_assert(*this, scope);
|
||||
|
||||
symbol_search_results sr;
|
||||
symbol_search(this, des, scope, path_.name, lexical_pos_, &sr);
|
||||
symbol_search(this, des, scope, path_.name, lexical_pos(), &sr);
|
||||
|
||||
if (!sr.require_non_type(this, des,
|
||||
"as a continuous assignment l-value"))
|
||||
return nullptr;
|
||||
|
||||
if (sr.eve != 0) {
|
||||
cerr << get_fileline() << ": error: named events (" << path_
|
||||
@@ -540,6 +554,10 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
if (sig == 0) {
|
||||
cerr << get_fileline() << ": error: Net " << path_
|
||||
<< " is not defined in this context." << endl;
|
||||
if (sr.is_found()) {
|
||||
cerr << sr.scope->get_fileline() << ": : Found a "
|
||||
<< sr.result_type() << " with this name here." << endl;
|
||||
}
|
||||
if (sr.decl_after_use) {
|
||||
cerr << sr.decl_after_use->get_fileline() << ": : "
|
||||
"A symbol with that name was declared here. "
|
||||
@@ -549,6 +567,9 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!check_interface_modport_access(this, des, sr, true))
|
||||
return 0;
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": " << __func__ << ": "
|
||||
<< "Found l-value path_=" << path_
|
||||
@@ -569,7 +590,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
// If this is SystemVerilog and the variable is not yet
|
||||
// assigned by anything, then convert it to an unresolved
|
||||
// wire.
|
||||
if (gn_var_can_be_uwire()
|
||||
if (gn_var_can_be_uwire() && var_allowed_in_sv
|
||||
&& (sig->type() == NetNet::REG)
|
||||
&& (sig->peek_lref() == 0) ) {
|
||||
sig->type(NetNet::UNRESOLVED_WIRE);
|
||||
@@ -577,11 +598,22 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
|
||||
// Don't allow registers as assign l-values.
|
||||
if (sig->type() == NetNet::REG) {
|
||||
cerr << get_fileline() << ": error: reg " << sig->name()
|
||||
<< "; cannot be driven by primitives"
|
||||
<< " or continuous assignment." << endl;
|
||||
cerr << get_fileline() << ": error: Variable '" << sig->name()
|
||||
<< "' cannot be driven by a ";
|
||||
if (var_allowed_in_sv) cerr << "continuous assignment/module";
|
||||
else cerr << "primitive";
|
||||
if (gn_var_can_be_uwire()) {
|
||||
cerr << " or continuous assignment with non-default strength." << endl;
|
||||
} else {
|
||||
cerr << "." << endl;
|
||||
if (var_allowed_in_sv) {
|
||||
cerr << get_fileline() << ": : "
|
||||
<< "This is allowed when SystemVerilog is enabled."
|
||||
<< endl;
|
||||
}
|
||||
}
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Some parts below need the tail component. This is a convenient
|
||||
@@ -597,7 +629,8 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
// array word assignment.
|
||||
bool widx_flag = false;
|
||||
|
||||
list<long> unpacked_indices_const;
|
||||
// Whether the signal is an array
|
||||
const bool sig_is_array = sig->unpacked_dimensions() > 0;
|
||||
|
||||
// Detect the net is a structure and there was a method path
|
||||
// detected. We have already broken the path_ into the path to
|
||||
@@ -666,6 +699,8 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
return 0;
|
||||
}
|
||||
|
||||
use_path.pop_front();
|
||||
|
||||
member_off += tmp_off;
|
||||
member_width = member->net_type->packed_width();
|
||||
|
||||
@@ -673,9 +708,8 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
struct_type = tmp_struct;
|
||||
} else {
|
||||
struct_type = 0;
|
||||
assert (use_path.empty());
|
||||
}
|
||||
|
||||
use_path.pop_front();
|
||||
}
|
||||
|
||||
// Look for part selects on the final member. For example if
|
||||
@@ -724,7 +758,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
member_select.sel = index_component_t::SEL_BIT;
|
||||
member_select.msb = new PENumber(new verinum(member_off));
|
||||
tmp_index.push_back(member_select);
|
||||
NetExpr*packed_base = collapse_array_indices(des, scope, sig, tmp_index);
|
||||
const NetExpr*packed_base = collapse_array_indices(des, scope, sig, tmp_index);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
|
||||
@@ -733,7 +767,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
}
|
||||
}
|
||||
|
||||
} else if (gn_system_verilog() && sig->unpacked_dimensions() > 0 && path_tail.index.empty()) {
|
||||
} else if (gn_system_verilog() && sig_is_array && path_tail.index.empty()) {
|
||||
|
||||
// In this case, we are doing a continuous assignment to
|
||||
// an unpacked array. The NetNet representation is a
|
||||
@@ -743,21 +777,24 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
// This can come up from code like this:
|
||||
// logic [...] data [0:3];
|
||||
// assign data = ...;
|
||||
// In this case, "sig" is "data", and sig->pin_count()
|
||||
// is 4 to account for the unpacked size.
|
||||
// In this case, "sig" is "data".
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
|
||||
<< "Net assign to unpacked array \"" << sig->name()
|
||||
<< "\" with " << sig->pin_count() << " elements." << endl;
|
||||
}
|
||||
|
||||
} else if (sig->unpacked_dimensions() > 0) {
|
||||
} else if (sig_is_array) {
|
||||
|
||||
list<long> unpacked_indices_const;
|
||||
|
||||
// Make sure there are enough indices to address an array element.
|
||||
if (path_tail.index.size() < sig->unpacked_dimensions()) {
|
||||
cerr << get_fileline() << ": error: Array " << path()
|
||||
<< " needs " << sig->unpacked_dimensions() << " indices,"
|
||||
<< " but got only " << path_tail.index.size() << ". (net)" << endl;
|
||||
cerr << get_fileline() << ": : Assignment to a whole array requires SystemVerilog."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -804,7 +841,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
widx_flag = true;
|
||||
|
||||
} else {
|
||||
NetEConst*canon_const = dynamic_cast<NetEConst*>(canon_index);
|
||||
const NetEConst*canon_const = dynamic_cast<NetEConst*>(canon_index);
|
||||
ivl_assert(*this, canon_const);
|
||||
|
||||
widx = canon_const->value().as_long();
|
||||
@@ -909,7 +946,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
}
|
||||
}
|
||||
|
||||
if (sig->pin_count() > 1 && widx_flag) {
|
||||
if (sig_is_array && widx_flag) {
|
||||
if (widx < 0 || widx >= (long) sig->pin_count())
|
||||
return 0;
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
@@ -919,7 +956,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
connect(sig->pin(widx), tmp->pin(0));
|
||||
sig = tmp;
|
||||
|
||||
} else if (sig->pin_count() > 1) {
|
||||
} else if (sig_is_array) {
|
||||
|
||||
// If this turns out to be an l-value unpacked array,
|
||||
// then let the caller handle it. It will probably be
|
||||
@@ -946,8 +983,8 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
<< " wid=" << subnet_wid <<"]"
|
||||
<< endl;
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(sig->data_type(),
|
||||
subnet_wid-1,0);
|
||||
const netvector_t*tmp2_vec = new netvector_t(sig->data_type(),
|
||||
subnet_wid-1,0);
|
||||
NetNet*subsig = new NetNet(sig->scope(),
|
||||
sig->scope()->local_symbol(),
|
||||
NetNet::WIRE, tmp2_vec);
|
||||
@@ -982,14 +1019,16 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
* Identifiers in continuous assignment l-values are limited to wires
|
||||
* and that ilk. Detect registers and memories here and report errors.
|
||||
*/
|
||||
NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope) const
|
||||
NetNet* PEIdent::elaborate_lnet(Design*des, NetScope*scope,
|
||||
bool var_allowed_in_sv) const
|
||||
{
|
||||
return elaborate_lnet_common_(des, scope, false);
|
||||
return elaborate_lnet_common_(des, scope, false, var_allowed_in_sv);
|
||||
}
|
||||
|
||||
NetNet* PEIdent::elaborate_bi_net(Design*des, NetScope*scope) const
|
||||
NetNet* PEIdent::elaborate_bi_net(Design*des, NetScope*scope,
|
||||
bool var_allowed_in_sv) const
|
||||
{
|
||||
return elaborate_lnet_common_(des, scope, true);
|
||||
return elaborate_lnet_common_(des, scope, true, var_allowed_in_sv);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1091,7 +1130,7 @@ NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const
|
||||
unsigned swid = abs(midx - lidx) + 1;
|
||||
ivl_assert(*this, swid > 0 && swid < sig->vector_width());
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(sig->data_type(),swid-1,0);
|
||||
const netvector_t*tmp2_vec = new netvector_t(sig->data_type(),swid-1,0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, tmp2_vec);
|
||||
tmp->port_type(sig->port_type());
|
||||
@@ -1138,10 +1177,14 @@ NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const
|
||||
NetNet*PEIdent::elaborate_unpacked_net(Design*des, NetScope*scope) const
|
||||
{
|
||||
symbol_search_results sr;
|
||||
symbol_search(this, des, scope, path_, lexical_pos_, &sr);
|
||||
symbol_search(this, des, scope, path_, lexical_pos(), &sr);
|
||||
if (!sr.net) {
|
||||
cerr << get_fileline() << ": error: Net " << path_
|
||||
<< " is not defined in this context." << endl;
|
||||
if (sr.is_found()) {
|
||||
cerr << sr.scope->get_fileline() << ": : Found a "
|
||||
<< sr.result_type() << " with this name here." << endl;
|
||||
}
|
||||
if (sr.decl_after_use) {
|
||||
cerr << sr.decl_after_use->get_fileline() << ": : "
|
||||
"A symbol with that name was declared here. "
|
||||
@@ -1168,7 +1211,7 @@ bool PEIdent::is_collapsible_net(Design*des, NetScope*scope,
|
||||
ivl_assert(*this, scope);
|
||||
|
||||
symbol_search_results sr;
|
||||
symbol_search(this, des, scope, path_.name, lexical_pos_, &sr);
|
||||
symbol_search(this, des, scope, path_.name, lexical_pos(), &sr);
|
||||
|
||||
if (sr.eve != 0)
|
||||
return false;
|
||||
|
||||
+132
-36
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2024 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2025 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
void set_scope_timescale(Design*des, NetScope*scope, PScope*pscope)
|
||||
void set_scope_timescale(Design*des, NetScope*scope, const PScope*pscope)
|
||||
{
|
||||
scope->time_unit(pscope->time_unit);
|
||||
scope->time_precision(pscope->time_precision);
|
||||
@@ -218,7 +218,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||
// There is an explicit value. elaborate/evaluate
|
||||
// the value and assign it to the enumeration name.
|
||||
NetExpr*val = elab_and_eval(des, scope, cur->parm, -1);
|
||||
NetEConst*val_const = dynamic_cast<NetEConst*> (val);
|
||||
const NetEConst*val_const = dynamic_cast<NetEConst*> (val);
|
||||
if (val_const == 0) {
|
||||
cerr << use_enum->get_fileline()
|
||||
<< ": error: Enumeration expression for "
|
||||
@@ -241,7 +241,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||
}
|
||||
// If this is a literal constant and it has a defined
|
||||
// width then the width must match the enumeration width.
|
||||
if (PENumber *tmp = dynamic_cast<PENumber*>(cur->parm)) {
|
||||
if (const PENumber *tmp = dynamic_cast<PENumber*>(cur->parm)) {
|
||||
if (tmp->value().has_len() &&
|
||||
(tmp->value().len() != enum_width)) {
|
||||
cerr << use_enum->get_fileline()
|
||||
@@ -355,7 +355,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||
}
|
||||
|
||||
rc_flag = use_enum->insert_name(name_idx, cur->name, cur_value);
|
||||
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
|
||||
rc_flag &= scope->add_enumeration_name(use_enum, cur->name, *cur);
|
||||
|
||||
if (! rc_flag) {
|
||||
cerr << use_enum->get_fileline()
|
||||
@@ -487,19 +487,7 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||
}
|
||||
|
||||
|
||||
const netclass_t*use_base_class = 0;
|
||||
if (use_type->base_type) {
|
||||
ivl_type_t base_type = use_type->base_type->elaborate_type(des, scope);
|
||||
use_base_class = dynamic_cast<const netclass_t *>(base_type);
|
||||
if (!use_base_class) {
|
||||
cerr << pclass->get_fileline() << ": error: "
|
||||
<< "Base type of " << use_type->name
|
||||
<< " is not a class." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
netclass_t*use_class = new netclass_t(use_type->name, use_base_class);
|
||||
netclass_t*use_class = new netclass_t(use_type->name);
|
||||
|
||||
NetScope*class_scope = new NetScope(scope, hname_t(pclass->pscope_name()),
|
||||
NetScope::CLASS, scope->unit());
|
||||
@@ -583,6 +571,43 @@ static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||
scope->add_class(use_class);
|
||||
}
|
||||
|
||||
static void elaborate_scope_class_bind_super(Design *des, NetScope *scope,
|
||||
PClass *pclass)
|
||||
{
|
||||
auto *class_type = pclass->type;
|
||||
|
||||
if (!class_type->base_type)
|
||||
return;
|
||||
|
||||
ivl_type_t elaborated_base_type =
|
||||
class_type->base_type->elaborate_type(des, scope);
|
||||
const auto *base_class =
|
||||
dynamic_cast<const netclass_t *>(elaborated_base_type);
|
||||
if (!base_class) {
|
||||
cerr << pclass->get_fileline() << ": error: "
|
||||
<< "Base type of " << class_type->name
|
||||
<< " is not a class." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
auto *derived_class = scope->find_class(des, class_type->name);
|
||||
ivl_assert(*pclass, derived_class);
|
||||
|
||||
for (auto ancestor = base_class; ancestor;
|
||||
ancestor = ancestor->get_super()) {
|
||||
if (ancestor == derived_class) {
|
||||
cerr << pclass->get_fileline() << ": error: "
|
||||
<< "Inheritance cycle detected for class `"
|
||||
<< class_type->name << "`." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
derived_class->set_super(base_class);
|
||||
}
|
||||
|
||||
static void elaborate_scope_classes(Design*des, NetScope*scope,
|
||||
const vector<PClass*>&classes)
|
||||
{
|
||||
@@ -597,6 +622,9 @@ static void elaborate_scope_classes(Design*des, NetScope*scope,
|
||||
blend_class_constructors(classes[idx]);
|
||||
elaborate_scope_class(des, scope, classes[idx]);
|
||||
}
|
||||
|
||||
for (auto pclass : classes)
|
||||
elaborate_scope_class_bind_super(des, scope, pclass);
|
||||
}
|
||||
|
||||
static void replace_scope_parameters(Design *des, NetScope*scope, const LineInfo&loc,
|
||||
@@ -706,7 +734,7 @@ class generate_schemes_work_item_t : public elaborator_work_item_t {
|
||||
: elaborator_work_item_t(des__), scope_(scope), mod_(mod)
|
||||
{ }
|
||||
|
||||
void elaborate_runrun()
|
||||
void elaborate_runrun() override
|
||||
{
|
||||
if (debug_scopes)
|
||||
cerr << mod_->get_fileline() << ": debug: "
|
||||
@@ -942,7 +970,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
while (cscope && !cscope->find_genvar(loop_index)) {
|
||||
if (cscope->symbol_exists(loop_index)) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "generate loop variable '" << loop_index
|
||||
<< "generate \"loop\" variable '" << loop_index
|
||||
<< "' is not a genvar in this scope." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
@@ -965,10 +993,18 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
// use) the genvar itself, so we can evaluate this expression
|
||||
// the same way any other parameter value is evaluated.
|
||||
NetExpr*init_ex = elab_and_eval(des, container, loop_init, -1, true);
|
||||
NetEConst*init = dynamic_cast<NetEConst*> (init_ex);
|
||||
const NetEConst*init = dynamic_cast<NetEConst*> (init_ex);
|
||||
if (init == 0) {
|
||||
cerr << get_fileline() << ": error: Cannot evaluate genvar"
|
||||
<< " init expression: " << *loop_init << endl;
|
||||
cerr << get_fileline() << ": error: "
|
||||
"Cannot evaluate generate \"loop\" initialization "
|
||||
"expression: " << *loop_init << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
if (! init->value().is_defined()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Generate \"loop\" initialization expression cannot have "
|
||||
"undefined bits. given (" << *loop_init << ")." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
@@ -979,16 +1015,25 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: genvar init = " << genvar << endl;
|
||||
|
||||
container->genvar_tmp = loop_index;
|
||||
container->genvar_tmp_val = genvar;
|
||||
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1, true);
|
||||
NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
|
||||
const NetEConst*test = dynamic_cast<NetEConst*>(test_ex);
|
||||
if (test == 0) {
|
||||
cerr << get_fileline() << ": error: Cannot evaluate genvar"
|
||||
<< " conditional expression: " << *loop_test << endl;
|
||||
cerr << get_fileline() << ": error: Cannot evaluate generate \"loop\" "
|
||||
"conditional expression: " << *loop_test << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
if (! test->value().is_defined()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
"Generate \"loop\" conditional expression cannot have "
|
||||
"undefined bits. given (" << *loop_test << ")." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
unsigned long loop_count = 1;
|
||||
while (test->value().as_long()) {
|
||||
|
||||
// The actual name of the scope includes the genvar so
|
||||
@@ -996,10 +1041,17 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
// container. The format of using [] is part of the
|
||||
// Verilog standard.
|
||||
hname_t use_name (scope_name, genvar);
|
||||
if (container->child(use_name)) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
"Trying to create a duplicate generate scope named \""
|
||||
<< use_name << "\"." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Create generated scope " << use_name << endl;
|
||||
"Create generated scope " << use_name << endl;
|
||||
|
||||
NetScope*scope = new NetScope(container, use_name,
|
||||
NetScope::GENBLOCK);
|
||||
@@ -1025,7 +1077,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
scope->set_parameter(loop_index, gp, *this);
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Create implicit localparam "
|
||||
"Create implicit localparam "
|
||||
<< loop_index << " = " << genvar_verinum << endl;
|
||||
}
|
||||
|
||||
@@ -1035,8 +1087,8 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
NetExpr*step_ex = elab_and_eval(des, container, loop_step, -1, true);
|
||||
NetEConst*step = dynamic_cast<NetEConst*>(step_ex);
|
||||
if (step == 0) {
|
||||
cerr << get_fileline() << ": error: Cannot evaluate genvar"
|
||||
<< " step expression: " << *loop_step << endl;
|
||||
cerr << get_fileline() << ": error: Cannot evaluate generate "
|
||||
"\"loop\" increment expression: " << *loop_step << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
@@ -1044,7 +1096,24 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
cerr << get_fileline() << ": debug: genvar step from "
|
||||
<< genvar << " to " << step->value().as_long() << endl;
|
||||
|
||||
genvar = step->value().as_long();
|
||||
if (! step->value().is_defined()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
"Generate \"loop\" increment expression cannot have "
|
||||
"undefined bits, given (" << *loop_step << ")." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
long next_genvar;
|
||||
next_genvar = step->value().as_long();
|
||||
if (next_genvar == genvar) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "The generate \"loop\" is not incrementing. The "
|
||||
"previous and next genvar values are ("
|
||||
<< genvar << ")." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
genvar = next_genvar;
|
||||
check_for_valid_genvar_value_(genvar);
|
||||
container->genvar_tmp_val = genvar;
|
||||
delete step;
|
||||
@@ -1052,6 +1121,24 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
test_ex = elab_and_eval(des, container, loop_test, -1, true);
|
||||
test = dynamic_cast<NetEConst*>(test_ex);
|
||||
ivl_assert(*this, test);
|
||||
if (! test->value().is_defined()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
"The generate \"loop\" conditional expression cannot have "
|
||||
"undefined bits. given (" << *loop_test << ")." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// If there are half a million iterations this is likely an infinite loop!
|
||||
if (loop_count > 500000) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Probable infinite loop detected in generate \"loop\". "
|
||||
"It has run for " << loop_count
|
||||
<< " iterations." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
++loop_count;
|
||||
}
|
||||
|
||||
// Clear the genvar_tmp field in the scope to reflect that the
|
||||
@@ -1064,7 +1151,7 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
bool PGenerate::generate_scope_condit_(Design*des, NetScope*container, bool else_flag)
|
||||
{
|
||||
NetExpr*test_ex = elab_and_eval(des, container, loop_test, -1, true);
|
||||
NetEConst*test = dynamic_cast<NetEConst*> (test_ex);
|
||||
const NetEConst*test = dynamic_cast<NetEConst*> (test_ex);
|
||||
if (test == 0) {
|
||||
cerr << get_fileline() << ": error: Cannot evaluate genvar"
|
||||
<< " conditional expression: " << *loop_test << endl;
|
||||
@@ -1263,6 +1350,10 @@ void PGenerate::elaborate_subscope_(Design*des, NetScope*scope)
|
||||
|
||||
collect_scope_signals(scope, wires);
|
||||
|
||||
elaborate_scope_enumerations(des, scope, enum_sets);
|
||||
|
||||
elaborate_scope_classes(des, scope, classes_lexical);
|
||||
|
||||
// Run through the defparams for this scope and save the result
|
||||
// in a table for later final override.
|
||||
|
||||
@@ -1321,9 +1412,9 @@ class delayed_elaborate_scope_mod_instances : public elaborator_work_item_t {
|
||||
NetScope*sc)
|
||||
: elaborator_work_item_t(des__), obj_(obj), mod_(mod), sc_(sc)
|
||||
{ }
|
||||
~delayed_elaborate_scope_mod_instances() { }
|
||||
~delayed_elaborate_scope_mod_instances() override { }
|
||||
|
||||
virtual void elaborate_runrun();
|
||||
virtual void elaborate_runrun() override;
|
||||
|
||||
private:
|
||||
const PGModule*obj_;
|
||||
@@ -1577,7 +1668,6 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
||||
void PEvent::elaborate_scope(Design*, NetScope*scope) const
|
||||
{
|
||||
NetEvent*ev = new NetEvent(name_);
|
||||
ev->lexical_pos(lexical_pos_);
|
||||
ev->set_line(*this);
|
||||
scope->add_event(ev);
|
||||
}
|
||||
@@ -1603,6 +1693,8 @@ void PFunction::elaborate_scope(Design*des, NetScope*scope) const
|
||||
|
||||
collect_scope_signals(scope, wires);
|
||||
|
||||
elaborate_scope_enumerations(des, scope, enum_sets);
|
||||
|
||||
// Scan through all the named events in this scope.
|
||||
elaborate_scope_events_(des, scope, events);
|
||||
|
||||
@@ -1623,6 +1715,8 @@ void PTask::elaborate_scope(Design*des, NetScope*scope) const
|
||||
|
||||
collect_scope_signals(scope, wires);
|
||||
|
||||
elaborate_scope_enumerations(des, scope, enum_sets);
|
||||
|
||||
// Scan through all the named events in this scope.
|
||||
elaborate_scope_events_(des, scope, events);
|
||||
|
||||
@@ -1673,6 +1767,8 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
||||
|
||||
collect_scope_signals(my_scope, wires);
|
||||
|
||||
elaborate_scope_enumerations(des, my_scope, enum_sets);
|
||||
|
||||
// Scan through all the named events in this scope.
|
||||
elaborate_scope_events_(des, my_scope, events);
|
||||
}
|
||||
@@ -1692,7 +1788,7 @@ void PCase::elaborate_scope(Design*des, NetScope*scope) const
|
||||
for (unsigned idx = 0 ; idx < (*items_).size() ; idx += 1) {
|
||||
ivl_assert(*this, (*items_)[idx]);
|
||||
|
||||
if (Statement*sp = (*items_)[idx]->stat)
|
||||
if (const Statement*sp = (*items_)[idx]->stat)
|
||||
sp -> elaborate_scope(des, scope);
|
||||
}
|
||||
}
|
||||
|
||||
+50
-38
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2024 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2026 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -44,6 +44,7 @@
|
||||
# include "netqueue.h"
|
||||
# include "netscalar.h"
|
||||
# include "util.h"
|
||||
# include "parse_api.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
using namespace std;
|
||||
@@ -90,8 +91,8 @@ void Statement::elaborate_sig(Design*, NetScope*) const
|
||||
{
|
||||
}
|
||||
|
||||
static void sig_check_data_type(Design*des, NetScope*scope,
|
||||
PWire *wire, NetNet *sig)
|
||||
static void sig_check_data_type(Design*des, const NetScope*scope,
|
||||
const PWire *wire, NetNet *sig)
|
||||
{
|
||||
ivl_type_t type = sig->net_type();
|
||||
|
||||
@@ -141,8 +142,8 @@ static void sig_check_data_type(Design*des, NetScope*scope,
|
||||
}
|
||||
}
|
||||
|
||||
static void sig_check_port_type(Design*des, NetScope*scope,
|
||||
PWire *wire, NetNet *sig)
|
||||
static void sig_check_port_type(Design*des, const NetScope*scope,
|
||||
const PWire *wire, const NetNet *sig)
|
||||
{
|
||||
if (sig->port_type() == NetNet::PREF) {
|
||||
cerr << wire->get_fileline() << ": sorry: "
|
||||
@@ -298,6 +299,12 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
if (pp == 0)
|
||||
continue;
|
||||
|
||||
if (pp->is_interface_port()) {
|
||||
interface_formal_port_t formal;
|
||||
resolve_interface_formal_port(this, des, pp, formal, true);
|
||||
continue;
|
||||
}
|
||||
|
||||
// The port has a name and an array of expressions. The
|
||||
// expression are all identifiers that should reference
|
||||
// wires within the scope.
|
||||
@@ -397,11 +404,6 @@ void netclass_t::elaborate_sig(Design*des, PClass*pclass)
|
||||
<< " type=" << *use_type << endl;
|
||||
}
|
||||
|
||||
if (dynamic_cast<const netqueue_t *> (use_type)) {
|
||||
cerr << cur->second.get_fileline() << ": sorry: "
|
||||
<< "Queues inside classes are not yet supported." << endl;
|
||||
des->errors++;
|
||||
}
|
||||
set_property(cur->first, cur->second.qual, use_type);
|
||||
|
||||
if (! cur->second.qual.test_static())
|
||||
@@ -414,8 +416,17 @@ void netclass_t::elaborate_sig(Design*des, PClass*pclass)
|
||||
<< "." << endl;
|
||||
}
|
||||
|
||||
/* NetNet*sig = */ new NetNet(class_scope_, cur->first, NetNet::REG,
|
||||
use_type);
|
||||
auto sig = new NetNet(class_scope_, cur->first, NetNet::REG,
|
||||
use_type);
|
||||
sig->set_line(cur->second);
|
||||
sig->set_const(cur->second.qual.test_const());
|
||||
|
||||
if (cur->second.qual.test_const() &&
|
||||
cur->second.has_initializer) {
|
||||
int pidx = property_idx_from_name(cur->first);
|
||||
ivl_assert(cur->second, pidx >= 0);
|
||||
set_prop_initialized(pidx);
|
||||
}
|
||||
}
|
||||
|
||||
for (map<perm_string,PFunction*>::iterator cur = pclass->funcs.begin()
|
||||
@@ -449,23 +460,19 @@ bool PGate::elaborate_sig(Design*, NetScope*) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PGBuiltin::elaborate_sig(Design*, NetScope*) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PGAssign::elaborate_sig(Design*, NetScope*) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
|
||||
Module*rmod) const
|
||||
const Module*rmod) const
|
||||
{
|
||||
bool flag = true;
|
||||
|
||||
NetScope::scope_vec_t instance = scope->instance_arrays[get_name()];
|
||||
|
||||
vector<PExpr*>pins (rmod->port_count());
|
||||
vector<bool>pins_fromwc (rmod->port_count(), false);
|
||||
vector<bool>pins_is_explicitly_not_connected (rmod->port_count(), false);
|
||||
flag &= match_module_ports_(des, rmod, scope, pins, pins_fromwc,
|
||||
pins_is_explicitly_not_connected);
|
||||
|
||||
for (unsigned idx = 0 ; idx < instance.size() ; idx += 1) {
|
||||
// I know a priori that the elaborate_scope created the scope
|
||||
// already, so just look it up as a child of the current scope.
|
||||
@@ -481,6 +488,9 @@ bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
|
||||
}
|
||||
ivl_assert(*this, my_scope->parent() == scope);
|
||||
|
||||
if (!bind_interface_ports_(des, rmod, scope, my_scope, pins, pins_fromwc))
|
||||
flag = false;
|
||||
|
||||
if (! rmod->elaborate_sig(des, my_scope))
|
||||
flag = false;
|
||||
|
||||
@@ -517,7 +527,7 @@ bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
|
||||
typedef list<PGenerate*>::const_iterator generate_it_t;
|
||||
for (generate_it_t cur = generate_schemes.begin()
|
||||
; cur != generate_schemes.end() ; ++ cur ) {
|
||||
PGenerate*item = *cur;
|
||||
const PGenerate*item = *cur;
|
||||
if (item->directly_nested || !item->scope_list_.empty()) {
|
||||
flag &= item->elaborate_sig(des, container);
|
||||
}
|
||||
@@ -538,7 +548,7 @@ bool PGenerate::elaborate_sig(Design*des, NetScope*container) const
|
||||
cerr << get_fileline() << ": debug: Elaborate nets in "
|
||||
<< "scope " << scope_path(*cur)
|
||||
<< " in generate " << id_number << endl;
|
||||
flag = elaborate_sig_(des, *cur) & flag;
|
||||
flag &= elaborate_sig_(des, *cur) && flag;
|
||||
}
|
||||
|
||||
return flag;
|
||||
@@ -565,7 +575,7 @@ bool PGenerate::elaborate_sig_direct_(Design*des, NetScope*container) const
|
||||
if (item->scheme_type == PGenerate::GS_CASE) {
|
||||
for (generate_it_t icur = item->generate_schemes.begin()
|
||||
; icur != item->generate_schemes.end() ; ++ icur ) {
|
||||
PGenerate*case_item = *icur;
|
||||
const PGenerate*case_item = *icur;
|
||||
if (case_item->directly_nested || !case_item->scope_list_.empty()) {
|
||||
flag &= case_item->elaborate_sig(des, container);
|
||||
}
|
||||
@@ -584,6 +594,7 @@ bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
|
||||
{
|
||||
// Scan the declared PWires to elaborate the obvious signals
|
||||
// in the current scope.
|
||||
bool flag = true;
|
||||
typedef map<perm_string,PWire*>::const_iterator wires_it_t;
|
||||
for (wires_it_t wt = wires.begin()
|
||||
; wt != wires.end() ; ++ wt ) {
|
||||
@@ -594,32 +605,34 @@ bool PGenerate::elaborate_sig_(Design*des, NetScope*scope) const
|
||||
cerr << get_fileline() << ": debug: Elaborate PWire "
|
||||
<< cur->basename() << " in scope " << scope_path(scope) << endl;
|
||||
|
||||
cur->elaborate_sig(des, scope);
|
||||
const NetNet* res = cur->elaborate_sig(des, scope);
|
||||
flag &= (res != nullptr);
|
||||
}
|
||||
|
||||
elaborate_sig_funcs(des, scope, funcs);
|
||||
elaborate_sig_tasks(des, scope, tasks);
|
||||
elaborate_sig_classes(des, scope, classes);
|
||||
|
||||
typedef list<PGenerate*>::const_iterator generate_it_t;
|
||||
for (generate_it_t cur = generate_schemes.begin()
|
||||
; cur != generate_schemes.end() ; ++ cur ) {
|
||||
(*cur) -> elaborate_sig(des, scope);
|
||||
flag &= (*cur)->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
typedef list<PGate*>::const_iterator pgate_list_it_t;
|
||||
for (pgate_list_it_t cur = gates.begin()
|
||||
; cur != gates.end() ; ++ cur ) {
|
||||
(*cur) ->elaborate_sig(des, scope);
|
||||
flag &= (*cur)->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
typedef list<PProcess*>::const_iterator proc_it_t;
|
||||
for (proc_it_t cur = behaviors.begin()
|
||||
; cur != behaviors.end() ; ++ cur ) {
|
||||
(*cur) -> statement() -> elaborate_sig(des, scope);
|
||||
(*cur)->statement()->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
return flag;
|
||||
}
|
||||
|
||||
|
||||
@@ -671,7 +684,7 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
ivl_assert(*this, ret_type);
|
||||
}
|
||||
} else {
|
||||
netvector_t*tmp = new netvector_t(IVL_VT_LOGIC);
|
||||
const netvector_t*tmp = new netvector_t(IVL_VT_LOGIC);
|
||||
ret_type = tmp;
|
||||
}
|
||||
|
||||
@@ -970,7 +983,7 @@ bool test_ranges_eeq(const netranges_t&lef, const netranges_t&rig)
|
||||
ivl_type_t PWire::elaborate_type(Design*des, NetScope*scope,
|
||||
const netranges_t &packed_dimensions) const
|
||||
{
|
||||
vector_type_t *vec_type = dynamic_cast<vector_type_t*>(set_data_type_.get());
|
||||
const vector_type_t *vec_type = dynamic_cast<vector_type_t*>(set_data_type_.get());
|
||||
if (set_data_type_ && !vec_type) {
|
||||
ivl_assert(*this, packed_dimensions.empty());
|
||||
return set_data_type_->elaborate_type(des, scope);
|
||||
@@ -1156,8 +1169,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope)
|
||||
}
|
||||
|
||||
unsigned nattrib = 0;
|
||||
attrib_list_t*attrib_list = evaluate_attributes(attributes, nattrib,
|
||||
des, scope);
|
||||
const attrib_list_t*attrib_list = evaluate_attributes(attributes, nattrib,
|
||||
des, scope);
|
||||
|
||||
/* If the net type is supply0 or supply1, replace it
|
||||
with a simple wire with a pulldown/pullup with supply
|
||||
@@ -1189,8 +1202,8 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope)
|
||||
pull = new NetLogic(scope, scope->local_symbol(),
|
||||
1, pull_type, wid);
|
||||
pull->set_line(*this);
|
||||
pull->pin(0).drive0(IVL_DR_SUPPLY);
|
||||
pull->pin(0).drive1(IVL_DR_SUPPLY);
|
||||
pull->pin(0).drive(drive_strength_t(IVL_DR_SUPPLY,
|
||||
IVL_DR_SUPPLY));
|
||||
des->add_node(pull);
|
||||
wtype = NetNet::WIRE;
|
||||
}
|
||||
@@ -1223,7 +1236,6 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope)
|
||||
if (wtype == NetNet::WIRE) sig->devirtualize_pins();
|
||||
sig->set_line(*this);
|
||||
sig->port_type(port_type_);
|
||||
sig->lexical_pos(lexical_pos_);
|
||||
|
||||
if (ivl_discipline_t dis = get_discipline()) {
|
||||
sig->set_discipline(dis);
|
||||
|
||||
+10
-29
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012-2024 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2012-2026 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -220,11 +220,13 @@ ivl_type_t struct_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
|
||||
res->set_line(*this);
|
||||
|
||||
res->packed(packed_flag);
|
||||
bool is_packed = packed_flag || (union_flag && soft_flag);
|
||||
res->packed(is_packed);
|
||||
res->set_signed(signed_flag);
|
||||
|
||||
if (union_flag)
|
||||
res->union_flag(true);
|
||||
if (union_flag) {
|
||||
res->union_flag(true, soft_flag);
|
||||
}
|
||||
|
||||
for (list<struct_member_t*>::iterator cur = members->begin()
|
||||
; cur != members->end() ; ++ cur) {
|
||||
@@ -242,7 +244,7 @@ ivl_type_t struct_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
; cur_name != curp->names->end() ; ++ cur_name) {
|
||||
decl_assignment_t*namep = *cur_name;
|
||||
|
||||
if (packed_flag && namep->expr) {
|
||||
if (is_packed && namep->expr) {
|
||||
cerr << namep->expr->get_fileline() << " error: "
|
||||
<< "Packed structs must not have default member values."
|
||||
<< endl;
|
||||
@@ -372,9 +374,8 @@ ivl_type_t elaborate_array_type(Design *des, NetScope *scope,
|
||||
type = elaborate_darray_check_type(des, li, type, "Dynamic array");
|
||||
type = new netdarray_t(type);
|
||||
continue;
|
||||
} else if (dynamic_cast<PENull*>(lidx)) {
|
||||
// Special case: Detect the mark for a QUEUE declaration,
|
||||
// which is the dimensions [null:max_idx].
|
||||
} else if (dynamic_cast<PEQueueDimension*>(lidx)) {
|
||||
// Special case: Detect the mark for a QUEUE declaration.
|
||||
type = elaborate_static_array_type(des, li, type, dimensions);
|
||||
type = elaborate_queue_type(des, scope, li, type, ridx);
|
||||
continue;
|
||||
@@ -450,27 +451,7 @@ ivl_type_t typedef_t::elaborate_type(Design *des, NetScope *scope)
|
||||
if (!elab_type)
|
||||
return netvector_t::integer_type();
|
||||
|
||||
bool type_ok = true;
|
||||
switch (basic_type) {
|
||||
case ENUM:
|
||||
type_ok = dynamic_cast<const netenum_t *>(elab_type);
|
||||
break;
|
||||
case STRUCT: {
|
||||
const netstruct_t *struct_type = dynamic_cast<const netstruct_t *>(elab_type);
|
||||
type_ok = struct_type && !struct_type->union_flag();
|
||||
break;
|
||||
}
|
||||
case UNION: {
|
||||
const netstruct_t *struct_type = dynamic_cast<const netstruct_t *>(elab_type);
|
||||
type_ok = struct_type && struct_type->union_flag();
|
||||
break;
|
||||
}
|
||||
case CLASS:
|
||||
type_ok = dynamic_cast<const netclass_t *>(elab_type);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
bool type_ok = basic_type.matches(elab_type);
|
||||
|
||||
if (!type_ok) {
|
||||
cerr << data_type->get_fileline() << " error: "
|
||||
|
||||
+919
-285
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2021 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2025 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -391,7 +391,7 @@ void NetBlock::emit_recurse(struct target_t*tgt) const
|
||||
if (last_ == 0)
|
||||
return;
|
||||
|
||||
NetProc*cur = last_;
|
||||
const NetProc*cur = last_;
|
||||
do {
|
||||
cur = cur->next_;
|
||||
cur->emit_proc(tgt);
|
||||
@@ -467,7 +467,7 @@ void NetScope::emit_scope(struct target_t*tgt) const
|
||||
|
||||
tgt->scope(this);
|
||||
|
||||
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_)
|
||||
for (const NetEvent*cur = events_ ; cur ; cur = cur->snext_)
|
||||
tgt->event(cur);
|
||||
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
@@ -566,7 +566,7 @@ int Design::emit(struct target_t*tgt) const
|
||||
// emit nodes
|
||||
bool nodes_rc = true;
|
||||
if (nodes_) {
|
||||
NetNode*cur = nodes_->node_next_;
|
||||
const NetNode*cur = nodes_->node_next_;
|
||||
do {
|
||||
nodes_rc = nodes_rc && cur->emit_node(tgt);
|
||||
cur = cur->node_next_;
|
||||
@@ -575,7 +575,7 @@ int Design::emit(struct target_t*tgt) const
|
||||
|
||||
|
||||
bool branches_rc = true;
|
||||
for (NetBranch*cur = branches_ ; cur ; cur = cur->next_) {
|
||||
for (const NetBranch*cur = branches_ ; cur ; cur = cur->next_) {
|
||||
branches_rc = tgt->branch(cur) && branches_rc;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2021 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-2025 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -58,9 +58,9 @@ attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
|
||||
if (!tmp)
|
||||
continue;
|
||||
|
||||
if (NetEConst *ce = dynamic_cast<NetEConst*>(tmp)) {
|
||||
if (const NetEConst *ce = dynamic_cast<NetEConst*>(tmp)) {
|
||||
table[idx].val = ce->value();
|
||||
} else if (NetECReal *cer = dynamic_cast<NetECReal*>(tmp)) {
|
||||
} else if (const NetECReal *cer = dynamic_cast<NetECReal*>(tmp)) {
|
||||
table[idx].val = verinum(cer->value().as_long());
|
||||
} else {
|
||||
cerr << exp->get_fileline() << ": error: ``"
|
||||
|
||||
+32
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2022 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2026 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -26,6 +26,7 @@
|
||||
# include <cmath>
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netclass.h"
|
||||
# include "ivl_assert.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
@@ -153,8 +154,8 @@ NetExpr* NetEBAdd::eval_tree()
|
||||
// example, the expression (a + 2) - 1 can be rewritten as a + 1.
|
||||
|
||||
NetEBAdd*se = dynamic_cast<NetEBAdd*>(left_);
|
||||
NetEConst*lc = se? dynamic_cast<NetEConst*>(se->right_) : NULL;
|
||||
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
|
||||
const NetEConst*lc = se? dynamic_cast<NetEConst*>(se->right_) : NULL;
|
||||
const NetEConst*rc = dynamic_cast<NetEConst*>(right_);
|
||||
|
||||
if (lc != 0 && rc != 0) {
|
||||
ivl_assert(*this, se != 0);
|
||||
@@ -1194,12 +1195,12 @@ NetEConst* NetEConcat::eval_arguments_(const vector<NetExpr*>&vals,
|
||||
NetEConst* NetESelect::eval_tree()
|
||||
{
|
||||
eval_expr(expr_);
|
||||
NetEConst*expr = dynamic_cast<NetEConst*>(expr_);
|
||||
const NetEConst*expr = dynamic_cast<NetEConst*>(expr_);
|
||||
|
||||
long bval = 0;
|
||||
if (base_) {
|
||||
eval_expr(base_);
|
||||
NetEConst*base = dynamic_cast<NetEConst*>(base_);
|
||||
const NetEConst*base = dynamic_cast<NetEConst*>(base_);
|
||||
|
||||
if (base == 0) return 0;
|
||||
|
||||
@@ -1242,11 +1243,11 @@ NetEConst* NetESelect::eval_tree()
|
||||
|
||||
static void print_ternary_cond(NetExpr*expr)
|
||||
{
|
||||
if (NetEConst*c = dynamic_cast<NetEConst*>(expr)) {
|
||||
if (const NetEConst*c = dynamic_cast<NetEConst*>(expr)) {
|
||||
cerr << c->value() << endl;
|
||||
return;
|
||||
}
|
||||
if (NetECReal*c = dynamic_cast<NetECReal*>(expr)) {
|
||||
if (const NetECReal*c = dynamic_cast<NetECReal*>(expr)) {
|
||||
cerr << c->value() << endl;
|
||||
return;
|
||||
}
|
||||
@@ -1687,7 +1688,7 @@ NetEConst* NetESFunc::evaluate_clog2_(const NetExpr*arg_) const
|
||||
return rtn;
|
||||
}
|
||||
|
||||
NetEConst* NetESFunc::evaluate_rtoi_(const NetExpr*arg_) const
|
||||
NetEConst* NetESFunc::evaluate_rtoi_(const NetExpr*arg_)
|
||||
{
|
||||
const NetEConst*tmpi = dynamic_cast<const NetEConst*>(arg_);
|
||||
const NetECReal*tmpr = dynamic_cast<const NetECReal*>(arg_);
|
||||
@@ -1710,7 +1711,7 @@ NetEConst* NetESFunc::evaluate_rtoi_(const NetExpr*arg_) const
|
||||
return new NetEConst(verinum(verinum(arg, false), integer_width));
|
||||
}
|
||||
|
||||
NetECReal* NetESFunc::evaluate_itor_(const NetExpr*arg_) const
|
||||
NetECReal* NetESFunc::evaluate_itor_(const NetExpr*arg_)
|
||||
{
|
||||
const NetEConst*tmpi = dynamic_cast<const NetEConst*>(arg_);
|
||||
const NetECReal*tmpr = dynamic_cast<const NetECReal*>(arg_);
|
||||
@@ -1727,8 +1728,7 @@ NetECReal* NetESFunc::evaluate_itor_(const NetExpr*arg_) const
|
||||
return new NetECReal(verireal(0.0));
|
||||
}
|
||||
|
||||
if (arg >= 0.0) arg = floor(arg + 0.5);
|
||||
else arg = ceil(arg - 0.5);
|
||||
arg = std::round(arg);
|
||||
|
||||
return new NetECReal(verireal(arg));
|
||||
}
|
||||
@@ -2140,7 +2140,7 @@ NetEConst* NetESFunc::evaluate_onehot0_(const NetExpr* arg) const
|
||||
}
|
||||
|
||||
/* Get the number of unpacked dimensions for the given expression. */
|
||||
NetEConst* NetESFunc::evaluate_unpacked_dimensions_(const NetExpr*arg) const
|
||||
NetEConst* NetESFunc::evaluate_unpacked_dimensions_(const NetExpr*arg)
|
||||
{
|
||||
const NetESignal*esig = dynamic_cast<const NetESignal*>(arg);
|
||||
long res = 0;
|
||||
@@ -2183,6 +2183,25 @@ static bool get_array_info(const NetExpr*arg, long dim,
|
||||
left = range.get_msb();
|
||||
right = range.get_lsb();
|
||||
return false;
|
||||
}
|
||||
/* Class property (e.g. queue field): size is dynamic; defer to runtime
|
||||
* instead of folding to all-X in evaluate_array_funcs_. */
|
||||
if (const NetEProperty*prop = dynamic_cast<const NetEProperty*>(arg)) {
|
||||
const NetNet*obj = prop->get_sig();
|
||||
const netclass_t*cls = dynamic_cast<const netclass_t*>(obj->net_type());
|
||||
if (cls == 0) return true;
|
||||
ivl_type_t ptype = cls->get_prop_type(prop->property_idx());
|
||||
if (ptype == 0) return true;
|
||||
switch (ptype->base_type()) {
|
||||
case IVL_VT_DARRAY:
|
||||
case IVL_VT_QUEUE:
|
||||
case IVL_VT_STRING:
|
||||
defer = true;
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/* The argument must be a signal that has enough dimensions. */
|
||||
const NetESignal*esig = dynamic_cast<const NetESignal*>(arg);
|
||||
@@ -2499,7 +2518,7 @@ NetExpr* NetEUFunc::eval_tree()
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetFuncDef*def = func_->func_def();
|
||||
const NetFuncDef*def = func_->func_def();
|
||||
ivl_assert(*this, def);
|
||||
|
||||
vector<NetExpr*>args(parms_.size());
|
||||
|
||||
+4
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2021 Martin Whitaker (icarus@martin-whitaker.me.uk)
|
||||
* Copyright (c) 2016-2025 Martin Whitaker (icarus@martin-whitaker.me.uk)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -47,9 +47,9 @@ struct exposenodes_functor : public functor_t {
|
||||
|
||||
unsigned count;
|
||||
|
||||
virtual void lpm_mux(Design*des, NetMux*obj);
|
||||
virtual void lpm_part_select(Design*des, NetPartSelect*obj);
|
||||
virtual void lpm_substitute(Design*des, NetSubstitute*obj);
|
||||
virtual void lpm_mux(Design*des, NetMux*obj) override;
|
||||
virtual void lpm_part_select(Design*des, NetPartSelect*obj) override;
|
||||
virtual void lpm_substitute(Design*des, NetSubstitute*obj) override;
|
||||
};
|
||||
|
||||
static bool expose_nexus(Nexus*nex)
|
||||
|
||||
+33
-33
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2024 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2025 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
static NetNet* convert_to_real_const(Design*des, NetScope*scope, NetEConst*expr)
|
||||
static NetNet* convert_to_real_const(Design*des, NetScope*scope, const NetEConst*expr)
|
||||
{
|
||||
verireal vrl(expr->value().as_double());
|
||||
NetECReal rlval(vrl);
|
||||
@@ -53,7 +53,7 @@ static bool process_binary_args(Design*des, NetScope*scope, NetExpr*root,
|
||||
cases of constants, which can be converted more directly. */
|
||||
if (left->expr_type() == IVL_VT_REAL) {
|
||||
lsig = left->synthesize(des, scope, root);
|
||||
} else if (NetEConst*tmpc = dynamic_cast<NetEConst*> (left)) {
|
||||
} else if (const NetEConst*tmpc = dynamic_cast<NetEConst*> (left)) {
|
||||
lsig = convert_to_real_const(des, scope, tmpc);
|
||||
} else {
|
||||
NetNet*tmp = left->synthesize(des, scope, root);
|
||||
@@ -62,7 +62,7 @@ static bool process_binary_args(Design*des, NetScope*scope, NetExpr*root,
|
||||
|
||||
if (right->expr_type() == IVL_VT_REAL) {
|
||||
rsig = right->synthesize(des, scope, root);
|
||||
} else if (NetEConst*tmpc = dynamic_cast<NetEConst*> (right)) {
|
||||
} else if (const NetEConst*tmpc = dynamic_cast<NetEConst*> (right)) {
|
||||
rsig = convert_to_real_const(des, scope, tmpc);
|
||||
} else {
|
||||
NetNet*tmp = right->synthesize(des, scope, root);
|
||||
@@ -177,7 +177,7 @@ NetNet* NetEBBits::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
rsig = pad_to_width(des, rsig, width, *this);
|
||||
|
||||
ivl_assert(*this, lsig->vector_width() == rsig->vector_width());
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
const netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
@@ -247,7 +247,7 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
rsig = pad_to_width(des, rsig, width, *this);
|
||||
}
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(IVL_VT_LOGIC);
|
||||
const netvector_t*osig_vec = new netvector_t(IVL_VT_LOGIC);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
@@ -576,7 +576,7 @@ NetNet* NetEBLogic::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
olog->set_line(*this);
|
||||
des->add_node(olog);
|
||||
|
||||
netvector_t*osig_tmp = new netvector_t(expr_type());
|
||||
const netvector_t*osig_tmp = new netvector_t(expr_type());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, osig_tmp);
|
||||
osig->set_line(*this);
|
||||
@@ -618,7 +618,7 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
/* Detect the special case where the shift amount is
|
||||
constant. Evaluate the shift amount, and simply reconnect
|
||||
the left operand to the output, but shifted. */
|
||||
if (NetEConst*rcon = dynamic_cast<NetEConst*>(right_)) {
|
||||
if (const NetEConst*rcon = dynamic_cast<NetEConst*>(right_)) {
|
||||
verinum shift_v = rcon->value();
|
||||
long shift = shift_v.as_long();
|
||||
|
||||
@@ -628,7 +628,7 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
if (shift == 0)
|
||||
return lsig;
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), expr_width()-1,0);
|
||||
const netvector_t*osig_vec = new netvector_t(expr_type(), expr_width()-1,0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
@@ -650,7 +650,7 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
psel->set_line(*this);
|
||||
des->add_node(psel);
|
||||
|
||||
netvector_t*psig_vec = new netvector_t(expr_type(), part_width-1, 0);
|
||||
const netvector_t*psig_vec = new netvector_t(expr_type(), part_width-1, 0);
|
||||
NetNet*psig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, psig_vec);
|
||||
psig->set_line(*this);
|
||||
@@ -678,8 +678,8 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
znum);
|
||||
des->add_node(zcon);
|
||||
|
||||
netvector_t*zsig_vec = new netvector_t(osig->data_type(),
|
||||
znum.len()-1, 0);
|
||||
const netvector_t*zsig_vec = new netvector_t(osig->data_type(),
|
||||
znum.len()-1, 0);
|
||||
NetNet*zsig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, zsig_vec);
|
||||
zsig->set_line(*this);
|
||||
@@ -709,7 +709,7 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
|
||||
if (rsig == 0) return 0;
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), expr_width()-1, 0);
|
||||
const netvector_t*osig_vec = new netvector_t(expr_type(), expr_width()-1, 0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
@@ -966,7 +966,7 @@ NetNet* NetEUBits::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
}
|
||||
|
||||
unsigned width = isig->vector_width();
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
const netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
@@ -1009,8 +1009,8 @@ NetNet* NetEUnary::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
if (expr_->has_sign() == false)
|
||||
return sub;
|
||||
|
||||
netvector_t*sig_vec = new netvector_t(sub->data_type(),
|
||||
sub->vector_width()-1, 0);
|
||||
const netvector_t*sig_vec = new netvector_t(sub->data_type(),
|
||||
sub->vector_width()-1, 0);
|
||||
NetNet*sig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, sig_vec);
|
||||
sig->set_line(*this);
|
||||
@@ -1084,7 +1084,7 @@ NetNet* NetEUReduce::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
gate->set_line(*this);
|
||||
des->add_node(gate);
|
||||
|
||||
netvector_t*osig_vec = new netvector_t(expr_type());
|
||||
const netvector_t*osig_vec = new netvector_t(expr_type());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
@@ -1139,7 +1139,7 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
||||
|
||||
// Detect the special case that there is a base expression and
|
||||
// it is constant. In this case we can generate fixed part selects.
|
||||
if (NetEConst*base_const = dynamic_cast<NetEConst*>(base_)) {
|
||||
if (const NetEConst*base_const = dynamic_cast<NetEConst*>(base_)) {
|
||||
verinum base_tmp = base_const->value();
|
||||
unsigned select_width = expr_width();
|
||||
|
||||
@@ -1194,8 +1194,8 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
||||
des->add_node(sel);
|
||||
|
||||
ivl_assert(*this, select_width > 0);
|
||||
netvector_t*tmp_vec = new netvector_t(sub->data_type(),
|
||||
select_width-1, 0);
|
||||
const netvector_t*tmp_vec = new netvector_t(sub->data_type(),
|
||||
select_width-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
@@ -1243,8 +1243,8 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
||||
sel->set_line(*this);
|
||||
des->add_node(sel);
|
||||
|
||||
netvector_t*tmp_vec = new netvector_t(sub->data_type(),
|
||||
expr_width()-1, 0);
|
||||
const netvector_t*tmp_vec = new netvector_t(sub->data_type(),
|
||||
expr_width()-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, tmp_vec);
|
||||
tmp->local_flag(true);
|
||||
@@ -1321,7 +1321,7 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
||||
con->set_line(*this);
|
||||
des->add_node(con);
|
||||
|
||||
netvector_t*tmp_vec = new netvector_t(expr_type(), pad_width-1, 0);
|
||||
const netvector_t*tmp_vec = new netvector_t(expr_type(), pad_width-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
@@ -1376,7 +1376,7 @@ NetNet* NetETernary::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
||||
ivl_assert(*this, csig->vector_width() == 1);
|
||||
|
||||
unsigned width=expr_width();
|
||||
netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
const netvector_t*osig_vec = new netvector_t(expr_type(), width-1, 0);
|
||||
NetNet*osig = new NetNet(csig->scope(), path, NetNet::IMPLICIT, osig_vec);
|
||||
osig->set_line(*this);
|
||||
osig->local_flag(true);
|
||||
@@ -1421,8 +1421,8 @@ NetNet* NetESignal::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
// If this is a synthesis with a specific value for the
|
||||
// signal, then replace it (here) with a constant value.
|
||||
if (net_->scope()==scope && net_->name()==scope->genvar_tmp) {
|
||||
netvector_t*tmp_vec = new netvector_t(net_->data_type(),
|
||||
net_->vector_width()-1, 0);
|
||||
const netvector_t*tmp_vec = new netvector_t(net_->data_type(),
|
||||
net_->vector_width()-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
@@ -1452,8 +1452,8 @@ NetNet* NetESignal::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
netvector_t*tmp_vec = new netvector_t(net_->data_type(),
|
||||
net_->vector_width()-1, 0);
|
||||
const netvector_t*tmp_vec = new netvector_t(net_->data_type(),
|
||||
net_->vector_width()-1, 0);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
@@ -1462,7 +1462,7 @@ NetNet* NetESignal::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
// For NetExpr objects, the word index is already converted to
|
||||
// a canonical (lsb==0) address. Just use the index directly.
|
||||
|
||||
if (NetEConst*index_co = dynamic_cast<NetEConst*> (word_)) {
|
||||
if (const NetEConst*index_co = dynamic_cast<NetEConst*> (word_)) {
|
||||
|
||||
long index = index_co->value().as_long();
|
||||
connect(tmp->pin(0), net_->pin(index));
|
||||
@@ -1483,7 +1483,7 @@ NetNet* NetESignal::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static NetEvWait* make_func_trigger(Design*des, NetScope*scope, NetExpr*root)
|
||||
static NetEvWait* make_func_trigger(Design*des, NetScope*scope, const NetExpr*root)
|
||||
{
|
||||
NetEvWait*trigger = 0;
|
||||
|
||||
@@ -1611,8 +1611,8 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
des->add_node(net);
|
||||
|
||||
/* Create an output signal and connect it to the function. */
|
||||
netvector_t*osig_vec = new netvector_t(result_sig_->expr_type(),
|
||||
result_sig_->vector_width()-1, 0);
|
||||
const netvector_t*osig_vec = new netvector_t(result_sig_->expr_type(),
|
||||
result_sig_->vector_width()-1, 0);
|
||||
NetNet*osig = new NetNet(scope_, scope_->local_symbol(), NetNet::WIRE,
|
||||
osig_vec);
|
||||
osig->set_line(*this);
|
||||
@@ -1626,7 +1626,7 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
}
|
||||
|
||||
/* Connect the pins to the arguments. */
|
||||
NetFuncDef*def = func_->func_def();
|
||||
const NetFuncDef*def = func_->func_def();
|
||||
for (unsigned idx = 0; idx < eparms.size(); idx += 1) {
|
||||
unsigned width = def->port(idx)->vector_width();
|
||||
NetNet*tmp;
|
||||
|
||||
@@ -337,6 +337,7 @@ ivl_type_packed_width
|
||||
ivl_type_prop_name
|
||||
ivl_type_prop_type
|
||||
ivl_type_properties
|
||||
ivl_type_queue_max
|
||||
ivl_type_signed
|
||||
|
||||
ivl_udp_init
|
||||
|
||||
+22
-3
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_ivl_alloc_H
|
||||
#define IVL_ivl_alloc_H
|
||||
/*
|
||||
* Copyright (C) 2010-2014 Cary R. (cygcary@yahoo.com)
|
||||
* Copyright (C) 2010-2025 Cary R. (cygcary@yahoo.com)
|
||||
*
|
||||
* 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
|
||||
@@ -21,12 +21,30 @@
|
||||
#ifdef __cplusplus
|
||||
# include <cstdlib>
|
||||
# include <cstdio>
|
||||
# include <cstring>
|
||||
#else
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# include <string.h>
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if !defined(_MSC_VER)
|
||||
/*
|
||||
* Define a safer version of strdup().
|
||||
*/
|
||||
|
||||
#define strdup(__ivl_str) \
|
||||
({ \
|
||||
char *__ivl_rtn = strdup(__ivl_str); \
|
||||
/* If we run out of memory then exit with a message. */ \
|
||||
if (__ivl_rtn == NULL) { \
|
||||
fprintf(stderr, "%s:%d: Error: strdup() ran out of memory.\n", \
|
||||
__FILE__, __LINE__); \
|
||||
exit(1); \
|
||||
} \
|
||||
__ivl_rtn; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Define a safer version of malloc().
|
||||
*/
|
||||
@@ -83,6 +101,7 @@
|
||||
} \
|
||||
__ivl_rtn; \
|
||||
})
|
||||
#endif
|
||||
|
||||
#endif // !defined(_MSC_VER)
|
||||
|
||||
#endif /* IVL_ivl_alloc_H */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef IVL_ivl_dlfcn_H
|
||||
#define IVL_ivl_dlfcn_H
|
||||
/*
|
||||
* Copyright (c) 2001-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001-2026 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -21,7 +21,11 @@
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
# include <windows.h>
|
||||
#if defined(__cplusplus)
|
||||
# include <cstdio>
|
||||
#else
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
typedef void * ivl_dll_t;
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
# include <dlfcn.h>
|
||||
@@ -32,7 +36,7 @@ typedef shl_t ivl_dll_t;
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
inline ivl_dll_t ivl_dlopen(const char *name, bool)
|
||||
static inline ivl_dll_t ivl_dlopen(const char *name, bool global_flag)
|
||||
{
|
||||
static char full_name[4096];
|
||||
unsigned long length = GetFullPathName(name, sizeof(full_name),
|
||||
@@ -40,16 +44,18 @@ inline ivl_dll_t ivl_dlopen(const char *name, bool)
|
||||
if ((length == 0) || (length > sizeof(full_name)))
|
||||
return 0;
|
||||
|
||||
(void)global_flag;
|
||||
|
||||
return (void *)LoadLibrary(full_name);
|
||||
}
|
||||
|
||||
inline void *ivl_dlsym(ivl_dll_t dll, const char *nm)
|
||||
static inline void *ivl_dlsym(ivl_dll_t dll, const char *nm)
|
||||
{ return (void *)GetProcAddress((HINSTANCE)dll,nm);}
|
||||
|
||||
inline void ivl_dlclose(ivl_dll_t dll)
|
||||
static inline void ivl_dlclose(ivl_dll_t dll)
|
||||
{ (void)FreeLibrary((HINSTANCE)dll);}
|
||||
|
||||
inline const char *dlerror(void)
|
||||
static inline const char *dlerror(void)
|
||||
{
|
||||
static char msg[256];
|
||||
unsigned long err = GetLastError();
|
||||
@@ -66,10 +72,10 @@ inline const char *dlerror(void)
|
||||
}
|
||||
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
inline ivl_dll_t ivl_dlopen(const char*name, bool global_flag)
|
||||
static inline ivl_dll_t ivl_dlopen(const char*name, bool global_flag)
|
||||
{ return dlopen(name,RTLD_LAZY|(global_flag?RTLD_GLOBAL:0)); }
|
||||
|
||||
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
static inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
{
|
||||
void*sym = dlsym(dll, nm);
|
||||
/* Not found? try without the leading _ */
|
||||
@@ -78,24 +84,28 @@ inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
return sym;
|
||||
}
|
||||
|
||||
inline void ivl_dlclose(ivl_dll_t dll)
|
||||
static inline void ivl_dlclose(ivl_dll_t dll)
|
||||
{ dlclose(dll); }
|
||||
|
||||
#elif defined(HAVE_DL_H)
|
||||
inline ivl_dll_t ivl_dlopen(const char*name)
|
||||
{ return shl_load(name, BIND_IMMEDIATE, 0); }
|
||||
static inline ivl_dll_t ivl_dlopen(const char*name, bool global_flag)
|
||||
{
|
||||
(void)global_flag;
|
||||
|
||||
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
return shl_load(name, BIND_IMMEDIATE, 0);
|
||||
}
|
||||
|
||||
static inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
{
|
||||
void*sym;
|
||||
int rc = shl_findsym(&dll, nm, TYPE_PROCEDURE, &sym);
|
||||
return (rc == 0) ? sym : 0;
|
||||
}
|
||||
|
||||
inline void ivl_dlclose(ivl_dll_t dll)
|
||||
static inline void ivl_dlclose(ivl_dll_t dll)
|
||||
{ shl_unload(dll); }
|
||||
|
||||
inline const char*dlerror(void)
|
||||
static inline const char*dlerror(void)
|
||||
{ return strerror( errno ); }
|
||||
#endif
|
||||
|
||||
@@ -2400,6 +2400,10 @@ extern int ivl_type_properties(ivl_type_t net);
|
||||
extern const char* ivl_type_prop_name(ivl_type_t net, int idx);
|
||||
extern ivl_type_t ivl_type_prop_type(ivl_type_t net, int idx);
|
||||
|
||||
/* Maximum element count for a queue type (0 = unbounded). Only valid
|
||||
* when ivl_type_base(net) == IVL_VT_QUEUE. */
|
||||
extern unsigned ivl_type_queue_max(ivl_type_t net);
|
||||
|
||||
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN__)
|
||||
# define DLLEXPORT __declspec(dllexport)
|
||||
|
||||
+6
-2
@@ -60,7 +60,11 @@ distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
||||
cppcheck: $(O:.o=.c)
|
||||
cppcheck --enable=all --std=c99 --std=c++11 -f $(INCLUDE_PATH) $^
|
||||
cppcheck --enable=all --std=c99 --std=c++11 -f \
|
||||
--check-level=exhaustive \
|
||||
--suppressions-list=$(srcdir)/../cppcheck-global.sup \
|
||||
--suppressions-list=$(srcdir)/cppcheck.sup \
|
||||
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
cd ..; ./config.status --file=ivlpp/$@
|
||||
@@ -85,4 +89,4 @@ uninstall:
|
||||
rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/ivlpp@EXEEXT@"
|
||||
|
||||
lexor.o: lexor.c globals.h
|
||||
main.o: main.c globals.h $(srcdir)/../version_base.h ../version_tag.h
|
||||
main.o: main.c globals.h ../version_base.h ../version_tag.h
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// Skip the sscanf() field width limit warning
|
||||
invalidscanf:lexor.lex:1495
|
||||
|
||||
// Skip all memory issues since they should be handled by ivl_alloc.h
|
||||
memleakOnRealloc
|
||||
nullPointerArithmeticOutOfMemory
|
||||
nullPointerOutOfMemory
|
||||
|
||||
// Errors/limitations in the generated yacc and lex files
|
||||
ctunullpointerOutOfMemory:lexor.lex
|
||||
memleakOnRealloc:lexor.lex
|
||||
nullPointerOutOfMemory:lexor.lex
|
||||
constVariablePointer:<stdout>
|
||||
nullPointer:<stdout>
|
||||
staticFunction:<stdout>
|
||||
unusedFunction:<stdout>
|
||||
+552
-555
File diff suppressed because it is too large
Load Diff
+4
-4
@@ -1,5 +1,5 @@
|
||||
const char COPYRIGHT[] =
|
||||
"Copyright (c) 1999-2024 Stephen Williams ([email protected])";
|
||||
"Copyright (c) 1999-2026 Stephen Williams ([email protected])";
|
||||
/*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -73,7 +73,7 @@ unsigned vhdlpp_libdir_cnt = 0;
|
||||
static char**source_list = 0;
|
||||
static unsigned source_cnt = 0;
|
||||
|
||||
void add_source_file(const char*name)
|
||||
static void add_source_file(const char*name)
|
||||
{
|
||||
if (source_list == 0) {
|
||||
source_list = calloc(2, sizeof(char*));
|
||||
@@ -245,9 +245,9 @@ int main(int argc, char*argv[])
|
||||
unsigned lp;
|
||||
const char*flist_path = 0;
|
||||
unsigned flag_errors = 0;
|
||||
char*out_path = 0;
|
||||
const char*out_path = 0;
|
||||
FILE*out;
|
||||
char*precomp_out_path = 0;
|
||||
const char*precomp_out_path = 0;
|
||||
FILE*precomp_out = NULL;
|
||||
|
||||
/* Define preprocessor keywords that I plan to just pass. */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user