mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-26 07:46:31 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3d14281e0d | ||
|
|
2564554178 | ||
|
|
8cd697fd24 | ||
|
|
306d2fb53b | ||
|
|
52b497f74c | ||
|
|
ce7f28202a | ||
|
|
49bea6a01a | ||
|
|
8ab100c1c7 | ||
|
|
177ae7c220 | ||
|
|
b04d5a9068 | ||
|
|
b8c8f03037 | ||
|
|
38013f7a34 | ||
|
|
561638a31f | ||
|
|
bb91512e75 | ||
|
|
09ff851483 | ||
|
|
19d8f43e9b | ||
|
|
ce88deaa97 | ||
|
|
1a8b19baf2 | ||
|
|
b3cf533b3c | ||
|
|
ba3856ebb0 | ||
|
|
c06e2790a7 | ||
|
|
6e460a6a3f | ||
|
|
dbc536c4fb | ||
|
|
5e41c86d01 | ||
|
|
572124e1e9 | ||
|
|
37ecdb4cfb | ||
|
|
a11dc8b472 | ||
|
|
e7852f8f9c | ||
|
|
9449c46865 | ||
|
|
8a780ece56 | ||
|
|
8bb4777789 | ||
|
|
3b705d95a6 | ||
|
|
f9559853f1 | ||
|
|
cda95c1554 | ||
|
|
4066031add | ||
|
|
d6d50e9b68 | ||
|
|
0ffbb2b1de | ||
|
|
9b55a3d67f | ||
|
|
07623bef2e | ||
|
|
73d688c313 | ||
|
|
6155986d1c | ||
|
|
face462cc2 | ||
|
|
a5f6329500 | ||
|
|
3e13594816 | ||
|
|
99138eafb1 | ||
|
|
86968e3752 | ||
|
|
27a46f4afe | ||
|
|
d770199550 | ||
|
|
06f6a72770 | ||
|
|
30257e0914 | ||
|
|
b2281b0e65 | ||
|
|
161cebb178 | ||
|
|
b46d8b8389 | ||
|
|
2689ebacfe | ||
|
|
5bbb054173 | ||
|
|
7d2eeb0137 | ||
|
|
4aef636559 | ||
|
|
72fc3d712d | ||
|
|
3f75f6b155 | ||
|
|
9be3fc3a56 | ||
|
|
aa2260f4fa | ||
|
|
6974613bff | ||
|
|
8bd4e9d481 | ||
|
|
04ae07f03c | ||
|
|
d9be5318f9 | ||
|
|
88cd5534c4 | ||
|
|
3b577340ad | ||
|
|
583a31c121 | ||
|
|
a391c3ae28 | ||
|
|
b551a783e8 | ||
|
|
33db07ab8d | ||
|
|
e2aae72880 | ||
|
|
ec9897af5a | ||
|
|
2771abf86a | ||
|
|
b0461787c8 | ||
|
|
6f41576930 | ||
|
|
cc7516eab3 | ||
|
|
1a5ae96540 | ||
|
|
1ea8a13bf8 | ||
|
|
490884cf7b | ||
|
|
ca1d7ccffe | ||
|
|
faf9bfe158 | ||
|
|
086ce04cf5 | ||
|
|
7b7231c417 | ||
|
|
d7b919f6d0 | ||
|
|
9b34a96cb9 | ||
|
|
90cf0e5794 | ||
|
|
818379b9bc | ||
|
|
9fbb7f84e6 | ||
|
|
ed7d6c1002 | ||
|
|
a4306dbac1 | ||
|
|
a682e13d82 | ||
|
|
643e0a984e | ||
|
|
63d2059b85 | ||
|
|
d9e09ceb59 | ||
|
|
6d0ab9978f | ||
|
|
e25cdf86ac | ||
|
|
13bff8c50d | ||
|
|
b1b017251a | ||
|
|
e13a52637a | ||
|
|
4803f0d12b | ||
|
|
be44289fc0 | ||
|
|
e682166253 | ||
|
|
e2a1f21896 | ||
|
|
cb73accd84 | ||
|
|
a66361a4f2 | ||
|
|
1159de0482 | ||
|
|
ac5d4114ad | ||
|
|
85f796fda2 | ||
|
|
8612ec5452 | ||
|
|
870a351944 | ||
|
|
434bf0fe46 | ||
|
|
5147105042 | ||
|
|
fc2139f01c | ||
|
|
775904ab0f | ||
|
|
0ae3414ec5 | ||
|
|
f3321126ed | ||
|
|
428f059c58 | ||
|
|
e98bcb61bb | ||
|
|
5facf243cd | ||
|
|
853f119d83 | ||
|
|
3e2196651a | ||
|
|
64b72cf7e1 | ||
|
|
d766e82aa1 | ||
|
|
c35f2f8334 | ||
|
|
afd225a44d | ||
|
|
b36a0a2c54 | ||
|
|
a3728dcf20 | ||
|
|
4cf4cdabcd | ||
|
|
5f906369b5 | ||
|
|
12f4d29df3 | ||
|
|
5e931b7e89 | ||
|
|
11d7cbd3e2 | ||
|
|
7aff1adf99 | ||
|
|
093e7eb2c8 | ||
|
|
82d46a5e1a | ||
|
|
fc976bdb97 | ||
|
|
9f7995f648 | ||
|
|
9bcafe39c6 | ||
|
|
9635f031a1 | ||
|
|
e6be9dec08 | ||
|
|
97c6339241 | ||
|
|
8d2149f5aa | ||
|
|
e8225bd39e | ||
|
|
935ee6137d | ||
|
|
586e415d96 | ||
|
|
637fc40dd9 | ||
|
|
05a52e55e9 | ||
|
|
59c211d20c | ||
|
|
dad223316e | ||
|
|
df597e19cb | ||
|
|
7597270939 | ||
|
|
5509b3c7a5 | ||
|
|
49253c43ba | ||
|
|
311ffb27f2 | ||
|
|
f0fd73e146 | ||
|
|
5858e1bbac | ||
|
|
95044d9ac7 | ||
|
|
c6f934964f | ||
|
|
6f867d6f01 | ||
|
|
e6b57910a4 | ||
|
|
cc9b182eb6 | ||
|
|
d39f692cfd | ||
|
|
b666b9c0bf | ||
|
|
b3c1fa3e85 | ||
|
|
169228ad0f | ||
|
|
356a09d295 | ||
|
|
47c5ce0ab6 | ||
|
|
3c437874e2 | ||
|
|
c28000c55f | ||
|
|
5a0d967682 | ||
|
|
49efe6573c | ||
|
|
ea12c0fe23 | ||
|
|
44dfc41004 | ||
|
|
bdd0657140 | ||
|
|
1d279798d8 | ||
|
|
0e66e9781a | ||
|
|
b23faff27c | ||
|
|
b242663cae | ||
|
|
d39c284055 | ||
|
|
6a73de0c43 | ||
|
|
e0cdd71984 | ||
|
|
81e1735959 | ||
|
|
3fb65eb51a | ||
|
|
3080f5730d | ||
|
|
29ddd5208f | ||
|
|
4a31f36646 | ||
|
|
1f1d47887e | ||
|
|
80403d2ade | ||
|
|
cd3180d1c2 | ||
|
|
68f8007fc4 | ||
|
|
d6ff1946f9 | ||
|
|
4068c172f4 | ||
|
|
9ac9f1c9f2 | ||
|
|
2739f83702 | ||
|
|
7af3280215 | ||
|
|
05d591ccd6 | ||
|
|
fbedf4ae22 | ||
|
|
e6c6f6c81e | ||
|
|
33c651aa00 | ||
|
|
358bb4d5d9 | ||
|
|
d5b41853fd | ||
|
|
0fc10e3e70 | ||
|
|
ab688613cc | ||
|
|
79042e38ad | ||
|
|
ced9759c65 | ||
|
|
8f22998447 | ||
|
|
51d7237d52 | ||
|
|
7aab315ce5 | ||
|
|
bc83d2914a | ||
|
|
bb2e6782fa | ||
|
|
9231ad51a4 | ||
|
|
25458b8cc2 | ||
|
|
515ab40ffe | ||
|
|
ddc204391e | ||
|
|
a33bbecc98 | ||
|
|
61ace52f31 | ||
|
|
71b1546a7d | ||
|
|
578a2543f7 | ||
|
|
a479bd6b16 | ||
|
|
c75498b1d4 | ||
|
|
b6304129fa | ||
|
|
bb444b6178 | ||
|
|
7442c14689 | ||
|
|
0082795967 | ||
|
|
ac4f4cf1a0 | ||
|
|
676d23f973 | ||
|
|
6069cbfc3c | ||
|
|
cfbc90812b | ||
|
|
e530b4e642 | ||
|
|
6a3edc63d5 | ||
|
|
3069b8dd51 | ||
|
|
7db01d8ded | ||
|
|
e4694cb6cb | ||
|
|
08e5aa021a | ||
|
|
4304fd503e | ||
|
|
5438464d67 | ||
|
|
6df2979998 | ||
|
|
9de4ced133 | ||
|
|
45dc13e496 | ||
|
|
9e3f1ef1ff | ||
|
|
1b3e321d35 | ||
|
|
a27274aa04 | ||
|
|
f1be16be7c | ||
|
|
9ac374501c | ||
|
|
250b278d0e | ||
|
|
52275deb0e | ||
|
|
120ad59017 | ||
|
|
2ac8a555e1 | ||
|
|
8d845ae49f | ||
|
|
352175d921 | ||
|
|
e78205eacf | ||
|
|
c6e618350d | ||
|
|
301a7e587b | ||
|
|
3cee5d4567 | ||
|
|
e1ae5020c4 | ||
|
|
22d15f9ca9 | ||
|
|
19d966e235 | ||
|
|
c8fe897446 | ||
|
|
5101b3b64b | ||
|
|
bed5ee4529 | ||
|
|
7c0a191626 | ||
|
|
cfa43c7742 | ||
|
|
a5138e238f | ||
|
|
d352d8ead3 | ||
|
|
02ee3874e7 | ||
|
|
f9fef5d00b | ||
|
|
891399185f | ||
|
|
5dc1396eea | ||
|
|
ccf7c042c9 | ||
|
|
560b9530fd | ||
|
|
b89c059153 | ||
|
|
8326fe843b | ||
|
|
1cbc38100e | ||
|
|
ba31252226 | ||
|
|
008affe557 | ||
|
|
0ca856d4e8 | ||
|
|
2a210dfee1 | ||
|
|
83d721232d | ||
|
|
d5ffb55bfd | ||
|
|
ab9a8ccbf3 | ||
|
|
e6525ec35f | ||
|
|
afaedbd06d | ||
|
|
d4237774a5 | ||
|
|
2f2539e557 | ||
|
|
11a86794d9 | ||
|
|
3b14797075 | ||
|
|
e006f9e132 | ||
|
|
437dc10341 | ||
|
|
102d2d534f | ||
|
|
5e437145bf | ||
|
|
d1dc98b7f7 | ||
|
|
50b45dac7b | ||
|
|
295e4e7dfb | ||
|
|
807ad8002d | ||
|
|
d3229b9068 | ||
|
|
099bb427bc | ||
|
|
d406545331 | ||
|
|
1de3fb1625 | ||
|
|
e33b8b4dde | ||
|
|
9128eb67b9 | ||
|
|
afbda099fb | ||
|
|
4b0d220671 | ||
|
|
a42b056b24 | ||
|
|
1852c5ab9d | ||
|
|
24be13d825 | ||
|
|
bddfcac823 | ||
|
|
ea1c07e234 | ||
|
|
8e0ae733ca | ||
|
|
feb710a186 | ||
|
|
62abb199d7 | ||
|
|
7373bf2224 | ||
|
|
ae629f8c41 | ||
|
|
03e0e96832 | ||
|
|
3c38b2972d | ||
|
|
4f1fc6e302 | ||
|
|
f1436fbe62 | ||
|
|
a79533ddc9 | ||
|
|
d47afb588b | ||
|
|
386774ac19 | ||
|
|
9ca754b6db | ||
|
|
0f0bef32f2 | ||
|
|
cd55f30a27 | ||
|
|
5884879b02 | ||
|
|
a1a4f47894 | ||
|
|
e569e07d4e | ||
|
|
ee840391d6 | ||
|
|
0046e9eca0 | ||
|
|
f51c037432 | ||
|
|
763c6fe3c9 | ||
|
|
49b6ddf93c | ||
|
|
12b4914b63 | ||
|
|
fc0728ab6f | ||
|
|
46c41f9be2 | ||
|
|
cdf18de10e | ||
|
|
19ff6a434b | ||
|
|
5349ca9a55 | ||
|
|
5b7b980ead | ||
|
|
a1c2a8e605 | ||
|
|
8777cd8e7c | ||
|
|
11bb7ac348 | ||
|
|
9de69f2f24 | ||
|
|
dae3410dcd | ||
|
|
1a367c84b6 | ||
|
|
8a854affa6 | ||
|
|
60077f4f06 | ||
|
|
51ce9f1a60 | ||
|
|
48265ecd9b | ||
|
|
abbcea64d0 | ||
|
|
25c3798248 | ||
|
|
90293d8e0a | ||
|
|
621cf37339 | ||
|
|
6d75af86e6 | ||
|
|
5d26f0e28d | ||
|
|
774609fbbb | ||
|
|
9ba7694484 | ||
|
|
870a826225 | ||
|
|
2ecfed0baa | ||
|
|
56e410f386 | ||
|
|
d4dd635bf6 | ||
|
|
c287281bbe | ||
|
|
962330f20a | ||
|
|
777e7e0a3d | ||
|
|
839f9cd7ae | ||
|
|
b8b2f53027 | ||
|
|
9b3bd039bb | ||
|
|
51b9191021 | ||
|
|
756c9ceccf | ||
|
|
8b3667f76e | ||
|
|
a52242745a | ||
|
|
ff5b696569 | ||
|
|
b05a19dffc | ||
|
|
e6b22a2bea | ||
|
|
a02ebc3114 | ||
|
|
0592ba042e | ||
|
|
bcca3cf395 | ||
|
|
01ba41afd8 | ||
|
|
84c592b068 | ||
|
|
bb93a585b6 | ||
|
|
47688d234b | ||
|
|
b3425d6cf3 | ||
|
|
40ae1051d4 | ||
|
|
21c60b38e1 | ||
|
|
78c6b3cad2 | ||
|
|
a04104077f | ||
|
|
0e3a758894 | ||
|
|
d682029240 | ||
|
|
1ffcd40336 | ||
|
|
09439c55ab | ||
|
|
c858dea2d5 | ||
|
|
228a3f123a | ||
|
|
074f7a7a49 | ||
|
|
f642313e1b | ||
|
|
dd9d96eb07 | ||
|
|
35401f0e2c | ||
|
|
b6e16aea6b | ||
|
|
eeaf23041b | ||
|
|
e8096eda80 | ||
|
|
961d6a8f3b | ||
|
|
288ebf011c | ||
|
|
0ae304b6a8 | ||
|
|
5e61bb64b7 | ||
|
|
3f847fd927 | ||
|
|
4a41a53b42 | ||
|
|
a1630e1d30 | ||
|
|
bca84d9dbb | ||
|
|
e61ed48914 | ||
|
|
d29a6d134f | ||
|
|
6310b47538 | ||
|
|
9c75a4b96b | ||
|
|
c57e68292c | ||
|
|
0fecdcbeda | ||
|
|
23ad62f317 | ||
|
|
ac20008606 | ||
|
|
96d181efed | ||
|
|
18bfe7d497 | ||
|
|
86562e60ba | ||
|
|
b400532169 | ||
|
|
6fd10dedb6 | ||
|
|
c8255952a3 | ||
|
|
71c4ea36e8 | ||
|
|
5df179cd5f | ||
|
|
ce5c4ca8ba | ||
|
|
6aa8e49b09 | ||
|
|
f29f4ff4e3 | ||
|
|
3ccc59eaa3 | ||
|
|
0282b8450c | ||
|
|
43841af2f3 | ||
|
|
b2d8d41e3f | ||
|
|
0e38843ae9 | ||
|
|
96472e5537 | ||
|
|
48b0fed29e | ||
|
|
1efa220773 | ||
|
|
2d6622e543 | ||
|
|
edf112b900 | ||
|
|
f0a0ab100f | ||
|
|
c28188618b | ||
|
|
0d7daf5862 | ||
|
|
60ab1daa1f | ||
|
|
105521b547 | ||
|
|
fd3086f0a9 | ||
|
|
77ebfcacb9 | ||
|
|
d62a307c34 | ||
|
|
011519cb5b | ||
|
|
8a0b9acadc | ||
|
|
77d1671d8f | ||
|
|
561564065d | ||
|
|
409f8c5823 | ||
|
|
03198356a5 | ||
|
|
b1d2393789 | ||
|
|
0f740289e9 | ||
|
|
46ce236cfb | ||
|
|
86139c855d | ||
|
|
eb070b061b | ||
|
|
2b1393e7b9 | ||
|
|
85c7b07a9b | ||
|
|
0c5ed2b60f | ||
|
|
8fd1ead082 | ||
|
|
3bd307db85 | ||
|
|
35db02d35d | ||
|
|
f287546f49 | ||
|
|
1645e682f4 | ||
|
|
a57e0a1e3f | ||
|
|
b83144c552 | ||
|
|
58fb80aec4 | ||
|
|
38f277d81b | ||
|
|
f3ba335493 | ||
|
|
fb5ae48b18 | ||
|
|
68258f244e | ||
|
|
ee34ccec70 | ||
|
|
1834d470cb | ||
|
|
9bc463aac0 | ||
|
|
7c77097f71 | ||
|
|
cc4c5f4998 | ||
|
|
230c435ae7 | ||
|
|
4ddef32631 | ||
|
|
a236c274f3 | ||
|
|
21a8cb71ee | ||
|
|
b4ccaa1b0c | ||
|
|
a8d43fa743 | ||
|
|
ca2ef5c956 | ||
|
|
6015aceda2 | ||
|
|
9538501b54 | ||
|
|
ea7fa24f9e | ||
|
|
48d3701c02 | ||
|
|
c1164dcc33 | ||
|
|
1166cd932a | ||
|
|
c3a318f14e | ||
|
|
b2deae7ba9 | ||
|
|
675dd91403 | ||
|
|
b12e00d875 | ||
|
|
103828577b | ||
|
|
21c8b8ca5a | ||
|
|
25c588252f | ||
|
|
89d1125979 | ||
|
|
43c6a0bacd | ||
|
|
610ca95cbe | ||
|
|
daa59a95ad | ||
|
|
13f861a963 | ||
|
|
82ca4cf641 | ||
|
|
ac2e8dd6cd | ||
|
|
cd992b4d5a | ||
|
|
679021a1b5 | ||
|
|
f3392561ed | ||
|
|
7a9a022744 | ||
|
|
c222b3b6a4 | ||
|
|
663c79d4af | ||
|
|
bea03db25d | ||
|
|
b96f04ccce | ||
|
|
a9db765f98 | ||
|
|
c71ab5869a | ||
|
|
04bdfbccee | ||
|
|
2acc9fbdee | ||
|
|
725ed869ba | ||
|
|
301edf69d3 | ||
|
|
1612c6d638 | ||
|
|
aadd67cd3b | ||
|
|
c2ca9c3b73 | ||
|
|
0601b4e43b | ||
|
|
8aca66b109 | ||
|
|
2aeb3871ed | ||
|
|
ea21fb856e | ||
|
|
754899c99e | ||
|
|
4e94b81a4b | ||
|
|
6948c27c2d | ||
|
|
2e9c4cde55 | ||
|
|
2e8c4e3dbc | ||
|
|
cc9fcfd13d | ||
|
|
4660e0bf2f | ||
|
|
1e7509a021 | ||
|
|
c2e53f0d63 | ||
|
|
f171161822 | ||
|
|
0237297e93 | ||
|
|
e38b5d9fb7 | ||
|
|
d5123011b3 | ||
|
|
9a471bd81c | ||
|
|
632e15a55c | ||
|
|
d4313dad75 | ||
|
|
c25538d750 | ||
|
|
871d447ff7 | ||
|
|
b286b76134 | ||
|
|
4f62a0d1f2 | ||
|
|
e7df9774aa | ||
|
|
08afbde08d | ||
|
|
7ab0824adf | ||
|
|
7fad4779c5 | ||
|
|
8ac06fb63f | ||
|
|
4e727adc25 | ||
|
|
3e9c14060f | ||
|
|
702a8c3a05 | ||
|
|
48d3972299 | ||
|
|
62fce50f8c | ||
|
|
e4b862f3d1 | ||
|
|
09d3a5de59 | ||
|
|
97bde47c31 | ||
|
|
1c80c6e37a | ||
|
|
4588f7c615 | ||
|
|
006aef93d0 | ||
|
|
24b8752475 | ||
|
|
3ddcf03764 | ||
|
|
35f5d51028 | ||
|
|
87c019c65c | ||
|
|
69a1fecd2e | ||
|
|
9964d67e5e | ||
|
|
a98f21aa65 | ||
|
|
a63ca15735 | ||
|
|
d139142c29 | ||
|
|
af85d44d9f | ||
|
|
c5e0507941 | ||
|
|
c55a013162 | ||
|
|
dfbca0b186 | ||
|
|
4a779f43bd | ||
|
|
97df6183a9 | ||
|
|
95faed8e9d | ||
|
|
76aab15798 | ||
|
|
e896f0c8e6 | ||
|
|
f36bebf0e1 | ||
|
|
3fd622e4eb | ||
|
|
da4200c5bd | ||
|
|
712f394224 | ||
|
|
d6685f40a1 | ||
|
|
9ff9cbf4aa | ||
|
|
a992f3ce7c | ||
|
|
1a4edcac48 | ||
|
|
8cac72192f | ||
|
|
7f6100be2a | ||
|
|
4b60d2737e | ||
|
|
c7beef907d | ||
|
|
44da7de651 | ||
|
|
6887c82540 | ||
|
|
1333bc54a2 | ||
|
|
fddb3ec129 | ||
|
|
bfafd175fa | ||
|
|
23238aa7ac | ||
|
|
2397aa1587 | ||
|
|
b4119de9b1 | ||
|
|
338a0eb11a | ||
|
|
fde6525acb | ||
|
|
c5fee8bdb9 | ||
|
|
194a950f8d | ||
|
|
9951521212 | ||
|
|
9e856810b9 | ||
|
|
675b7d8efa | ||
|
|
e352bea476 | ||
|
|
747e656a0e | ||
|
|
7b5470c8a7 | ||
|
|
985a3eb206 | ||
|
|
e1ec27e18c | ||
|
|
d13e488f4c | ||
|
|
f5dd2ac87e | ||
|
|
94abef195a | ||
|
|
54696e0127 | ||
|
|
d85096c56a | ||
|
|
d16a9dcfc6 | ||
|
|
9842035d89 | ||
|
|
480668fee6 | ||
|
|
fa21527e9f | ||
|
|
98799ff7fa | ||
|
|
ea4b000be6 | ||
|
|
e330a0bd6e | ||
|
|
cb03802a17 | ||
|
|
22d18cb28d | ||
|
|
c98c3e5d14 | ||
|
|
a63289c2fc | ||
|
|
251b75003f | ||
|
|
01b4d49d4a | ||
|
|
f851fc6981 | ||
|
|
a25cde3bc7 | ||
|
|
51b121ae7a | ||
|
|
94caa4881e | ||
|
|
ef7ac5ed03 | ||
|
|
acce9fc2a0 | ||
|
|
1cfbd2db63 | ||
|
|
853512868b | ||
|
|
9b1de4b038 | ||
|
|
ec2793c9b0 | ||
|
|
697701a26e | ||
|
|
facc982af4 | ||
|
|
8bb1d3dabe | ||
|
|
88e951418b | ||
|
|
1572dcd3fd | ||
|
|
96d793ed6b | ||
|
|
15ccd8f4c9 | ||
|
|
d1a35d5152 | ||
|
|
3b0dfaadba | ||
|
|
1465fd1570 | ||
|
|
886b6cd349 | ||
|
|
0dc28c0fc3 | ||
|
|
dec4cd5071 | ||
|
|
0cd6fbaf41 | ||
|
|
9fa764285a | ||
|
|
fe8e7a6261 | ||
|
|
a0ea7e17cf | ||
|
|
8c3f7d78b9 | ||
|
|
684c2fe19e | ||
|
|
a67f18f8ef | ||
|
|
931039761a | ||
|
|
3852545f21 | ||
|
|
b4d0c43a96 | ||
|
|
c24c26725e | ||
|
|
1269c12054 | ||
|
|
4fb91ec7c7 | ||
|
|
e5f49baaac | ||
|
|
0f728b9150 | ||
|
|
b0c79d5d1c | ||
|
|
150fe088a6 | ||
|
|
bb66ed8b9d | ||
|
|
447e402d16 | ||
|
|
86bb269d47 | ||
|
|
486dc7abeb | ||
|
|
6765e32ab9 | ||
|
|
b1d15436fd | ||
|
|
c846b2cf3f | ||
|
|
10446df80e | ||
|
|
0a2100c87f | ||
|
|
27730395ca | ||
|
|
8e9c25a23e | ||
|
|
feccae56bf | ||
|
|
5de83906f7 | ||
|
|
8b969202c0 | ||
|
|
ea5789e4d9 | ||
|
|
f602ae84ab | ||
|
|
335db49282 | ||
|
|
8c2d51142b | ||
|
|
5ee253b03b | ||
|
|
c9ff48bd4e | ||
|
|
9b4681918b | ||
|
|
0894bc6409 | ||
|
|
da63ef02d4 | ||
|
|
a730572e37 | ||
|
|
d891285326 | ||
|
|
e8b8fcba57 | ||
|
|
6d052d4ff7 | ||
|
|
72ff9ac00b | ||
|
|
c92dea77fc | ||
|
|
4ea512c4fd | ||
|
|
89f1344288 | ||
|
|
96414af721 | ||
|
|
2d2a720ea8 | ||
|
|
9031f392ba | ||
|
|
4786f80b0b | ||
|
|
0f294cb607 | ||
|
|
f4c88b4a01 | ||
|
|
374948ce1b | ||
|
|
6a2b579fb0 | ||
|
|
d2ad7a4d28 | ||
|
|
5830ecd67e | ||
|
|
69b145e216 | ||
|
|
5ed60a151f | ||
|
|
c7a36722e3 | ||
|
|
66d31b02be | ||
|
|
0a6d75f1db | ||
|
|
6a2956c672 | ||
|
|
cdb1ea6264 | ||
|
|
df1d0a7b47 | ||
|
|
8d9ac35202 | ||
|
|
945584c310 | ||
|
|
d6b6b76015 | ||
|
|
0cbd6d99af | ||
|
|
8e7e3c7493 | ||
|
|
588409389e | ||
|
|
cc9d5f90e0 | ||
|
|
714795709c | ||
|
|
7b10570e11 | ||
|
|
cb381b3ee3 | ||
|
|
f5e01081d1 | ||
|
|
9c5113194d | ||
|
|
6bc3f98e0a | ||
|
|
b99b4b0223 | ||
|
|
fa38a8e08d | ||
|
|
14f597acdd | ||
|
|
b991a991a7 | ||
|
|
515137c8c7 | ||
|
|
d26a081cbc | ||
|
|
dff9953bc2 | ||
|
|
d8f10e7aa2 | ||
|
|
d5fb0f4344 | ||
|
|
c1e533d484 | ||
|
|
58ec35a6af | ||
|
|
ae6743cf69 | ||
|
|
850d8c3ee9 | ||
|
|
467e8afc41 | ||
|
|
f17690ebde | ||
|
|
774d173d69 | ||
|
|
9d99a64bf0 | ||
|
|
00a9c69348 | ||
|
|
8f7277a5ab | ||
|
|
e221a8ced9 | ||
|
|
a575eeb29d | ||
|
|
0dc12676f0 | ||
|
|
6ebb57195b | ||
|
|
78cb0a7876 | ||
|
|
47ddb18d54 | ||
|
|
0611135758 | ||
|
|
0ffd61a835 | ||
|
|
0728690df2 | ||
|
|
e82bafcb84 | ||
|
|
54f4c1147b | ||
|
|
642acb4082 | ||
|
|
6101044bff | ||
|
|
c6e44f2da1 | ||
|
|
3c0a982ab3 | ||
|
|
0f85bf0b9a | ||
|
|
ccce9d9271 | ||
|
|
9c79e321ae | ||
|
|
6d2fa6e579 | ||
|
|
f8dc430fe5 | ||
|
|
26f71f2d94 | ||
|
|
7cd3bdb0d0 | ||
|
|
81947edaa5 | ||
|
|
684e46a6c1 | ||
|
|
2bc9cb90dd | ||
|
|
1e18d43107 | ||
|
|
6a45a0d570 | ||
|
|
529e029abd | ||
|
|
855bf9cfe8 | ||
|
|
35a8485a44 | ||
|
|
12379ed26a | ||
|
|
6323e6a0a5 | ||
|
|
41ff18206a | ||
|
|
f104ffc133 | ||
|
|
ded1bd4949 | ||
|
|
579b59b8eb | ||
|
|
ef79f538d5 | ||
|
|
76883fa18c | ||
|
|
d05abf5ca4 | ||
|
|
ff72782ec6 | ||
|
|
d96e8872c1 | ||
|
|
6547fdee3d | ||
|
|
b7b77b2e75 | ||
|
|
f16c67d45a | ||
|
|
020e280a98 | ||
|
|
109c5d895d | ||
|
|
ce864fc634 | ||
|
|
be0c61051d | ||
|
|
ec0c66ff25 | ||
|
|
5893d13ea3 | ||
|
|
8d9f3a0920 | ||
|
|
17be8e8c7c | ||
|
|
c32610d135 | ||
|
|
be8df11217 | ||
|
|
650cedb516 | ||
|
|
a1d65336d2 | ||
|
|
d6405f86d4 | ||
|
|
8c80193fc5 | ||
|
|
e4476d544f | ||
|
|
c6cbaf3076 | ||
|
|
b687cc5f21 | ||
|
|
4d29df17b8 | ||
|
|
fdcb073c14 | ||
|
|
734d56ce25 | ||
|
|
a5423ce5ce | ||
|
|
e336eca00f | ||
|
|
3a77537ed8 | ||
|
|
c8b20da4be | ||
|
|
97e1151388 | ||
|
|
e6b394f825 | ||
|
|
f752007e9c | ||
|
|
40b36337e2 | ||
|
|
df4889ba3d | ||
|
|
2e2317b7c7 | ||
|
|
e2bad56a5c | ||
|
|
0accab6ec4 | ||
|
|
e55e832ea0 | ||
|
|
fc1f9ac6a5 | ||
|
|
6caa41cc93 | ||
|
|
751f19cc46 | ||
|
|
f8e33b12cd | ||
|
|
aaee9989c2 | ||
|
|
a849249a86 | ||
|
|
849ba64cf7 | ||
|
|
bb182cf3ce | ||
|
|
bc9382eea3 | ||
|
|
88e4938074 | ||
|
|
e932c7a637 | ||
|
|
b5e0099f28 | ||
|
|
1afe7476e3 | ||
|
|
4068570f43 | ||
|
|
3e41a93f3e | ||
|
|
7ceb18fb37 | ||
|
|
d2ff77d56c | ||
|
|
3c660d04f3 | ||
|
|
d0d421ebe2 | ||
|
|
13c1925045 | ||
|
|
c61d2151c1 | ||
|
|
065c48527c | ||
|
|
ed2e339dd6 | ||
|
|
5dcd2e8957 | ||
|
|
1f81d4c081 | ||
|
|
a3450bf856 | ||
|
|
91b7c6ab55 | ||
|
|
ebed793dec | ||
|
|
320f6d008c | ||
|
|
a76be3571d | ||
|
|
345c9cf21c | ||
|
|
5a06602af2 | ||
|
|
830083d99b | ||
|
|
6902bf44e3 | ||
|
|
8f849a9944 | ||
|
|
b1ef0997ed | ||
|
|
ecce1d25bc | ||
|
|
f43080fbcb | ||
|
|
463407572f | ||
|
|
6b6574dd8a | ||
|
|
4e81939eda | ||
|
|
66bdbb77ec | ||
|
|
5853f7d867 | ||
|
|
68f8de28af | ||
|
|
ac3aee0172 | ||
|
|
8135f369a5 | ||
|
|
be5bfeb172 | ||
|
|
801e795112 | ||
|
|
e66fc7e5cc | ||
|
|
1d63875e5d | ||
|
|
be1130ddbf | ||
|
|
9f2b7d6553 | ||
|
|
f5041e6c09 | ||
|
|
959ac3229e | ||
|
|
554fb7ebdd | ||
|
|
c9e8392dc7 | ||
|
|
60d37e1f53 | ||
|
|
e0ac4893f0 | ||
|
|
401fccdf6e | ||
|
|
f5564a195f | ||
|
|
c7e61f3aa4 | ||
|
|
a012406ca4 | ||
|
|
52a9fdde8a | ||
|
|
4f1c43b690 | ||
|
|
7f59c51ca2 | ||
|
|
0be577cc44 | ||
|
|
49cf5556a2 | ||
|
|
1805598eae | ||
|
|
0eca210722 | ||
|
|
3e95966d70 | ||
|
|
fdc9e8590d | ||
|
|
f76d56beb8 | ||
|
|
be17bfc0e9 | ||
|
|
77a01f65d0 | ||
|
|
e497f63e29 | ||
|
|
75233a9bca | ||
|
|
11197baf86 | ||
|
|
23ba0bc019 | ||
|
|
9cfb15a302 | ||
|
|
607b63a758 | ||
|
|
8bebe59e20 | ||
|
|
20d415463a | ||
|
|
9c1dcad994 | ||
|
|
0e13726e83 | ||
|
|
54346d7095 | ||
|
|
0121fbc88c | ||
|
|
f1855eed0e | ||
|
|
0f9828f179 | ||
|
|
d2c2d6d8dc | ||
|
|
f94a655121 | ||
|
|
078a3fd409 | ||
|
|
dfaed128c0 | ||
|
|
1fc4093191 | ||
|
|
ae1f8be277 | ||
|
|
d8533104b0 | ||
|
|
c6c697bdb7 | ||
|
|
660d59a7a9 | ||
|
|
92a5e6a698 | ||
|
|
aaa054a932 | ||
|
|
079065ea73 | ||
|
|
1905264061 | ||
|
|
b0a9430e98 | ||
|
|
f906384423 | ||
|
|
fc42f40770 | ||
|
|
6ec31517a9 | ||
|
|
8a4d769b3d | ||
|
|
a3b29dd70b | ||
|
|
b0491b9c54 | ||
|
|
6a93b6a7e4 | ||
|
|
ec6009dd8f | ||
|
|
4820d46353 | ||
|
|
a2845cee70 | ||
|
|
c897ca017c | ||
|
|
aee540d8bb | ||
|
|
19402aeef2 | ||
|
|
fcc0a6a203 | ||
|
|
2165905613 | ||
|
|
e5eb754150 | ||
|
|
d1c9dd554b | ||
|
|
063c6d6065 | ||
|
|
2fc8ce8a16 | ||
|
|
1a3adbe9cd | ||
|
|
63fa44fa4a | ||
|
|
f89dbd48c8 | ||
|
|
9fc3e84e93 | ||
|
|
e708a5b59d | ||
|
|
d55e4c0552 | ||
|
|
ef06bf7589 | ||
|
|
54926840e6 | ||
|
|
5ef077fdf6 | ||
|
|
336b29955d | ||
|
|
7fa2a4ccf3 | ||
|
|
e4fc5806c4 | ||
|
|
4def0110b5 | ||
|
|
503a1bf6d7 | ||
|
|
92e4ca3a92 | ||
|
|
9e25884f12 | ||
|
|
819770a6c4 | ||
|
|
7669a42cfb | ||
|
|
0495d75fcb | ||
|
|
0d6c15e45a | ||
|
|
49756a8e7a | ||
|
|
0b4056817a | ||
|
|
aced587461 | ||
|
|
077bd5b7ef | ||
|
|
bf9781e8fd | ||
|
|
40840368bb | ||
|
|
5946fa46a6 | ||
|
|
196df151aa | ||
|
|
c1566bc02b | ||
|
|
f349197df3 | ||
|
|
7e55babb62 | ||
|
|
5a0f9f4604 | ||
|
|
ae90da9951 | ||
|
|
9544cb516d | ||
|
|
fa8d35ae9c | ||
|
|
37ac1ed474 | ||
|
|
483d0534ae | ||
|
|
be7d763352 | ||
|
|
04bab6b197 | ||
|
|
f47af361cd | ||
|
|
676786a399 | ||
|
|
0692cd54e7 | ||
|
|
68d83383ff | ||
|
|
9bd9c8f301 | ||
|
|
f16fd03dab | ||
|
|
a7d8c983ba | ||
|
|
d192f545ac | ||
|
|
0157a156fb | ||
|
|
9f83882bcc | ||
|
|
bfb14fbbc6 | ||
|
|
be2595085f | ||
|
|
4625e7e2b6 | ||
|
|
bb39d09d5e | ||
|
|
36c91491cc | ||
|
|
d291e2b23d | ||
|
|
1814c24a90 | ||
|
|
92e08fdcd8 | ||
|
|
7875880aa1 | ||
|
|
383708fde8 | ||
|
|
4047ed7976 | ||
|
|
3c7d7a7856 | ||
|
|
d7c2118d10 | ||
|
|
97d06b107f | ||
|
|
61fbfb562e | ||
|
|
7e82a37fa3 | ||
|
|
141a23690e | ||
|
|
a024efb615 | ||
|
|
e60804cf41 | ||
|
|
d5a0f2fc07 | ||
|
|
2464582587 | ||
|
|
82ebf6372c | ||
|
|
3945b9df45 | ||
|
|
96813f76c1 | ||
|
|
2030e06988 | ||
|
|
cd85a42acc | ||
|
|
18c338ad09 | ||
|
|
2355e1ed8e | ||
|
|
5494c9ae09 | ||
|
|
20ad1ff261 | ||
|
|
589bb59268 | ||
|
|
e12d2b2f36 | ||
|
|
c64b8900ca | ||
|
|
1cd72d375c | ||
|
|
aa9a7435dd | ||
|
|
12c588fc35 | ||
|
|
8f0687adb7 | ||
|
|
281556e93d | ||
|
|
a196af8e15 | ||
|
|
7b07fca285 | ||
|
|
095cedb305 | ||
|
|
d5823b3e55 | ||
|
|
51ca2d1243 | ||
|
|
ec8081f983 | ||
|
|
34643d9628 | ||
|
|
68db6c5a65 | ||
|
|
d564e054e5 | ||
|
|
8616e3d6fa | ||
|
|
2c2ab24c8f | ||
|
|
d025c8aa93 | ||
|
|
7534abe325 | ||
|
|
7bc94d7810 | ||
|
|
a9a1c50268 | ||
|
|
5084a23417 | ||
|
|
46f551073e | ||
|
|
d9e1bcf3d0 | ||
|
|
13bb927d8a | ||
|
|
16414f921f | ||
|
|
9a116498a2 | ||
|
|
d8f945be23 | ||
|
|
8412d0d55f | ||
|
|
07cc18284c | ||
|
|
7d6d93e4e2 | ||
|
|
64b2345cf2 | ||
|
|
9b3987bf3c | ||
|
|
15cda5fef2 | ||
|
|
a10e07908e | ||
|
|
c2c9e09a49 | ||
|
|
1b79df810f | ||
|
|
9dde4b705d | ||
|
|
1abf4f1aa1 | ||
|
|
a47447610f | ||
|
|
d209d8ee39 | ||
|
|
8117f4b383 | ||
|
|
6b5ae5e4db | ||
|
|
a40c8f6bca | ||
|
|
a6fb6be8b5 | ||
|
|
ec99faff05 | ||
|
|
1352abfc98 | ||
|
|
687d0a928b | ||
|
|
947d642da7 | ||
|
|
1cbd6c3a80 | ||
|
|
11be93ce55 | ||
|
|
aaf35ca6ab | ||
|
|
4294a47cec | ||
|
|
b983d5546b | ||
|
|
ed9a3c3b10 | ||
|
|
d8f4ff4b57 | ||
|
|
af29735f44 | ||
|
|
638300045c | ||
|
|
71552b7d1a | ||
|
|
7c0a75cf0c | ||
|
|
f054500fe2 | ||
|
|
6684b2db04 | ||
|
|
999a53ab75 | ||
|
|
534d44ba55 | ||
|
|
c7c10613d7 | ||
|
|
dfc44db0ef | ||
|
|
7a6192b5c8 | ||
|
|
05f90bcf55 | ||
|
|
1be59d8ae7 | ||
|
|
b4dbb81af7 | ||
|
|
e709849243 | ||
|
|
1b2fa39cdc | ||
|
|
b4ec36ec78 | ||
|
|
dddaacc6fd | ||
|
|
e0c9efd129 | ||
|
|
01b81e0dbc | ||
|
|
d2034a6458 | ||
|
|
c4edbda969 | ||
|
|
f3917778bc | ||
|
|
032f12af45 | ||
|
|
bb37b74f98 | ||
|
|
817a38494c | ||
|
|
d6fe6ea936 | ||
|
|
af48acca14 | ||
|
|
11696e23d1 | ||
|
|
8b7dde0e41 | ||
|
|
54cb85adfc | ||
|
|
f636ffde48 | ||
|
|
87235b618b | ||
|
|
e4cc12f3b9 | ||
|
|
9d1084d3c0 | ||
|
|
21b24c7725 | ||
|
|
3e75f8e41f | ||
|
|
dec0fa622c | ||
|
|
dbd05557ca | ||
|
|
e30334e527 | ||
|
|
3e76f6d656 | ||
|
|
91ad8a72c6 | ||
|
|
e2361fab29 | ||
|
|
f6b8d613ab | ||
|
|
3a3cd8565d | ||
|
|
b9bcacd803 | ||
|
|
cbd1b948a2 | ||
|
|
d1c1997acf | ||
|
|
fcbb41c391 | ||
|
|
e736c022b1 | ||
|
|
d08e0270e4 | ||
|
|
bb1d26f4f7 | ||
|
|
173577d5f7 | ||
|
|
5326790932 | ||
|
|
4ef3ac5ca6 | ||
|
|
cf47a759d1 | ||
|
|
046535cfbb | ||
|
|
637d43fb5a | ||
|
|
fbc5557a10 | ||
|
|
75b4b94061 | ||
|
|
d346fb098f | ||
|
|
633360a0f9 | ||
|
|
0e8a257ec2 | ||
|
|
7fa4cf5a34 | ||
|
|
eecc3312b7 | ||
|
|
11e5641089 | ||
|
|
f631cb6314 | ||
|
|
a586bfd1ec | ||
|
|
4dbd0442aa | ||
|
|
fa9a439bf1 | ||
|
|
11e394aacf | ||
|
|
9af0811a1c | ||
|
|
503487e9ea | ||
|
|
ca9616dc7b | ||
|
|
24bd630cb2 | ||
|
|
8487cb5616 | ||
|
|
d630e4dfe9 | ||
|
|
3d5765949e | ||
|
|
0fcd2d9db6 | ||
|
|
3446455055 | ||
|
|
af304fea65 | ||
|
|
bcaa6accec | ||
|
|
5c00b96127 | ||
|
|
bfe3998eaa | ||
|
|
096e53dea4 | ||
|
|
bc77a19059 | ||
|
|
1b178d56b7 | ||
|
|
dca6171f5f | ||
|
|
164b5f9348 | ||
|
|
e927960121 | ||
|
|
6394a4d78d | ||
|
|
13be45bd73 | ||
|
|
7f7decde03 | ||
|
|
d9fea802da | ||
|
|
34f6e25b4e | ||
|
|
afe1e79338 | ||
|
|
cbaf36d4b8 | ||
|
|
6f8eede371 | ||
|
|
c693930595 | ||
|
|
6364aba975 | ||
|
|
10ec58703f | ||
|
|
9a69fcff7b | ||
|
|
26dc6d68cd | ||
|
|
0aca19356c | ||
|
|
5e94554d72 | ||
|
|
7d26515bc4 | ||
|
|
71c6193ff1 | ||
|
|
b0b6be0d23 | ||
|
|
7c1638652a | ||
|
|
1b1aa06dee | ||
|
|
51d3c03922 | ||
|
|
431d62185b | ||
|
|
c55eb37148 | ||
|
|
de6c57d661 | ||
|
|
ac78ba588f | ||
|
|
8e559e4e91 | ||
|
|
eff6e7a441 | ||
|
|
8994ef1483 | ||
|
|
20ee350601 | ||
|
|
c4257ecfc9 | ||
|
|
a91840c15d | ||
|
|
a748736d10 | ||
|
|
11682fc7eb | ||
|
|
255922e545 | ||
|
|
98694f15ce | ||
|
|
36b04748d4 | ||
|
|
d2928d500d | ||
|
|
15379f1750 | ||
|
|
0a4d8acefb | ||
|
|
632fd006c5 | ||
|
|
256c0986bb | ||
|
|
db7fbba08e | ||
|
|
f536a43e92 | ||
|
|
283ae6e538 | ||
|
|
fbafb915d2 | ||
|
|
4c52f66f5d | ||
|
|
46f63db746 | ||
|
|
4ad556d464 | ||
|
|
4dffd97d28 | ||
|
|
b1d853bf9b | ||
|
|
eba3d407ca | ||
|
|
44cd9158e8 | ||
|
|
b122ec2a1a | ||
|
|
bae0f1d3a7 | ||
|
|
23dbfabb1e | ||
|
|
6da71fdf56 | ||
|
|
bdfd5b9b55 | ||
|
|
64dffa5745 | ||
|
|
b9011d89ae | ||
|
|
3b3a4d3ddc | ||
|
|
b1613e99e6 | ||
|
|
d0f2a9e961 | ||
|
|
fb23493a98 | ||
|
|
17330a3073 | ||
|
|
fac5cbca43 | ||
|
|
670601bc2a | ||
|
|
25b48fa790 | ||
|
|
dd5fb47c6c | ||
|
|
b80401e1ee | ||
|
|
1bcd3a97ad | ||
|
|
09f90ab4e1 | ||
|
|
5929a00845 | ||
|
|
5d7558b5e0 | ||
|
|
ee71ade720 | ||
|
|
e437321ea7 | ||
|
|
6da610fe1e | ||
|
|
e8d4039175 | ||
|
|
faece5816c | ||
|
|
bc2a4c01c9 | ||
|
|
22769afd20 | ||
|
|
03ebd2f98d | ||
|
|
b378dccbe9 | ||
|
|
1f9489a65d | ||
|
|
f436b5d18e | ||
|
|
64401ab815 | ||
|
|
952169ded9 | ||
|
|
1b36aa5560 | ||
|
|
69705ef32b | ||
|
|
2e86c208d1 | ||
|
|
27b8738d06 | ||
|
|
8fa79ceb30 | ||
|
|
60cb78e4ab | ||
|
|
97f3a01dc5 | ||
|
|
99b8086ad2 | ||
|
|
c4386da666 | ||
|
|
51112131ad | ||
|
|
8808cd9514 | ||
|
|
890589191c | ||
|
|
75c78c7c5b | ||
|
|
69de1da172 | ||
|
|
28bc333cba | ||
|
|
8b4dc05ff8 | ||
|
|
6de80adbe8 | ||
|
|
fdcef3cbc4 | ||
|
|
41c7aa9e83 | ||
|
|
1929cfc4f9 | ||
|
|
8b70fefa59 | ||
|
|
af91920a17 | ||
|
|
89244e0f70 | ||
|
|
5abd939655 | ||
|
|
06ce23d9c2 | ||
|
|
a581e0ef0e | ||
|
|
b6ec138644 | ||
|
|
dc387ad9d1 | ||
|
|
48b186576e | ||
|
|
15b0946fc4 | ||
|
|
5830e65829 | ||
|
|
f3a51fdfd1 | ||
|
|
afd23d13d5 | ||
|
|
11f479e028 | ||
|
|
838f6ce862 | ||
|
|
e99d53b80b | ||
|
|
1d314faf97 | ||
|
|
751587e112 | ||
|
|
673675fecd | ||
|
|
ee58fd749c | ||
|
|
bcc7973792 | ||
|
|
b176a6410d | ||
|
|
d8592b1444 | ||
|
|
4568766cff | ||
|
|
c49b21115a | ||
|
|
106850ca7d | ||
|
|
2ea5919a4a | ||
|
|
0375ff3923 | ||
|
|
59ce217ce2 | ||
|
|
350369f3fc | ||
|
|
d9c400ac0c | ||
|
|
922b74be9e | ||
|
|
cd239a9857 | ||
|
|
8e515a9a64 | ||
|
|
45bb1313e7 | ||
|
|
d04aa4b234 | ||
|
|
074055bc58 | ||
|
|
d6726f62fc | ||
|
|
bc9e31a444 | ||
|
|
f682d9cad1 | ||
|
|
1305d7659c | ||
|
|
502a0708ea | ||
|
|
c64407f7cf | ||
|
|
cdbfe28c4e | ||
|
|
fbd2843cad | ||
|
|
10b5a82904 | ||
|
|
1527b87595 | ||
|
|
4407bc1d50 | ||
|
|
927edf03d6 | ||
|
|
f5717a6e87 | ||
|
|
84a24f2a34 | ||
|
|
60b1ade52d | ||
|
|
81ba40456f | ||
|
|
1b684a4846 | ||
|
|
3b43fcfc21 | ||
|
|
4b3ef8a314 | ||
|
|
679ef3a380 | ||
|
|
367d7bf94b | ||
|
|
e5f84002b1 | ||
|
|
f926cbcc59 | ||
|
|
5451a4830f |
@@ -0,0 +1,2 @@
|
||||
# gperf in MSYS chokes on DOS line endings
|
||||
*.gperf text eol=lf
|
||||
@@ -30,6 +30,10 @@ 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
|
||||
/vpi/vpi_config.h
|
||||
@@ -47,6 +51,8 @@ dep
|
||||
*.vpi
|
||||
/cadpli/cadpli.vpl
|
||||
|
||||
/tgt-blif/Makefile
|
||||
|
||||
# lex, yacc and gperf output
|
||||
/driver/cflexor.c
|
||||
/driver/cfparse.c
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
#ifndef __AStatement_H
|
||||
#define __AStatement_H
|
||||
#ifndef IVL_AStatement_H
|
||||
#define IVL_AStatement_H
|
||||
/*
|
||||
* Copyright (c) 2008 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2008-2014 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
|
||||
@@ -82,4 +82,4 @@ class AProcess : public LineInfo {
|
||||
AProcess& operator= (const AProcess&);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_AStatement_H */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __Attrib_H
|
||||
#define __Attrib_H
|
||||
#ifndef IVL_Attrib_H
|
||||
#define IVL_Attrib_H
|
||||
/*
|
||||
* Copyright (c) 2000-2009 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000-2014 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
|
||||
@@ -57,4 +57,4 @@ class Attrib {
|
||||
Attrib& operator= (const Attrib&);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_Attrib_H */
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
@@ -16,7 +15,7 @@ software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
@@ -56,8 +55,8 @@ patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
@@ -111,7 +110,7 @@ above, provided that you also meet all of these conditions:
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
@@ -169,7 +168,7 @@ access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
@@ -226,7 +225,7 @@ impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
@@ -256,7 +255,7 @@ make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
@@ -278,9 +277,9 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
Appendix: How to Apply These Terms to Your New Programs
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
@@ -292,7 +291,7 @@ convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) 19yy <name of author>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@@ -304,16 +303,16 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
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
|
||||
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.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) 19yy name of author
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
@@ -336,5 +335,5 @@ necessary. Here is a sample; alter the names:
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001-2012 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001-2014 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
|
||||
@@ -22,22 +22,26 @@
|
||||
# include <iostream>
|
||||
# include <cstring>
|
||||
# include <cstdlib>
|
||||
# include <climits>
|
||||
|
||||
using namespace std;
|
||||
|
||||
hname_t::hname_t()
|
||||
{
|
||||
number_ = INT_MIN;
|
||||
}
|
||||
|
||||
hname_t::hname_t(perm_string text)
|
||||
: name_(text)
|
||||
{
|
||||
number_ = INT_MIN;
|
||||
}
|
||||
|
||||
hname_t::hname_t(perm_string text, int num)
|
||||
: name_(text), number_(num)
|
||||
: name_(text), number_(1)
|
||||
{
|
||||
number_[0] = num;
|
||||
}
|
||||
|
||||
hname_t::hname_t(perm_string text, const vector<int>&nums)
|
||||
: name_(text), number_(nums)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -53,24 +57,50 @@ hname_t& hname_t::operator = (const hname_t&that)
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator < (const hname_t&l, const hname_t&r)
|
||||
bool hname_t::operator < (const hname_t&r) const
|
||||
{
|
||||
int cmp = strcmp(l.peek_name(), r.peek_name());
|
||||
int cmp = strcmp(name_, r.name_);
|
||||
if (cmp < 0) return true;
|
||||
if (cmp > 0) return false;
|
||||
if (l.has_number() && r.has_number())
|
||||
return l.peek_number() < r.peek_number();
|
||||
else
|
||||
return false;
|
||||
|
||||
// The text parts are equal, so compare then number
|
||||
// parts. Finish as soon as we find one to be less or more
|
||||
// than the other.
|
||||
size_t idx = 0;
|
||||
while (number_.size() > idx || r.number_.size() > idx) {
|
||||
|
||||
// Ran out of l numbers, so less.
|
||||
if (number_.size() <= idx)
|
||||
return true;
|
||||
|
||||
// Ran out of r numbers, so greater.
|
||||
if (r.number_.size() <= idx)
|
||||
return false;
|
||||
|
||||
if (number_[idx] < r.number_[idx])
|
||||
return true;
|
||||
|
||||
if (number_[idx] > r.number_[idx])
|
||||
return false;
|
||||
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
// Fall-through means that we are equal, including all the
|
||||
// number parts, so not less.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator == (const hname_t&l, const hname_t&r)
|
||||
bool hname_t::operator == (const hname_t&r) const
|
||||
{
|
||||
if (l.peek_name() == r.peek_name()) {
|
||||
if (l.has_number() && r.has_number())
|
||||
return l.peek_number() == r.peek_number();
|
||||
else
|
||||
return true;
|
||||
if (name_ == r.name_) {
|
||||
if (number_.size() != r.number_.size())
|
||||
return false;
|
||||
|
||||
for (size_t idx = 0 ; idx < number_.size() ; idx += 1)
|
||||
if (number_[idx] != r.number_[idx]) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -84,8 +114,8 @@ ostream& operator<< (ostream&out, const hname_t&that)
|
||||
}
|
||||
|
||||
out << that.peek_name();
|
||||
if (that.has_number())
|
||||
out << "[" << that.peek_number() << "]";
|
||||
for (size_t idx = 0 ; idx < that.number_.size() ; idx += 1)
|
||||
out << "[" << that.number_[idx] << "]";
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __HName_H
|
||||
#define __HName_H
|
||||
#ifndef IVL_HName_H
|
||||
#define IVL_HName_H
|
||||
/*
|
||||
* Copyright (c) 2001-2010 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001-2014 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,10 @@
|
||||
|
||||
# include <iostream>
|
||||
# include <list>
|
||||
# include <vector>
|
||||
# include "StringHeap.h"
|
||||
# include <climits>
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ > 2
|
||||
using namespace std;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
# include <cassert>
|
||||
|
||||
/*
|
||||
* This class represents a component of a Verilog hierarchical name. A
|
||||
@@ -39,27 +36,33 @@ using namespace std;
|
||||
|
||||
class hname_t {
|
||||
|
||||
friend ostream& operator<< (ostream&out, const hname_t&that);
|
||||
|
||||
public:
|
||||
hname_t ();
|
||||
explicit hname_t (perm_string text);
|
||||
explicit hname_t (perm_string text, int num);
|
||||
explicit hname_t (perm_string text, const std::vector<int>&nums);
|
||||
hname_t (const hname_t&that);
|
||||
~hname_t();
|
||||
|
||||
hname_t& operator= (const hname_t&);
|
||||
|
||||
bool operator == (const hname_t&that) const;
|
||||
bool operator < (const hname_t&that) const;
|
||||
|
||||
// Return the string part of the hname_t.
|
||||
perm_string peek_name(void) const;
|
||||
|
||||
bool has_number() const;
|
||||
int peek_number() const;
|
||||
size_t has_numbers() const;
|
||||
int peek_number(size_t idx) const;
|
||||
const std::vector<int>&peek_numbers() const;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
// If the number is anything other than INT_MIN, then this is
|
||||
// the numeric part of the name. Otherwise, it is not part of
|
||||
// the name at all.
|
||||
int number_;
|
||||
// If this vector has size, then the numbers all together make
|
||||
// up part of the hierarchical name.
|
||||
std::vector<int> number_;
|
||||
|
||||
private: // not implemented
|
||||
};
|
||||
@@ -73,18 +76,22 @@ inline perm_string hname_t::peek_name(void) const
|
||||
return name_;
|
||||
}
|
||||
|
||||
inline int hname_t::peek_number() const
|
||||
inline int hname_t::peek_number(size_t idx) const
|
||||
{
|
||||
assert(number_.size() > idx);
|
||||
return number_[idx];
|
||||
}
|
||||
|
||||
inline const std::vector<int>& hname_t::peek_numbers(void) const
|
||||
{
|
||||
return number_;
|
||||
}
|
||||
|
||||
inline bool hname_t::has_number() const
|
||||
inline size_t hname_t::has_numbers() const
|
||||
{
|
||||
return number_ != INT_MIN;
|
||||
return number_.size();
|
||||
}
|
||||
|
||||
extern bool operator < (const hname_t&, const hname_t&);
|
||||
extern bool operator == (const hname_t&, const hname_t&);
|
||||
extern ostream& operator<< (ostream&, const hname_t&);
|
||||
|
||||
inline bool operator != (const hname_t&l, const hname_t&r)
|
||||
@@ -102,4 +109,4 @@ inline ostream& operator<< (ostream&out, const list<hname_t>&ll)
|
||||
return out;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif /* IVL_HName_H */
|
||||
|
||||
+11
-8
@@ -38,7 +38,7 @@ srcdir = @srcdir@
|
||||
datarootdir = @datarootdir@
|
||||
|
||||
SUBDIRS = ivlpp vhdlpp vvp vpi libveriuser cadpli tgt-null tgt-stub tgt-vvp \
|
||||
tgt-vhdl tgt-vlog95 tgt-pcb driver
|
||||
tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif tgt-sizer driver
|
||||
# Only run distclean for these directories.
|
||||
NOTUSED = tgt-fpga tgt-pal tgt-verilog
|
||||
|
||||
@@ -68,7 +68,7 @@ dllib=@DLLIB@
|
||||
|
||||
# For a cross compile these defines will need to be set accordingly.
|
||||
HOSTCC = @CC@
|
||||
HOSTCFLAGS = @WARNING_FLAGS@ @CFLAGS@
|
||||
HOSTCFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
@@ -90,7 +90,7 @@ INCLUDE_PATH = -I. -I$(srcdir) -I$(srcdir)/libmisc
|
||||
endif
|
||||
|
||||
CPPFLAGS = @DEFS@ $(INCLUDE_PATH) @CPPFLAGS@
|
||||
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
|
||||
PICFLAGS = @PICFLAG@
|
||||
LDFLAGS = @rdynamic@ @LDFLAGS@
|
||||
@@ -109,7 +109,8 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
|
||||
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
||||
load_module.o netlist.o netmisc.o nettypes.o net_analog.o net_assign.o \
|
||||
net_design.o netclass.o netdarray.o \
|
||||
netenum.o netparray.o netstruct.o netvector.o net_event.o net_expr.o net_func.o \
|
||||
netenum.o netparray.o netqueue.o netscalar.o netstruct.o netvector.o \
|
||||
net_event.o net_expr.o net_func.o \
|
||||
net_func_eval.o net_link.o net_modulo.o \
|
||||
net_nex_input.o net_nex_output.o net_proc.o net_scope.o net_tran.o \
|
||||
net_udp.o pad_to_width.o parse.o parse_misc.o pform.o pform_analog.o \
|
||||
@@ -117,8 +118,8 @@ O = main.o async.o design_dump.o discipline.o dup_expr.o elaborate.o \
|
||||
pform_class_type.o pform_string_type.o pform_struct_type.o pform_types.o \
|
||||
symbol_search.o sync.o sys_funcs.o verinum.o verireal.o target.o \
|
||||
Attrib.o HName.o Module.o PClass.o PDelays.o PEvent.o PExpr.o PGate.o \
|
||||
PGenerate.o PPackage.o PScope.o PSpec.o PTask.o PUdp.o PFunction.o PWire.o \
|
||||
Statement.o AStatement.o $M $(FF) $(TT)
|
||||
PGenerate.o PModport.o PPackage.o PScope.o PSpec.o PTask.o PUdp.o \
|
||||
PFunction.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
|
||||
$(foreach dir,$(SUBDIRS),$(MAKE) -C $(dir) $@ && ) true
|
||||
@@ -174,6 +175,8 @@ endif
|
||||
|
||||
cppcheck: $(O:.o=.cc) $(srcdir)/dosify.c $(srcdir)/version.c
|
||||
cppcheck --enable=all -f --suppressions-list=$(srcdir)/cppcheck.sup \
|
||||
-UYYPARSE_PARAM -UYYPRINT -Ushort -Usize_t -Uyyoverflow \
|
||||
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \
|
||||
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
|
||||
|
||||
cppcheck-all:
|
||||
@@ -264,7 +267,7 @@ 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,$$ -L ANSI-C -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 $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
|
||||
|
||||
iverilog-vpi.man: $(srcdir)/iverilog-vpi.man.in version.exe
|
||||
./version.exe `head -1 $(srcdir)/iverilog-vpi.man.in`'\n' > $@
|
||||
@@ -289,7 +292,7 @@ endif
|
||||
version_tag.h version:
|
||||
@if $(GIT_PRESENT) && test -d $(srcdir)/.git; then \
|
||||
echo "Using git-describe for VERSION_TAG"; \
|
||||
tmp=`$(GIT) --git-dir $(srcdir)/.git describe --always --dirty \
|
||||
tmp=`(cd $(srcdir) && $(GIT) describe --always --dirty) \
|
||||
| sed -e 's;\(.*\);#define VERSION_TAG "\1";'`; \
|
||||
echo "$$tmp" | diff - version_tag.h > /dev/null 2>&1 || echo "$$tmp" > version_tag.h || exit 1; \
|
||||
elif test -r $(srcdir)/version_tag.h; then \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2010 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2016 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
|
||||
@@ -35,9 +35,6 @@ Module::Module(LexicalScope*parent, perm_string n)
|
||||
program_block = false;
|
||||
uc_drive = UCD_NONE;
|
||||
timescale_warn_done = false;
|
||||
time_unit = 0;
|
||||
time_precision = 0;
|
||||
time_from_timescale = false;
|
||||
}
|
||||
|
||||
Module::~Module()
|
||||
@@ -94,13 +91,15 @@ perm_string Module::get_port_name(unsigned idx) const
|
||||
{
|
||||
|
||||
assert(idx < ports.size());
|
||||
if (ports[idx] == 0) {
|
||||
if (ports[idx] == 0 || ports[idx]->name.str() == 0) {
|
||||
/* It is possible to have undeclared ports. These
|
||||
are ports that are skipped in the declaration,
|
||||
for example like so: module foo(x ,, y); The
|
||||
port between x and y is unnamed and thus
|
||||
inaccessible to binding by name. */
|
||||
return perm_string::literal("");
|
||||
inaccessible to binding by name. Port references
|
||||
that aren't simple or escaped identifiers are
|
||||
also inaccessible to binding by name. */
|
||||
return perm_string::literal("unnamed");
|
||||
}
|
||||
return ports[idx]->name;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __Module_H
|
||||
#define __Module_H
|
||||
#ifndef IVL_Module_H
|
||||
#define IVL_Module_H
|
||||
/*
|
||||
* Copyright (c) 1998-2010,2012 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2016 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
|
||||
@@ -35,6 +35,7 @@ class PExpr;
|
||||
class PEIdent;
|
||||
class PGate;
|
||||
class PGenerate;
|
||||
class PModport;
|
||||
class PSpecPath;
|
||||
class PTask;
|
||||
class PFunction;
|
||||
@@ -47,6 +48,10 @@ class NetScope;
|
||||
* A module is a named container and scope. A module holds a bunch of
|
||||
* semantic quantities such as wires and gates. The module is
|
||||
* therefore the handle for grasping the described circuit.
|
||||
*
|
||||
* SystemVerilog introduces program blocks and interfaces. These have
|
||||
* much in common with modules, so the Module class is used to represent
|
||||
* these containers as well.
|
||||
*/
|
||||
|
||||
class Module : public PScopeExtra, public LineInfo {
|
||||
@@ -64,7 +69,7 @@ class Module : public PScopeExtra, public LineInfo {
|
||||
|
||||
public:
|
||||
/* The name passed here is the module name, not the instance
|
||||
name. This make must be a permallocated string. */
|
||||
name. This name must be a permallocated string. */
|
||||
explicit Module(LexicalScope*parent, perm_string name);
|
||||
~Module();
|
||||
|
||||
@@ -81,6 +86,11 @@ class Module : public PScopeExtra, public LineInfo {
|
||||
restrictions and slightly modify scheduling semantics. */
|
||||
bool program_block;
|
||||
|
||||
/* This is true if the module represents a interface
|
||||
instead of a module/cell. Interfaces have different
|
||||
content restrictions and some extra allowed items. */
|
||||
bool is_interface;
|
||||
|
||||
enum UCDriveType { UCD_NONE, UCD_PULL0, UCD_PULL1 };
|
||||
UCDriveType uc_drive;
|
||||
|
||||
@@ -111,10 +121,6 @@ class Module : public PScopeExtra, public LineInfo {
|
||||
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
/* These are the timescale for this module. The default is
|
||||
set by the `timescale directive. */
|
||||
int time_unit, time_precision;
|
||||
bool time_from_timescale;
|
||||
bool timescale_warn_done;
|
||||
|
||||
/* The module has a list of generate schemes that appear in
|
||||
@@ -125,6 +131,11 @@ class Module : public PScopeExtra, public LineInfo {
|
||||
unless they are instantiated, implicitly or explicitly. */
|
||||
std::map<perm_string,Module*> nested_modules;
|
||||
|
||||
/* An interface can contain one or more named modport lists.
|
||||
The parser will ensure these don't appear in modules or
|
||||
program blocks. */
|
||||
map<perm_string,PModport*> modports;
|
||||
|
||||
list<PSpecPath*> specify_paths;
|
||||
|
||||
// The mod_name() is the name of the module type.
|
||||
@@ -160,4 +171,4 @@ class Module : public PScopeExtra, public LineInfo {
|
||||
Module& operator= (const Module&);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_Module_H */
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
# include "PClass.h"
|
||||
|
||||
PClass::PClass(perm_string name, LexicalScope*parent)
|
||||
: PScopeExtra(name, parent)
|
||||
: PScopeExtra(name, parent), type(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PClass_H
|
||||
#define __PClass_H
|
||||
#ifndef IVL_PClass_H
|
||||
#define IVL_PClass_H
|
||||
/*
|
||||
* Copyright (c) 2012 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2012-2014 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
|
||||
@@ -24,6 +24,8 @@
|
||||
# include "StringHeap.h"
|
||||
# include <iostream>
|
||||
|
||||
class PChainConstructor;
|
||||
|
||||
/*
|
||||
* SystemVerilog supports class declarations with their own lexical
|
||||
* scope, etc. The parser arranges for these to be created and
|
||||
@@ -42,4 +44,4 @@ class PClass : public PScopeExtra, public LineInfo {
|
||||
class_type_t*type;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_PClass_H */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PDelays_H
|
||||
#define __PDelays_H
|
||||
#ifndef IVL_PDelays_H
|
||||
#define IVL_PDelays_H
|
||||
/*
|
||||
* Copyright (c) 1999-2010 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2014 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
|
||||
@@ -72,4 +72,4 @@ class PDelays {
|
||||
|
||||
ostream& operator << (ostream&o, const PDelays&);
|
||||
|
||||
#endif
|
||||
#endif /* IVL_PDelays_H */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PEvent_H
|
||||
#define __PEvent_H
|
||||
#ifndef IVL_PEvent_H
|
||||
#define IVL_PEvent_H
|
||||
/*
|
||||
* Copyright (c) 2000-2004 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000-2014 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
|
||||
@@ -51,4 +51,4 @@ class PEvent : public LineInfo {
|
||||
PEvent& operator= (const PEvent&);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_PEvent_H */
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2012 Stephen Williams <[email protected]>
|
||||
* Copyright (c) 1998-2016 Stephen Williams <[email protected]>
|
||||
* Copyright CERN 2013 / 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
|
||||
@@ -76,6 +77,44 @@ bool PExpr::is_collapsible_net(Design*, NetScope*) const
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const char* PExpr::width_mode_name(width_mode_t mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case PExpr::SIZED:
|
||||
return "sized";
|
||||
case PExpr::UNSIZED:
|
||||
return "unsized";
|
||||
case PExpr::EXPAND:
|
||||
return "expand";
|
||||
case PExpr::LOSSLESS:
|
||||
return "lossless";
|
||||
case PExpr::UPSIZE:
|
||||
return "upsize";
|
||||
default:
|
||||
return "??";
|
||||
}
|
||||
}
|
||||
|
||||
PEAssignPattern::PEAssignPattern()
|
||||
{
|
||||
}
|
||||
|
||||
PEAssignPattern::PEAssignPattern(const list<PExpr*>&p)
|
||||
: parms_(p.size())
|
||||
{
|
||||
size_t idx = 0;
|
||||
for (list<PExpr*>::const_iterator cur = p.begin()
|
||||
; cur != p.end() ; ++cur) {
|
||||
parms_[idx] = *cur;
|
||||
idx += 1;
|
||||
}
|
||||
}
|
||||
|
||||
PEAssignPattern::~PEAssignPattern()
|
||||
{
|
||||
}
|
||||
|
||||
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
|
||||
: op_(op), left_(l), right_(r)
|
||||
{
|
||||
@@ -98,7 +137,7 @@ 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(unsigned si, PExpr*b)
|
||||
PECastSize::PECastSize(PExpr*si, PExpr*b)
|
||||
: size_(si), base_(b)
|
||||
{
|
||||
}
|
||||
@@ -107,6 +146,15 @@ PECastSize::~PECastSize()
|
||||
{
|
||||
}
|
||||
|
||||
PECastType::PECastType(data_type_t*t, PExpr*b)
|
||||
: target_(t), base_(b)
|
||||
{
|
||||
}
|
||||
|
||||
PECastType::~PECastType()
|
||||
{
|
||||
}
|
||||
|
||||
PEBComp::PEBComp(char op, PExpr*l, PExpr*r)
|
||||
: PEBinary(op, l, r)
|
||||
{
|
||||
@@ -156,7 +204,12 @@ PEBShift::~PEBShift()
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms)
|
||||
: path_(n), parms_(parms)
|
||||
: package_(0), path_(n), parms_(parms)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(PPackage*pkg, const pform_name_t&n, const vector<PExpr *> &parms)
|
||||
: package_(pkg), path_(n), parms_(parms)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -168,19 +221,29 @@ static pform_name_t pn_from_ps(perm_string n)
|
||||
return tmp;
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(PPackage*pkg, perm_string n, const list<PExpr *> &parms)
|
||||
: package_(pkg), path_(pn_from_ps(n)), parms_(parms.size())
|
||||
{
|
||||
int tmp_idx = 0;
|
||||
assert(parms_.size() == parms.size());
|
||||
for (list<PExpr*>::const_iterator idx = parms.begin()
|
||||
; idx != parms.end() ; ++idx)
|
||||
parms_[tmp_idx++] = *idx;
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(perm_string n, const vector<PExpr*>&parms)
|
||||
: path_(pn_from_ps(n)), parms_(parms)
|
||||
: package_(0), path_(pn_from_ps(n)), parms_(parms)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(perm_string n)
|
||||
: path_(pn_from_ps(n))
|
||||
: package_(0), path_(pn_from_ps(n))
|
||||
{
|
||||
}
|
||||
|
||||
// NOTE: Anachronism. Try to work all use of svector out.
|
||||
PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
|
||||
: path_(n), parms_(parms.size())
|
||||
: package_(0), path_(n), parms_(parms.size())
|
||||
{
|
||||
int tmp_idx = 0;
|
||||
assert(parms_.size() == parms.size());
|
||||
@@ -190,7 +253,7 @@ PECallFunction::PECallFunction(const pform_name_t&n, const list<PExpr *> &parms)
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(perm_string n, const list<PExpr*>&parms)
|
||||
: path_(pn_from_ps(n)), parms_(parms.size())
|
||||
: package_(0), path_(pn_from_ps(n)), parms_(parms.size())
|
||||
{
|
||||
int tmp_idx = 0;
|
||||
assert(parms_.size() == parms.size());
|
||||
@@ -305,16 +368,21 @@ const verireal& PEFNumber::value() const
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(const pform_name_t&that)
|
||||
: path_(that), no_implicit_sig_(false)
|
||||
: package_(0), path_(that), no_implicit_sig_(false)
|
||||
{
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(perm_string s, bool no_implicit_sig)
|
||||
: no_implicit_sig_(no_implicit_sig)
|
||||
: package_(0), no_implicit_sig_(no_implicit_sig)
|
||||
{
|
||||
path_.push_back(name_component_t(s));
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(PPackage*pkg, const pform_name_t&that)
|
||||
: package_(pkg), path_(that), no_implicit_sig_(true)
|
||||
{
|
||||
}
|
||||
|
||||
PEIdent::~PEIdent()
|
||||
{
|
||||
}
|
||||
@@ -379,12 +447,12 @@ bool PEIdent::has_aa_term(Design*des, NetScope*scope) const
|
||||
return false;
|
||||
}
|
||||
|
||||
PENew::PENew(PExpr*size_expr)
|
||||
: size_(size_expr)
|
||||
PENewArray::PENewArray(PExpr*size_expr, PExpr*init_expr)
|
||||
: size_(size_expr), init_(init_expr)
|
||||
{
|
||||
}
|
||||
|
||||
PENew::~PENew()
|
||||
PENewArray::~PENewArray()
|
||||
{
|
||||
delete size_;
|
||||
}
|
||||
@@ -393,10 +461,29 @@ PENewClass::PENewClass(void)
|
||||
{
|
||||
}
|
||||
|
||||
PENewClass::PENewClass(const list<PExpr*>&p)
|
||||
: parms_(p.size())
|
||||
{
|
||||
size_t tmp_idx = 0;
|
||||
for (list<PExpr*>::const_iterator cur = p.begin()
|
||||
; cur != p.end() ; ++ cur) {
|
||||
parms_[tmp_idx++] = *cur;
|
||||
}
|
||||
}
|
||||
|
||||
PENewClass::~PENewClass()
|
||||
{
|
||||
}
|
||||
|
||||
PENewCopy::PENewCopy(PExpr*src)
|
||||
: src_(src)
|
||||
{
|
||||
}
|
||||
|
||||
PENewCopy::~PENewCopy()
|
||||
{
|
||||
}
|
||||
|
||||
PENumber::PENumber(verinum*vp)
|
||||
: value_(vp)
|
||||
{
|
||||
@@ -462,6 +549,15 @@ bool PETernary::has_aa_term(Design*des, NetScope*scope) const
|
||||
|| fal_->has_aa_term(des, scope);
|
||||
}
|
||||
|
||||
PETypename::PETypename(data_type_t*dt)
|
||||
: data_type_(dt)
|
||||
{
|
||||
}
|
||||
|
||||
PETypename::~PETypename()
|
||||
{
|
||||
}
|
||||
|
||||
PEUnary::PEUnary(char op, PExpr*ex)
|
||||
: op_(op), expr_(ex)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#ifndef __PExpr_H
|
||||
#define __PExpr_H
|
||||
#ifndef IVL_PExpr_H
|
||||
#define IVL_PExpr_H
|
||||
/*
|
||||
* Copyright (c) 1998-2011 Stephen Williams <[email protected]>
|
||||
* Copyright (c) 1998-2016 Stephen Williams <[email protected]>
|
||||
* Copyright CERN 2013 / 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
|
||||
@@ -33,6 +34,7 @@ class LexicalScope;
|
||||
class NetNet;
|
||||
class NetExpr;
|
||||
class NetScope;
|
||||
class PPackage;
|
||||
|
||||
/*
|
||||
* The PExpr class hierarchy supports the description of
|
||||
@@ -43,14 +45,18 @@ class NetScope;
|
||||
class PExpr : public LineInfo {
|
||||
|
||||
public:
|
||||
enum width_mode_t { SIZED, EXPAND, LOSSLESS, UNSIZED };
|
||||
// Mode values used by test_width() (see below for description).
|
||||
enum width_mode_t { SIZED, UNSIZED, EXPAND, LOSSLESS, UPSIZE };
|
||||
|
||||
// Flag values that can be passed to elaborate_expr.
|
||||
// Flag values that can be passed to elaborate_expr().
|
||||
static const unsigned NO_FLAGS = 0x0;
|
||||
static const unsigned NEED_CONST = 0x1;
|
||||
static const unsigned SYS_TASK_ARG = 0x2;
|
||||
static const unsigned ANNOTATABLE = 0x4;
|
||||
|
||||
// Convert width mode to human-readable form.
|
||||
static const char*width_mode_name(width_mode_t mode);
|
||||
|
||||
PExpr();
|
||||
virtual ~PExpr();
|
||||
|
||||
@@ -77,33 +83,42 @@ class PExpr : public LineInfo {
|
||||
// without changing the result. This allows the expression width to
|
||||
// be pruned when not all bits of the result are used.
|
||||
//
|
||||
// Normally mode should be initialised to SIZED before starting to
|
||||
// Normally mode should be initialized to SIZED before starting to
|
||||
// test the width of an expression. In SIZED mode the expression
|
||||
// width will be calculated strictly according to the IEEE standard
|
||||
// rules for expression width.
|
||||
// If the expression contains an unsized literal, mode will be
|
||||
// changed to LOSSLESS. In LOSSLESS mode the expression width will
|
||||
// be calculated as the minimum width necessary to avoid arithmetic
|
||||
// overflow or underflow.
|
||||
// If the expression both contains an unsized literal and contains
|
||||
// an operation that coerces a vector operand to a different type
|
||||
// (signed <-> unsigned), mode is changed to UNSIZED. UNSIZED mode
|
||||
// is the same as LOSSLESS, except that the final expression width
|
||||
// will be forced to be at least integer_width. This is necessary
|
||||
// to ensure compatibility with the IEEE standard, which requires
|
||||
// unsized literals to be treated as having the same width as an
|
||||
// integer. The lossless width calculation is inadequate in this
|
||||
// case because coercing an operand to a different type means that
|
||||
// the expression no longer obeys the normal rules of arithmetic.
|
||||
//
|
||||
// If mode is initialised to EXPAND instead of SIZED, the expression
|
||||
// If the expression is found to contain an unsized literal number
|
||||
// and gn_strict_expr_width_flag is set, mode will be changed to
|
||||
// UNSIZED. In UNSIZED mode the expression width will be calculated
|
||||
// exactly as in SIZED mode - the change in mode simply flags that
|
||||
// the expression contains an unsized numbers.
|
||||
//
|
||||
// If the expression is found to contain an unsized literal number
|
||||
// and gn_strict_expr_width_flag is not set, mode will be changed
|
||||
// to LOSSLESS. In LOSSLESS mode the expression width will be
|
||||
// calculated as the minimum width necessary to avoid arithmetic
|
||||
// overflow or underflow.
|
||||
//
|
||||
// Once in LOSSLESS mode, if the expression is found to contain
|
||||
// an operation that coerces a vector operand to a different type
|
||||
// (signed <-> unsigned), mode will be changed to UPSIZE. UPSIZE
|
||||
// mode is the same as LOSSLESS, except that the final expression
|
||||
// width will be forced to be at least integer_width. This is
|
||||
// necessary to ensure compatibility with the IEEE standard, which
|
||||
// requires unsized numbers to be treated as having the same width
|
||||
// as an integer. The lossless width calculation is inadequate in
|
||||
// this case because coercing an operand to a different type means
|
||||
// that the expression no longer obeys the normal rules of arithmetic.
|
||||
//
|
||||
// If mode is initialized to EXPAND instead of SIZED, the expression
|
||||
// width will be calculated as the minimum width necessary to avoid
|
||||
// arithmetic overflow or underflow, even if it contains no unsized
|
||||
// literals. mode will be changed LOSSLESS or UNSIZED as described
|
||||
// literals. mode will be changed LOSSLESS or UPSIZE as described
|
||||
// above. This supports a non-standard mode of expression width
|
||||
// calculation.
|
||||
//
|
||||
// When the final value of mode is UNSIZED, the width returned by
|
||||
// When the final value of mode is UPSIZE, the width returned by
|
||||
// this method is the calculated lossless width, but the width
|
||||
// returned by a subsequent call to the expr_width method will be
|
||||
// the final expression width.
|
||||
@@ -149,11 +164,12 @@ class PExpr : public LineInfo {
|
||||
|
||||
// Expressions that can be in the l-value of procedural
|
||||
// assignments can be elaborated with this method. If the
|
||||
// is_force flag is true, then the set of valid l-value types
|
||||
// is slightly modified to accommodate the Verilog force
|
||||
// statement
|
||||
// is_cassign or is_force flags are true, then the set of
|
||||
// valid l-value types is slightly modified to accommodate
|
||||
// the Verilog procedural continuous assignment statements.
|
||||
virtual NetAssign_* elaborate_lval(Design*des,
|
||||
NetScope*scope,
|
||||
bool is_cassign,
|
||||
bool is_force) const;
|
||||
|
||||
// This attempts to evaluate a constant expression, and return
|
||||
@@ -188,6 +204,29 @@ class PExpr : public LineInfo {
|
||||
|
||||
ostream& operator << (ostream&, const PExpr&);
|
||||
|
||||
class PEAssignPattern : public PExpr {
|
||||
public:
|
||||
explicit PEAssignPattern();
|
||||
explicit PEAssignPattern(const std::list<PExpr*>&p);
|
||||
~PEAssignPattern();
|
||||
|
||||
void dump(std::ostream&) const;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope, width_mode_t&mode);
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
private:
|
||||
NetExpr* elaborate_expr_darray_(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
|
||||
private:
|
||||
std::vector<PExpr*>parms_;
|
||||
};
|
||||
|
||||
class PEConcat : public PExpr {
|
||||
|
||||
public:
|
||||
@@ -206,11 +245,16 @@ class PEConcat : public PExpr {
|
||||
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
|
||||
virtual NetNet* elaborate_bi_net(Design*des, NetScope*scope) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
virtual NetAssign_* elaborate_lval(Design*des,
|
||||
NetScope*scope,
|
||||
bool is_cassign,
|
||||
bool is_force) const;
|
||||
virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
|
||||
private:
|
||||
@@ -272,6 +316,8 @@ class PEFNumber : public PExpr {
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
@@ -286,6 +332,7 @@ class PEIdent : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEIdent(perm_string, bool no_implicit_sig=false);
|
||||
explicit PEIdent(PPackage*pkg, const pform_name_t&name);
|
||||
explicit PEIdent(const pform_name_t&);
|
||||
~PEIdent();
|
||||
|
||||
@@ -310,6 +357,7 @@ class PEIdent : public PExpr {
|
||||
// Identifiers are also allowed as procedural assignment l-values.
|
||||
virtual NetAssign_* elaborate_lval(Design*des,
|
||||
NetScope*scope,
|
||||
bool is_cassign,
|
||||
bool is_force) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
@@ -322,6 +370,11 @@ class PEIdent : public PExpr {
|
||||
// only applies to Ident expressions.
|
||||
NetNet* elaborate_subport(Design*des, NetScope*sc) const;
|
||||
|
||||
// Elaborate the identifier allowing for unpacked arrays. This
|
||||
// method only applies to Ident expressions because only Ident
|
||||
// expressions can can be unpacked arrays.
|
||||
NetNet* elaborate_unpacked_net(Design*des, NetScope*sc) const;
|
||||
|
||||
verinum* eval_const(Design*des, NetScope*sc) const;
|
||||
|
||||
virtual bool is_collapsible_net(Design*des, NetScope*scope) const;
|
||||
@@ -329,6 +382,7 @@ class PEIdent : public PExpr {
|
||||
const pform_name_t& path() const { return path_; }
|
||||
|
||||
private:
|
||||
PPackage*package_;
|
||||
pform_name_t path_;
|
||||
bool no_implicit_sig_;
|
||||
|
||||
@@ -368,17 +422,21 @@ class PEIdent : public PExpr {
|
||||
std::list<long>&prefix_indices) const;
|
||||
|
||||
private:
|
||||
NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*) const;
|
||||
bool elaborate_lval_net_bit_(Design*, NetScope*, NetAssign_*) const;
|
||||
NetAssign_*elaborate_lval_method_class_member_(Design*, NetScope*) const;
|
||||
NetAssign_*elaborate_lval_net_word_(Design*, NetScope*, NetNet*,
|
||||
bool need_const_idx) const;
|
||||
bool elaborate_lval_net_bit_(Design*, NetScope*, NetAssign_*,
|
||||
bool need_const_idx) const;
|
||||
bool elaborate_lval_net_part_(Design*, NetScope*, NetAssign_*) const;
|
||||
bool elaborate_lval_net_idx_(Design*, NetScope*, NetAssign_*,
|
||||
index_component_t::ctype_t) const;
|
||||
bool elaborate_lval_net_class_member_(Design*, NetScope*,
|
||||
NetAssign_*,
|
||||
const perm_string&) const;
|
||||
index_component_t::ctype_t,
|
||||
bool need_const_idx) const;
|
||||
NetAssign_*elaborate_lval_net_class_member_(Design*, NetScope*,
|
||||
NetNet*,
|
||||
const perm_string&) const;
|
||||
bool elaborate_lval_net_packed_member_(Design*, NetScope*,
|
||||
NetAssign_*,
|
||||
const perm_string&) const;
|
||||
const name_component_t&) const;
|
||||
bool elaborate_lval_darray_bit_(Design*, NetScope*,
|
||||
NetAssign_*) const;
|
||||
|
||||
@@ -391,6 +449,13 @@ class PEIdent : public PExpr {
|
||||
const NetExpr*par_lsb,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
NetExpr*elaborate_expr_param_bit_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
NetScope*found_in,
|
||||
const NetExpr*par_msb,
|
||||
const NetExpr*par_lsb,
|
||||
bool need_const) const;
|
||||
NetExpr*elaborate_expr_param_part_(Design*des,
|
||||
NetScope*scope,
|
||||
const NetExpr*par,
|
||||
@@ -444,20 +509,38 @@ class PEIdent : public PExpr {
|
||||
NetESignal*net,
|
||||
NetScope*found,
|
||||
bool need_const) const;
|
||||
NetExpr*elaborate_expr_net_bit_last_(Design*des,
|
||||
NetScope*scope,
|
||||
NetESignal*net,
|
||||
NetScope*found,
|
||||
bool need_const) const;
|
||||
|
||||
NetExpr*elaborate_expr_class_member_(Design*des,
|
||||
NetScope*scope,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
|
||||
unsigned test_width_method_(Design*des, NetScope*scope, width_mode_t&mode);
|
||||
NetExpr*elaborate_expr_method_(Design*des,
|
||||
NetScope*scope,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
|
||||
private:
|
||||
NetNet* elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
bool bidirectional_flag) const;
|
||||
|
||||
NetAssign_*scan_lname_for_nested_members_(Design*des, NetScope*scope,
|
||||
const pform_name_t&path) const;
|
||||
bool eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||
long&midx, long&lidx) const;
|
||||
};
|
||||
|
||||
class PENew : public PExpr {
|
||||
class PENewArray : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PENew (PExpr*s);
|
||||
~PENew();
|
||||
explicit PENewArray (PExpr*s, PExpr*i);
|
||||
~PENewArray();
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
@@ -470,13 +553,19 @@ class PENew : public PExpr {
|
||||
|
||||
private:
|
||||
PExpr*size_;
|
||||
PExpr*init_;
|
||||
};
|
||||
|
||||
class PENewClass : public PExpr {
|
||||
|
||||
public:
|
||||
// New without (or with default) constructor
|
||||
explicit PENewClass ();
|
||||
// New with constructor arguments
|
||||
explicit PENewClass (const std::list<PExpr*>&p);
|
||||
|
||||
~PENewClass();
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
// Class objects don't have a useful width, but the expression
|
||||
// is IVL_VT_CLASS.
|
||||
@@ -484,11 +573,37 @@ class PENewClass : public PExpr {
|
||||
width_mode_t&mode);
|
||||
// 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 netclas_t object.
|
||||
// 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;
|
||||
|
||||
private:
|
||||
NetExpr* elaborate_expr_constructor_(Design*des, NetScope*scope,
|
||||
const netclass_t*ctype,
|
||||
NetExpr*obj, unsigned flags) const;
|
||||
|
||||
private:
|
||||
std::vector<PExpr*>parms_;
|
||||
};
|
||||
|
||||
class PENewCopy : public PExpr {
|
||||
public:
|
||||
explicit PENewCopy(PExpr*src);
|
||||
~PENewCopy();
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
// 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);
|
||||
// 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;
|
||||
|
||||
private:
|
||||
PExpr*src_;
|
||||
};
|
||||
|
||||
class PENull : public PExpr {
|
||||
@@ -518,10 +633,13 @@ class PENumber : public PExpr {
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
|
||||
virtual NetExpr *elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid, unsigned) const;
|
||||
virtual NetAssign_* elaborate_lval(Design*des,
|
||||
NetScope*scope,
|
||||
bool is_cassign,
|
||||
bool is_force) const;
|
||||
|
||||
virtual verinum* eval_const(Design*des, NetScope*sc) const;
|
||||
@@ -551,6 +669,9 @@ class PEString : public PExpr {
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
||||
unsigned expr_wid, unsigned) const;
|
||||
verinum* eval_const(Design*, NetScope*) const;
|
||||
@@ -559,6 +680,23 @@ class PEString : public PExpr {
|
||||
char*text_;
|
||||
};
|
||||
|
||||
class PETypename : public PExpr {
|
||||
public:
|
||||
explicit PETypename(data_type_t*data_type);
|
||||
~PETypename();
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
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_; }
|
||||
|
||||
private:
|
||||
data_type_t*data_type_;
|
||||
};
|
||||
|
||||
class PEUnary : public PExpr {
|
||||
|
||||
public:
|
||||
@@ -739,7 +877,7 @@ class PETernary : public PExpr {
|
||||
private:
|
||||
NetExpr* elab_and_eval_alternative_(Design*des, NetScope*scope,
|
||||
PExpr*expr, unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
unsigned flags, bool short_cct) const;
|
||||
|
||||
private:
|
||||
PExpr*expr_;
|
||||
@@ -755,11 +893,18 @@ class PETernary : public PExpr {
|
||||
class PECallFunction : public PExpr {
|
||||
public:
|
||||
explicit PECallFunction(const pform_name_t&n, const vector<PExpr *> &parms);
|
||||
// Call function defined in package.
|
||||
explicit PECallFunction(PPackage*pkg, perm_string n, const std::vector<PExpr *> &parms);
|
||||
explicit PECallFunction(PPackage*pkg, perm_string n, const std::list<PExpr *> &parms);
|
||||
|
||||
// Used to convert a user function called as a task
|
||||
explicit PECallFunction(PPackage*pkg, const pform_name_t&n, const std::vector<PExpr *> &parms);
|
||||
|
||||
// Call of system function (name is not hierarchical)
|
||||
explicit PECallFunction(perm_string n, const vector<PExpr *> &parms);
|
||||
explicit PECallFunction(perm_string n);
|
||||
|
||||
// svector versions. Should be removed!
|
||||
// std::list versions. Should be removed!
|
||||
explicit PECallFunction(const pform_name_t&n, const list<PExpr *> &parms);
|
||||
explicit PECallFunction(perm_string n, const list<PExpr *> &parms);
|
||||
|
||||
@@ -772,23 +917,29 @@ class PECallFunction : public PExpr {
|
||||
virtual bool has_aa_term(Design*des, NetScope*scope) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid,
|
||||
unsigned flags) const;
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid, unsigned flags) const;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
|
||||
private:
|
||||
PPackage*package_;
|
||||
pform_name_t path_;
|
||||
vector<PExpr *> parms_;
|
||||
std::vector<PExpr *> parms_;
|
||||
|
||||
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
|
||||
|
||||
|
||||
NetExpr* cast_to_width_(NetExpr*expr, unsigned wid) const;
|
||||
|
||||
NetExpr*elaborate_expr_pkg_(Design*des, NetScope*scope,
|
||||
unsigned expr_wid, unsigned flags)const;
|
||||
NetExpr*elaborate_expr_method_(Design*des, NetScope*scope,
|
||||
unsigned expr_wid) const;
|
||||
unsigned expr_wid,
|
||||
bool add_this_flag = false) const;
|
||||
#if 0
|
||||
NetExpr*elaborate_expr_string_method_(Design*des, NetScope*scope) const;
|
||||
NetExpr*elaborate_expr_enum_method_(Design*des, NetScope*scope,
|
||||
@@ -804,6 +955,14 @@ class PECallFunction : public PExpr {
|
||||
width_mode_t&mode);
|
||||
unsigned test_width_method_(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
|
||||
NetExpr*elaborate_base_(Design*des, NetScope*scope, NetScope*dscope,
|
||||
unsigned expr_wid, unsigned flags) const;
|
||||
|
||||
unsigned elaborate_arguments_(Design*des, NetScope*scope,
|
||||
NetFuncDef*def, bool need_const,
|
||||
std::vector<NetExpr*>&parms,
|
||||
unsigned parm_off) const;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -812,7 +971,7 @@ class PECallFunction : public PExpr {
|
||||
class PECastSize : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PECastSize(unsigned expr_wid, PExpr*base);
|
||||
explicit PECastSize(PExpr*size, PExpr*base);
|
||||
~PECastSize();
|
||||
|
||||
void dump(ostream &out) const;
|
||||
@@ -825,7 +984,32 @@ class PECastSize : public PExpr {
|
||||
width_mode_t&mode);
|
||||
|
||||
private:
|
||||
unsigned size_;
|
||||
PExpr* size_;
|
||||
PExpr* base_;
|
||||
};
|
||||
|
||||
/*
|
||||
* Support the SystemVerilog cast to a different type.
|
||||
*/
|
||||
class PECastType : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PECastType(data_type_t*target, PExpr*base);
|
||||
~PECastType();
|
||||
|
||||
void dump(ostream &out) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
ivl_type_t type, unsigned flags) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
unsigned expr_wid, unsigned flags) const;
|
||||
|
||||
virtual unsigned test_width(Design*des, NetScope*scope,
|
||||
width_mode_t&mode);
|
||||
|
||||
private:
|
||||
data_type_t* target_;
|
||||
PExpr* base_;
|
||||
};
|
||||
|
||||
@@ -844,4 +1028,4 @@ class PEVoid : public PExpr {
|
||||
unsigned flags) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_PExpr_H */
|
||||
|
||||
+46
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2008,2010 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2013 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
|
||||
@@ -18,26 +18,22 @@
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
||||
#include "PTask.h"
|
||||
# include "PTask.h"
|
||||
# include "Statement.h"
|
||||
# include <cassert>
|
||||
# include "ivl_assert.h"
|
||||
|
||||
PFunction::PFunction(perm_string name, LexicalScope*parent, bool is_auto__)
|
||||
: PScope(name, parent), ports_(0), statement_(0)
|
||||
: PTaskFunc(name, parent), statement_(0)
|
||||
{
|
||||
is_auto_ = is_auto__;
|
||||
return_type_.type = PTF_NONE;
|
||||
return_type_ = 0;
|
||||
}
|
||||
|
||||
PFunction::~PFunction()
|
||||
{
|
||||
}
|
||||
|
||||
void PFunction::set_ports(svector<PWire *>*p)
|
||||
{
|
||||
assert(ports_ == 0);
|
||||
ports_ = p;
|
||||
}
|
||||
|
||||
void PFunction::set_statement(Statement*s)
|
||||
{
|
||||
assert(s != 0);
|
||||
@@ -45,7 +41,45 @@ void PFunction::set_statement(Statement*s)
|
||||
statement_ = s;
|
||||
}
|
||||
|
||||
void PFunction::set_return(PTaskFuncArg t)
|
||||
void PFunction::push_statement_front(Statement*stmt)
|
||||
{
|
||||
// This can only happen after the statement is initially set.
|
||||
ivl_assert(*this, statement_);
|
||||
|
||||
// Get the PBlock of the statement. If it is not a PBlock,
|
||||
// then create one to wrap the existing statement and the new
|
||||
// statement that we're pushing.
|
||||
PBlock*blk = dynamic_cast<PBlock*> (statement_);
|
||||
if (blk == 0) {
|
||||
PBlock*tmp = new PBlock(PBlock::BL_SEQ);
|
||||
tmp->set_line(*this);
|
||||
vector<Statement*>tmp_list(1);
|
||||
tmp_list[0] = statement_;
|
||||
tmp->set_statement(tmp_list);
|
||||
|
||||
statement_ = tmp;
|
||||
blk = tmp;
|
||||
}
|
||||
|
||||
// Now do the push.
|
||||
blk->push_statement_front(stmt);
|
||||
}
|
||||
|
||||
void PFunction::set_return(data_type_t*t)
|
||||
{
|
||||
return_type_ = t;
|
||||
}
|
||||
|
||||
PChainConstructor* PFunction::extract_chain_constructor()
|
||||
{
|
||||
PChainConstructor*res = 0;
|
||||
|
||||
if ((res = dynamic_cast<PChainConstructor*> (statement_))) {
|
||||
statement_ = 0;
|
||||
|
||||
} else if (PBlock*blk = dynamic_cast<PBlock*>(statement_)) {
|
||||
res = blk->extract_chain_constructor();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2010 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2013 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
|
||||
@@ -260,18 +260,16 @@ const char* PGBuiltin::gate_name() const
|
||||
}
|
||||
|
||||
PGModule::PGModule(perm_string type, perm_string name, list<PExpr*>*pins)
|
||||
: PGate(name, pins), bound_type_(0), overrides_(0), pins_(0),
|
||||
: PGate(name, pins), bound_type_(0), type_(type), overrides_(0), pins_(0),
|
||||
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
PGModule::PGModule(perm_string type, perm_string name,
|
||||
named<PExpr*>*pins, unsigned npins)
|
||||
: PGate(name, 0), bound_type_(0), overrides_(0), pins_(pins),
|
||||
: PGate(name, 0), bound_type_(0), type_(type), overrides_(0), pins_(pins),
|
||||
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
PGModule::PGModule(Module*type, perm_string name)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PGate_H
|
||||
#define __PGate_H
|
||||
#ifndef IVL_PGate_H
|
||||
#define IVL_PGate_H
|
||||
/*
|
||||
* Copyright (c) 1998-2011 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2014 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
|
||||
@@ -124,6 +124,7 @@ class PGAssign : public PGate {
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
void elaborate_unpacked_array_(Design*des, NetScope*scope, NetNet*lval) const;
|
||||
};
|
||||
|
||||
|
||||
@@ -259,4 +260,4 @@ class PGModule : public PGate {
|
||||
NetNet::PortType dir, bool as_signed) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_PGate_H */
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
#ifndef __PGenerate_H
|
||||
#define __PGenerate_H
|
||||
#ifndef IVL_PGenerate_H
|
||||
#define IVL_PGenerate_H
|
||||
/*
|
||||
* Copyright (c) 2006-2010,2012 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2006-2014 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
|
||||
@@ -139,4 +139,4 @@ class PGenerate : public LineInfo, public LexicalScope {
|
||||
|
||||
extern std::ostream& operator << (std::ostream&, PGenerate::scheme_t);
|
||||
|
||||
#endif
|
||||
#endif /* IVL_PGenerate_H */
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2015 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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PModport.h"
|
||||
|
||||
PModport::PModport(perm_string n)
|
||||
: name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
PModport::~PModport()
|
||||
{
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
#ifndef IVL_PModport_H
|
||||
#define IVL_PModport_H
|
||||
/*
|
||||
* Copyright (c) 2015 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
|
||||
* 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.
|
||||
*/
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "PScope.h"
|
||||
# include "StringHeap.h"
|
||||
# include "netlist.h"
|
||||
# include <vector>
|
||||
|
||||
/*
|
||||
* The PModport class represents a parsed SystemVerilog modport list.
|
||||
*/
|
||||
class PModport : public LineInfo {
|
||||
|
||||
public:
|
||||
// The name is a perm-allocated string. It is the simple name
|
||||
// of the modport, without any scope.
|
||||
explicit PModport(perm_string name);
|
||||
~PModport();
|
||||
|
||||
perm_string name() const { return name_; }
|
||||
|
||||
typedef pair <NetNet::PortType,PExpr*> simple_port_t;
|
||||
map<perm_string,simple_port_t> simple_ports;
|
||||
|
||||
private:
|
||||
perm_string name_;
|
||||
|
||||
private: // not implemented
|
||||
PModport(const PModport&);
|
||||
PModport& operator= (const PModport&);
|
||||
};
|
||||
|
||||
#endif /* IVL_PModport_H */
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Picture Elements, Inc.
|
||||
* Stephen Williams ([email protected])
|
||||
* Copyright (c) 2012 Stephen Williams ([email protected])
|
||||
* Copyright CERN 2013 / 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
|
||||
|
||||
+11
-4
@@ -1,7 +1,8 @@
|
||||
#ifndef __PPackage_H
|
||||
#define __PPackage_H
|
||||
#ifndef IVL_PPackage_H
|
||||
#define IVL_PPackage_H
|
||||
/*
|
||||
* Copyright (c) 2012 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2012-2014 Stephen Williams ([email protected])
|
||||
* Copyright CERN 2013 / 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
|
||||
@@ -22,6 +23,7 @@
|
||||
# include "PScope.h"
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include <iostream>
|
||||
|
||||
/*
|
||||
* SystemVerilog supports class declarations with their own lexical
|
||||
@@ -35,6 +37,11 @@ class PPackage : public PScopeExtra, public LineInfo {
|
||||
explicit PPackage (perm_string name, LexicalScope*parent);
|
||||
~PPackage();
|
||||
|
||||
bool elaborate_scope(Design*des, NetScope*scope);
|
||||
bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
bool elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
void pform_dump(std::ostream&out) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_PPackage_H */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2008,2010 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2008,2016 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
|
||||
@@ -19,18 +19,9 @@
|
||||
|
||||
# include "PScope.h"
|
||||
|
||||
PScope::PScope(perm_string n, LexicalScope*parent)
|
||||
: LexicalScope(parent), name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
PScope::PScope(perm_string n)
|
||||
: LexicalScope(0), name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
PScope::~PScope()
|
||||
bool LexicalScope::var_init_needs_explicit_lifetime() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PWire* LexicalScope::wires_find(perm_string name)
|
||||
@@ -42,17 +33,26 @@ PWire* LexicalScope::wires_find(perm_string name)
|
||||
return (*cur).second;
|
||||
}
|
||||
|
||||
PScopeExtra::PScopeExtra(perm_string n, LexicalScope*parent)
|
||||
: PScope(n, parent)
|
||||
PScope::PScope(perm_string n, LexicalScope*parent)
|
||||
: LexicalScope(parent), name_(n)
|
||||
{
|
||||
time_unit = 0;
|
||||
time_precision = 0;
|
||||
time_from_timescale = false;
|
||||
}
|
||||
|
||||
PScopeExtra::PScopeExtra(perm_string n)
|
||||
: PScope(n)
|
||||
PScope::~PScope()
|
||||
{
|
||||
for(map<perm_string, data_type_t*>::iterator it = typedefs.begin();
|
||||
it != typedefs.end(); ++it)
|
||||
delete it->second;
|
||||
}
|
||||
|
||||
PScopeExtra::PScopeExtra(perm_string n, LexicalScope*parent)
|
||||
: PScope(n, parent)
|
||||
{
|
||||
}
|
||||
|
||||
PScopeExtra::~PScopeExtra()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PScope_H
|
||||
#define __PScope_H
|
||||
#ifndef IVL_PScope_H
|
||||
#define IVL_PScope_H
|
||||
/*
|
||||
* Copyright (c) 2008,2010 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2008-2016 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
|
||||
@@ -24,15 +24,19 @@
|
||||
# include "pform_types.h"
|
||||
# include "ivl_target.h"
|
||||
# include <map>
|
||||
# include <set>
|
||||
# include <vector>
|
||||
|
||||
class PEvent;
|
||||
class PExpr;
|
||||
class PFunction;
|
||||
class PPackage;
|
||||
class AProcess;
|
||||
class PProcess;
|
||||
class PClass;
|
||||
class PTask;
|
||||
class PWire;
|
||||
class Statement;
|
||||
|
||||
class Design;
|
||||
class NetScope;
|
||||
@@ -49,10 +53,14 @@ class NetScope;
|
||||
class LexicalScope {
|
||||
|
||||
public:
|
||||
explicit LexicalScope(LexicalScope*parent) : parent_(parent) { }
|
||||
enum lifetime_t { INHERITED, STATIC, AUTOMATIC };
|
||||
|
||||
explicit LexicalScope(LexicalScope*parent) : default_lifetime(INHERITED), parent_(parent) { }
|
||||
// A virtual destructor is so that dynamic_cast can work.
|
||||
virtual ~LexicalScope() { }
|
||||
|
||||
lifetime_t default_lifetime;
|
||||
|
||||
struct range_t {
|
||||
// True if this is an exclude
|
||||
bool exclude_flag;
|
||||
@@ -92,6 +100,10 @@ class LexicalScope {
|
||||
// Named events in the scope.
|
||||
map<perm_string,PEvent*>events;
|
||||
|
||||
// Symbols that are imported. Bind the imported name to the
|
||||
// package from which the name is imported.
|
||||
std::map<perm_string,PPackage*>imports;
|
||||
|
||||
// Nets and variables (wires) in the scope
|
||||
map<perm_string,PWire*>wires;
|
||||
PWire* wires_find(perm_string name);
|
||||
@@ -101,15 +113,20 @@ class LexicalScope {
|
||||
// creating implicit nets.
|
||||
map<perm_string,LineInfo*> genvars;
|
||||
|
||||
// Variable initializations in this scope
|
||||
vector<Statement*> var_inits;
|
||||
|
||||
// Behaviors (processes) in this scope
|
||||
list<PProcess*> behaviors;
|
||||
list<AProcess*> analog_behaviors;
|
||||
|
||||
// Enumeration sets.
|
||||
list<enum_type_t*> enum_sets;
|
||||
std::set<enum_type_t*> enum_sets;
|
||||
|
||||
LexicalScope* parent_scope() const { return parent_; }
|
||||
|
||||
virtual bool var_init_needs_explicit_lifetime() const;
|
||||
|
||||
protected:
|
||||
void dump_typedefs_(ostream&out, unsigned indent) const;
|
||||
|
||||
@@ -123,6 +140,10 @@ class LexicalScope {
|
||||
|
||||
void dump_wires_(ostream&out, unsigned indent) const;
|
||||
|
||||
void dump_var_inits_(ostream&out, unsigned indent) const;
|
||||
|
||||
bool elaborate_var_inits_(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
LexicalScope*parent_;
|
||||
};
|
||||
@@ -138,12 +159,17 @@ class PScope : public LexicalScope {
|
||||
// modules do not nest in Verilog, the parent must be nil for
|
||||
// modules. Scopes for tasks and functions point to their
|
||||
// containing module.
|
||||
PScope(perm_string name, LexicalScope*parent);
|
||||
PScope(perm_string name);
|
||||
explicit PScope(perm_string name, LexicalScope*parent =0);
|
||||
virtual ~PScope();
|
||||
|
||||
perm_string pscope_name() const { return name_; }
|
||||
|
||||
/* These are the timescale for this scope. The default is
|
||||
set by the `timescale directive or, in SystemVerilog,
|
||||
by timeunit and timeprecision statements. */
|
||||
int time_unit, time_precision;
|
||||
bool time_from_timescale;
|
||||
|
||||
protected:
|
||||
bool elaborate_sig_wires_(Design*des, NetScope*scope) const;
|
||||
|
||||
@@ -161,18 +187,22 @@ class PScope : public LexicalScope {
|
||||
class PScopeExtra : public PScope {
|
||||
|
||||
public:
|
||||
PScopeExtra(perm_string, LexicalScope*parent);
|
||||
PScopeExtra(perm_string);
|
||||
explicit PScopeExtra(perm_string, LexicalScope*parent =0);
|
||||
~PScopeExtra();
|
||||
|
||||
/* Task definitions within this module */
|
||||
std::map<perm_string,PTask*> tasks;
|
||||
std::map<perm_string,PFunction*> funcs;
|
||||
/* class definitions within this module. */
|
||||
/* Class definitions within this module. */
|
||||
std::map<perm_string,PClass*> classes;
|
||||
/* This is the lexical order of the classes, and is used by
|
||||
elaboration to choose an elaboration order. */
|
||||
std::vector<PClass*> classes_lexical;
|
||||
|
||||
protected:
|
||||
void dump_classes_(ostream&out, unsigned indent) const;
|
||||
void dump_tasks_(ostream&out, unsigned indent) const;
|
||||
void dump_funcs_(ostream&out, unsigned indent) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_PScope_H */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PSpec_H
|
||||
#define __PSpec_H
|
||||
#ifndef IVL_PSpec_H
|
||||
#define IVL_PSpec_H
|
||||
/*
|
||||
* Copyright (c) 2006-2011 Stephen Williams <[email protected]>
|
||||
* Copyright (c) 2006-2014 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
|
||||
@@ -84,4 +84,4 @@ class PSpecPath : public LineInfo {
|
||||
std::vector<class PExpr*>delays;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_PSpec_H */
|
||||
|
||||
@@ -18,11 +18,48 @@
|
||||
*/
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PTask.h"
|
||||
# include <cassert>
|
||||
|
||||
PTaskFunc::PTaskFunc(perm_string n, LexicalScope*p)
|
||||
: PScope(n,p), this_type_(0), ports_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PTaskFunc::~PTaskFunc()
|
||||
{
|
||||
}
|
||||
|
||||
bool PTaskFunc::var_init_needs_explicit_lifetime() const
|
||||
{
|
||||
return default_lifetime == STATIC;
|
||||
}
|
||||
|
||||
void PTaskFunc::set_ports(vector<pform_tf_port_t>*p)
|
||||
{
|
||||
assert(ports_ == 0);
|
||||
ports_ = p;
|
||||
}
|
||||
|
||||
void PTaskFunc::set_this(class_type_t*type, PWire*this_wire)
|
||||
{
|
||||
assert(this_type_ == 0);
|
||||
this_type_ = type;
|
||||
|
||||
// Push a synthesis argument that is the "this" value.
|
||||
if (ports_==0)
|
||||
ports_ = new vector<pform_tf_port_t>;
|
||||
|
||||
size_t use_size = ports_->size();
|
||||
ports_->resize(use_size + 1);
|
||||
for (size_t idx = use_size ; idx > 0 ; idx -= 1)
|
||||
ports_->at(idx) = ports_->at(idx-1);
|
||||
|
||||
ports_->at(0) = pform_tf_port_t(this_wire);
|
||||
}
|
||||
|
||||
PTask::PTask(perm_string name, LexicalScope*parent, bool is_auto__)
|
||||
: PScope(name, parent), ports_(0), statement_(0)
|
||||
: PTaskFunc(name, parent), statement_(0)
|
||||
{
|
||||
is_auto_ = is_auto__;
|
||||
}
|
||||
@@ -31,12 +68,6 @@ PTask::~PTask()
|
||||
{
|
||||
}
|
||||
|
||||
void PTask::set_ports(svector<PWire*>*p)
|
||||
{
|
||||
assert(ports_ == 0);
|
||||
ports_ = p;
|
||||
}
|
||||
|
||||
void PTask::set_statement(Statement*s)
|
||||
{
|
||||
assert(statement_ == 0);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PTask_H
|
||||
#define __PTask_H
|
||||
#ifndef IVL_PTask_H
|
||||
#define IVL_PTask_H
|
||||
/*
|
||||
* Copyright (c) 1999-2008,2010,2012 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2014 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,46 +21,66 @@
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "PScope.h"
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include <string>
|
||||
# include <vector>
|
||||
# include <list>
|
||||
class Design;
|
||||
class NetExpr;
|
||||
class NetNet;
|
||||
class NetScope;
|
||||
class PChainConstructor;
|
||||
class PWire;
|
||||
class Statement;
|
||||
class PExpr;
|
||||
|
||||
enum PTaskFuncEnum {
|
||||
PTF_NONE,
|
||||
PTF_REG,
|
||||
PTF_REG_S,
|
||||
PTF_INTEGER,
|
||||
PTF_REAL,
|
||||
PTF_REALTIME,
|
||||
PTF_TIME,
|
||||
PTF_ATOM2,
|
||||
PTF_ATOM2_S,
|
||||
PTF_STRING,
|
||||
PTF_VOID
|
||||
};
|
||||
|
||||
struct PTaskFuncArg {
|
||||
PTaskFuncEnum type;
|
||||
std::list<pform_range_t>*range;
|
||||
class PTaskFunc : public PScope, public LineInfo {
|
||||
|
||||
public:
|
||||
PTaskFunc(perm_string name, LexicalScope*parent);
|
||||
~PTaskFunc();
|
||||
|
||||
bool var_init_needs_explicit_lifetime() const;
|
||||
|
||||
void set_ports(std::vector<pform_tf_port_t>*p);
|
||||
|
||||
void set_this(class_type_t*use_type, PWire*this_wire);
|
||||
|
||||
// If this task is a method of a class, this returns a pointer
|
||||
// to the class type.
|
||||
inline class_type_t* method_of() const { return this_type_; }
|
||||
|
||||
|
||||
virtual void elaborate_sig(Design*des, NetScope*scope) const =0;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const =0;
|
||||
|
||||
virtual void dump(std::ostream&, unsigned) const =0;
|
||||
|
||||
protected:
|
||||
// Elaborate the ports list. Write into the ports vector the
|
||||
// NetNet pointers for the ports, and write into the pdefs the
|
||||
// default value expressions, if any.
|
||||
void elaborate_sig_ports_(Design*des, NetScope*scope,
|
||||
std::vector<NetNet*>&ports,
|
||||
std::vector<NetExpr*>&pdefs) const;
|
||||
|
||||
void dump_ports_(std::ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
class_type_t*this_type_;
|
||||
std::vector<pform_tf_port_t>*ports_;
|
||||
};
|
||||
|
||||
/*
|
||||
* The PTask holds the parsed definitions of a task.
|
||||
*/
|
||||
class PTask : public PScope, public LineInfo {
|
||||
class PTask : public PTaskFunc {
|
||||
|
||||
public:
|
||||
explicit PTask(perm_string name, LexicalScope*parent, bool is_auto);
|
||||
~PTask();
|
||||
|
||||
void set_ports(svector<PWire *>*p);
|
||||
void set_statement(Statement *s);
|
||||
|
||||
// Tasks introduce scope, to need to be handled during the
|
||||
@@ -80,7 +100,6 @@ class PTask : public PScope, public LineInfo {
|
||||
void dump(ostream&, unsigned) const;
|
||||
|
||||
private:
|
||||
svector<PWire*>*ports_;
|
||||
Statement*statement_;
|
||||
bool is_auto_;
|
||||
|
||||
@@ -96,15 +115,26 @@ class PTask : public PScope, public LineInfo {
|
||||
*
|
||||
* The output value is not elaborated until elaborate_sig.
|
||||
*/
|
||||
class PFunction : public PScope, public LineInfo {
|
||||
class PFunction : public PTaskFunc {
|
||||
|
||||
public:
|
||||
explicit PFunction(perm_string name, LexicalScope*parent, bool is_auto);
|
||||
~PFunction();
|
||||
|
||||
void set_ports(svector<PWire *>*p);
|
||||
void set_statement(Statement *s);
|
||||
void set_return(PTaskFuncArg t);
|
||||
void set_return(data_type_t*t);
|
||||
|
||||
inline Statement* get_statement() { return statement_; }
|
||||
|
||||
// Push this statement to the front of the existing
|
||||
// definition. If the statement is a simple statement, make a
|
||||
// block to contain the statements.
|
||||
void push_statement_front(Statement*stmt);
|
||||
|
||||
// This is only used if this function is a constructor. In
|
||||
// that case, this method looks for a PChainConstructor in the
|
||||
// statement and extracts it if found.
|
||||
PChainConstructor*extract_chain_constructor();
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
@@ -119,10 +149,9 @@ class PFunction : public PScope, public LineInfo {
|
||||
void dump(ostream&, unsigned) const;
|
||||
|
||||
private:
|
||||
PTaskFuncArg return_type_;
|
||||
svector<PWire *> *ports_;
|
||||
data_type_t* return_type_;
|
||||
Statement *statement_;
|
||||
bool is_auto_;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_PTask_H */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PUdp_H
|
||||
#define __PUdp_H
|
||||
#ifndef IVL_PUdp_H
|
||||
#define IVL_PUdp_H
|
||||
/*
|
||||
* Copyright (c) 1998-2011 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2014 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
|
||||
@@ -76,4 +76,4 @@ class PUdp : public LineInfo {
|
||||
PUdp& operator= (const PUdp&);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_PUdp_H */
|
||||
|
||||
@@ -120,6 +120,7 @@ bool PWire::set_data_type(ivl_variable_type_t dt)
|
||||
|
||||
assert(data_type_ == IVL_VT_NO_TYPE);
|
||||
data_type_ = dt;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -140,7 +141,14 @@ bool PWire::get_signed() const
|
||||
|
||||
bool PWire::get_isint() const
|
||||
{
|
||||
return isint_;
|
||||
if (isint_)
|
||||
return true;
|
||||
|
||||
if (vector_type_t*tmp = dynamic_cast<vector_type_t*>(set_data_type_)) {
|
||||
return tmp->integer_flag;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PWire::get_scalar() const
|
||||
@@ -257,6 +265,11 @@ void PWire::set_data_type(data_type_t*type)
|
||||
{
|
||||
assert(set_data_type_ == 0);
|
||||
set_data_type_ = type;
|
||||
|
||||
if (vector_type_t*tmp = dynamic_cast<vector_type_t*>(type)) {
|
||||
if (tmp->integer_flag)
|
||||
isint_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
void PWire::set_discipline(ivl_discipline_t d)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PWire_H
|
||||
#define __PWire_H
|
||||
#ifndef IVL_PWire_H
|
||||
#define IVL_PWire_H
|
||||
/*
|
||||
* Copyright (c) 1998-2009,2012 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2014 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
|
||||
@@ -129,4 +129,4 @@ class PWire : public LineInfo {
|
||||
PWire& operator= (const PWire&);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_PWire_H */
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ 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 behavioral
|
||||
constructs. For a view of the current state of Icarus Verilog, see its
|
||||
home page at <http://www.icarus.com/eda/verilog>.
|
||||
home page at <http://iverilog.icarus.com/>.
|
||||
|
||||
Icarus Verilog is not aimed at being a simulator in the traditional
|
||||
sense, but a compiler that generates code employed by back-end
|
||||
|
||||
+98
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2008,2010,2012 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2013 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,6 +21,7 @@
|
||||
|
||||
# include "Statement.h"
|
||||
# include "PExpr.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
Statement::~Statement()
|
||||
{
|
||||
@@ -114,6 +115,26 @@ PBlock::~PBlock()
|
||||
delete list_[idx];
|
||||
}
|
||||
|
||||
bool PBlock::var_init_needs_explicit_lifetime() const
|
||||
{
|
||||
return default_lifetime == STATIC;
|
||||
}
|
||||
|
||||
PChainConstructor* PBlock::extract_chain_constructor()
|
||||
{
|
||||
if (list_.empty())
|
||||
return 0;
|
||||
|
||||
if (PChainConstructor*res = dynamic_cast<PChainConstructor*> (list_[0])) {
|
||||
for (size_t idx = 0 ; idx < list_.size()-1 ; idx += 1)
|
||||
list_[idx] = list_[idx+1];
|
||||
list_.resize(list_.size()-1);
|
||||
return res;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PBlock::set_join_type(PBlock::BL_TYPE type)
|
||||
{
|
||||
assert(bl_type_ == BL_PAR);
|
||||
@@ -126,8 +147,30 @@ void PBlock::set_statement(const vector<Statement*>&st)
|
||||
list_ = st;
|
||||
}
|
||||
|
||||
void PBlock::push_statement_front(Statement*that)
|
||||
{
|
||||
ivl_assert(*this, bl_type_==BL_SEQ);
|
||||
|
||||
list_.resize(list_.size()+1);
|
||||
for (size_t idx = list_.size()-1 ; idx > 0 ; idx -= 1)
|
||||
list_[idx] = list_[idx-1];
|
||||
|
||||
list_[0] = that;
|
||||
}
|
||||
|
||||
PCallTask::PCallTask(const pform_name_t&n, const list<PExpr*>&p)
|
||||
: path_(n), parms_(p.size())
|
||||
: package_(0), path_(n), parms_(p.size())
|
||||
{
|
||||
list<PExpr*>::const_iterator cur = p.begin();
|
||||
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
parms_[idx] = *cur;
|
||||
++cur;
|
||||
}
|
||||
assert(cur == p.end());
|
||||
}
|
||||
|
||||
PCallTask::PCallTask(PPackage*pkg, const pform_name_t&n, const list<PExpr*>&p)
|
||||
: package_(pkg), path_(n), parms_(p.size())
|
||||
{
|
||||
list<PExpr*>::const_iterator cur = p.begin();
|
||||
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
@@ -138,7 +181,7 @@ PCallTask::PCallTask(const pform_name_t&n, const list<PExpr*>&p)
|
||||
}
|
||||
|
||||
PCallTask::PCallTask(perm_string n, const list<PExpr*>&p)
|
||||
: parms_(p.size())
|
||||
: package_(0), parms_(p.size())
|
||||
{
|
||||
list<PExpr*>::const_iterator cur = p.begin();
|
||||
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
@@ -183,6 +226,21 @@ PCAssign::~PCAssign()
|
||||
delete expr_;
|
||||
}
|
||||
|
||||
PChainConstructor::PChainConstructor(const list<PExpr*>&parms)
|
||||
: parms_(parms.size())
|
||||
{
|
||||
list<PExpr*>::const_iterator cur = parms.begin();
|
||||
for (size_t idx = 0 ; idx < parms_.size() ; idx += 1) {
|
||||
parms_[idx] = *cur;
|
||||
++cur;
|
||||
}
|
||||
assert(cur == parms.end());
|
||||
}
|
||||
|
||||
PChainConstructor::~PChainConstructor()
|
||||
{
|
||||
}
|
||||
|
||||
PCondit::PCondit(PExpr*ex, Statement*i, Statement*e)
|
||||
: expr_(ex), if_(i), else_(e)
|
||||
{
|
||||
@@ -224,6 +282,17 @@ PDisable::~PDisable()
|
||||
{
|
||||
}
|
||||
|
||||
PDoWhile::PDoWhile(PExpr*ex, Statement*st)
|
||||
: cond_(ex), statement_(st)
|
||||
{
|
||||
}
|
||||
|
||||
PDoWhile::~PDoWhile()
|
||||
{
|
||||
delete cond_;
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
|
||||
: expr_(ee), statement_(0)
|
||||
{
|
||||
@@ -272,6 +341,20 @@ PForce::~PForce()
|
||||
delete expr_;
|
||||
}
|
||||
|
||||
PForeach::PForeach(perm_string av, const list<perm_string>&ix, Statement*s)
|
||||
: array_var_(av), index_vars_(ix.size()), statement_(s)
|
||||
{
|
||||
size_t idx = 0;
|
||||
for (list<perm_string>::const_iterator cur = ix.begin()
|
||||
; cur != ix.end() ; ++cur)
|
||||
index_vars_[idx++] = *cur;
|
||||
}
|
||||
|
||||
PForeach::~PForeach()
|
||||
{
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
PForever::PForever(Statement*s)
|
||||
: statement_(s)
|
||||
{
|
||||
@@ -318,6 +401,16 @@ PRepeat::~PRepeat()
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
PReturn::PReturn(PExpr*e)
|
||||
: expr_(e)
|
||||
{
|
||||
}
|
||||
|
||||
PReturn::~PReturn()
|
||||
{
|
||||
delete expr_;
|
||||
}
|
||||
|
||||
PTrigger::PTrigger(const pform_name_t&e)
|
||||
: event_(e)
|
||||
{
|
||||
@@ -327,8 +420,8 @@ PTrigger::~PTrigger()
|
||||
{
|
||||
}
|
||||
|
||||
PWhile::PWhile(PExpr*e1, Statement*st)
|
||||
: cond_(e1), statement_(st)
|
||||
PWhile::PWhile(PExpr*ex, Statement*st)
|
||||
: cond_(ex), statement_(st)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
+105
-8
@@ -1,7 +1,7 @@
|
||||
#ifndef __Statement_H
|
||||
#define __Statement_H
|
||||
#ifndef IVL_Statement_H
|
||||
#define IVL_Statement_H
|
||||
/*
|
||||
* Copyright (c) 1998-2008,2012 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2014 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 @@
|
||||
# include "HName.h"
|
||||
# include "LineInfo.h"
|
||||
class PExpr;
|
||||
class PChainConstructor;
|
||||
class PPackage;
|
||||
class Statement;
|
||||
class PEventStatement;
|
||||
class Design;
|
||||
@@ -104,8 +106,10 @@ class PAssign_ : public Statement {
|
||||
|
||||
protected:
|
||||
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
|
||||
NetExpr* elaborate_rval_(Design*, NetScope*, unsigned lv_width,
|
||||
ivl_variable_type_t type) const;
|
||||
NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t lv_net_type,
|
||||
ivl_variable_type_t lv_type,
|
||||
unsigned lv_width,
|
||||
bool force_unsigned =false) const;
|
||||
NetExpr* elaborate_rval_(Design*, NetScope*, ivl_type_t ntype) const;
|
||||
|
||||
NetExpr* elaborate_rval_obj_(Design*, NetScope*,
|
||||
@@ -179,12 +183,23 @@ class PBlock : public PScope, public Statement {
|
||||
|
||||
BL_TYPE bl_type() const { return bl_type_; }
|
||||
|
||||
bool var_init_needs_explicit_lifetime() const;
|
||||
|
||||
// This is only used if this block is the statement list for a
|
||||
// constructor. We look for a PChainConstructor as the first
|
||||
// statement, and if it is there, extract it.
|
||||
PChainConstructor*extract_chain_constructor();
|
||||
|
||||
// If the bl_type() is BL_PAR, it is possible to replace it
|
||||
// with JOIN_NONE or JOIN_ANY. This is to help the parser.
|
||||
void set_join_type(BL_TYPE);
|
||||
|
||||
void set_statement(const std::vector<Statement*>&st);
|
||||
|
||||
// Copy the statement from that block to the front of this
|
||||
// block.
|
||||
void push_statement_front(Statement*that);
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
@@ -198,6 +213,7 @@ class PBlock : public PScope, public Statement {
|
||||
class PCallTask : public Statement {
|
||||
|
||||
public:
|
||||
explicit PCallTask(PPackage*pkg, const pform_name_t&n, const list<PExpr*>&parms);
|
||||
explicit PCallTask(const pform_name_t&n, const list<PExpr*>&parms);
|
||||
explicit PCallTask(perm_string n, const list<PExpr*>&parms);
|
||||
~PCallTask();
|
||||
@@ -211,8 +227,19 @@ class PCallTask : public Statement {
|
||||
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
|
||||
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
|
||||
|
||||
NetProc*elaborate_method_(Design*des, NetScope*scope) const;
|
||||
NetProc*elaborate_method_(Design*des, NetScope*scope,
|
||||
bool add_this_flag = false) const;
|
||||
NetProc*elaborate_function_(Design*des, NetScope*scope) const;
|
||||
|
||||
NetProc*elaborate_build_call_(Design*des, NetScope*scope,
|
||||
NetScope*task, NetExpr*use_this) const;
|
||||
NetProc*elaborate_sys_task_method_(Design*des, NetScope*scope,
|
||||
NetNet*net,
|
||||
perm_string method_name,
|
||||
const char*sys_task_name) const;
|
||||
bool test_task_calls_ok_(Design*des, NetScope*scope) const;
|
||||
|
||||
PPackage*package_;
|
||||
pform_name_t path_;
|
||||
vector<PExpr*> parms_;
|
||||
};
|
||||
@@ -258,6 +285,26 @@ class PCAssign : public Statement {
|
||||
PExpr*expr_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This represents the syntax "super.new(...)". This is not really an
|
||||
* executable statement, but the elaborator will handle these
|
||||
* specially and will remove them from the statement stream. If any
|
||||
*/
|
||||
class PChainConstructor : public Statement {
|
||||
public:
|
||||
PChainConstructor(const list<PExpr*>&parms);
|
||||
~PChainConstructor();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
inline const std::vector<PExpr*>& chain_args(void) const
|
||||
{ return parms_; }
|
||||
|
||||
private:
|
||||
std::vector<PExpr*> parms_;
|
||||
};
|
||||
|
||||
class PCondit : public Statement {
|
||||
|
||||
public:
|
||||
@@ -325,6 +372,22 @@ class PDisable : public Statement {
|
||||
pform_name_t scope_;
|
||||
};
|
||||
|
||||
class PDoWhile : public Statement {
|
||||
|
||||
public:
|
||||
PDoWhile(PExpr*ex, Statement*st);
|
||||
~PDoWhile();
|
||||
|
||||
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(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PExpr*cond_;
|
||||
Statement*statement_;
|
||||
};
|
||||
|
||||
/*
|
||||
* The event statement represents the event delay in behavioral
|
||||
* code. It comes from such things as:
|
||||
@@ -361,6 +424,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;
|
||||
|
||||
private:
|
||||
svector<PEEvent*>expr_;
|
||||
@@ -383,6 +447,26 @@ class PForce : public Statement {
|
||||
PExpr*expr_;
|
||||
};
|
||||
|
||||
class PForeach : public Statement {
|
||||
public:
|
||||
explicit PForeach(perm_string var, const std::list<perm_string>&ix, Statement*stmt);
|
||||
~PForeach();
|
||||
|
||||
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(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
NetProc* elaborate_static_array_(Design*des, NetScope*scope,
|
||||
const std::vector<netrange_t>&dims) const;
|
||||
|
||||
private:
|
||||
perm_string array_var_;
|
||||
std::vector<perm_string> index_vars_;
|
||||
Statement*statement_;
|
||||
};
|
||||
|
||||
class PForever : public Statement {
|
||||
public:
|
||||
explicit PForever(Statement*s);
|
||||
@@ -455,6 +539,19 @@ class PRelease : public Statement {
|
||||
PExpr*lval_;
|
||||
};
|
||||
|
||||
class PReturn : public Statement {
|
||||
|
||||
public:
|
||||
explicit PReturn(PExpr*e);
|
||||
~PReturn();
|
||||
|
||||
NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(std::ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
PExpr*expr_;
|
||||
};
|
||||
|
||||
/*
|
||||
* The PTrigger statement sends a trigger to a named event. Take the
|
||||
* name here.
|
||||
@@ -475,7 +572,7 @@ class PTrigger : public Statement {
|
||||
class PWhile : public Statement {
|
||||
|
||||
public:
|
||||
PWhile(PExpr*e1, Statement*st);
|
||||
PWhile(PExpr*ex, Statement*st);
|
||||
~PWhile();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
@@ -488,4 +585,4 @@ class PWhile : public Statement {
|
||||
Statement*statement_;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_Statement_H */
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
#ifndef PLI_TYPES
|
||||
#define PLI_TYPES
|
||||
#ifndef PLI_TYPES_H
|
||||
#define PLI_TYPES_H
|
||||
/*
|
||||
* Copyright (c) 2003 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2003-2014 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
|
||||
@@ -85,4 +85,4 @@ typedef char PLI_BYTE8;
|
||||
typedef unsigned char PLI_UBYTE8;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* PLI_TYPES_H */
|
||||
|
||||
+5
-4
@@ -1,7 +1,7 @@
|
||||
#ifndef __acc_user_H
|
||||
#define __acc_user_H
|
||||
#ifndef ACC_USER_H
|
||||
#define ACC_USER_H
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-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
|
||||
@@ -228,6 +228,7 @@ extern PLI_INT32 acc_fetch_size(handle obj);
|
||||
|
||||
extern PLI_INT32 acc_fetch_type(handle obj);
|
||||
extern PLI_INT32 acc_fetch_fulltype(handle obj);
|
||||
extern PLI_INT32 acc_fetch_paramtype(handle obj);
|
||||
extern PLI_INT32 acc_fetch_range(handle object, int *msb, int *lsb);
|
||||
extern const char* acc_fetch_type_str(PLI_INT32 type);
|
||||
|
||||
@@ -270,4 +271,4 @@ extern char* acc_version(void);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif
|
||||
#endif /* ACC_USER_H */
|
||||
|
||||
Vendored
+2
-12
@@ -218,24 +218,14 @@ AC_SUBST(strip_dynamic)
|
||||
# AC_MSG_RESULT($strip_dynamic)
|
||||
])# AX_LD_RDYNAMIC
|
||||
|
||||
# AX_CPP_PRECOMP
|
||||
# --------------
|
||||
AC_DEFUN([AX_CPP_PRECOMP],
|
||||
[# Darwin requires -no-cpp-precomp
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
CPPFLAGS="-no-cpp-precomp $CPPFLAGS"
|
||||
CFLAGS="-no-cpp-precomp $CFLAGS"
|
||||
;;
|
||||
esac
|
||||
])# AX_CPP_PRECOMP
|
||||
|
||||
# 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
|
||||
*-*-mingw*)
|
||||
*-*-mingw32)
|
||||
LDFLAGS+=" -Wl,--undefined=___strtod,--wrap,strtod,--defsym,___wrap_strtod=___strtod"
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -50,8 +50,8 @@ bool NetEvWait::is_asynchronous()
|
||||
level sensitive, but the nex_async_ method takes care of
|
||||
that test. */
|
||||
NexusSet*sense = new NexusSet;
|
||||
for (unsigned idx = 0 ; idx < nevents_ ; idx += 1) {
|
||||
NexusSet*tmp = event(idx)->nex_async_();
|
||||
for (unsigned idx = 0 ; idx < events_.size() ; idx += 1) {
|
||||
NexusSet*tmp = events_[idx]->nex_async_();
|
||||
if (tmp == 0) {
|
||||
delete sense;
|
||||
return false;
|
||||
|
||||
+4
-1
@@ -10,4 +10,7 @@ echo "Autoconf in root..."
|
||||
autoconf -f
|
||||
|
||||
echo "Precompiling lexor_keyword.gperf"
|
||||
gperf -o -i 7 -C -k 1-4,6,9,\$ -L ANSI-C -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
|
||||
gperf -o -i 7 -C -k 1-4,6,9,\$ -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
|
||||
|
||||
echo "Precompiling vhdlpp/lexor_keyword.gperf"
|
||||
(cd vhdlpp ; gperf -o -i 7 --ignore-case -C -k 1-4,6,9,\$ -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc )
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
|
||||
endif
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
O = cadpli.o
|
||||
|
||||
+1
-1
@@ -79,7 +79,7 @@ static void thunker_register(void)
|
||||
}
|
||||
}
|
||||
|
||||
void (*vlog_startup_routines[])() = {
|
||||
void (*vlog_startup_routines[])(void) = {
|
||||
thunker_register,
|
||||
0
|
||||
};
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
#ifndef __ivl_dlfcn_H
|
||||
#define __ivl_dlfcn_H
|
||||
#ifndef IVL_ivl_dlfcn_H
|
||||
#define IVL_ivl_dlfcn_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
* 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
|
||||
@@ -91,4 +91,4 @@ static __inline__ const char*dlerror(void)
|
||||
{ return strerror( errno ); }
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* IVL_ivl_dlfcn_H */
|
||||
|
||||
+48
-17
@@ -1,7 +1,7 @@
|
||||
#ifndef __compiler_H
|
||||
#define __compiler_H
|
||||
#ifndef IVL_compiler_H
|
||||
#define IVL_compiler_H
|
||||
/*
|
||||
* Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2016 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,6 +36,11 @@
|
||||
*/
|
||||
extern unsigned integer_width;
|
||||
|
||||
/*
|
||||
* The width_cap is the width limit for unsized expressions.
|
||||
*/
|
||||
extern unsigned width_cap;
|
||||
|
||||
/*
|
||||
* This is the maximum number of recursive module loops allowed within
|
||||
* a generate block.
|
||||
@@ -75,6 +80,10 @@ extern unsigned recursive_mod_limit;
|
||||
/* Implicit definitions of wires. */
|
||||
extern bool warn_implicit;
|
||||
|
||||
/* Warn if dimensions of port or var/net are implicitly taken from
|
||||
the input/output/inout declaration. */
|
||||
extern bool warn_implicit_dimensions;
|
||||
|
||||
/* inherit timescales across files. */
|
||||
extern bool warn_timescale;
|
||||
|
||||
@@ -92,7 +101,7 @@ extern bool warn_inf_loop;
|
||||
extern bool warn_sens_entire_vec;
|
||||
extern bool warn_sens_entire_arr;
|
||||
|
||||
/* Warn about level-appropriate anochronisms. */
|
||||
/* Warn about level-appropriate anachronisms. */
|
||||
extern bool warn_anachronisms;
|
||||
|
||||
/* This is true if verbose output is requested. */
|
||||
@@ -101,12 +110,26 @@ extern bool verbose_flag;
|
||||
extern bool debug_scopes;
|
||||
extern bool debug_eval_tree;
|
||||
extern bool debug_elaborate;
|
||||
extern bool debug_emit;
|
||||
extern bool debug_synth2;
|
||||
extern bool debug_optimizer;
|
||||
|
||||
/* Control evaluation of functions at compile time:
|
||||
* 0 = only for functions in constant expressions
|
||||
* 1 = only for automatic functions
|
||||
* 2 = for all functions
|
||||
* Level 2 should only be used if the user can guarantee that a
|
||||
* function's local variables are never accessed from outside the
|
||||
* function. */
|
||||
extern unsigned opt_const_func;
|
||||
|
||||
/* Possibly temporary flag to control virtualization of pin arrays */
|
||||
extern bool disable_virtual_pins;
|
||||
|
||||
/* The vlog95 code generator does not want the compiler to generate concat-Z
|
||||
* LPM objects so this flag is used to block them from being generated. */
|
||||
extern bool disable_concatz_generation;
|
||||
|
||||
/* Limit to size of devirtualized arrays */
|
||||
extern unsigned long array_size_limit;
|
||||
|
||||
@@ -119,7 +142,8 @@ extern int build_library_index(const char*path, bool key_case_sensitive);
|
||||
|
||||
/* This is the generation of Verilog that the compiler is asked to
|
||||
support. Then there are also more detailed controls for more
|
||||
specific language features. */
|
||||
specific language features. Note that the compiler often assumes
|
||||
this is an ordered list. */
|
||||
enum generation_t {
|
||||
GN_VER1995 = 1,
|
||||
GN_VER2001_NOCONFIG = 2,
|
||||
@@ -127,6 +151,7 @@ enum generation_t {
|
||||
GN_VER2005 = 4,
|
||||
GN_VER2005_SV = 5,
|
||||
GN_VER2009 = 6,
|
||||
GN_VER2012 = 7,
|
||||
GN_DEFAULT = 4
|
||||
};
|
||||
|
||||
@@ -142,6 +167,10 @@ extern bool gn_icarus_misc_flag;
|
||||
is false, then skip elaboration of specify behavior. */
|
||||
extern bool gn_specify_blocks_flag;
|
||||
|
||||
/* If this flag is true, then elaborate assertions. If this flag is
|
||||
false, then stub out assertion statements. */
|
||||
extern bool gn_assertions_flag;
|
||||
|
||||
/* If this flag is true, then support/elaborate Verilog-AMS. */
|
||||
extern bool gn_verilog_ams_flag;
|
||||
|
||||
@@ -158,23 +187,24 @@ extern bool gn_strict_ca_eval_flag;
|
||||
standard expression width rules. */
|
||||
extern bool gn_strict_expr_width_flag;
|
||||
|
||||
/* If variables can be converted to uwires by a continuous assignment
|
||||
(assuming no procedural assign, then return true. This will be true
|
||||
for SystemVerilog */
|
||||
static inline bool gn_var_can_be_uwire(void)
|
||||
/* If this flag is true, then don't add a for-loop control variable
|
||||
to an implicit event_expression list if it is only used inside the
|
||||
loop. */
|
||||
extern bool gn_shared_loop_index_flag;
|
||||
|
||||
static inline bool gn_system_verilog(void)
|
||||
{
|
||||
if (generation_flag == GN_VER2005_SV ||
|
||||
generation_flag == GN_VER2009)
|
||||
if (generation_flag >= GN_VER2005_SV)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline bool gn_system_verilog(void)
|
||||
/* If variables can be converted to uwires by a continuous assignment
|
||||
(assuming no procedural assign), then return true. This will be true
|
||||
for SystemVerilog */
|
||||
static inline bool gn_var_can_be_uwire(void)
|
||||
{
|
||||
if (generation_flag == GN_VER2005_SV ||
|
||||
generation_flag == GN_VER2009)
|
||||
return true;
|
||||
return false;
|
||||
return gn_system_verilog();
|
||||
}
|
||||
|
||||
static inline bool gn_modules_nest(void)
|
||||
@@ -193,6 +223,7 @@ enum { GN_KEYWORDS_1364_1995 = 0x0001,
|
||||
GN_KEYWORDS_VAMS_2_3 = 0x0010,
|
||||
GN_KEYWORDS_1800_2005 = 0x0020,
|
||||
GN_KEYWORDS_1800_2009 = 0x0040,
|
||||
GN_KEYWORDS_1800_2012 = 0x0080,
|
||||
GN_KEYWORDS_ICARUS = 0x8000
|
||||
};
|
||||
extern int lexor_keyword_mask;
|
||||
@@ -256,4 +287,4 @@ extern void cleanup_sys_func_table();
|
||||
*/
|
||||
extern ivl_sfunc_as_task_t def_sfunc_as_task;
|
||||
|
||||
#endif
|
||||
#endif /* IVL_compiler_H */
|
||||
|
||||
Vendored
+324
-447
File diff suppressed because it is too large
Load Diff
+5
-4
@@ -1,7 +1,7 @@
|
||||
#ifndef __config_H /* -*- c++ -*- */
|
||||
#define __config_H
|
||||
#ifndef IVL_config_H /* -*- c++ -*- */
|
||||
#define IVL_config_H
|
||||
/*
|
||||
* Copyright (c) 2001-2012 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001-2015 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
|
||||
@@ -55,6 +55,7 @@
|
||||
# undef HAVE_FSEEKO
|
||||
/* And this is needed by the fst files (copied from GTKWave). */
|
||||
# undef HAVE_LIBPTHREAD
|
||||
# undef HAVE_REALPATH
|
||||
|
||||
/*
|
||||
* Define this if you want to compile vvp with memory freeing and
|
||||
@@ -62,4 +63,4 @@
|
||||
*/
|
||||
# undef CHECK_WITH_VALGRIND
|
||||
|
||||
#endif /* __config_H */
|
||||
#endif /* IVL_config_H */
|
||||
|
||||
Vendored
+225
-101
@@ -1,44 +1,40 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
|
||||
# Free Software Foundation, Inc.
|
||||
# Copyright 1992-2015 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2009-04-17'
|
||||
timestamp='2015-03-08'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
# can handle that machine. It does not imply ALL GNU software can.
|
||||
#
|
||||
# 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
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# 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
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
# This 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.
|
||||
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
# the same distribution terms that you use for the rest of that
|
||||
# program. This Exception is an additional permission under section 7
|
||||
# of the GNU General Public License, version 3 ("GPLv3").
|
||||
|
||||
|
||||
# Please send patches to <[email protected]>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
# Please send patches to <[email protected]>.
|
||||
#
|
||||
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||
# Supply the specified configuration type as an argument.
|
||||
# If it is invalid, we print an error message on stderr and exit with code 1.
|
||||
# Otherwise, we print the canonical config type on stdout and succeed.
|
||||
|
||||
# You can get the latest version of this script from:
|
||||
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
|
||||
|
||||
# This file is supposed to be the same for all GNU packages
|
||||
# and recognize all the CPU types, system types and aliases
|
||||
# that are meaningful with *any* GNU software.
|
||||
@@ -72,8 +68,7 @@ Report bugs and patches to <[email protected]>."
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
|
||||
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
||||
Copyright 1992-2015 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."
|
||||
@@ -120,13 +115,18 @@ esac
|
||||
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
|
||||
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
|
||||
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
|
||||
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
|
||||
knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
|
||||
kopensolaris*-gnu* | \
|
||||
storm-chaos* | os2-emx* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
;;
|
||||
android-linux)
|
||||
os=-linux-android
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
|
||||
;;
|
||||
*)
|
||||
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
|
||||
if [ $basic_machine != $1 ]
|
||||
@@ -149,10 +149,13 @@ case $os in
|
||||
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
||||
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
||||
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
||||
-apple | -axis | -knuth | -cray)
|
||||
-apple | -axis | -knuth | -cray | -microblaze*)
|
||||
os=
|
||||
basic_machine=$1
|
||||
;;
|
||||
-bluegene*)
|
||||
os=-cnk
|
||||
;;
|
||||
-sim | -cisco | -oki | -wec | -winbond)
|
||||
os=
|
||||
basic_machine=$1
|
||||
@@ -167,10 +170,10 @@ case $os in
|
||||
os=-chorusos
|
||||
basic_machine=$1
|
||||
;;
|
||||
-chorusrdb)
|
||||
os=-chorusrdb
|
||||
-chorusrdb)
|
||||
os=-chorusrdb
|
||||
basic_machine=$1
|
||||
;;
|
||||
;;
|
||||
-hiux*)
|
||||
os=-hiuxwe2
|
||||
;;
|
||||
@@ -215,6 +218,12 @@ case $os in
|
||||
-isc*)
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-lynx*178)
|
||||
os=-lynxos178
|
||||
;;
|
||||
-lynx*5)
|
||||
os=-lynxos5
|
||||
;;
|
||||
-lynx*)
|
||||
os=-lynxos
|
||||
;;
|
||||
@@ -239,20 +248,28 @@ case $basic_machine in
|
||||
# Some are omitted here because they have special meanings below.
|
||||
1750a | 580 \
|
||||
| a29k \
|
||||
| aarch64 | aarch64_be \
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||
| am33_2.0 \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
|
||||
| arc | arceb \
|
||||
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
|
||||
| avr | avr32 \
|
||||
| be32 | be64 \
|
||||
| bfin \
|
||||
| c4x | clipper \
|
||||
| c4x | c8051 | clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| fido | fr30 | frv \
|
||||
| e2k | epiphany \
|
||||
| fido | fr30 | frv | ft32 \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| hexagon \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k | iq2000 \
|
||||
| k1om \
|
||||
| le32 | le64 \
|
||||
| lm32 \
|
||||
| m32c | m32r | m32rle | m68000 | m68k | m88k \
|
||||
| maxq | mb | microblaze | mcore | mep | metag \
|
||||
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
@@ -266,36 +283,55 @@ case $basic_machine in
|
||||
| mips64vr5900 | mips64vr5900el \
|
||||
| mipsisa32 | mipsisa32el \
|
||||
| mipsisa32r2 | mipsisa32r2el \
|
||||
| mipsisa32r6 | mipsisa32r6el \
|
||||
| mipsisa64 | mipsisa64el \
|
||||
| mipsisa64r2 | mipsisa64r2el \
|
||||
| mipsisa64r6 | mipsisa64r6el \
|
||||
| mipsisa64sb1 | mipsisa64sb1el \
|
||||
| mipsisa64sr71k | mipsisa64sr71kel \
|
||||
| mipsr5900 | mipsr5900el \
|
||||
| mipstx39 | mipstx39el \
|
||||
| mn10200 | mn10300 \
|
||||
| moxie \
|
||||
| mt \
|
||||
| msp430 \
|
||||
| nios | nios2 \
|
||||
| nds32 | nds32le | nds32be \
|
||||
| nios | nios2 | nios2eb | nios2el \
|
||||
| ns16k | ns32k \
|
||||
| or32 \
|
||||
| open8 | or1k | or1knd | or32 \
|
||||
| pdp10 | pdp11 | pj | pjl \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle \
|
||||
| pyramid \
|
||||
| riscv32 | riscv64 \
|
||||
| rl78 | rx \
|
||||
| score \
|
||||
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh64 | sh64le \
|
||||
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
|
||||
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
|
||||
| spu | strongarm \
|
||||
| tahoe | thumb | tic4x | tic80 | tron \
|
||||
| v850 | v850e \
|
||||
| spu \
|
||||
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
|
||||
| ubicom32 \
|
||||
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
|
||||
| visium \
|
||||
| we32k \
|
||||
| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
|
||||
| x86 | xc16x | xstormy16 | xtensa \
|
||||
| z8k | z80)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
m6811 | m68hc11 | m6812 | m68hc12)
|
||||
# Motorola 68HC11/12.
|
||||
c54x)
|
||||
basic_machine=tic54x-unknown
|
||||
;;
|
||||
c55x)
|
||||
basic_machine=tic55x-unknown
|
||||
;;
|
||||
c6x)
|
||||
basic_machine=tic6x-unknown
|
||||
;;
|
||||
leon|leon[3-9])
|
||||
basic_machine=sparc-$basic_machine
|
||||
;;
|
||||
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-none
|
||||
;;
|
||||
@@ -305,6 +341,21 @@ case $basic_machine in
|
||||
basic_machine=mt-unknown
|
||||
;;
|
||||
|
||||
strongarm | thumb | xscale)
|
||||
basic_machine=arm-unknown
|
||||
;;
|
||||
xgate)
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-none
|
||||
;;
|
||||
xscaleeb)
|
||||
basic_machine=armeb-unknown
|
||||
;;
|
||||
|
||||
xscaleel)
|
||||
basic_machine=armel-unknown
|
||||
;;
|
||||
|
||||
# We use `pc' rather than `unknown'
|
||||
# because (1) that's what they normally are, and
|
||||
# (2) the word "unknown" tends to confuse beginning users.
|
||||
@@ -319,25 +370,31 @@ case $basic_machine in
|
||||
# Recognize the basic CPU types with company name.
|
||||
580-* \
|
||||
| a29k-* \
|
||||
| aarch64-* | aarch64_be-* \
|
||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
||||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
|
||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||
| avr-* | avr32-* \
|
||||
| be32-* | be64-* \
|
||||
| bfin-* | bs2000-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
|
||||
| clipper-* | craynv-* | cydra-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c4x-* \
|
||||
| c8051-* | clipper-* | craynv-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| e2k-* | elxsi-* \
|
||||
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| hexagon-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* | iq2000-* \
|
||||
| k1om-* \
|
||||
| le32-* | le64-* \
|
||||
| lm32-* \
|
||||
| m32c-* | m32r-* | m32rle-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
|
||||
| microblaze-* | microblazeel-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
| mips16-* \
|
||||
| mips64-* | mips64el-* \
|
||||
@@ -351,32 +408,42 @@ case $basic_machine in
|
||||
| mips64vr5900-* | mips64vr5900el-* \
|
||||
| mipsisa32-* | mipsisa32el-* \
|
||||
| mipsisa32r2-* | mipsisa32r2el-* \
|
||||
| mipsisa32r6-* | mipsisa32r6el-* \
|
||||
| mipsisa64-* | mipsisa64el-* \
|
||||
| mipsisa64r2-* | mipsisa64r2el-* \
|
||||
| mipsisa64r6-* | mipsisa64r6el-* \
|
||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
|
||||
| mipsr5900-* | mipsr5900el-* \
|
||||
| mipstx39-* | mipstx39el-* \
|
||||
| mmix-* \
|
||||
| mt-* \
|
||||
| msp430-* \
|
||||
| nios-* | nios2-* \
|
||||
| nds32-* | nds32le-* | nds32be-* \
|
||||
| nios-* | nios2-* | nios2eb-* | nios2el-* \
|
||||
| none-* | np1-* | ns16k-* | ns32k-* \
|
||||
| open8-* \
|
||||
| or1k*-* \
|
||||
| orion-* \
|
||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
|
||||
| pyramid-* \
|
||||
| romp-* | rs6000-* \
|
||||
| rl78-* | romp-* | rs6000-* | rx-* \
|
||||
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
|
||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
|
||||
| sparclite-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
|
||||
| tahoe-* | thumb-* \
|
||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
|
||||
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
|
||||
| tahoe-* \
|
||||
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
|
||||
| tile*-* \
|
||||
| tron-* \
|
||||
| v850-* | v850e-* | vax-* \
|
||||
| ubicom32-* \
|
||||
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
|
||||
| vax-* \
|
||||
| visium-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
|
||||
| x86-* | x86_64-* | xc16x-* | xps100-* \
|
||||
| xstormy16-* | xtensa*-* \
|
||||
| ymp-* \
|
||||
| z8k-* | z80-*)
|
||||
@@ -401,7 +468,7 @@ case $basic_machine in
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
abacus)
|
||||
abacus)
|
||||
basic_machine=abacus-unknown
|
||||
;;
|
||||
adobe68k)
|
||||
@@ -451,6 +518,9 @@ case $basic_machine in
|
||||
basic_machine=i386-pc
|
||||
os=-aros
|
||||
;;
|
||||
asmjs)
|
||||
basic_machine=asmjs-unknown
|
||||
;;
|
||||
aux)
|
||||
basic_machine=m68k-apple
|
||||
os=-aux
|
||||
@@ -467,11 +537,24 @@ case $basic_machine in
|
||||
basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
os=-linux
|
||||
;;
|
||||
bluegene*)
|
||||
basic_machine=powerpc-ibm
|
||||
os=-cnk
|
||||
;;
|
||||
c54x-*)
|
||||
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
c55x-*)
|
||||
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
c6x-*)
|
||||
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
c90)
|
||||
basic_machine=c90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
cegcc)
|
||||
cegcc)
|
||||
basic_machine=arm-unknown
|
||||
os=-cegcc
|
||||
;;
|
||||
@@ -503,7 +586,7 @@ case $basic_machine in
|
||||
basic_machine=craynv-cray
|
||||
os=-unicosmp
|
||||
;;
|
||||
cr16)
|
||||
cr16 | cr16-*)
|
||||
basic_machine=cr16-unknown
|
||||
os=-elf
|
||||
;;
|
||||
@@ -661,7 +744,6 @@ case $basic_machine in
|
||||
i370-ibm* | ibm*)
|
||||
basic_machine=i370-ibm
|
||||
;;
|
||||
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
|
||||
i*86v32)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-sysv32
|
||||
@@ -700,6 +782,9 @@ case $basic_machine in
|
||||
basic_machine=m68k-isi
|
||||
os=-sysv
|
||||
;;
|
||||
leon-*|leon[3-9]-*)
|
||||
basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
|
||||
;;
|
||||
m68knommu)
|
||||
basic_machine=m68k-unknown
|
||||
os=-linux
|
||||
@@ -719,8 +804,15 @@ case $basic_machine in
|
||||
basic_machine=ns32k-utek
|
||||
os=-sysv
|
||||
;;
|
||||
microblaze*)
|
||||
basic_machine=microblaze-xilinx
|
||||
;;
|
||||
mingw64)
|
||||
basic_machine=x86_64-pc
|
||||
os=-mingw64
|
||||
;;
|
||||
mingw32)
|
||||
basic_machine=i386-pc
|
||||
basic_machine=i686-pc
|
||||
os=-mingw32
|
||||
;;
|
||||
mingw32ce)
|
||||
@@ -748,6 +840,10 @@ case $basic_machine in
|
||||
basic_machine=powerpc-unknown
|
||||
os=-morphos
|
||||
;;
|
||||
moxiebox)
|
||||
basic_machine=moxie-unknown
|
||||
os=-moxiebox
|
||||
;;
|
||||
msdos)
|
||||
basic_machine=i386-pc
|
||||
os=-msdos
|
||||
@@ -755,10 +851,18 @@ case $basic_machine in
|
||||
ms1-*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
|
||||
;;
|
||||
msys)
|
||||
basic_machine=i686-pc
|
||||
os=-msys
|
||||
;;
|
||||
mvs)
|
||||
basic_machine=i370-ibm
|
||||
os=-mvs
|
||||
;;
|
||||
nacl)
|
||||
basic_machine=le32-unknown
|
||||
os=-nacl
|
||||
;;
|
||||
ncr3000)
|
||||
basic_machine=i486-ncr
|
||||
os=-sysv4
|
||||
@@ -823,6 +927,12 @@ case $basic_machine in
|
||||
np1)
|
||||
basic_machine=np1-gould
|
||||
;;
|
||||
neo-tandem)
|
||||
basic_machine=neo-tandem
|
||||
;;
|
||||
nse-tandem)
|
||||
basic_machine=nse-tandem
|
||||
;;
|
||||
nsr-tandem)
|
||||
basic_machine=nsr-tandem
|
||||
;;
|
||||
@@ -905,9 +1015,10 @@ case $basic_machine in
|
||||
;;
|
||||
power) basic_machine=power-ibm
|
||||
;;
|
||||
ppc) basic_machine=powerpc-unknown
|
||||
ppc | ppcbe) basic_machine=powerpc-unknown
|
||||
;;
|
||||
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
ppc-* | ppcbe-*)
|
||||
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppcle | powerpclittle | ppc-le | powerpc-little)
|
||||
basic_machine=powerpcle-unknown
|
||||
@@ -932,7 +1043,11 @@ case $basic_machine in
|
||||
basic_machine=i586-unknown
|
||||
os=-pw32
|
||||
;;
|
||||
rdos)
|
||||
rdos | rdos64)
|
||||
basic_machine=x86_64-pc
|
||||
os=-rdos
|
||||
;;
|
||||
rdos32)
|
||||
basic_machine=i386-pc
|
||||
os=-rdos
|
||||
;;
|
||||
@@ -1001,6 +1116,9 @@ case $basic_machine in
|
||||
basic_machine=i860-stratus
|
||||
os=-sysv4
|
||||
;;
|
||||
strongarm-* | thumb-*)
|
||||
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
sun2)
|
||||
basic_machine=m68000-sun
|
||||
;;
|
||||
@@ -1057,20 +1175,8 @@ case $basic_machine in
|
||||
basic_machine=t90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
tic54x | c54x*)
|
||||
basic_machine=tic54x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tic55x | c55x*)
|
||||
basic_machine=tic55x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tic6x | c6x*)
|
||||
basic_machine=tic6x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tile*)
|
||||
basic_machine=tile-unknown
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-linux-gnu
|
||||
;;
|
||||
tx39)
|
||||
@@ -1140,6 +1246,9 @@ case $basic_machine in
|
||||
xps | xps100)
|
||||
basic_machine=xps100-honeywell
|
||||
;;
|
||||
xscale-* | xscalee[bl]-*)
|
||||
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
|
||||
;;
|
||||
ymp)
|
||||
basic_machine=ymp-cray
|
||||
os=-unicos
|
||||
@@ -1237,9 +1346,12 @@ esac
|
||||
if [ x"$os" != x"" ]
|
||||
then
|
||||
case $os in
|
||||
# First match some system type aliases
|
||||
# that might get confused with valid system types.
|
||||
# First match some system type aliases
|
||||
# that might get confused with valid system types.
|
||||
# -solaris* is a basic system type, with this one exception.
|
||||
-auroraux)
|
||||
os=-auroraux
|
||||
;;
|
||||
-solaris1 | -solaris1.*)
|
||||
os=`echo $os | sed -e 's|solaris1|sunos4|'`
|
||||
;;
|
||||
@@ -1260,30 +1372,31 @@ case $os in
|
||||
# Each alternative MUST END IN A *, to match a version number.
|
||||
# -sysv* is not here because it comes later, after sysvr4.
|
||||
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
|
||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
|
||||
| -kopensolaris* \
|
||||
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
|
||||
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
|
||||
| -sym* | -kopensolaris* | -plan9* \
|
||||
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
|
||||
| -aos* | -aros* \
|
||||
| -aos* | -aros* | -cloudabi* \
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
|
||||
| -openbsd* | -solidbsd* \
|
||||
| -bitrig* | -openbsd* | -solidbsd* \
|
||||
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
|
||||
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -chorusos* | -chorusrdb* | -cegcc* \
|
||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
|
||||
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
|
||||
| -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
|
||||
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
|
||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
|
||||
| -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops*)
|
||||
| -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
@@ -1322,7 +1435,7 @@ case $os in
|
||||
-opened*)
|
||||
os=-openedition
|
||||
;;
|
||||
-os400*)
|
||||
-os400*)
|
||||
os=-os400
|
||||
;;
|
||||
-wince*)
|
||||
@@ -1371,7 +1484,7 @@ case $os in
|
||||
-sinix*)
|
||||
os=-sysv4
|
||||
;;
|
||||
-tpf*)
|
||||
-tpf*)
|
||||
os=-tpf
|
||||
;;
|
||||
-triton*)
|
||||
@@ -1407,15 +1520,14 @@ case $os in
|
||||
-aros*)
|
||||
os=-aros
|
||||
;;
|
||||
-kaos*)
|
||||
os=-kaos
|
||||
;;
|
||||
-zvmoe)
|
||||
os=-zvmoe
|
||||
;;
|
||||
-dicos*)
|
||||
os=-dicos
|
||||
;;
|
||||
-nacl*)
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
*)
|
||||
@@ -1438,10 +1550,10 @@ else
|
||||
# system, and we'll never get to this point.
|
||||
|
||||
case $basic_machine in
|
||||
score-*)
|
||||
score-*)
|
||||
os=-elf
|
||||
;;
|
||||
spu-*)
|
||||
spu-*)
|
||||
os=-elf
|
||||
;;
|
||||
*-acorn)
|
||||
@@ -1453,8 +1565,23 @@ case $basic_machine in
|
||||
arm*-semi)
|
||||
os=-aout
|
||||
;;
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
c4x-* | tic4x-*)
|
||||
os=-coff
|
||||
;;
|
||||
c8051-*)
|
||||
os=-elf
|
||||
;;
|
||||
hexagon-*)
|
||||
os=-elf
|
||||
;;
|
||||
tic54x-*)
|
||||
os=-coff
|
||||
;;
|
||||
tic55x-*)
|
||||
os=-coff
|
||||
;;
|
||||
tic6x-*)
|
||||
os=-coff
|
||||
;;
|
||||
# This must come before the *-dec entry.
|
||||
pdp10-*)
|
||||
@@ -1474,14 +1601,11 @@ case $basic_machine in
|
||||
;;
|
||||
m68000-sun)
|
||||
os=-sunos3
|
||||
# This also exists in the configure program, but was not the
|
||||
# default.
|
||||
# os=-sunos4
|
||||
;;
|
||||
m68*-cisco)
|
||||
os=-aout
|
||||
;;
|
||||
mep-*)
|
||||
mep-*)
|
||||
os=-elf
|
||||
;;
|
||||
mips*-cisco)
|
||||
@@ -1508,7 +1632,7 @@ case $basic_machine in
|
||||
*-ibm)
|
||||
os=-aix
|
||||
;;
|
||||
*-knuth)
|
||||
*-knuth)
|
||||
os=-mmixware
|
||||
;;
|
||||
*-wec)
|
||||
@@ -1613,7 +1737,7 @@ case $basic_machine in
|
||||
-sunos*)
|
||||
vendor=sun
|
||||
;;
|
||||
-aix*)
|
||||
-cnk*|-aix*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-beos*)
|
||||
|
||||
+11
-10
@@ -14,10 +14,6 @@ AC_CANONICAL_HOST
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
# AC_PROG_CC_C99 is only available in autoconf version 2.60 and later.
|
||||
# If you must use an older version then comment out the following two
|
||||
# lines, but be warned that there could be issues with finding the
|
||||
# nan(), etc. functions. It is really best to upgrade to a supported
|
||||
# version of autoconf.
|
||||
AC_PREREQ([2.60])
|
||||
AC_PROG_CC_C99
|
||||
AC_PROG_CXX
|
||||
@@ -85,8 +81,9 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||
CFLAGS="$iverilog_temp_cflags"
|
||||
|
||||
AC_SUBST(DEPENDENCY_FLAG, [-MD])
|
||||
AC_SUBST(WARNING_FLAGS, ["-Wall -Wshadow"])
|
||||
AC_SUBST(WARNING_FLAGS_CXX, ["$iverilog_wextra_flag"])
|
||||
AC_SUBST(WARNING_FLAGS, ["-Wall $iverilog_wextra_flag -Wshadow"])
|
||||
AC_SUBST(WARNING_FLAGS_CC, ["-Wstrict-prototypes"])
|
||||
AC_SUBST(WARNING_FLAGS_CXX, [""])
|
||||
fi
|
||||
|
||||
AC_LANG(C++)
|
||||
@@ -217,9 +214,6 @@ AX_LD_EXTRALIBS
|
||||
# CFLAGS inherited by cadpli/Makefile?
|
||||
AX_C_PICFLAG
|
||||
|
||||
# may modify CPPFLAGS and CFLAGS
|
||||
AX_CPP_PRECOMP
|
||||
|
||||
# may modify LDFLAGS
|
||||
AX_C99_STRTOD
|
||||
|
||||
@@ -229,6 +223,10 @@ case "${host}" in
|
||||
CPPFLAGS="-mieee $CPPFLAGS"
|
||||
CFLAGS="-mieee $CFLAGS"
|
||||
;;
|
||||
*-*-mingw*)
|
||||
CXXFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CXXFLAGS"
|
||||
CFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CFLAGS"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Do some more operating system specific setup. We put the file64_support
|
||||
@@ -244,6 +242,9 @@ case "${host}" in
|
||||
esac
|
||||
AC_SUBST(file64_support)
|
||||
|
||||
# fstapi.c (from GTKWave) needs this define.
|
||||
AC_CHECK_FUNCS(realpath)
|
||||
|
||||
# Check that these functions exist. They are mostly C99
|
||||
# functions that older compilers may not yet support.
|
||||
AC_CHECK_FUNCS(fopen64)
|
||||
@@ -325,4 +326,4 @@ AC_MSG_ERROR(cannot configure white space in libdir: $libdir)
|
||||
fi
|
||||
AC_MSG_RESULT(ok)
|
||||
|
||||
AC_OUTPUT(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)
|
||||
AC_OUTPUT(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)
|
||||
|
||||
+2
-2
@@ -1,3 +1,3 @@
|
||||
// These are correct and are used to find the base (zero) pin.
|
||||
thisSubtraction:netlist.h:4430
|
||||
thisSubtraction:netlist.h:4439
|
||||
thisSubtraction:netlist.h:4976
|
||||
thisSubtraction:netlist.h:4985
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2013 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
|
||||
@@ -19,13 +19,14 @@
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <algorithm>
|
||||
# include <vector>
|
||||
# include <cstdlib>
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "functor.h"
|
||||
# include "compiler.h"
|
||||
# include "ivl_assert.h"
|
||||
# include <vector>
|
||||
|
||||
|
||||
/*
|
||||
@@ -42,11 +43,14 @@ struct cprop_functor : public functor_t {
|
||||
virtual void signal(Design*des, NetNet*obj);
|
||||
virtual void lpm_add_sub(Design*des, NetAddSub*obj);
|
||||
virtual void lpm_compare(Design*des, NetCompare*obj);
|
||||
virtual void lpm_compare_eq_(Design*des, 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);
|
||||
|
||||
void lpm_compare_eq_(Design*des, NetCompare*obj);
|
||||
};
|
||||
|
||||
void cprop_functor::signal(Design*, NetNet*)
|
||||
{
|
||||
@@ -74,6 +78,50 @@ void cprop_functor::lpm_compare_eq_(Design*, NetCompare*)
|
||||
{
|
||||
}
|
||||
|
||||
void cprop_functor::lpm_concat(Design*des, NetConcat*obj)
|
||||
{
|
||||
// Sorry, I don't know how to constant-propagate through
|
||||
// transparent concatenations.
|
||||
if (obj->transparent())
|
||||
return;
|
||||
|
||||
verinum result (verinum::Vz, obj->width());
|
||||
unsigned off = 0;
|
||||
|
||||
for (unsigned idx = 1 ; idx < obj->pin_count() ; idx += 1) {
|
||||
Nexus*nex = obj->pin(idx).nexus();
|
||||
// If there are non-constant drivers, then give up.
|
||||
if (! nex->drivers_constant())
|
||||
return;
|
||||
|
||||
verinum tmp = nex->driven_vector();
|
||||
result.set(off, tmp);
|
||||
off += tmp.len();
|
||||
}
|
||||
|
||||
if (debug_optimizer)
|
||||
cerr << obj->get_fileline() << ": cprop_functor::lpm_concat: "
|
||||
<< "Replace NetConcat with " << result << "." << endl;
|
||||
|
||||
|
||||
NetScope*scope = obj->scope();
|
||||
|
||||
// Create a NetConst object to carry the result. Give it the
|
||||
// same name as the Concat object that we are replacing, and
|
||||
// link the NetConst to the NetConcat object. Then delete the
|
||||
// concat that is now replaced.
|
||||
NetConst*result_obj = new NetConst(scope, obj->name(), result);
|
||||
result_obj->set_line(*obj);
|
||||
des->add_node(result_obj);
|
||||
connect(obj->pin(0), result_obj->pin(0));
|
||||
|
||||
// Note that this will leave the const inputs to dangle. They
|
||||
// will be reaped by other passes of cprop_functor.
|
||||
delete obj;
|
||||
|
||||
count += 1;
|
||||
}
|
||||
|
||||
void cprop_functor::lpm_ff(Design*, NetFF*obj)
|
||||
{
|
||||
// Look for and count unlinked FF outputs. Note that if the
|
||||
@@ -115,11 +163,6 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
||||
if (! sel_nex->drivers_constant())
|
||||
return;
|
||||
|
||||
// If the select input is assigned or forced, then again there
|
||||
// is nothing we can do here.
|
||||
if (sel_nex->assign_lval())
|
||||
return;
|
||||
|
||||
// If the constant select is 'bz or 'bx, then give up.
|
||||
verinum::V sel_val = sel_nex->driven_value();
|
||||
if (sel_val == verinum::Vz || sel_val == verinum::Vx)
|
||||
@@ -150,6 +193,142 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
||||
count += 1;
|
||||
}
|
||||
|
||||
static bool compare_base(NetPartSelect*a, NetPartSelect*b)
|
||||
{
|
||||
return a->base() < b->base();
|
||||
}
|
||||
|
||||
/*
|
||||
* This optimization searches for Nexa that are driven only by
|
||||
* NetPartSelect(PV) outputs. These might turn from Verilog input that
|
||||
* looks like this:
|
||||
* wire [7:0] foo
|
||||
* assign foo[7:4] = a;
|
||||
* assign foo[3:0] = b;
|
||||
* The idea is to convert the part selects of the above to a single
|
||||
* concatenation that looks like this:
|
||||
* assign foo = {a, b};
|
||||
*/
|
||||
void cprop_functor::lpm_part_select(Design*des, NetPartSelect*obj)
|
||||
{
|
||||
if (obj->dir() != NetPartSelect::PV)
|
||||
return;
|
||||
|
||||
NetScope*scope = obj->scope();
|
||||
Nexus*nex = obj->pin(1).nexus();
|
||||
vector<NetPartSelect*> obj_set;
|
||||
|
||||
for (Link*cur = nex->first_nlink() ; cur ; cur = cur->next_nlink()) {
|
||||
|
||||
// If this is an input (or passive) then ignore it.
|
||||
if (cur->get_dir() != Link::OUTPUT)
|
||||
continue;
|
||||
|
||||
// Check to see if this is the output of a
|
||||
// NetPartSelect::PV. If not, then give up on the blend.
|
||||
NetPins*tmp_obj = cur->get_obj();
|
||||
unsigned tmp_pin = cur->get_pin();
|
||||
|
||||
NetPartSelect*cur_obj = dynamic_cast<NetPartSelect*> (tmp_obj);
|
||||
if (cur_obj == 0)
|
||||
return;
|
||||
|
||||
if (cur_obj->dir() != NetPartSelect::PV)
|
||||
return;
|
||||
|
||||
if (tmp_pin != 1)
|
||||
return;
|
||||
|
||||
obj_set.push_back(cur_obj);
|
||||
}
|
||||
|
||||
if (obj_set.size() < 2)
|
||||
return;
|
||||
|
||||
if (debug_optimizer)
|
||||
cerr << obj->get_fileline() << ": cprop::lpm_part_select: "
|
||||
<< "Found " << obj_set.size() << " NetPartSelect(PV) objects."
|
||||
<< endl;
|
||||
|
||||
// Sort by increasing base offset.
|
||||
sort(obj_set.begin(), obj_set.end(), compare_base);
|
||||
|
||||
// Check and make sure there are no overlaps. If there are,
|
||||
// then give up on this optimization.
|
||||
for (size_t idx = 1 ; idx < obj_set.size() ; idx += 1) {
|
||||
unsigned top = obj_set[idx-1]->base() + obj_set[idx-1]->width();
|
||||
if (top > obj_set[idx]->base()) {
|
||||
if (debug_optimizer)
|
||||
cerr << obj->get_fileline() << ": cprop::lpm_part_select: "
|
||||
<< "Range [" << obj_set[idx-1]->base()
|
||||
<< " " << top << ") overlaps PV starting at "
|
||||
<< obj_set[idx]->base() << ". Give up." << endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the tail runs off the end of the target. If so it
|
||||
// should be possible to replace it with a bit select to
|
||||
// shorten the object for the target, but for now just give up.
|
||||
unsigned sig_width = nex->vector_width();
|
||||
if (obj_set.back()->base() + obj_set.back()->width() > sig_width) {
|
||||
if (debug_optimizer)
|
||||
cerr << obj->get_fileline() << ": cprop::lpm_part_select: "
|
||||
<< "Range [" << obj_set.back()->base()
|
||||
<< ":" << (obj_set.back()->base() + obj_set.back()->width() - 1)
|
||||
<< "] runs off the end of target." << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// Figure out how many components we are going to need.
|
||||
unsigned part_count = 0;
|
||||
unsigned off = 0;
|
||||
for (size_t idx = 0 ; idx < obj_set.size() ; idx += 1) {
|
||||
if (obj_set[idx]->base() > off) {
|
||||
off = obj_set[idx]->base();
|
||||
part_count += 1;
|
||||
}
|
||||
off += obj_set[idx]->width();
|
||||
part_count += 1;
|
||||
}
|
||||
|
||||
if (off < sig_width)
|
||||
part_count += 1;
|
||||
|
||||
NetConcat*concat = new NetConcat(scope, scope->local_symbol(),
|
||||
sig_width, part_count);
|
||||
concat->set_line(*obj);
|
||||
des->add_node(concat);
|
||||
connect(concat->pin(0), obj->pin(1));
|
||||
|
||||
off = 0;
|
||||
size_t concat_pin = 1;
|
||||
for (size_t idx = 0 ; idx < obj_set.size() ; idx += 1) {
|
||||
NetPartSelect*cobj = obj_set[idx];
|
||||
if (cobj->base() > off) {
|
||||
NetNet*zzz = make_const_z(des, scope, cobj->base()-off);
|
||||
connect(concat->pin(concat_pin), zzz->pin(0));
|
||||
concat_pin += 1;
|
||||
off = cobj->base();
|
||||
}
|
||||
connect(concat->pin(concat_pin), cobj->pin(0));
|
||||
concat_pin += 1;
|
||||
off += cobj->width();
|
||||
}
|
||||
if (off < sig_width) {
|
||||
NetNet*zzz = make_const_z(des, scope, sig_width-off);
|
||||
connect(concat->pin(concat_pin), zzz->pin(0));
|
||||
concat_pin += 1;
|
||||
}
|
||||
ivl_assert(*obj, concat_pin == concat->pin_count());
|
||||
|
||||
for (size_t idx = 0 ; idx < obj_set.size() ; idx += 1) {
|
||||
delete obj_set[idx];
|
||||
}
|
||||
|
||||
count += 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This functor looks to see if the constant is connected to nothing
|
||||
* but signals. If that is the case, delete the dangling constant and
|
||||
|
||||
+316
-50
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2012 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2015 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,9 @@
|
||||
# include "netlist.h"
|
||||
# include "compiler.h"
|
||||
# include "discipline.h"
|
||||
# include "netclass.h"
|
||||
# include "netdarray.h"
|
||||
# include "netqueue.h"
|
||||
# include "netvector.h"
|
||||
# include "ivl_assert.h"
|
||||
# include "PExpr.h"
|
||||
@@ -112,6 +114,9 @@ ostream& operator << (ostream&o, ivl_variable_type_t val)
|
||||
case IVL_VT_CLASS:
|
||||
o << "class";
|
||||
break;
|
||||
case IVL_VT_QUEUE:
|
||||
o << "queue";
|
||||
break;
|
||||
}
|
||||
return o;
|
||||
}
|
||||
@@ -144,18 +149,87 @@ ostream& operator << (ostream&o, ivl_switch_type_t val)
|
||||
return o;
|
||||
}
|
||||
|
||||
ostream& operator << (ostream&fd, PortType::Enum val)
|
||||
{
|
||||
switch (val) {
|
||||
case PortType::NOT_A_PORT:
|
||||
fd << "NOT_A_PORT";
|
||||
break;
|
||||
case PortType::PIMPLICIT:
|
||||
fd << "PIMPLICIT";
|
||||
break;
|
||||
case PortType::PINPUT:
|
||||
fd << "PINPUT";
|
||||
break;
|
||||
case PortType::POUTPUT:
|
||||
fd << "POUTPUT";
|
||||
break;
|
||||
case PortType::PINOUT:
|
||||
fd << "PINOUT";
|
||||
break;
|
||||
case PortType::PREF:
|
||||
fd << "PREF";
|
||||
break;
|
||||
default:
|
||||
fd << "PortType::Enum::?";
|
||||
break;
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
ostream& operator << (ostream&fd, NetCaseCmp::kind_t that)
|
||||
{
|
||||
switch (that) {
|
||||
case NetCaseCmp::EEQ:
|
||||
fd << "===";
|
||||
break;
|
||||
case NetCaseCmp::NEQ:
|
||||
fd << "!==";
|
||||
break;
|
||||
case NetCaseCmp::XEQ:
|
||||
fd << "==?";
|
||||
break;
|
||||
case NetCaseCmp::ZEQ:
|
||||
fd << "==z?";
|
||||
break;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
ostream& ivl_type_s::debug_dump(ostream&o) const
|
||||
{
|
||||
o << typeid(*this).name();
|
||||
return o;
|
||||
}
|
||||
|
||||
ostream& netclass_t::debug_dump(ostream&fd) const
|
||||
{
|
||||
fd << "class " << name_ << "{";
|
||||
for (size_t idx = 0 ; idx < property_table_.size() ; idx += 1) {
|
||||
if (idx != 0) fd << "; ";
|
||||
if (property_table_[idx].type)
|
||||
property_table_[idx].type->debug_dump(fd);
|
||||
else
|
||||
fd << "NO_TYPE";
|
||||
fd << " " << property_table_[idx].name;
|
||||
}
|
||||
fd << "}";
|
||||
return fd;
|
||||
}
|
||||
|
||||
ostream& netdarray_t::debug_dump(ostream&o) const
|
||||
{
|
||||
o << "dynamic array of " << *element_type();
|
||||
return o;
|
||||
}
|
||||
|
||||
ostream& netqueue_t::debug_dump(ostream&fd) const
|
||||
{
|
||||
fd << "queue of " << *element_type();
|
||||
return fd;
|
||||
}
|
||||
|
||||
ostream& netvector_t::debug_dump(ostream&o) const
|
||||
{
|
||||
o << type_ << (signed_? " signed" : " unsigned") << packed_dims_;
|
||||
@@ -169,10 +243,7 @@ static inline void dump_scope_path(ostream&o, const NetScope*scope)
|
||||
dump_scope_path(o, parent);
|
||||
o << ".";
|
||||
}
|
||||
const hname_t name = scope->fullname();
|
||||
o << name.peek_name();
|
||||
if (name.has_number())
|
||||
o << "[" << name.peek_number() << "]";
|
||||
o << scope->fullname();
|
||||
}
|
||||
|
||||
ostream& operator <<(ostream&o, struct __ScopePathManip marg)
|
||||
@@ -182,6 +253,77 @@ ostream& operator <<(ostream&o, struct __ScopePathManip marg)
|
||||
return o;
|
||||
}
|
||||
|
||||
ostream& operator <<(ostream&o, struct __ObjectPathManip marg)
|
||||
{
|
||||
if (marg.obj != 0) {
|
||||
dump_scope_path(o, marg.obj->scope());
|
||||
o << "." << marg.obj->name();
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
ostream& operator <<(ostream&fd, Link::DIR dir)
|
||||
{
|
||||
switch (dir) {
|
||||
case Link::PASSIVE:
|
||||
fd << "PASSIVE";
|
||||
break;
|
||||
case Link::INPUT:
|
||||
fd << "INPUT";
|
||||
break;
|
||||
case Link::OUTPUT:
|
||||
fd << "OUTPUT";
|
||||
break;
|
||||
default:
|
||||
fd << "<" << (int)dir << ">";
|
||||
break;
|
||||
}
|
||||
return fd;
|
||||
}
|
||||
|
||||
void NetPins::show_type(ostream&fd) const
|
||||
{
|
||||
fd << typeid(*this).name();
|
||||
}
|
||||
|
||||
void NetObj::show_type(ostream&fd) const
|
||||
{
|
||||
fd << typeid(*this).name() << "[" << scope_path(scope_) << "." << name_ << "]";
|
||||
}
|
||||
|
||||
struct __ShowTypeManip { const NetPins*pins; };
|
||||
inline __ShowTypeManip show_type(const NetPins*pins)
|
||||
{ __ShowTypeManip tmp; tmp.pins = pins; return tmp; }
|
||||
|
||||
inline ostream& operator << (ostream&fd, __ShowTypeManip man)
|
||||
{
|
||||
if (man.pins == 0)
|
||||
fd << "NexusSet";
|
||||
else
|
||||
man.pins->show_type(fd);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
void Link::dump_link(ostream&fd, unsigned ind) const
|
||||
{
|
||||
const Link*cur;
|
||||
const Nexus*nex = nexus();
|
||||
|
||||
if (nex == 0) {
|
||||
fd << setw(ind) << "" << "<unlinked>" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
for (cur = nex->first_nlink() ; cur; cur = cur->next_nlink()) {
|
||||
const NetPins*obj = cur->get_obj();
|
||||
unsigned pin = cur->get_pin();
|
||||
fd << setw(ind) << "" << "Pin " << pin
|
||||
<< " of " << show_type(obj)
|
||||
<< ", dir=" << cur->dir_ << endl;
|
||||
}
|
||||
}
|
||||
|
||||
void NetBranch::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
static const char*pin_names[2] = {
|
||||
@@ -445,8 +587,12 @@ void NetCompare::dump_node(ostream&o, unsigned ind) const
|
||||
|
||||
void NetConcat::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "NetConcat: "
|
||||
<< name();
|
||||
if (transparent_)
|
||||
o << setw(ind) << "" << "NetConcat8: ";
|
||||
else
|
||||
o << setw(ind) << "" << "NetConcat: ";
|
||||
o << name();
|
||||
|
||||
if (rise_time())
|
||||
o << " #(" << *rise_time()
|
||||
<< "," << *fall_time() << "," << *decay_time() << ")";
|
||||
@@ -509,19 +655,14 @@ void NetBUFZ::dump_node(ostream&o, unsigned ind) const
|
||||
|
||||
void NetCaseCmp::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
if (eeq_)
|
||||
o << setw(ind) << "" << "case compare === : " << name() << endl;
|
||||
else
|
||||
o << setw(ind) << "" << "case compare !== : " << name() << endl;
|
||||
o << setw(ind) << "" << "case compare " << kind_ << ": " << name() << endl;
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
}
|
||||
|
||||
void NetConst::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "constant " << width_ << "'b";
|
||||
for (unsigned idx = width_ ; idx > 0 ; idx -= 1)
|
||||
o << value_[idx-1];
|
||||
o << setw(ind) << "" << "constant " << value_;
|
||||
o << ": " << name();
|
||||
if (rise_time())
|
||||
o << " #(" << *rise_time()
|
||||
@@ -536,8 +677,12 @@ void NetConst::dump_node(ostream&o, unsigned ind) const
|
||||
void NetFF::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "LPM_FF: " << name()
|
||||
<< " scope=" << scope_path(scope())
|
||||
<< " aset_value=" << aset_value_ << endl;
|
||||
<< " scope=" << scope_path(scope());
|
||||
if (negedge_)
|
||||
o << " negedge";
|
||||
else
|
||||
o << " posedge";
|
||||
o << " aset_value=" << aset_value_ << endl;
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
@@ -662,6 +807,21 @@ void NetPartSelect::dump_node(ostream&o, unsigned ind) const
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetSubstitute::dump_node(ostream&fd, unsigned ind) const
|
||||
{
|
||||
fd << setw(ind) << "" << "NetSubstitute: "
|
||||
<< name();
|
||||
if (rise_time())
|
||||
fd << " #(" << *rise_time()
|
||||
<< "," << *fall_time()
|
||||
<< "," << *decay_time() << ")";
|
||||
else
|
||||
fd << " #(.,.,.)";
|
||||
fd << " width=" << wid_ << " base=" << off_ <<endl;
|
||||
dump_node_pins(fd, ind+4);
|
||||
dump_obj_attr(fd, ind+4);
|
||||
}
|
||||
|
||||
void NetReplicate::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "NetReplicate: "
|
||||
@@ -743,12 +903,13 @@ void NetUserFunc::dump_node(ostream&o, unsigned ind) const
|
||||
|
||||
void NetTaskDef::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "task " << scope_path(scope_) << ";" << endl;
|
||||
o << setw(ind) << "" << "task " << scope_path(scope()) << ";" << endl;
|
||||
|
||||
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1) {
|
||||
for (unsigned idx = 0 ; idx < port_count() ; idx += 1) {
|
||||
const NetNet*pnet = port(idx);
|
||||
o << setw(ind+4) << "";
|
||||
assert(ports_[idx]);
|
||||
switch (ports_[idx]->port_type()) {
|
||||
assert(pnet);
|
||||
switch (pnet->port_type()) {
|
||||
case NetNet::PINPUT:
|
||||
o << "input ";
|
||||
break;
|
||||
@@ -762,10 +923,13 @@ void NetTaskDef::dump(ostream&o, unsigned ind) const
|
||||
o << "NOT_A_PORT ";
|
||||
break;
|
||||
}
|
||||
o << ports_[idx]->name() << ";" << endl;
|
||||
o << pnet->name() << ";" << endl;
|
||||
}
|
||||
|
||||
proc_->dump(o, ind+4);
|
||||
if (proc_)
|
||||
proc_->dump(o, ind+4);
|
||||
else
|
||||
o << setw(ind+4) << "" << "MISSING PROCEDURAL CODE" << endl;
|
||||
|
||||
o << setw(ind) << "" << "endtask" << endl;
|
||||
}
|
||||
@@ -855,19 +1019,18 @@ void NetAlloc::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetAssign_::dump_lval(ostream&o) const
|
||||
{
|
||||
if (sig_) {
|
||||
o << sig_->name();
|
||||
if (! member_.nil()) {
|
||||
o << "." << member_;
|
||||
}
|
||||
if (word_) {
|
||||
o << "[word=" << *word_ << "]";
|
||||
}
|
||||
if (base_) {
|
||||
o << "[" << *base_ << " +: " << lwid_ << "]";
|
||||
}
|
||||
} else {
|
||||
o << "";
|
||||
if (sig_) o << sig_->name();
|
||||
else if (nest_) nest_->dump_lval(o);
|
||||
else o << "<?>";
|
||||
|
||||
if (! member_.nil()) {
|
||||
o << "." << member_;
|
||||
}
|
||||
if (word_) {
|
||||
o << "[word=" << *word_ << "]";
|
||||
}
|
||||
if (base_) {
|
||||
o << "[" << *base_ << " +: " << lwid_ << "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -962,7 +1125,7 @@ void NetCase::dump(ostream&o, unsigned ind) const
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned idx = 0 ; idx < nitems_ ; idx += 1) {
|
||||
for (unsigned idx = 0 ; idx < items_.size() ; idx += 1) {
|
||||
o << setw(ind+2) << "";
|
||||
if (items_[idx].guard)
|
||||
o << *items_[idx].guard << ":";
|
||||
@@ -1020,8 +1183,17 @@ void NetDeassign::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetDisable::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "disable " << scope_path(target_) << "; "
|
||||
<< "/* " << get_fileline() << " */" << endl;
|
||||
o << setw(ind) << "" << "disable ";
|
||||
if (target_) o << scope_path(target_);
|
||||
else o << "fork";
|
||||
o << "; " << "/* " << get_fileline() << " */" << endl;
|
||||
}
|
||||
|
||||
void NetDoWhile::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "do" << endl;
|
||||
proc_->dump(o, ind+3);
|
||||
o << setw(ind) << "" << "while (" << *cond_ << ");" << endl;
|
||||
}
|
||||
|
||||
void NetEvProbe::dump_node(ostream&o, unsigned ind) const
|
||||
@@ -1052,7 +1224,15 @@ void NetEvTrig::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetEvWait::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) <<"" << "@(";
|
||||
o << setw(ind) << "";
|
||||
|
||||
/* Check for a wait fork. */
|
||||
if ((nevents() == 1) && (event(0) == 0)) {
|
||||
o << "wait fork;";
|
||||
return;
|
||||
}
|
||||
|
||||
o << "@(";
|
||||
|
||||
if (nevents() > 0)
|
||||
o << event(0)->name();
|
||||
@@ -1076,6 +1256,12 @@ ostream& operator << (ostream&out, const NetEvWait&obj)
|
||||
|
||||
void NetEvWait::dump_inline(ostream&o) const
|
||||
{
|
||||
/* Check for a wait fork. */
|
||||
if ((nevents() == 1) && (event(0) == 0)) {
|
||||
o << "wait fork;";
|
||||
return;
|
||||
}
|
||||
|
||||
o << "@(";
|
||||
|
||||
if (nevents() > 0)
|
||||
@@ -1100,6 +1286,13 @@ void NetForever::dump(ostream&o, unsigned ind) const
|
||||
statement_->dump(o, ind+2);
|
||||
}
|
||||
|
||||
void NetForLoop::dump(ostream&fd, unsigned ind) const
|
||||
{
|
||||
fd << setw(ind) << "" << "FOR LOOP index=" << index_->name() << endl;
|
||||
statement_->dump(fd, ind+4);
|
||||
step_statement_->dump(fd, ind+4);
|
||||
}
|
||||
|
||||
void NetFree::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "// free storage : " << scope_path(scope_) << endl;
|
||||
@@ -1107,7 +1300,7 @@ void NetFree::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetFuncDef::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "function definition for " << scope_path(scope_) << endl;
|
||||
o << setw(ind) << "" << "function definition for " << scope_path(scope()) << endl;
|
||||
if (result_sig_) {
|
||||
o << setw(ind+2) << "" << "Return signal: ";
|
||||
if (result_sig_->get_signed()) o << "+";
|
||||
@@ -1135,10 +1328,10 @@ void NetFuncDef::dump(ostream&o, unsigned ind) const
|
||||
if (port(idx)->get_signed()) o << "+";
|
||||
o << port(idx)->name() << endl;
|
||||
}
|
||||
if (statement_)
|
||||
statement_->dump(o, ind+2);
|
||||
if (proc_)
|
||||
proc_->dump(o, ind+2);
|
||||
else
|
||||
o << setw(ind+2) << "" << "// NO STATEMENT" << endl;
|
||||
o << setw(ind+2) << "" << "MISSING PROCEDURAL CODE" << endl;
|
||||
}
|
||||
|
||||
void NetPDelay::dump(ostream&o, unsigned ind) const
|
||||
@@ -1171,6 +1364,11 @@ void NetRepeat::dump(ostream&o, unsigned ind) const
|
||||
statement_->dump(o, ind+2);
|
||||
}
|
||||
|
||||
void netclass_t::dump_scope(ostream&fd) const
|
||||
{
|
||||
class_scope_->dump(fd);
|
||||
}
|
||||
|
||||
void NetScope::dump(ostream&o) const
|
||||
{
|
||||
/* This is a constructed hierarchical name. */
|
||||
@@ -1181,8 +1379,9 @@ void NetScope::dump(ostream&o) const
|
||||
if (is_cell()) o << " (cell)";
|
||||
if (nested_module()) o << " (nested)";
|
||||
if (program_block()) o << " (program)";
|
||||
|
||||
o << endl;
|
||||
if (is_interface()) o << " (interface)";
|
||||
o << " " << children_.size() << " children, "
|
||||
<< classes_.size() << " classes" << endl;
|
||||
|
||||
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)
|
||||
o << " (* " << attr_key(idx) << " = "
|
||||
@@ -1270,9 +1469,9 @@ void NetScope::dump(ostream&o) const
|
||||
o << " enum sets {" << endl;
|
||||
|
||||
/* Dump the enumerations and enum names in this scope. */
|
||||
for (list<netenum_t*>::const_iterator cur = enum_sets_.begin()
|
||||
for (map<const enum_type_t*,netenum_t*>::const_iterator cur = enum_sets_.begin()
|
||||
; cur != enum_sets_.end() ; ++ cur) {
|
||||
o << " " << *cur << endl;
|
||||
o << " " << cur->second << endl;
|
||||
}
|
||||
o << " }" << endl;
|
||||
|
||||
@@ -1318,6 +1517,11 @@ void NetScope::dump(ostream&o) const
|
||||
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
|
||||
; cur != children_.end() ; ++ cur )
|
||||
cur->second->dump(o);
|
||||
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++ cur ) {
|
||||
cur->second->dump_scope(o);
|
||||
}
|
||||
}
|
||||
|
||||
void NetSTask::dump(ostream&o, unsigned ind) const
|
||||
@@ -1375,6 +1579,19 @@ void NetEAccess::dump(ostream&o) const
|
||||
o << ")";
|
||||
}
|
||||
|
||||
void NetEArrayPattern::dump(ostream&fd) const
|
||||
{
|
||||
fd << "'{";
|
||||
if (items_.size() >= 1) {
|
||||
if (items_[0]) fd << *items_[0];
|
||||
}
|
||||
for (size_t idx = 1 ; idx < items_.size() ; idx += 1) {
|
||||
fd << ", ";
|
||||
if (items_[idx]) fd << *items_[idx];
|
||||
}
|
||||
fd << "}";
|
||||
}
|
||||
|
||||
void NetEBinary::dump(ostream&o) const
|
||||
{
|
||||
if (op_ == 'm' || op_ == 'M') {
|
||||
@@ -1449,6 +1666,16 @@ void NetEBinary::dump(ostream&o) const
|
||||
o << ")";
|
||||
}
|
||||
|
||||
void NetECast::dump(ostream&fd) const
|
||||
{
|
||||
if (op_=='2')
|
||||
fd << "bool<" << expr_width() << ">(" << *expr_ << ")";
|
||||
else if (op_=='4')
|
||||
fd << "logic<" << expr_width() << ">(" << *expr_ << ")";
|
||||
else
|
||||
NetEUnary::dump(fd);
|
||||
}
|
||||
|
||||
void NetEConcat::dump(ostream&o) const
|
||||
{
|
||||
if (repeat_ != 1)
|
||||
@@ -1507,6 +1734,11 @@ void NetEEvent::dump(ostream&o) const
|
||||
o << "<event=" << event_->name() << ">";
|
||||
}
|
||||
|
||||
void NetELast::dump(ostream&fd) const
|
||||
{
|
||||
fd << "<last of " << sig_->name() << ">";
|
||||
}
|
||||
|
||||
void NetENetenum::dump(ostream&o) const
|
||||
{
|
||||
o << "<netenum=" << netenum_ << ">";
|
||||
@@ -1514,7 +1746,14 @@ void NetENetenum::dump(ostream&o) const
|
||||
|
||||
void NetENew::dump(ostream&o) const
|
||||
{
|
||||
o << "new <type>";
|
||||
o << "new <type> [";
|
||||
if (size_) size_->dump(o);
|
||||
o << "]";
|
||||
if (init_val_) {
|
||||
o << "(";
|
||||
init_val_->dump(o);
|
||||
o << ")";
|
||||
}
|
||||
}
|
||||
|
||||
void NetENull::dump(ostream&o) const
|
||||
@@ -1525,6 +1764,8 @@ void NetENull::dump(ostream&o) const
|
||||
void NetEProperty::dump(ostream&o) const
|
||||
{
|
||||
o << net_->name() << ".<" << pidx_ << ">";
|
||||
if (index_)
|
||||
o << "[" << *index_ << "]";
|
||||
}
|
||||
|
||||
void NetEScope::dump(ostream&o) const
|
||||
@@ -1568,6 +1809,11 @@ void NetESFunc::dump(ostream&o) const
|
||||
o << ")";
|
||||
}
|
||||
|
||||
void NetEShallowCopy::dump(ostream&o) const
|
||||
{
|
||||
o << "<ShallowCopy, " << *arg1_ << " <-- " << *arg2_ << ">";
|
||||
}
|
||||
|
||||
void NetESignal::dump(ostream&o) const
|
||||
{
|
||||
if (has_sign())
|
||||
@@ -1586,7 +1832,7 @@ void NetETernary::dump(ostream&o) const
|
||||
|
||||
void NetEUFunc::dump(ostream&o) const
|
||||
{
|
||||
o << func_->basename() << "(";
|
||||
o << scope_path(func_) << "(";
|
||||
if (! parms_.empty()) {
|
||||
parms_[0]->dump(o);
|
||||
for (unsigned idx = 1 ; idx < parms_.size() ; idx += 1) {
|
||||
@@ -1641,10 +1887,30 @@ void NetEUnary::dump(ostream&o) const
|
||||
void Design::dump(ostream&o) const
|
||||
{
|
||||
o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
|
||||
|
||||
o << "PACKAGES:" << endl;
|
||||
for (map<perm_string,NetScope*>::const_iterator cur = packages_.begin()
|
||||
; cur != packages_.end() ; ++cur) {
|
||||
cur->second->dump(o);
|
||||
}
|
||||
|
||||
o << "$ROOT CLASSES:" << endl;
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++cur) {
|
||||
cur->second->dump_scope(o);
|
||||
}
|
||||
|
||||
o << "$ROOT TASKS/FUNCTIONS:" << endl;
|
||||
for (map<NetScope*,PTaskFunc*>::const_iterator cur = root_tasks_.begin()
|
||||
; cur != root_tasks_.end() ; ++ cur) {
|
||||
cur->first->dump(o);
|
||||
}
|
||||
|
||||
o << "SCOPES:" << endl;
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); ++ scope )
|
||||
scope != root_scopes_.end(); ++ scope ) {
|
||||
(*scope)->dump(o);
|
||||
}
|
||||
|
||||
o << "ELABORATED NODES:" << endl;
|
||||
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
#ifndef __discipline_H
|
||||
#define __discipline_H
|
||||
#ifndef IVL_discipline_H
|
||||
#define IVL_discipline_H
|
||||
/*
|
||||
* Copyright (c) 2008-2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2008-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
|
||||
@@ -74,4 +74,4 @@ extern map<perm_string,ivl_discipline_t> disciplines;
|
||||
// Map access function name to the nature that it accesses.
|
||||
extern map<perm_string,ivl_nature_t> access_function_nature;
|
||||
|
||||
#endif
|
||||
#endif /* IVL_discipline_H */
|
||||
|
||||
@@ -48,7 +48,8 @@ INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
|
||||
endif
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
CXXFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CXX@ @CXXFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
O = main.o res.o
|
||||
@@ -80,11 +81,12 @@ config.h: $(srcdir)/config.h.in Makefile
|
||||
sed -e 's;@IVLCC@;@CC@;' -e 's;@IVLCXX@;@CXX@;' \
|
||||
-e 's;@SUFFIX@;$(suffix);g' \
|
||||
-e 's;@IVLCFLAGS@;$(CFLAGS);' \
|
||||
-e 's;@IVLCXXFLAGS@;$(CXXFLAGS);' \
|
||||
-e 's;@SHARED@;@shared@;' $< > $@
|
||||
|
||||
# Windows specific...
|
||||
res.rc: $(srcdir)/res.rc.in ../version.exe
|
||||
sed -e 's;@PRODUCTVERSION@;'`../version.exe '%M,%m,%n,0'`';' \
|
||||
sed -e 's;@PRODUCTVERSION@;'`../version.exe '%M,%n,0,0'`';' \
|
||||
$(srcdir)/res.rc.in > $@
|
||||
|
||||
res.o: res.rc
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#define IVERILOG_VPI_CC "@IVLCC@"
|
||||
#define IVERILOG_VPI_CXX "@IVLCXX@"
|
||||
#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_SUFFIX "@SUFFIX@"
|
||||
|
||||
+169
-164
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Gus Baldauf (gus@picturel.com)
|
||||
* Copyright (c) 2015 Martin Whitaker
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -20,7 +21,7 @@
|
||||
/*
|
||||
* iverilog-vpi.c
|
||||
*
|
||||
* this program provides the functionality of iverilog-vpi.sh under Win32
|
||||
* this program provides the functionality of iverilog-vpi.sh under Windows
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -32,7 +33,7 @@
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
static void setup_ivl_environment();
|
||||
static void setup_ivl_environment(void);
|
||||
static void assign(char **ptr, char *str);
|
||||
|
||||
/* The compile options: compiler, flags, etc. are in here */
|
||||
@@ -43,16 +44,17 @@ static void assign(char **ptr, char *str);
|
||||
static struct global_strings {
|
||||
char *pCCSRC; /* list of C source files (*.c) */
|
||||
char *pCXSRC; /* list of C++ source files (*.cc, *.cpp) */
|
||||
char *pOBJ; /* list of object files */
|
||||
char *pLIB; /* list of library files */
|
||||
char *pINCS; /* list of include directories */
|
||||
char *pDEFS; /* list of definitions */
|
||||
char *pOUT; /* output file name (.vpi extension), if 0 length then no source files specified */
|
||||
char *pOBJ; /* list of object files */
|
||||
char *pLIB; /* list of library files */
|
||||
char *pINCS; /* list of include directories */
|
||||
char *pDEFS; /* list of definitions */
|
||||
char *pOUT; /* output file name (.vpi extension), if 0 length then no source files specified */
|
||||
char *pMINGW; /* path to MinGW directory */
|
||||
char *pIVL; /* path to IVL directory */
|
||||
char *pCFLAGS; /* CFLAGS option */
|
||||
char *pLDLIBS; /* LDLIBS option */
|
||||
char *pNewPath; /* new PATH environment variable setting */
|
||||
char *pIVL; /* path to IVL directory */
|
||||
char *pCCFLAGS; /* compiler flags for compiling C source files */
|
||||
char *pCXFLAGS; /* compiler flags for compiling C++ source files */
|
||||
char *pLDLIBS; /* linker flags for final linking stage */
|
||||
char *pCCNAME; /* base name of compiler */
|
||||
char *pLD; /* what to use for a linker */
|
||||
} gstr;
|
||||
|
||||
@@ -75,21 +77,21 @@ static void myExit(int exitVal)
|
||||
deInitDynString(gstr.pOUT);
|
||||
deInitDynString(gstr.pMINGW);
|
||||
deInitDynString(gstr.pIVL);
|
||||
deInitDynString(gstr.pCFLAGS);
|
||||
deInitDynString(gstr.pCCFLAGS);
|
||||
deInitDynString(gstr.pCXFLAGS);
|
||||
deInitDynString(gstr.pLDLIBS);
|
||||
deInitDynString(gstr.pNewPath);
|
||||
free(gstr.pLD);
|
||||
deInitDynString(gstr.pCCNAME);
|
||||
deInitDynString(gstr.pLD);
|
||||
|
||||
exit(exitVal);
|
||||
}
|
||||
|
||||
/* display usage summary and exit */
|
||||
|
||||
static void usage()
|
||||
static void usage(void)
|
||||
{
|
||||
fprintf(stderr,"usage: iverilog-vpi" IVERILOG_SUFFIX " [src and obj files]...\n");
|
||||
fprintf(stderr," or iverilog-vpi" IVERILOG_SUFFIX " -mingw=dir\n");
|
||||
fprintf(stderr," or iverilog-vpi" IVERILOG_SUFFIX " -ivl=dir\n");
|
||||
fprintf(stderr, "usage: iverilog-vpi" IVERILOG_SUFFIX " [options] [src and obj files]...\n");
|
||||
fprintf(stderr, " or iverilog-vpi" IVERILOG_SUFFIX " -mingw=dir\n");
|
||||
myExit(1);
|
||||
}
|
||||
|
||||
@@ -98,7 +100,7 @@ static void initDynString(char **str)
|
||||
*str = (char *) malloc(1);
|
||||
|
||||
if (!*str) {
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
myExit(4);
|
||||
}
|
||||
|
||||
@@ -107,8 +109,10 @@ static void initDynString(char **str)
|
||||
|
||||
/* initialize dynamic memory buffers */
|
||||
|
||||
static void init()
|
||||
static void init(void)
|
||||
{
|
||||
char *ptr;
|
||||
|
||||
initDynString(&gstr.pCCSRC);
|
||||
initDynString(&gstr.pCXSRC);
|
||||
initDynString(&gstr.pOBJ);
|
||||
@@ -118,9 +122,17 @@ static void init()
|
||||
initDynString(&gstr.pOUT);
|
||||
initDynString(&gstr.pMINGW);
|
||||
initDynString(&gstr.pIVL);
|
||||
initDynString(&gstr.pCFLAGS);
|
||||
initDynString(&gstr.pCCFLAGS);
|
||||
initDynString(&gstr.pCXFLAGS);
|
||||
initDynString(&gstr.pLDLIBS);
|
||||
initDynString(&gstr.pNewPath);
|
||||
initDynString(&gstr.pCCNAME);
|
||||
initDynString(&gstr.pLD);
|
||||
|
||||
/* Get the base name of the C compiler. */
|
||||
assign(&gstr.pCCNAME, IVERILOG_VPI_CC);
|
||||
ptr = strchr(gstr.pCCNAME, ' ');
|
||||
if (ptr != NULL) *ptr = '\0';
|
||||
|
||||
/* By default use the C compiler to link the programs. */
|
||||
assign(&gstr.pLD, IVERILOG_VPI_CC);
|
||||
}
|
||||
@@ -136,7 +148,7 @@ static int endsIn (char *end, char *str)
|
||||
|
||||
ext = str + (strlen(str) - strlen(end));
|
||||
|
||||
return stricmp(end,ext) ? 0 : 1;
|
||||
return stricmp(end, ext) ? 0 : 1;
|
||||
}
|
||||
|
||||
/* return true if "str" begins with "prefix", case insensitive */
|
||||
@@ -146,35 +158,35 @@ static int startsWith (char *prefix, char *str)
|
||||
if (strlen(prefix) >= strlen(str))
|
||||
return 0;
|
||||
|
||||
return strnicmp(prefix,str,strlen(prefix)) ? 0 : 1;
|
||||
return strnicmp(prefix, str, strlen(prefix)) ? 0 : 1;
|
||||
}
|
||||
|
||||
/* 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, int count)
|
||||
static void appendn (char **ptr, char *app, size_t count)
|
||||
{
|
||||
char *nptr = (char *) realloc(*ptr, strlen(*ptr) +
|
||||
(count?count:strlen(app)) + 1);
|
||||
(count ? count : strlen(app)) + 1);
|
||||
|
||||
if (nptr == NULL) {
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
free(*ptr);
|
||||
myExit(4);
|
||||
}
|
||||
*ptr = nptr;
|
||||
|
||||
if (count)
|
||||
strncat(*ptr,app,count);
|
||||
strncat(*ptr, app, count);
|
||||
else
|
||||
strcat(*ptr,app);
|
||||
strcat(*ptr, app);
|
||||
}
|
||||
|
||||
/* append "app" to "ptr", allocating memory as needed */
|
||||
|
||||
static void append (char **ptr, char *app)
|
||||
{
|
||||
appendn(ptr,app,0);
|
||||
appendn(ptr, app, 0);
|
||||
}
|
||||
|
||||
/* if the string does not end with a backslash, add one */
|
||||
@@ -182,36 +194,36 @@ static void append (char **ptr, char *app)
|
||||
static void appendBackSlash(char **str)
|
||||
{
|
||||
if ((*str)[strlen(*str)-1] != '\\')
|
||||
append(str,"\\");
|
||||
append(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, int count)
|
||||
static void assignn (char **ptr, char *str, size_t count)
|
||||
{
|
||||
char *nptr = (char *) realloc(*ptr, (count?count:strlen(str)) + 1);
|
||||
char *nptr = (char *) realloc(*ptr, (count ? count : strlen(str)) + 1);
|
||||
|
||||
if (nptr == NULL) {
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
free(*ptr);
|
||||
myExit(4);
|
||||
}
|
||||
*ptr = nptr;
|
||||
|
||||
if (count) {
|
||||
strncpy(*ptr,str,count);
|
||||
strncpy(*ptr, str, count);
|
||||
(*ptr)[count] = 0;
|
||||
}
|
||||
else
|
||||
strcpy(*ptr,str);
|
||||
strcpy(*ptr, str);
|
||||
}
|
||||
|
||||
/* copy count characters of "str" to "ptr", allocating memory as needed */
|
||||
|
||||
static void assign (char **ptr, char *str)
|
||||
{
|
||||
assignn(ptr,str,0);
|
||||
assignn(ptr, str, 0);
|
||||
}
|
||||
|
||||
/* get a copy of a Icarus Verilog registry string key */
|
||||
@@ -223,11 +235,11 @@ static int GetRegistryKey(char *key, char **value)
|
||||
char *regKeyBuffer;
|
||||
DWORD regKeyType, regKeySize;
|
||||
|
||||
lrv = RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software\\Icarus Verilog",0,KEY_QUERY_VALUE,&hkKey);
|
||||
lrv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Icarus Verilog", 0, KEY_QUERY_VALUE, &hkKey);
|
||||
if (lrv != ERROR_SUCCESS)
|
||||
return 0;
|
||||
|
||||
lrv = RegQueryValueEx(hkKey,key,NULL,®KeyType,NULL,®KeySize);
|
||||
lrv = RegQueryValueEx(hkKey, key, NULL, ®KeyType, NULL, ®KeySize);
|
||||
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
|
||||
lrv = RegCloseKey(hkKey);
|
||||
return 0;
|
||||
@@ -236,7 +248,7 @@ static int GetRegistryKey(char *key, char **value)
|
||||
regKeyBuffer = (char *) malloc(regKeySize+1);
|
||||
if (!regKeyBuffer) {
|
||||
lrv = RegCloseKey(hkKey);
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
fprintf(stderr, "error: out of memory\n");
|
||||
myExit(4);
|
||||
}
|
||||
regKeyBuffer[regKeySize] = 0; /* makes sure there is a trailing NULL */
|
||||
@@ -252,7 +264,7 @@ static int GetRegistryKey(char *key, char **value)
|
||||
|
||||
RegCloseKey(hkKey);
|
||||
|
||||
assign(value,regKeyBuffer);
|
||||
assign(value, regKeyBuffer);
|
||||
free(regKeyBuffer);
|
||||
|
||||
return 1;
|
||||
@@ -262,27 +274,30 @@ static int GetRegistryKey(char *key, char **value)
|
||||
|
||||
static void SetRegistryKey(char *key, char *value)
|
||||
{
|
||||
long lrv;
|
||||
HKEY hkKey;
|
||||
DWORD res;
|
||||
|
||||
if (RegCreateKeyEx(
|
||||
HKEY_LOCAL_MACHINE,
|
||||
"Software\\Icarus Verilog",
|
||||
0,
|
||||
"",
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
KEY_ALL_ACCESS,NULL,
|
||||
&hkKey,
|
||||
&res) != ERROR_SUCCESS)
|
||||
return;
|
||||
lrv = RegCreateKeyEx(HKEY_LOCAL_MACHINE, "Software\\Icarus Verilog", 0, "",
|
||||
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkKey, &res);
|
||||
if (lrv != ERROR_SUCCESS) {
|
||||
char message[1024];
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, lrv, LANG_USER_DEFAULT,
|
||||
message, sizeof(message), NULL);
|
||||
fprintf(stderr, "error: couldn't write to registry - %s\n", message);
|
||||
if (lrv == ERROR_ACCESS_DENIED) {
|
||||
fprintf(stderr, " try running as administrator\n");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* This needs an unsigned char *, but for MinGW the char is signed. */
|
||||
RegSetValueEx(hkKey, key, 0, REG_SZ, (unsigned char *) value,
|
||||
strlen(value)+1);
|
||||
RegCloseKey(hkKey);
|
||||
|
||||
printf("info: storing %s in Windows' registry entry\n",value);
|
||||
printf(" HKEY_LOCAL_MACHINE\\Software\\Icarus Verilog\\%s\n",key);
|
||||
printf("info: storing %s in Windows' registry entry\n", value);
|
||||
printf(" HKEY_LOCAL_MACHINE\\Software\\Icarus Verilog\\%s\n", key);
|
||||
}
|
||||
|
||||
/* parse the command line, assign results to global variable strings */
|
||||
@@ -299,7 +314,6 @@ static int parse(int argc, char *argv[])
|
||||
char lib_option[] = "-l";
|
||||
char inc_option[] = "-I";
|
||||
char mingw_option[] = "-mingw=";
|
||||
char ivl_option[] = "-ivl=";
|
||||
char def_option[] = "-D";
|
||||
|
||||
if (argc == 1) return 0;
|
||||
@@ -339,7 +353,7 @@ static int parse(int argc, char *argv[])
|
||||
/* Check for compiled object files */
|
||||
else if (endsIn(dot_o_ext, argv[idx])) {
|
||||
++srcFileCnt;
|
||||
append(&gstr.pOBJ," ");
|
||||
append(&gstr.pOBJ, " ");
|
||||
append(&gstr.pOBJ, argv[idx]);
|
||||
if (!*gstr.pOUT)
|
||||
assignn(&gstr.pOUT, argv[idx],
|
||||
@@ -349,10 +363,6 @@ static int parse(int argc, char *argv[])
|
||||
else if (startsWith(mingw_option, argv[idx]))
|
||||
assignn(&gstr.pMINGW, argv[idx]+sizeof(mingw_option)-1,
|
||||
strlen(argv[idx])-(sizeof(mingw_option)-1));
|
||||
/* Check for the -ivl option */
|
||||
else if (startsWith(ivl_option, argv[idx]))
|
||||
assignn(&gstr.pIVL, argv[idx]+sizeof(ivl_option)-1,
|
||||
strlen(argv[idx])-(sizeof(ivl_option)-1));
|
||||
/* Check for the --name option */
|
||||
else if (startsWith(name_option, argv[idx])) {
|
||||
assignn(&gstr.pOUT, argv[idx]+sizeof(name_option)-1,
|
||||
@@ -376,7 +386,7 @@ static int parse(int argc, char *argv[])
|
||||
/* Check for the --cflags option */
|
||||
else if (stricmp("--cflags", argv[idx]) == 0) {
|
||||
setup_ivl_environment();
|
||||
printf("%s\n", gstr.pCFLAGS);
|
||||
printf("%s\n", gstr.pCCFLAGS);
|
||||
myExit(0);
|
||||
}
|
||||
/* Check for the --ldflags option */
|
||||
@@ -393,7 +403,7 @@ static int parse(int argc, char *argv[])
|
||||
/* Check for the --install-dir option */
|
||||
else if (stricmp("--install-dir", argv[idx]) == 0) {
|
||||
setup_ivl_environment();
|
||||
printf("%s\\\\lib\\\\ivl" IVERILOG_SUFFIX "\\\\.\n", gstr.pIVL);
|
||||
printf("%s\\lib\\ivl" IVERILOG_SUFFIX "\\.\n", gstr.pIVL);
|
||||
myExit(0);
|
||||
}
|
||||
/* This is different than iverilog-vpi.sh, we don't
|
||||
@@ -402,15 +412,16 @@ static int parse(int argc, char *argv[])
|
||||
}
|
||||
|
||||
/* In case there is a --name without source/object files */
|
||||
if (0 == srcFileCnt) assign(&gstr.pOUT,"");
|
||||
if (0 == srcFileCnt) assign(&gstr.pOUT, "");
|
||||
|
||||
/* Normally it's an error if there are no source or object files */
|
||||
/* Unless we are setting the IVL or MinGW registry entries */
|
||||
if (!*gstr.pOUT) {
|
||||
if (!*gstr.pMINGW && !*gstr.pIVL) return 0;
|
||||
} else
|
||||
if (*gstr.pOUT) {
|
||||
/* We have a valid result file so add the .vpi extension */
|
||||
append(&gstr.pOUT, ".vpi");
|
||||
} else {
|
||||
/* Unless we are setting the MinGW registry entry, it's
|
||||
an error if there are no source or object files */
|
||||
if (!*gstr.pMINGW) return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -421,58 +432,27 @@ static void checkMingwDir(char *root)
|
||||
{
|
||||
int irv;
|
||||
struct _stat stat_buf;
|
||||
|
||||
char *path, *comp, *cp;
|
||||
initDynString(&path);
|
||||
assign(&path,gstr.pMINGW);
|
||||
appendBackSlash(&path);
|
||||
append(&path,"bin\\");
|
||||
/* Get just the compiler name (the first word) */
|
||||
comp = strdup(IVERILOG_VPI_CC);
|
||||
cp = strchr(comp, ' ');
|
||||
if (cp != NULL) *cp = '\0';
|
||||
append(&path, comp);
|
||||
append(&path,".exe");
|
||||
free(comp);
|
||||
|
||||
irv = _stat(path,&stat_buf);
|
||||
deInitDynString(path);
|
||||
|
||||
if (irv) {
|
||||
fprintf(stderr,"error: %s does not appear to be the valid root directory\n",root);
|
||||
fprintf(stderr," of MinGW. Use the -mingw option of iverilog-vpi.exe to\n");
|
||||
fprintf(stderr," point to the MinGW root directory. For a Windows command\n");
|
||||
fprintf(stderr," shell the option would be something like -mingw=c:\\mingw\n");
|
||||
fprintf(stderr," For a Cygwin shell the option would be something like\n");
|
||||
fprintf(stderr," -mingw=c:\\\\mingw\n");
|
||||
myExit(5);
|
||||
}
|
||||
}
|
||||
|
||||
/* do minimal check that the Icarus Verilog root directory looks valid */
|
||||
|
||||
static void checkIvlDir(char *root)
|
||||
{
|
||||
int irv;
|
||||
struct _stat stat_buf;
|
||||
|
||||
char *path;
|
||||
|
||||
initDynString(&path);
|
||||
assign(&path,gstr.pIVL);
|
||||
assign(&path, gstr.pMINGW);
|
||||
appendBackSlash(&path);
|
||||
append(&path,"bin\\vvp" IVERILOG_SUFFIX ".exe");
|
||||
append(&path, "bin\\");
|
||||
append(&path, gstr.pCCNAME);
|
||||
append(&path, ".exe");
|
||||
|
||||
irv = _stat(path,&stat_buf);
|
||||
deInitDynString(path);
|
||||
|
||||
if (irv) {
|
||||
fprintf(stderr,"error: %s does not appear to be the valid root directory of\n",root);
|
||||
fprintf(stderr," Icarus Verilog. Use the -ivl option of iverilog-vpi" IVERILOG_SUFFIX " to\n");
|
||||
fprintf(stderr," point to the Icarus Verilog root directory. For a Windows\n");
|
||||
fprintf(stderr," command shell the option would be something like -ivl=c:\\iverilog\n");
|
||||
fprintf(stderr," For a Cygwin shell the option would be something like\n");
|
||||
fprintf(stderr," -ivl=c:\\\\iverilog\n");
|
||||
myExit(6);
|
||||
fprintf(stderr, "error: %s\n", root);
|
||||
fprintf(stderr, " does not appear to be the valid root directory of\n");
|
||||
fprintf(stderr, " MinGW. Use the -mingw option of iverilog-vpi.exe to\n");
|
||||
fprintf(stderr, " point to the MinGW root directory. For a Windows command\n");
|
||||
fprintf(stderr, " shell the option would be something like -mingw=c:\\mingw\n");
|
||||
fprintf(stderr, " For a Cygwin shell the option would be something like\n");
|
||||
fprintf(stderr, " -mingw=c:\\\\mingw\n");
|
||||
myExit(5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -480,68 +460,98 @@ static void checkIvlDir(char *root)
|
||||
|
||||
#define IVL_REGKEY_MINGW "MingwDir"
|
||||
|
||||
static void setup_mingw_environment()
|
||||
static void setup_mingw_environment(void)
|
||||
{
|
||||
char *pOldPATH = getenv("PATH"); /* get current path */
|
||||
char buffer[1]; /* doesn't matter how big this is, as we don't use the result */
|
||||
char *path;
|
||||
|
||||
if (*gstr.pMINGW) {
|
||||
checkMingwDir(gstr.pMINGW);
|
||||
SetRegistryKey(IVL_REGKEY_MINGW,gstr.pMINGW);
|
||||
} else if (!GetRegistryKey(IVL_REGKEY_MINGW,&gstr.pMINGW)) {
|
||||
fprintf(stderr,"error: can not locate the MinGW root directory, use the -mingw option of\n");
|
||||
fprintf(stderr," iverilog-vpi.exe to point to the MinGW root directory. For\n");
|
||||
fprintf(stderr," a Windows command shell the option would be something like\n");
|
||||
fprintf(stderr," -mingw=c:\\mingw For a Cygwin shell the option would be\n");
|
||||
fprintf(stderr," something like -mingw=c:\\\\mingw\n");
|
||||
myExit(5);
|
||||
}
|
||||
if (!*gstr.pOUT) SetRegistryKey(IVL_REGKEY_MINGW, gstr.pMINGW);
|
||||
|
||||
} else if (GetRegistryKey(IVL_REGKEY_MINGW, &gstr.pMINGW)) {
|
||||
checkMingwDir(gstr.pMINGW);
|
||||
|
||||
} else if (SearchPath(NULL, gstr.pCCNAME, ".exe", sizeof(buffer), buffer, NULL)) {
|
||||
return;
|
||||
|
||||
} else {
|
||||
fprintf(stderr, "error: cannot locate the MinGW C compiler - either add its location\n");
|
||||
fprintf(stderr, " to the PATH environment variable or use the -mingw option of\n");
|
||||
fprintf(stderr, " iverilog-vpi.exe to point to the MinGW root directory. For\n");
|
||||
fprintf(stderr, " a Windows command shell the option would be something like\n");
|
||||
fprintf(stderr, " -mingw=c:\\mingw For a Cygwin shell the option would be\n");
|
||||
fprintf(stderr, " something like -mingw=c:\\\\mingw\n");
|
||||
myExit(5);
|
||||
}
|
||||
|
||||
/* Create new path with MinGW in it */
|
||||
assign(&gstr.pNewPath,"PATH=");
|
||||
append(&gstr.pNewPath,gstr.pMINGW);
|
||||
appendBackSlash(&gstr.pNewPath);
|
||||
append(&gstr.pNewPath, "\\");
|
||||
append(&gstr.pNewPath,"bin;");
|
||||
append(&gstr.pNewPath,pOldPATH);
|
||||
initDynString(&path);
|
||||
assign(&path, "PATH=");
|
||||
append(&path, gstr.pMINGW);
|
||||
appendBackSlash(&path);
|
||||
append(&path, "bin;");
|
||||
append(&path, getenv("PATH"));
|
||||
|
||||
/* Place new path in environment */
|
||||
_putenv(gstr.pNewPath);
|
||||
_putenv(path);
|
||||
deInitDynString(path);
|
||||
}
|
||||
|
||||
/* see if we can find iverilog root */
|
||||
/* find the iverilog root and initialise the compiler options */
|
||||
|
||||
#define IVL_REGKEY_IVL "InstallDir"
|
||||
|
||||
static void setup_ivl_environment()
|
||||
static void setup_ivl_environment(void)
|
||||
{
|
||||
if (*gstr.pIVL) {
|
||||
checkIvlDir(gstr.pIVL);
|
||||
SetRegistryKey(IVL_REGKEY_IVL,gstr.pIVL);
|
||||
} else if (!GetRegistryKey(IVL_REGKEY_IVL,&gstr.pIVL)) {
|
||||
fprintf(stderr,"error: can not locate the Icarus Verilog root directory, use the -ivl option\n");
|
||||
fprintf(stderr," of iverilog-vpi" IVERILOG_SUFFIX " to point to the Icarus Verilog root directory.\n");
|
||||
fprintf(stderr," For a Windows command shell the option would be something like\n");
|
||||
fprintf(stderr," -ivl=c:\\iverilog For a Cygwin shell the option would be something\n");
|
||||
fprintf(stderr," like -ivl=c:\\\\iverilog\n");
|
||||
myExit(6);
|
||||
}
|
||||
char path[4096];
|
||||
char *ptr;
|
||||
|
||||
/* Build up the CFLAGS option string */
|
||||
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS " -I\"");
|
||||
append(&gstr.pCFLAGS,gstr.pIVL);
|
||||
appendBackSlash(&gstr.pCFLAGS);
|
||||
append(&gstr.pCFLAGS,"\\include\\\\iverilog\"" IVERILOG_SUFFIX);
|
||||
/* Extract the Icarus Verilog root directory from the path to the
|
||||
command. The command path will look something like this:
|
||||
|
||||
C:\iverilog\bin\iverilog-vpi.exe
|
||||
|
||||
The corresponding root directory is
|
||||
|
||||
C:\iverilog
|
||||
|
||||
so we chop off the file name and the last directory. */
|
||||
GetModuleFileName(NULL, path, sizeof(path));
|
||||
ptr = strrchr(path, '\\');
|
||||
if (!ptr) {
|
||||
fprintf(stderr, "error: couldn't find start of program name in command path '%s'\n", path);
|
||||
myExit(6);
|
||||
}
|
||||
*ptr = 0;
|
||||
ptr = strrchr(path, '\\');
|
||||
if (!ptr) {
|
||||
fprintf(stderr, "error: couldn't find start of bin directory in command path '%s'\n", path);
|
||||
myExit(6);
|
||||
}
|
||||
*ptr = 0;
|
||||
assign(&gstr.pIVL, path);
|
||||
|
||||
/* Build up the CCFLAGS option string */
|
||||
assign(&gstr.pCCFLAGS, IVERILOG_VPI_CFLAGS " -I\"");
|
||||
append(&gstr.pCCFLAGS, gstr.pIVL);
|
||||
appendBackSlash(&gstr.pCCFLAGS);
|
||||
append(&gstr.pCCFLAGS, "include\\iverilog\"" IVERILOG_SUFFIX);
|
||||
|
||||
/* Build up the CXFLAGS option string */
|
||||
assign(&gstr.pCXFLAGS, IVERILOG_VPI_CXXFLAGS " -I\"");
|
||||
append(&gstr.pCXFLAGS, gstr.pIVL);
|
||||
appendBackSlash(&gstr.pCXFLAGS);
|
||||
append(&gstr.pCXFLAGS, "include\\iverilog\"" IVERILOG_SUFFIX);
|
||||
|
||||
/* Build up the LDFLAGS option string */
|
||||
assign(&gstr.pLDLIBS,"-L\"");
|
||||
append(&gstr.pLDLIBS,gstr.pIVL);
|
||||
assign(&gstr.pLDLIBS, "-L\"");
|
||||
append(&gstr.pLDLIBS, gstr.pIVL);
|
||||
appendBackSlash(&gstr.pLDLIBS);
|
||||
append(&gstr.pLDLIBS,"\\lib\" " IVERILOG_VPI_LDLIBS);
|
||||
append(&gstr.pLDLIBS, "lib\" " IVERILOG_VPI_LDLIBS);
|
||||
}
|
||||
|
||||
/* compile source modules */
|
||||
|
||||
static void compile(char *pSource, char **pObject, int *compile_errors, char *compiler)
|
||||
static void compile(char *pSource, char *pFlags, char **pObject, int *compile_errors, char *compiler)
|
||||
{
|
||||
char *ptr1 = pSource;
|
||||
char *ptr2 = strchr(ptr1, ' ');
|
||||
@@ -568,7 +578,7 @@ static void compile(char *pSource, char **pObject, int *compile_errors, char *co
|
||||
append(&buf, " ");
|
||||
append(&buf, gstr.pDEFS);
|
||||
append(&buf, " ");
|
||||
append(&buf, gstr.pCFLAGS);
|
||||
append(&buf, pFlags);
|
||||
append(&buf, " ");
|
||||
append(&buf, gstr.pINCS);
|
||||
append(&buf, " ");
|
||||
@@ -593,27 +603,22 @@ static void compile(char *pSource, char **pObject, int *compile_errors, char *co
|
||||
|
||||
/* using the global strings, compile and link */
|
||||
|
||||
static void compile_and_link()
|
||||
static void compile_and_link(void)
|
||||
{
|
||||
char *buf=0;
|
||||
int iRet, compile_errors = 0;
|
||||
|
||||
/* To make the output match iverilog-vpi.sh do not print out the
|
||||
* root directories */
|
||||
|
||||
// printf("MinGW root directory: %s.\n", gstr.pMINGW);
|
||||
checkMingwDir(gstr.pMINGW);
|
||||
|
||||
// printf("Icarus Verilog root directory: %s.\n", gstr.pIVL);
|
||||
checkIvlDir(gstr.pIVL);
|
||||
|
||||
/* compile the C source files (*.c) */
|
||||
compile(gstr.pCCSRC, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CC );
|
||||
compile(gstr.pCCSRC, gstr.pCCFLAGS, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CC );
|
||||
/* compile the C++ source files (*.cc, *.cpp) */
|
||||
compile(gstr.pCXSRC, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CXX);
|
||||
compile(gstr.pCXSRC, gstr.pCXFLAGS, &gstr.pOBJ, &compile_errors, IVERILOG_VPI_CXX);
|
||||
|
||||
if (compile_errors) {
|
||||
fprintf(stderr,"iverilog-vpi: %d file(s) failed to compile.\n",
|
||||
fprintf(stderr, "iverilog-vpi: %d file(s) failed to compile.\n",
|
||||
compile_errors);
|
||||
myExit(2);
|
||||
}
|
||||
@@ -644,7 +649,7 @@ int main(int argc, char *argv[])
|
||||
{
|
||||
init();
|
||||
|
||||
if (!parse(argc,argv)) usage();
|
||||
if (!parse(argc, argv)) usage();
|
||||
|
||||
setup_mingw_environment();
|
||||
setup_ivl_environment();
|
||||
|
||||
+6
-2
@@ -49,7 +49,7 @@ INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
|
||||
endif
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
O = main.o substit.o cflexor.o cfparse.o
|
||||
@@ -67,7 +67,11 @@ distclean: clean
|
||||
rm -f Makefile config.log
|
||||
|
||||
cppcheck: $(O:.o=.c)
|
||||
cppcheck --enable=all -f $(INCLUDE_PATH) $^
|
||||
cppcheck --enable=all -f \
|
||||
-UYY_USER_INIT \
|
||||
-UYYPARSE_PARAM -UYYPRINT -Ushort -Uyyoverflow \
|
||||
-UYYTYPE_INT8 -UYYTYPE_INT16 -UYYTYPE_UINT8 -UYYTYPE_UINT16 \
|
||||
$(INCLUDE_PATH) $^
|
||||
|
||||
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||
cd ..; ./config.status --file=driver/$@
|
||||
|
||||
+6
-3
@@ -4,7 +4,7 @@
|
||||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2001-2009 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001-2016 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
|
||||
@@ -92,6 +92,8 @@ int cmdfile_stack_ptr = 0;
|
||||
|
||||
"+vhdl-libdir+" { BEGIN(PLUS_ARGS); return TOK_VHDL_LIBDIR; }
|
||||
|
||||
"+width-cap+" { BEGIN(PLUS_ARGS); return TOK_WIDTH_CAP; }
|
||||
|
||||
/* If it is not any known plus-flag, return the generic form. */
|
||||
"+"[^\n \t\b\f\r+]* {
|
||||
cflval.text = strdup(yytext);
|
||||
@@ -122,7 +124,8 @@ int cmdfile_stack_ptr = 0;
|
||||
"-c" { return TOK_Dc; }
|
||||
"-f" { return TOK_Dc; }
|
||||
|
||||
/* Notice the -v flag. */
|
||||
/* Notice the -l or -v flag. */
|
||||
"-l" { return TOK_Dv; }
|
||||
"-v" { return TOK_Dv; }
|
||||
|
||||
/* Notice the -y flag. */
|
||||
@@ -245,7 +248,7 @@ void cfreset(FILE*fd, const char*path)
|
||||
/*
|
||||
* Modern version of flex (>=2.5.9) can clean up the scanner data.
|
||||
*/
|
||||
void destroy_lexor()
|
||||
void destroy_lexor(void)
|
||||
{
|
||||
# ifdef FLEX_SCANNER
|
||||
# if YY_FLEX_MAJOR_VERSION >= 2 && YY_FLEX_MINOR_VERSION >= 5
|
||||
|
||||
+11
-2
@@ -1,6 +1,6 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2001-2011 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2001-2014 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
|
||||
@@ -61,6 +61,7 @@ static void translate_file_name(char*text)
|
||||
%token TOK_Da TOK_Dc TOK_Dv TOK_Dy
|
||||
%token TOK_DEFINE TOK_INCDIR TOK_INTEGER_WIDTH TOK_LIBDIR TOK_LIBDIR_NOCASE
|
||||
%token TOK_LIBEXT TOK_PARAMETER TOK_TIMESCALE TOK_VHDL_WORK TOK_VHDL_LIBDIR
|
||||
%token TOK_WIDTH_CAP
|
||||
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
|
||||
|
||||
%%
|
||||
@@ -191,6 +192,13 @@ item
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
| TOK_WIDTH_CAP TOK_PLUSARG
|
||||
{ char*tmp = substitutions($2);
|
||||
free($2);
|
||||
width_cap = strtoul(tmp,0,10);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* The +<word> tokens that are not otherwise matched, are
|
||||
ignored. The skip_args rule arranges for all the argument words
|
||||
to be consumed. */
|
||||
@@ -213,7 +221,7 @@ item
|
||||
}
|
||||
|
||||
| error
|
||||
{ fprintf(stderr, "Error: unable to parse line %d in "
|
||||
{ fprintf(stderr, "Error: unable to parse line %u in "
|
||||
"%s.\n", cflloc.first_line, current_file);
|
||||
return 1;
|
||||
}
|
||||
@@ -262,5 +270,6 @@ skip_arg : TOK_PLUSARG
|
||||
|
||||
int yyerror(const char*msg)
|
||||
{
|
||||
(void)msg; /* Parameter is not used. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __cfparse_misc_H
|
||||
#define __cfparse_misc_H
|
||||
#ifndef IVL_cfparse_misc_H
|
||||
#define IVL_cfparse_misc_H
|
||||
/*
|
||||
* Copyright (c) 2001-2009 Picture Elements, Inc.
|
||||
* Copyright (c) 2001-2014 Picture Elements, Inc.
|
||||
* Stephen Williams (steve@picturel.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -38,7 +38,7 @@ int cflex(void);
|
||||
int cferror(const char *);
|
||||
int cfparse(void);
|
||||
void switch_to_command_file(const char *);
|
||||
void destroy_lexor();
|
||||
void destroy_lexor(void);
|
||||
char *current_file;
|
||||
|
||||
#endif
|
||||
#endif /* IVL_cfparse_misc_H */
|
||||
|
||||
+7
-4
@@ -1,7 +1,7 @@
|
||||
#ifndef __globals_H
|
||||
#define __globals_H
|
||||
#ifndef IVL_globals_H
|
||||
#define IVL_globals_H
|
||||
/*
|
||||
* Copyright (c) 2000-2009 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-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
|
||||
@@ -24,6 +24,9 @@
|
||||
/* This is the integer-width argument that will be passed to ivl. */
|
||||
extern unsigned integer_width;
|
||||
|
||||
/* This is the width-cap argument that will be passed to ivl. */
|
||||
extern unsigned width_cap;
|
||||
|
||||
extern const char*vhdlpp_work;
|
||||
extern const char**vhdlpp_libdir;
|
||||
extern unsigned vhdlpp_libdir_cnt;
|
||||
@@ -51,4 +54,4 @@ extern void process_parameter(const char*name);
|
||||
/* Set the default timescale for the simulator. */
|
||||
extern void process_timescale(const char*ts_string);
|
||||
|
||||
#endif
|
||||
#endif /* IVL_globals_H */
|
||||
|
||||
+59
-12
@@ -1,14 +1,15 @@
|
||||
.TH iverilog 1 "February 27th, 2011" "" "Version %M.%m.%n %E"
|
||||
.TH iverilog 1 "Oct 2nd, 2016" "" "Version %M.%n%E"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog
|
||||
[\-ESVv] [\-Bpath] [\-ccmdfile|\-fcmdfile] [\-Dmacro[=defn]]
|
||||
[\-Pparameter=value] [\-pflag=value]
|
||||
[\-dname] [\-g1995|\-g2001|\-g2005|\-g2005-sv|\-g2009|\-g<feature>]
|
||||
[\-Pparameter=value] [\-pflag=value] [\-dname]
|
||||
[\-g1995\:|\-g2001\:|\-g2005\:|\-g2005-sv\:|\-g2009\:|\-g2012\:|\-g<feature>]
|
||||
[\-Iincludedir] [\-mmodule] [\-M[mode=]file] [\-Nfile] [\-ooutputfilename]
|
||||
[\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass] [\-ypath] sourcefile
|
||||
[\-stopmodule] [\-ttype] [\-Tmin/typ/max] [\-Wclass] [\-ypath] [\-lfile]
|
||||
sourcefile
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
@@ -30,7 +31,7 @@ different set of programs. The path given is used to locate
|
||||
\fIivlpp\fP, \fIivl\fP, code generators and the VPI modules.
|
||||
.TP 8
|
||||
.B -c\fIfile\fP -f\fIfile\fP
|
||||
These flags specifies an input file that contains a list of Verilog
|
||||
These flags specify an input file that contains a list of Verilog
|
||||
source files. This is similar to the \fIcommand file\fP of other
|
||||
Verilog simulators, in that it is a file that contains the file names
|
||||
instead of taking them on the command line. See \fBCommand Files\fP below.
|
||||
@@ -61,10 +62,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
|
||||
.B -g1995\fI|\fP-g2001\fI|\fP-g2001-noconfig\fI|\fP-g2005\fI|\fP-g2005-sv\fI|\fP-g2009\fI|\fP-g2012
|
||||
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, or \fIIEEE1800\-2009\fP.
|
||||
\fIIEEE1364\-2005\fP, \fIIEEE1800\-2005\fP, \fIIEEE1800\-2009\fP, or
|
||||
\fIIEEE1800\-2012\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
|
||||
@@ -128,7 +130,20 @@ standard compliant behavior (with some loss in performance).
|
||||
.B -gstrict-expr-width\fI|\fP-gno-strict-expr-width
|
||||
Enable or disable (default) strict compliance with the standard rules
|
||||
for determining expression bit lengths. When disabled, the RHS of a
|
||||
parameter assignment is evaluated as a lossless expression.
|
||||
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 -gshared-loop-index\fI|\fP-gno-shared-loop-index
|
||||
Enable or disable (default) the exclusion of for-loop control variables
|
||||
from implicit event_expression lists. When enabled, if a for-loop control
|
||||
variable (loop index) is only used inside the for-loop statement, the
|
||||
compiler will not include it in an implicit event_expression list it
|
||||
calculates for that statement or any enclosing statement. This allows
|
||||
the same control variable to be used in multiple processes without risk
|
||||
of entering an infinite loop caused by each process triggering all other
|
||||
processes that use the same varaible. For strict compliance with the
|
||||
standards, this behaviour should be disabled.
|
||||
.TP 8
|
||||
.B -I\fIincludedir\fP
|
||||
Append directory \fIincludedir\fP to list of directories searched
|
||||
@@ -136,6 +151,12 @@ for Verilog include files. The \fB\-I\fP switch may be used many times
|
||||
to specify several directories to search, the directories are searched
|
||||
in the order they appear on the command line.
|
||||
.TP 8
|
||||
.B -l\fIfile\fP
|
||||
Add the specified file to the list of source files to be compiled,
|
||||
but mark it as a library file. All modules contained within that
|
||||
file will be treated as library modules, and only elaborated if
|
||||
they are instantiated by other modules in the design.
|
||||
.TP 8
|
||||
.B -M\fIpath\fP
|
||||
This is equivalent to \fB\-Mall=path\fP. Preserved for backwards
|
||||
compatibility.
|
||||
@@ -210,6 +231,12 @@ a reference to a key temporary file that passes information to the
|
||||
compiler proper. To keep that file from being deleted at the end
|
||||
of the process, provide a file name of your own in the environment
|
||||
variable \fBIVERILOG_ICONFIG\fP.
|
||||
|
||||
If the selected target is \fIvvp\fP, the \fB\-v\fP switch is appended
|
||||
to the shebang line in the compiler output file, so directly executing
|
||||
the compiler output file will turn on verbose messages in \fIvvp\fP.
|
||||
This extra verbosity can be avoided by using the \fIvvp\fP command to
|
||||
indirectly execute the compiler output file.
|
||||
.TP 8
|
||||
.B -V
|
||||
Print the version of the compiler, and exit.
|
||||
@@ -283,8 +310,13 @@ after a \fB\-Wall\fP argument to suppress isolated warning types.
|
||||
|
||||
.TP 8
|
||||
.B all
|
||||
This enables the implicit, portbind, select\-range, timescale, and
|
||||
sensitivity\-entire\-array warning categories.
|
||||
This enables the anachronisms, implicit, portbind, select\-range,
|
||||
timescale, and sensitivity\-entire\-array warning categories.
|
||||
|
||||
.TP 8
|
||||
.B anachronisms
|
||||
This enables warnings for use of features that have been deprecated
|
||||
or removed in the selected generation of the Verilog language.
|
||||
|
||||
.TP 8
|
||||
.B implicit
|
||||
@@ -388,6 +420,15 @@ A \fB\-c\fP or \fB\-f\fP token prefixes a command file, exactly like it
|
||||
does on the command line. The cmdfile may be on the same line or the
|
||||
next non-comment line.
|
||||
|
||||
.TP 8
|
||||
.B -l\ \fIfile\fP -v\ \fIfile\fP
|
||||
A \fB\-l\fP token prefixes a library file in the command file,
|
||||
exactly like it does on the command line. The parameter to the \fB\-l\fP
|
||||
flag may be on the same line or the next non-comment line. \fB\-v\fP is
|
||||
an alias for \fB\-l\fP, provided for compatibility with other simulators.
|
||||
|
||||
Variables in the \fIfile\fP are substituted.
|
||||
|
||||
.TP 8
|
||||
.B -y\ \fIlibdir\fP
|
||||
A \fB\-y\fP token prefixes a library directory in the command file,
|
||||
@@ -459,6 +500,12 @@ This allows the programmer to select the width for integer variables
|
||||
in the Verilog source. The default is 32, the value can be any desired
|
||||
integer value.
|
||||
|
||||
.TP 8
|
||||
.B +width-cap+\fIvalue\fP
|
||||
This allows the programmer to select the width cap for unsized expressions.
|
||||
If the calculated width for an unsized expression exceeds this value, the
|
||||
compiler will issue a warning and limit the expression width to this value.
|
||||
|
||||
.SH "VARIABLES IN COMMAND FILES"
|
||||
|
||||
In certain cases, iverilog supports variables in command files. These
|
||||
@@ -505,14 +552,14 @@ Steve Williams ([email protected])
|
||||
|
||||
.SH SEE ALSO
|
||||
vvp(1),
|
||||
.BR "<http://www.icarus.com/eda/verilog/>"
|
||||
.BR "<http://iverilog.icarus.com/>"
|
||||
|
||||
Tips on using, debugging, and developing the compiler can be found at
|
||||
.BR "<http://iverilog.wikia.com/>"
|
||||
|
||||
.SH COPYRIGHT
|
||||
.nf
|
||||
Copyright \(co 2002\-2011 Stephen Williams
|
||||
Copyright \(co 2002\-2016 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
|
||||
+62
-27
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2016 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
|
||||
@@ -39,12 +39,12 @@ const char NOTICE[] =
|
||||
|
||||
const char HELP[] =
|
||||
"Usage: iverilog [-ESvV] [-B base] [-c cmdfile|-f cmdfile]\n"
|
||||
" [-g1995|-g2001|-g2005|-g2005-sv|-g2009] [-g<feature>]\n"
|
||||
" [-g1995|-g2001|-g2005|-g2005-sv|-g2009|-g2012] [-g<feature>]\n"
|
||||
" [-D macro[=defn]] [-I includedir]\n"
|
||||
" [-M [mode=]depfile] [-m module]\n"
|
||||
" [-N file] [-o filename] [-p flag=value]\n"
|
||||
" [-s topmodule] [-t target] [-T min|typ|max]\n"
|
||||
" [-W class] [-y dir] [-Y suf] source_file(s)\n"
|
||||
" [-W class] [-y dir] [-Y suf] [-l file] source_file(s)\n"
|
||||
"\n"
|
||||
"See the man page for details.";
|
||||
|
||||
@@ -71,7 +71,7 @@ const char HELP[] =
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
|
||||
#if HAVE_GETOPT_H
|
||||
#ifdef HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
@@ -122,11 +122,13 @@ char depmode = 'a';
|
||||
|
||||
const char*generation = "2005";
|
||||
const char*gen_specify = "no-specify";
|
||||
const char*gen_assertions = "assertions";
|
||||
const char*gen_xtypes = "xtypes";
|
||||
const char*gen_icarus = "icarus-misc";
|
||||
const char*gen_io_range_error = "io-range-error";
|
||||
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 = "no-shared-loop-index";
|
||||
const char*gen_verilog_ams = "no-verilog-ams";
|
||||
|
||||
/* Boolean: true means use a default include dir, false means don't */
|
||||
@@ -140,6 +142,8 @@ char warning_flags[16] = "n";
|
||||
|
||||
unsigned integer_width = 32;
|
||||
|
||||
unsigned width_cap = 65536;
|
||||
|
||||
char*mod_list = 0;
|
||||
char*command_filename = 0;
|
||||
|
||||
@@ -185,7 +189,7 @@ static const char** defparm_base = 0;
|
||||
static int defparm_size = 0;
|
||||
|
||||
/* Function to add a command file name to the FIFO. */
|
||||
void add_cmd_file(const char* filename)
|
||||
static void add_cmd_file(const char* filename)
|
||||
{
|
||||
p_command_file new;
|
||||
|
||||
@@ -202,7 +206,7 @@ void add_cmd_file(const char* filename)
|
||||
}
|
||||
|
||||
/* Function to return the top command file name from the FIFO. */
|
||||
char *get_cmd_file()
|
||||
static char *get_cmd_file(void)
|
||||
{
|
||||
char *filename;
|
||||
|
||||
@@ -399,7 +403,7 @@ static int t_preprocess_only(void)
|
||||
* needed to run the command from the configuration file (which is
|
||||
* already parsed for us) so we can handle must of the generic cases.
|
||||
*/
|
||||
static int t_compile()
|
||||
static int t_compile(void)
|
||||
{
|
||||
unsigned rc;
|
||||
|
||||
@@ -493,6 +497,7 @@ static void process_warning_switch(const char*name)
|
||||
if (strcmp(name,"all") == 0) {
|
||||
process_warning_switch("anachronisms");
|
||||
process_warning_switch("implicit");
|
||||
process_warning_switch("implicit-dimensions");
|
||||
process_warning_switch("portbind");
|
||||
process_warning_switch("select-range");
|
||||
process_warning_switch("timescale");
|
||||
@@ -503,6 +508,9 @@ static void process_warning_switch(const char*name)
|
||||
} else if (strcmp(name,"implicit") == 0) {
|
||||
if (! strchr(warning_flags, 'i'))
|
||||
strcat(warning_flags, "i");
|
||||
} else if (strcmp(name,"implicit-dimensions") == 0) {
|
||||
if (! strchr(warning_flags, 'd'))
|
||||
strcat(warning_flags, "d");
|
||||
} else if (strcmp(name,"portbind") == 0) {
|
||||
if (! strchr(warning_flags, 'p'))
|
||||
strcat(warning_flags, "p");
|
||||
@@ -535,6 +543,12 @@ static void process_warning_switch(const char*name)
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-implicit-dimensions") == 0) {
|
||||
char*cp = strchr(warning_flags, 'd');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-portbind") == 0) {
|
||||
char*cp = strchr(warning_flags, 'p');
|
||||
if (cp) while (*cp) {
|
||||
@@ -565,6 +579,9 @@ static void process_warning_switch(const char*name)
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Ignoring unknown warning class "
|
||||
"%s\n", name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -622,7 +639,7 @@ void process_file_name(const char*name, int lib_flag)
|
||||
}
|
||||
}
|
||||
|
||||
int process_generation(const char*name)
|
||||
static int process_generation(const char*name)
|
||||
{
|
||||
if (strcmp(name,"1995") == 0)
|
||||
generation = "1995";
|
||||
@@ -642,6 +659,9 @@ int process_generation(const char*name)
|
||||
else if (strcmp(name,"2009") == 0)
|
||||
generation = "2009";
|
||||
|
||||
else if (strcmp(name,"2012") == 0)
|
||||
generation = "2012";
|
||||
|
||||
else if (strcmp(name,"1") == 0) { /* Deprecated: use 1995 */
|
||||
generation = "1995";
|
||||
gen_xtypes = "no-xtypes";
|
||||
@@ -675,6 +695,12 @@ int process_generation(const char*name)
|
||||
else if (strcmp(name,"no-specify") == 0)
|
||||
gen_specify = "no-specify";
|
||||
|
||||
else if (strcmp(name,"assertions") == 0)
|
||||
gen_assertions = "assertions";
|
||||
|
||||
else if (strcmp(name,"no-assertions") == 0)
|
||||
gen_assertions = "no-assertions";
|
||||
|
||||
else if (strcmp(name,"std-include") == 0)
|
||||
gen_std_include = 1;
|
||||
|
||||
@@ -705,6 +731,12 @@ int process_generation(const char*name)
|
||||
else if (strcmp(name,"no-strict-expr-width") == 0)
|
||||
gen_strict_expr_width = "no-strict-expr-width";
|
||||
|
||||
else if (strcmp(name,"shared-loop-index") == 0)
|
||||
gen_shared_loop_index = "shared-loop-index";
|
||||
|
||||
else if (strcmp(name,"no-shared-loop-index") == 0)
|
||||
gen_shared_loop_index = "no-shared-loop-index";
|
||||
|
||||
else if (strcmp(name,"verilog-ams") == 0)
|
||||
gen_verilog_ams = "verilog-ams";
|
||||
|
||||
@@ -720,6 +752,7 @@ int process_generation(const char*name)
|
||||
" 2005 -- IEEE1364-2005\n"
|
||||
" 2005-sv -- IEEE1800-2005\n"
|
||||
" 2009 -- IEEE1800-2009\n"
|
||||
" 2012 -- IEEE1800-2012\n"
|
||||
"Other generation flags:\n"
|
||||
" specify | no-specify\n"
|
||||
" verilog-ams | no-verilog-ams\n"
|
||||
@@ -729,7 +762,8 @@ int process_generation(const char*name)
|
||||
" icarus-misc | no-icarus-misc\n"
|
||||
" io-range-error | no-io-range-error\n"
|
||||
" strict-ca-eval | no-strict-ca-eval\n"
|
||||
" strict-expr-width | no-strict-expr-width\n");
|
||||
" strict-expr-width | no-strict-expr-width\n"
|
||||
" shared-loop-index | no-shared-loop-index\n");
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -737,7 +771,7 @@ int process_generation(const char*name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int process_depfile(const char*name)
|
||||
static int process_depfile(const char*name)
|
||||
{
|
||||
const char*cp = strchr(name, '=');
|
||||
if (cp) {
|
||||
@@ -771,7 +805,7 @@ int process_depfile(const char*name)
|
||||
/*
|
||||
* If it exists add the SFT file for the given module.
|
||||
*/
|
||||
void add_sft_file(const char *module)
|
||||
static void add_sft_file(const char *module)
|
||||
{
|
||||
char *file;
|
||||
|
||||
@@ -786,7 +820,7 @@ int main(int argc, char **argv)
|
||||
{
|
||||
int e_flag = 0;
|
||||
int version_flag = 0;
|
||||
int opt, idx;
|
||||
int opt;
|
||||
|
||||
#ifdef __MINGW32__
|
||||
/* Calculate the ivl_root from the path to the command. This
|
||||
@@ -894,7 +928,7 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hI:M:m:N::o:P:p:Ss:T:t:vVW:y:Y:")) != EOF) {
|
||||
while ((opt = getopt(argc, argv, "B:c:D:d:Ef:g:hl:I:M:m:N:o:P:p:Ss:T:t:vVW:y:Y:")) != EOF) {
|
||||
|
||||
switch (opt) {
|
||||
case 'B':
|
||||
@@ -949,6 +983,10 @@ int main(int argc, char **argv)
|
||||
process_include_dir(optarg);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
process_file_name(optarg, 1);
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
if (process_depfile(optarg) != 0)
|
||||
return -1;
|
||||
@@ -1031,19 +1069,10 @@ int main(int argc, char **argv)
|
||||
|
||||
if (version_flag || verbose_flag) {
|
||||
printf("Icarus Verilog version " VERSION " (" VERSION_TAG ")\n\n");
|
||||
printf("Copyright 1998-2011 Stephen Williams\n\n");
|
||||
printf("Copyright 1998-2015 Stephen Williams\n\n");
|
||||
puts(NOTICE);
|
||||
}
|
||||
|
||||
if (synth_flag) {
|
||||
fprintf(stderr, "Warning: Synthesis is not currently being "
|
||||
"maintained and may not\n");
|
||||
fprintf(stderr, " function correctly. V0.8 was the "
|
||||
"last release branch to\n");
|
||||
fprintf(stderr, " have active synthesis development "
|
||||
"and support!\n");
|
||||
}
|
||||
|
||||
/* 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" : "");
|
||||
@@ -1057,10 +1086,11 @@ int main(int argc, char **argv)
|
||||
fprintf(iconfig_file, "sys_func:%s%csystem.sft\n", base, sep);
|
||||
fprintf(iconfig_file, "sys_func:%s%cvhdl_sys.sft\n", base, sep);
|
||||
|
||||
/* If verilog-2005/9 is enabled or icarus-misc or verilog-ams,
|
||||
/* If verilog-2005/09/12 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(gen_icarus, "icarus-misc") == 0 ||
|
||||
strcmp(gen_verilog_ams, "verilog-ams") == 0) {
|
||||
fprintf(iconfig_file, "sys_func:%s%cv2005_math.sft\n", base, sep);
|
||||
@@ -1076,7 +1106,8 @@ int main(int argc, char **argv)
|
||||
/* If verilog-2009 (SystemVerilog) is enabled, then include the
|
||||
v2009 module. */
|
||||
if (strcmp(generation, "2005-sv") == 0 ||
|
||||
strcmp(generation, "2009") == 0) {
|
||||
strcmp(generation, "2009") == 0 ||
|
||||
strcmp(generation, "2012") == 0) {
|
||||
fprintf(iconfig_file, "sys_func:%s%cv2009.sft\n", base, sep);
|
||||
fprintf(iconfig_file, "module:v2009\n");
|
||||
}
|
||||
@@ -1084,10 +1115,12 @@ int main(int argc, char **argv)
|
||||
if (mtm != 0) fprintf(iconfig_file, "-T:%s\n", mtm);
|
||||
fprintf(iconfig_file, "generation:%s\n", generation);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_specify);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_assertions);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_xtypes);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_io_range_error);
|
||||
fprintf(iconfig_file, "generation:%s\n", gen_strict_ca_eval);
|
||||
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_icarus);
|
||||
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
|
||||
@@ -1126,7 +1159,7 @@ int main(int argc, char **argv)
|
||||
vhdlpp_work = "ivl_vhdl_work";
|
||||
fprintf(defines_file, "vhdlpp:%s%cvhdlpp\n", vhdlpp_dir, sep);
|
||||
fprintf(defines_file, "vhdlpp-work:%s\n", vhdlpp_work);
|
||||
for (idx = 0 ; idx < vhdlpp_libdir_cnt ; idx += 1)
|
||||
for (unsigned idx = 0 ; idx < vhdlpp_libdir_cnt ; idx += 1)
|
||||
fprintf(defines_file, "vhdlpp-libdir:%s\n", vhdlpp_libdir[idx]);
|
||||
|
||||
/* Process parameter definition from command line. The last
|
||||
@@ -1140,7 +1173,7 @@ int main(int argc, char **argv)
|
||||
|
||||
/* Finally, process all the remaining words on the command
|
||||
line as file names. */
|
||||
for (idx = optind ; idx < argc ; idx += 1)
|
||||
for (int idx = optind ; idx < argc ; idx += 1)
|
||||
process_file_name(argv[idx], 0);
|
||||
|
||||
/* If the use of a default include directory is not
|
||||
@@ -1178,6 +1211,8 @@ int main(int argc, char **argv)
|
||||
|
||||
fprintf(iconfig_file, "iwidth:%u\n", integer_width);
|
||||
|
||||
fprintf(iconfig_file, "widthcap:%u\n", width_cap);
|
||||
|
||||
/* Write the preprocessor command needed to preprocess a
|
||||
single file. This may be used to preprocess library
|
||||
files. */
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
# include <stdlib.h>
|
||||
# include <stdio.h>
|
||||
# include "ivl_alloc.h"
|
||||
# include "globals.h"
|
||||
|
||||
|
||||
char* substitutions(const char*str)
|
||||
|
||||
+28
-1
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2013 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
|
||||
@@ -32,6 +32,17 @@ NetEAccess* NetEAccess::dup_expr() const
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEArrayPattern*NetEArrayPattern::dup_expr() const
|
||||
{
|
||||
vector<NetExpr*>tmp (items_.size());
|
||||
for (size_t idx = 0 ; idx < tmp.size() ; idx += 1)
|
||||
tmp[idx] = items_[idx]->dup_expr();
|
||||
|
||||
NetEArrayPattern*res = new NetEArrayPattern(net_type(), tmp);
|
||||
res->set_line(*this);
|
||||
return res;
|
||||
}
|
||||
|
||||
NetEBinary* NetEBinary::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
@@ -171,6 +182,14 @@ NetEEvent* NetEEvent::dup_expr() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetELast* NetELast::dup_expr() const
|
||||
{
|
||||
NetELast*tmp = new NetELast(sig_);
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetENetenum* NetENetenum::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
@@ -207,6 +226,7 @@ NetESelect* NetESelect::dup_expr() const
|
||||
base_? base_->dup_expr() : 0,
|
||||
expr_width(), sel_type_);
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->cast_signed(has_sign());
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
@@ -226,11 +246,18 @@ NetESFunc* NetESFunc::dup_expr() const
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEShallowCopy* NetEShallowCopy::dup_expr() const
|
||||
{
|
||||
ivl_assert(*this, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetESignal* NetESignal::dup_expr() const
|
||||
{
|
||||
NetESignal*tmp = new NetESignal(net_, word_);
|
||||
ivl_assert(*this, tmp);
|
||||
tmp->expr_width(expr_width());
|
||||
tmp->cast_signed(has_sign());
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
+1900
-435
File diff suppressed because it is too large
Load Diff
+558
-115
File diff suppressed because it is too large
Load Diff
+221
-70
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2012 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2014 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -255,7 +255,7 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||
} else {
|
||||
cerr << "-:";
|
||||
}
|
||||
cerr << wid << "] is always outside vector."
|
||||
cerr << wid << "] is always outside the vector."
|
||||
<< endl;
|
||||
}
|
||||
return false;
|
||||
@@ -315,41 +315,79 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||
long msb, lsb;
|
||||
bool part_defined_flag;
|
||||
/* bool flag = */ calculate_parts_(des, scope, msb, lsb, part_defined_flag);
|
||||
ivl_assert(*this, part_defined_flag);
|
||||
|
||||
long lidx_tmp = sig->sb_to_idx(prefix_indices, lsb);
|
||||
long midx_tmp = sig->sb_to_idx(prefix_indices, msb);
|
||||
/* Detect reversed indices of a part select. */
|
||||
if (lidx_tmp > midx_tmp) {
|
||||
cerr << get_fileline() << ": error: Part select "
|
||||
<< sig->name() << "[" << msb << ":"
|
||||
<< lsb << "] indices reversed." << endl;
|
||||
cerr << get_fileline() << ": : Did you mean "
|
||||
<< sig->name() << "[" << lsb << ":"
|
||||
<< msb << "]?" << endl;
|
||||
long tmp = midx_tmp;
|
||||
midx_tmp = lidx_tmp;
|
||||
lidx_tmp = tmp;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
/* Warn about a part select that is out of range. */
|
||||
if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) {
|
||||
cerr << get_fileline() << ": warning: Part select "
|
||||
<< sig->name();
|
||||
if (sig->unpacked_dimensions() > 0) {
|
||||
cerr << "[]";
|
||||
/* We have an undefined index and that is out of range. */
|
||||
if (!part_defined_flag) {
|
||||
if (warn_ob_select) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< sig->name();
|
||||
if (sig->unpacked_dimensions() > 0) cerr << "[]";
|
||||
cerr << "['bx] is always outside the vector."
|
||||
<< endl;
|
||||
}
|
||||
cerr << "[" << msb << ":" << lsb
|
||||
<< "] is out of range." << endl;
|
||||
}
|
||||
/* This is completely out side the signal so just skip it. */
|
||||
if (lidx_tmp >= (long)sig->vector_width() || midx_tmp < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
midx = midx_tmp;
|
||||
lidx = lidx_tmp;
|
||||
if (prefix_indices.size()+1 < sig->packed_dims().size()) {
|
||||
// Here we have a slice that doesn't have enough indices
|
||||
// to get to a single slice. For example:
|
||||
// wire [9:0][5:1] foo
|
||||
// ... foo[4:3] ...
|
||||
// Make this work by finding the indexed slices and
|
||||
// creating a generated slice that spans the whole
|
||||
// range.
|
||||
long loff, moff;
|
||||
unsigned long lwid, mwid;
|
||||
bool lrc;
|
||||
lrc = sig->sb_to_slice(prefix_indices, lsb, loff, lwid);
|
||||
ivl_assert(*this, lrc);
|
||||
lrc = sig->sb_to_slice(prefix_indices, msb, moff, mwid);
|
||||
ivl_assert(*this, lrc);
|
||||
ivl_assert(*this, lwid == mwid);
|
||||
|
||||
if (moff > loff) {
|
||||
lidx = loff;
|
||||
midx = moff + mwid - 1;
|
||||
} else {
|
||||
lidx = moff;
|
||||
midx = loff + lwid - 1;
|
||||
}
|
||||
} else {
|
||||
long lidx_tmp = sig->sb_to_idx(prefix_indices, lsb);
|
||||
long midx_tmp = sig->sb_to_idx(prefix_indices, msb);
|
||||
|
||||
/* Detect reversed indices of a part select. */
|
||||
if (lidx_tmp > midx_tmp) {
|
||||
cerr << get_fileline() << ": error: Part select "
|
||||
<< sig->name() << "[" << msb << ":"
|
||||
<< lsb << "] indices reversed." << endl;
|
||||
cerr << get_fileline() << ": : Did you mean "
|
||||
<< sig->name() << "[" << lsb << ":"
|
||||
<< msb << "]?" << endl;
|
||||
long tmp = midx_tmp;
|
||||
midx_tmp = lidx_tmp;
|
||||
lidx_tmp = tmp;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
/* Warn about a part select that is out of range. */
|
||||
if (midx_tmp >= (long)sig->vector_width() || lidx_tmp < 0) {
|
||||
cerr << get_fileline() << ": warning: Part select "
|
||||
<< sig->name();
|
||||
if (sig->unpacked_dimensions() > 0) {
|
||||
cerr << "[]";
|
||||
}
|
||||
cerr << "[" << msb << ":" << lsb
|
||||
<< "] is out of range." << endl;
|
||||
}
|
||||
/* This is completely out side the signal so just skip it. */
|
||||
if (lidx_tmp >= (long)sig->vector_width() || midx_tmp < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
midx = midx_tmp;
|
||||
lidx = lidx_tmp;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -358,7 +396,19 @@ bool PEIdent::eval_part_select_(Design*des, NetScope*scope, NetNet*sig,
|
||||
long msb;
|
||||
bool bit_defined_flag;
|
||||
/* bool flag = */ calculate_bits_(des, scope, msb, bit_defined_flag);
|
||||
ivl_assert(*this, bit_defined_flag);
|
||||
|
||||
/* We have an undefined index and that is out of range. */
|
||||
if (!bit_defined_flag) {
|
||||
if (warn_ob_select) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< sig->name();
|
||||
if (sig->unpacked_dimensions() > 0) cerr << "[]";
|
||||
cerr << "['bx] is always outside the vector."
|
||||
<< endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (prefix_indices.size()+2 <= sig->packed_dims().size()) {
|
||||
long tmp_loff;
|
||||
@@ -478,6 +528,10 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
unsigned midx = sig->vector_width()-1, lidx = 0;
|
||||
// The default word select is the first.
|
||||
long widx = 0;
|
||||
// Set this to true if we calculate the word index. This is
|
||||
// used to distinguish between unpacked array assignment and
|
||||
// array word assignment.
|
||||
bool widx_flag = false;
|
||||
|
||||
list<long> unpacked_indices_const;
|
||||
|
||||
@@ -501,7 +555,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
|
||||
<< "Member " << method_name
|
||||
<< " has packed dimensions " << member->packed_dims << "." << endl;
|
||||
<< " has type " << *member->net_type << "." << endl;
|
||||
cerr << get_fileline() << ": : "
|
||||
<< "Tail name has " << path_tail.index.size() << " indices." << endl;
|
||||
}
|
||||
@@ -509,13 +563,13 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
// Rewrite a member select of a packed structure as a
|
||||
// part select of the base variable.
|
||||
lidx = member_off;
|
||||
midx = lidx + member->width() - 1;
|
||||
midx = lidx + member->net_type->packed_width() - 1;
|
||||
|
||||
// The dimensions of the tail of the prefix must match
|
||||
// the dimensions of the signal at this point. (The sig
|
||||
// has a packed dimension for the packed struct size.)
|
||||
// For example, if the path_=a[<m>][<n>].member, then
|
||||
// sig must have 3 packed dimenions: one for the struct
|
||||
// sig must have 3 packed dimensions: one for the struct
|
||||
// members and two actual packed dimensions.
|
||||
ivl_assert(*this, path_prefix.back().index.size()+1 == sig->packed_dimensions());
|
||||
|
||||
@@ -532,15 +586,16 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
packed_base = collapse_array_indices(des, scope, sig, tmp_index);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "packed_base expression = " << *packed_base << endl;
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
|
||||
<< "packed_base=" << *packed_base
|
||||
<< ", member_off=" << member_off << endl;
|
||||
}
|
||||
}
|
||||
|
||||
long tmp;
|
||||
if (packed_base && eval_as_long(tmp, packed_base)) {
|
||||
lidx = tmp;
|
||||
midx = lidx + member->width() - 1;
|
||||
midx = lidx + member->net_type->packed_width() - 1;
|
||||
delete packed_base;
|
||||
packed_base = 0;
|
||||
}
|
||||
@@ -551,7 +606,7 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
// Now the lidx/midx values get us to the member. Next
|
||||
// up, deal with bit/part selects from the member
|
||||
// itself.
|
||||
ivl_assert(*this, member->packed_dims.size() <= 1);
|
||||
//XXXXivl_assert(*this, member->packed_dims.size() <= 1);
|
||||
ivl_assert(*this, path_tail.index.size() <= 1);
|
||||
if (! path_tail.index.empty()) {
|
||||
long tmp_off;
|
||||
@@ -567,13 +622,31 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
midx = lidx + tmp_wid - 1;
|
||||
}
|
||||
|
||||
} else if (gn_system_verilog() && sig->unpacked_dimensions() > 0 && path_tail.index.empty()) {
|
||||
|
||||
// In this case, we are doing a continuous assignment to
|
||||
// an unpacked array. The NetNet representation is a
|
||||
// NetNet with a pin for each array element, so there is
|
||||
// nothing more needed here.
|
||||
//
|
||||
// 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.
|
||||
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) {
|
||||
|
||||
// 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() << "." << endl;
|
||||
<< " but got only " << path_tail.index.size() << ". (net)" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -581,35 +654,52 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
// Evaluate all the index expressions into an
|
||||
// "unpacked_indices" array.
|
||||
list<NetExpr*>unpacked_indices;
|
||||
bool flag = indices_to_expressions(des, scope, this,
|
||||
path_tail.index, sig->unpacked_dimensions(),
|
||||
true,
|
||||
unpacked_indices,
|
||||
unpacked_indices_const);
|
||||
// Note that !flag includes that there were any other
|
||||
// elaboration errors generating the unpacked_indices list.
|
||||
if (!flag) {
|
||||
cerr << get_fileline() << ": error: array " << sig->name()
|
||||
<< " index must be a constant in this context." << endl;
|
||||
indices_flags flags;
|
||||
indices_to_expressions(des, scope, this,
|
||||
path_tail.index, sig->unpacked_dimensions(),
|
||||
true,
|
||||
flags,
|
||||
unpacked_indices,
|
||||
unpacked_indices_const);
|
||||
|
||||
if (flags.invalid) {
|
||||
return 0;
|
||||
|
||||
} else if (flags.variable) {
|
||||
cerr << get_fileline() << ": error: array '" << sig->name()
|
||||
<< "' index must be a constant in this context." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetExpr*canon_index = 0;
|
||||
ivl_assert(*this, unpacked_indices_const.size() == sig->unpacked_dimensions());
|
||||
canon_index = normalize_variable_unpacked(sig, unpacked_indices_const);
|
||||
if (canon_index == 0) {
|
||||
// Normalize detected an out-of-bounds
|
||||
// index. Indicate that by setting the generated
|
||||
// widx to -1.
|
||||
} else if (flags.undefined) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< "ignoring undefined l-value array access "
|
||||
<< sig->name() << as_indices(unpacked_indices)
|
||||
<< "." << endl;
|
||||
widx = -1;
|
||||
widx_flag = true;
|
||||
|
||||
} else {
|
||||
NetEConst*canon_const = dynamic_cast<NetEConst*>(canon_index);
|
||||
ivl_assert(*this, canon_const);
|
||||
NetExpr*canon_index = 0;
|
||||
ivl_assert(*this, unpacked_indices_const.size() == sig->unpacked_dimensions());
|
||||
canon_index = normalize_variable_unpacked(sig, unpacked_indices_const);
|
||||
|
||||
widx = canon_const->value().as_long();
|
||||
delete canon_index;
|
||||
if (canon_index == 0) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< "ignoring out of bounds l-value array access "
|
||||
<< sig->name() << as_indices(unpacked_indices_const)
|
||||
<< "." << endl;
|
||||
widx = -1;
|
||||
widx_flag = true;
|
||||
|
||||
} else {
|
||||
NetEConst*canon_const = dynamic_cast<NetEConst*>(canon_index);
|
||||
ivl_assert(*this, canon_const);
|
||||
|
||||
widx = canon_const->value().as_long();
|
||||
widx_flag = true;
|
||||
delete canon_index;
|
||||
}
|
||||
}
|
||||
|
||||
if (debug_elaborate)
|
||||
@@ -645,6 +735,16 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
}
|
||||
|
||||
} else if (!path_tail.index.empty()) {
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_lnet_common_: "
|
||||
<< "path_tail.index.size()=" << path_tail.index.size()
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// There are index expressions on the name, so this is a
|
||||
// bit/slice select of the name. Calculate a canonical
|
||||
// part select.
|
||||
|
||||
if (sig->get_scalar()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "can not select part of ";
|
||||
@@ -673,20 +773,23 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
unsigned subnet_wid = midx-lidx+1;
|
||||
|
||||
/* Check if the l-value bits are double-driven. */
|
||||
if (sig->type() == NetNet::UNRESOLVED_WIRE && sig->test_part_lref(midx,lidx)) {
|
||||
if (sig->type() == NetNet::UNRESOLVED_WIRE && sig->test_and_set_part_driver(midx,lidx, widx_flag? widx : 0)) {
|
||||
cerr << get_fileline() << ": error: Unresolved net/uwire "
|
||||
<< sig->name() << " cannot have multiple drivers." << endl;
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": : Overlap in "
|
||||
<< "[" << midx << ":" << lidx << "] (canonical)"
|
||||
<< ", widx=" << (widx_flag? widx : 0)
|
||||
<< ", vector width=" << sig->vector_width()
|
||||
<< endl;
|
||||
}
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sig->pin_count() > 1) {
|
||||
if (widx < 0 || widx >= (long) sig->pin_count()) {
|
||||
cerr << get_fileline() << ": warning: ignoring out of "
|
||||
"bounds l-value array access "
|
||||
<< sig->name() << as_indices(unpacked_indices_const) << "." << endl;
|
||||
if (sig->pin_count() > 1 && widx_flag) {
|
||||
if (widx < 0 || widx >= (long) sig->pin_count())
|
||||
return 0;
|
||||
}
|
||||
|
||||
netvector_t*tmp2_vec = new netvector_t(sig->data_type(),
|
||||
sig->vector_width()-1,0);
|
||||
@@ -696,6 +799,13 @@ NetNet* PEIdent::elaborate_lnet_common_(Design*des, NetScope*scope,
|
||||
tmp->local_flag(true);
|
||||
connect(sig->pin(widx), tmp->pin(0));
|
||||
sig = tmp;
|
||||
|
||||
} else if (sig->pin_count() > 1) {
|
||||
|
||||
// If this turns out to be an l-value unpacked array,
|
||||
// then let the caller handle it. It will probably be
|
||||
// converted into an array of assignments.
|
||||
return sig;
|
||||
}
|
||||
|
||||
/* If the desired l-value vector is narrower than the
|
||||
@@ -818,6 +928,33 @@ NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const
|
||||
long midx;
|
||||
long lidx;
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_subport: "
|
||||
<< "path_ = \"" << path_
|
||||
<< "\", unpacked_dimensions=" << sig->unpacked_dimensions()
|
||||
<< ", port_type()=" << sig->port_type() << endl;
|
||||
}
|
||||
|
||||
if (sig->unpacked_dimensions() && !gn_system_verilog()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Ports cannot be unpacked arrays. Try enabling SystemVerilog support." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// There cannot be parts to an unpacked array, so process this
|
||||
// simply as an unpacked array.
|
||||
if (sig->unpacked_dimensions()) {
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PEIdent::elaborate_subport: "
|
||||
<< "path_=\"" << path_
|
||||
<< "\" is an unpacked array with " << sig->pin_count()
|
||||
<< " elements." << endl;
|
||||
}
|
||||
scope->add_module_port_net(sig);
|
||||
return sig;
|
||||
}
|
||||
|
||||
/* Evaluate the part/bit select expressions, to get the part
|
||||
select of the signal that attaches to the port. Also handle
|
||||
range and direction checking here. */
|
||||
@@ -879,6 +1016,20 @@ NetNet* PEIdent::elaborate_subport(Design*des, NetScope*scope) const
|
||||
return sig;
|
||||
}
|
||||
|
||||
NetNet*PEIdent::elaborate_unpacked_net(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetNet* sig = 0;
|
||||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
perm_string method_name;
|
||||
|
||||
symbol_search(this, des, scope, path_, sig, par, eve);
|
||||
|
||||
ivl_assert(*this, sig);
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
bool PEIdent::is_collapsible_net(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(scope);
|
||||
|
||||
+488
-95
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2013 / 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
|
||||
@@ -39,6 +40,7 @@
|
||||
# include "PClass.h"
|
||||
# include "PGate.h"
|
||||
# include "PGenerate.h"
|
||||
# include "PPackage.h"
|
||||
# include "PTask.h"
|
||||
# include "PWire.h"
|
||||
# include "Statement.h"
|
||||
@@ -46,11 +48,21 @@
|
||||
# include "netlist.h"
|
||||
# include "netclass.h"
|
||||
# include "netenum.h"
|
||||
# include "parse_api.h"
|
||||
# include "util.h"
|
||||
# include <typeinfo>
|
||||
# include <cassert>
|
||||
# include "ivl_assert.h"
|
||||
|
||||
|
||||
void set_scope_timescale(Design*des, NetScope*scope, PScope*pscope)
|
||||
{
|
||||
scope->time_unit(pscope->time_unit);
|
||||
scope->time_precision(pscope->time_precision);
|
||||
scope->time_from_timescale(pscope->time_from_timescale);
|
||||
des->set_precision(pscope->time_precision);
|
||||
}
|
||||
|
||||
typedef map<perm_string,LexicalScope::param_expr_t>::const_iterator mparm_it_t;
|
||||
|
||||
static void collect_parm_item_(Design*des, NetScope*scope, perm_string name,
|
||||
@@ -154,6 +166,10 @@ static void collect_scope_specparams_(Design*des, NetScope*scope,
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate the enumeration into the given scope. If scope==0, then
|
||||
* the enumeration goes into $root instead of a scope.
|
||||
*/
|
||||
static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||
enum_type_t*enum_type)
|
||||
{
|
||||
@@ -161,7 +177,7 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||
assert(enum_type->range->size() == 1);
|
||||
pform_range_t&range = enum_type->range->front();
|
||||
NetExpr*msb_ex = elab_and_eval(des, scope, range.first, -1);
|
||||
NetExpr*lsb_ex = elab_and_eval(des, scope, range.second, -1);
|
||||
NetExpr*lsb_ex = elab_and_eval(des, scope, range.second, -1);
|
||||
|
||||
long msb = 0;
|
||||
rc_flag = eval_as_long(msb, msb_ex);
|
||||
@@ -170,34 +186,43 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||
rc_flag = eval_as_long(lsb, lsb_ex);
|
||||
assert(rc_flag);
|
||||
|
||||
netenum_t*use_enum = new netenum_t(enum_type->base_type, enum_type->signed_flag,
|
||||
msb, lsb, enum_type->names->size());
|
||||
netenum_t*use_enum = new netenum_t(enum_type->base_type,
|
||||
enum_type->signed_flag,
|
||||
enum_type->integer_flag, msb, lsb,
|
||||
enum_type->names->size(),
|
||||
enum_type);
|
||||
|
||||
use_enum->set_line(enum_type->li);
|
||||
scope->add_enumeration_set(use_enum);
|
||||
if (scope)
|
||||
scope->add_enumeration_set(enum_type, use_enum);
|
||||
else
|
||||
des->add_enumeration_set(enum_type, use_enum);
|
||||
|
||||
verinum cur_value (0);
|
||||
verinum one_value (1);
|
||||
size_t name_idx = 0;
|
||||
// Find the minimum and maximum allowed enumeration values.
|
||||
verinum min_value (0);
|
||||
// Find the enumeration width.
|
||||
long raw_width = use_enum->packed_width();
|
||||
assert(raw_width > 0);
|
||||
unsigned enum_width = (unsigned)raw_width;
|
||||
// Define the default start value and the increment value to be the
|
||||
// correct type for this enumeration.
|
||||
verinum cur_value ((uint64_t)0, enum_width);
|
||||
cur_value.has_sign(enum_type->signed_flag);
|
||||
verinum one_value ((uint64_t)1, enum_width);
|
||||
one_value.has_sign(enum_type->signed_flag);
|
||||
// Find the maximum allowed enumeration value.
|
||||
verinum max_value (0);
|
||||
if (enum_type->signed_flag) {
|
||||
min_value = v_not((pow(verinum(2),
|
||||
verinum(use_enum->packed_width()-1)))) +
|
||||
one_value;
|
||||
max_value = pow(verinum(2), verinum(use_enum->packed_width()-1)) -
|
||||
one_value;
|
||||
max_value = pow(verinum(2), verinum(enum_width-1)) - one_value;
|
||||
} else {
|
||||
max_value = pow(verinum(2), verinum(use_enum->packed_width())) -
|
||||
one_value;
|
||||
max_value = pow(verinum(2), verinum(enum_width)) - one_value;
|
||||
}
|
||||
min_value.has_sign(true);
|
||||
max_value.has_sign(enum_type->signed_flag);
|
||||
// Variable to indicate when a defined value wraps.
|
||||
bool implicit_wrapped = false;
|
||||
// Process the enumeration definition.
|
||||
for (list<named_pexpr_t>::const_iterator cur = enum_type->names->begin()
|
||||
; cur != enum_type->names->end() ; ++ cur, name_idx += 1) {
|
||||
|
||||
|
||||
// Check to see if the enumeration name has a value given.
|
||||
if (cur->parm) {
|
||||
// There is an explicit value. elaborate/evaluate
|
||||
// the value and assign it to the enumeration name.
|
||||
@@ -205,37 +230,126 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||
NetEConst*val_const = dynamic_cast<NetEConst*> (val);
|
||||
if (val_const == 0) {
|
||||
cerr << use_enum->get_fileline()
|
||||
<< ": error: Enumeration expression is not "
|
||||
"constant." << endl;
|
||||
<< ": error: Enumeration expression for "
|
||||
<< cur->name <<" is not an integer constant."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
cur_value = val_const->value();
|
||||
// Clear the implicit wrapped flag if a parameter is given.
|
||||
implicit_wrapped = false;
|
||||
|
||||
// A 2-state value can not have a constant with X/Z bits.
|
||||
if (enum_type->base_type==IVL_VT_BOOL &&
|
||||
! cur_value.is_defined()) {
|
||||
cerr << use_enum->get_fileline()
|
||||
<< ": error: Enumeration name " << cur->name
|
||||
<< " cannot have an undefined value." << endl;
|
||||
<< " can not have an undefined value." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
// 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 (tmp->value().has_len() &&
|
||||
(tmp->value().len() != enum_width)) {
|
||||
cerr << use_enum->get_fileline()
|
||||
<< ": error: Enumeration name " << cur->name
|
||||
<< " has an incorrectly sized constant."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// If we are padding/truncating a negative value for an
|
||||
// unsigned enumeration that is an error or if the new
|
||||
// value does not have a defined width.
|
||||
if (((cur_value.len() != enum_width) ||
|
||||
! cur_value.has_len()) &&
|
||||
! enum_type->signed_flag && cur_value.is_negative()) {
|
||||
cerr << use_enum->get_fileline()
|
||||
<< ": error: Enumeration name " << cur->name
|
||||
<< " has a negative value." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// Narrower values need to be padded to the width of the
|
||||
// enumeration and defined to have the specified width.
|
||||
if (cur_value.len() < enum_width) {
|
||||
cur_value = pad_to_width(cur_value, enum_width);
|
||||
}
|
||||
|
||||
// Some wider values can be truncated.
|
||||
if (cur_value.len() > enum_width) {
|
||||
unsigned check_width = enum_width - 1;
|
||||
// Check that the upper bits match the MSB
|
||||
for (unsigned idx = enum_width;
|
||||
idx < cur_value.len();
|
||||
idx += 1) {
|
||||
if (cur_value[idx] != cur_value[check_width]) {
|
||||
// If this is an unsigned enumeration
|
||||
// then zero padding is okay.
|
||||
if (! enum_type->signed_flag &&
|
||||
(idx == enum_width) &&
|
||||
(cur_value[idx] == verinum::V0)) {
|
||||
check_width += 1;
|
||||
continue;
|
||||
}
|
||||
if (cur_value.is_defined()) {
|
||||
cerr << use_enum->get_fileline()
|
||||
<< ": error: Enumeration name "
|
||||
<< cur->name
|
||||
<< " has a value that is too "
|
||||
<< ((cur_value > max_value) ?
|
||||
"large" : "small")
|
||||
<< " " << cur_value << "."
|
||||
<< endl;
|
||||
} else {
|
||||
cerr << use_enum->get_fileline()
|
||||
<< ": error: Enumeration name "
|
||||
<< cur->name
|
||||
<< " has trimmed bits that do "
|
||||
<< "not match the enumeration "
|
||||
<< "MSB: " << cur_value << "."
|
||||
<< endl;
|
||||
}
|
||||
des->errors += 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If this is an unsigned value then make sure
|
||||
// The upper bits are not 1.
|
||||
if (! cur_value.has_sign() &&
|
||||
(cur_value[enum_width] == verinum::V1)) {
|
||||
cerr << use_enum->get_fileline()
|
||||
<< ": error: Enumeration name "
|
||||
<< cur->name
|
||||
<< " has a value that is too large: "
|
||||
<< cur_value << "." << endl;
|
||||
des->errors += 1;
|
||||
break;
|
||||
}
|
||||
cur_value = verinum(cur_value, enum_width);
|
||||
}
|
||||
|
||||
// At this point the value has the correct size and needs
|
||||
// to have the correct sign attribute set.
|
||||
cur_value.has_len(true);
|
||||
cur_value.has_sign(enum_type->signed_flag);
|
||||
|
||||
} else if (! cur_value.is_defined()) {
|
||||
cerr << use_enum->get_fileline()
|
||||
<< ": error: Enumeration name " << cur->name
|
||||
<< " cannot have an undefined inferred value." << endl;
|
||||
<< " has an undefined inferred value." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// The enumeration value must fit into the enumeration bits.
|
||||
if ((cur_value > max_value) ||
|
||||
(cur_value.has_sign() && (cur_value < min_value))) {
|
||||
// Check to see if an implicitly wrapped value is used.
|
||||
if (implicit_wrapped) {
|
||||
cerr << use_enum->get_fileline()
|
||||
<< ": error: Enumeration name " << cur->name
|
||||
<< " cannot have a value equal to " << cur_value
|
||||
<< "." << endl;
|
||||
<< " has an inferred value that overflowed." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
@@ -249,23 +363,12 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
// The values are explicitly sized to the width of the
|
||||
// base type of the enumeration.
|
||||
verinum tmp_val (0);
|
||||
if (cur_value.len() < (unsigned long)use_enum->packed_width()) {
|
||||
// Pad the current value if it is narrower than the final
|
||||
// width of the enum.
|
||||
tmp_val = pad_to_width (cur_value, use_enum->packed_width());
|
||||
tmp_val.has_len(true);
|
||||
} else {
|
||||
// Truncate an oversized value. We report out of bound
|
||||
// values above. This may create duplicates.
|
||||
tmp_val = verinum(cur_value, use_enum->packed_width());
|
||||
}
|
||||
tmp_val.has_sign(enum_type->signed_flag);
|
||||
rc_flag = use_enum->insert_name(name_idx, cur->name, cur_value);
|
||||
if (scope)
|
||||
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
|
||||
else
|
||||
rc_flag &= des->add_enumeration_name(use_enum, cur->name);
|
||||
|
||||
rc_flag = use_enum->insert_name(name_idx, cur->name, tmp_val);
|
||||
rc_flag &= scope->add_enumeration_name(use_enum, cur->name);
|
||||
if (! rc_flag) {
|
||||
cerr << use_enum->get_fileline()
|
||||
<< ": error: Duplicate enumeration name "
|
||||
@@ -275,41 +378,240 @@ static void elaborate_scope_enumeration(Design*des, NetScope*scope,
|
||||
|
||||
// In case the next name has an implicit value,
|
||||
// increment the current value by one.
|
||||
if (cur_value.is_defined())
|
||||
if (cur_value.is_defined()) {
|
||||
if (cur_value == max_value) implicit_wrapped = true;
|
||||
cur_value = cur_value + one_value;
|
||||
}
|
||||
}
|
||||
|
||||
use_enum->insert_name_close();
|
||||
}
|
||||
|
||||
static void elaborate_scope_enumerations(Design*des, NetScope*scope,
|
||||
const list<enum_type_t*>&enum_types)
|
||||
const set<enum_type_t*>&enum_types)
|
||||
{
|
||||
for (list<enum_type_t*>::const_iterator cur = enum_types.begin()
|
||||
for (set<enum_type_t*>::const_iterator cur = enum_types.begin()
|
||||
; cur != enum_types.end() ; ++ cur) {
|
||||
elaborate_scope_enumeration(des, scope, *cur);
|
||||
enum_type_t*curp = *cur;
|
||||
elaborate_scope_enumeration(des, scope, curp);
|
||||
}
|
||||
}
|
||||
|
||||
static void elaborate_scope_class(Design*des, NetScope*scope,
|
||||
PClass*pclass)
|
||||
void elaborate_rootscope_enumerations(Design*des)
|
||||
{
|
||||
class_type_t*use_type = pclass->type;
|
||||
netclass_t*use_class = new netclass_t(use_type->name);
|
||||
for (set<enum_type_t*>::const_iterator cur = pform_enum_sets.begin()
|
||||
; cur != pform_enum_sets.end() ; ++ cur) {
|
||||
enum_type_t*curp = *cur;
|
||||
elaborate_scope_enumeration(des, 0, curp);
|
||||
}
|
||||
}
|
||||
|
||||
for (map<perm_string, data_type_t*>::iterator cur = use_type->properties.begin()
|
||||
; cur != use_type->properties.end() ; ++ cur) {
|
||||
ivl_type_s*tmp = cur->second->elaborate_type(des, scope);
|
||||
use_class->set_property(cur->first, tmp);
|
||||
/*
|
||||
* If the pclass includes an implicit and explicit constructor, then
|
||||
* merge the implicit constructor into the explicit constructor as
|
||||
* statements in the beginning.
|
||||
*
|
||||
* This is not necessary for proper functionality, it is an
|
||||
* optimization, so we can easily give up if it doesn't seem like it
|
||||
* will obviously work.
|
||||
*/
|
||||
static void blend_class_constructors(PClass*pclass)
|
||||
{
|
||||
perm_string new1 = perm_string::literal("new");
|
||||
perm_string new2 = perm_string::literal("new@");
|
||||
|
||||
PFunction*use_new;
|
||||
PFunction*use_new2;
|
||||
|
||||
// Locate the explicit constructor.
|
||||
map<perm_string,PFunction*>::iterator iter_new = pclass->funcs.find(new1);
|
||||
if (iter_new == pclass->funcs.end())
|
||||
use_new = 0;
|
||||
else
|
||||
use_new = iter_new->second;
|
||||
|
||||
// Locate the implicit constructor.
|
||||
map<perm_string,PFunction*>::iterator iter_new2 = pclass->funcs.find(new2);
|
||||
if (iter_new2 == pclass->funcs.end())
|
||||
use_new2 = 0;
|
||||
else
|
||||
use_new2 = iter_new2->second;
|
||||
|
||||
// If there are no constructors, then we are done.
|
||||
if (use_new==0 && use_new2==0)
|
||||
return;
|
||||
|
||||
// While we're here, look for a super.new() call. If we find
|
||||
// it, strip it out of the constructor and set it aside for
|
||||
// when we actually call the chained constructor.
|
||||
PChainConstructor*chain_new = use_new? use_new->extract_chain_constructor() : 0;
|
||||
|
||||
// If we do not have an explicit constructor chain, but there
|
||||
// is a parent class, then create an implicit chain.
|
||||
if (chain_new==0 && pclass->type->base_type!=0) {
|
||||
chain_new = new PChainConstructor(pclass->type->base_args);
|
||||
chain_new->set_line(*pclass);
|
||||
}
|
||||
|
||||
scope->add_class(use_class);
|
||||
// If there are both an implicit and explicit constructor,
|
||||
// then blend the implicit constructor into the explicit
|
||||
// constructor. This eases the task for the elaborator later.
|
||||
if (use_new && use_new2) {
|
||||
// These constructors must be methods of the same class.
|
||||
ivl_assert(*use_new, use_new->method_of() == use_new2->method_of());
|
||||
|
||||
Statement*def_new = use_new->get_statement();
|
||||
Statement*def_new2 = use_new2->get_statement();
|
||||
|
||||
// It is possible, i.e. recovering from a parse error,
|
||||
// for the statement from the constructor to be
|
||||
// missing. In that case, create an empty one.
|
||||
if (def_new==0) {
|
||||
def_new = new PBlock(PBlock::BL_SEQ);
|
||||
use_new->set_statement(def_new);
|
||||
}
|
||||
|
||||
if (def_new2) use_new->push_statement_front(def_new2);
|
||||
|
||||
// Now the implicit initializations are all built into
|
||||
// the constructor. Delete the "new@" constructor.
|
||||
pclass->funcs.erase(iter_new2);
|
||||
delete use_new2;
|
||||
use_new2 = 0;
|
||||
}
|
||||
|
||||
if (chain_new) {
|
||||
if (use_new2) {
|
||||
use_new2->push_statement_front(chain_new);
|
||||
} else {
|
||||
use_new->push_statement_front(chain_new);
|
||||
}
|
||||
chain_new = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void elaborate_scope_class(Design*des, NetScope*scope, PClass*pclass)
|
||||
{
|
||||
class_type_t*use_type = pclass->type;
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << pclass->get_fileline() <<": elaborate_scope_class: "
|
||||
<< "Elaborate scope class " << pclass->pscope_name() << endl;
|
||||
}
|
||||
|
||||
class_type_t*base_class = dynamic_cast<class_type_t*> (use_type->base_type);
|
||||
if (use_type->base_type && !base_class) {
|
||||
cerr << pclass->get_fileline() << ": error: "
|
||||
<< "Base type of " << use_type->name
|
||||
<< " is not a class." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
netclass_t*use_base_class = 0;
|
||||
if (base_class) {
|
||||
ivl_assert(*pclass, scope);
|
||||
use_base_class = scope->find_class(base_class->name);
|
||||
if (use_base_class == 0) {
|
||||
cerr << pclass->get_fileline() << ": error: "
|
||||
<< "Base class " << base_class->name
|
||||
<< " not found." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
netclass_t*use_class = new netclass_t(use_type->name, use_base_class);
|
||||
|
||||
ivl_assert(*pclass, use_type->save_elaborated_type == 0);
|
||||
use_type->save_elaborated_type = use_class;
|
||||
|
||||
// Class scopes have no parent scope, because references are
|
||||
// not allowed to escape a class method.
|
||||
NetScope*class_scope = new NetScope(0, hname_t(pclass->pscope_name()),
|
||||
NetScope::CLASS);
|
||||
class_scope->set_line(pclass);
|
||||
class_scope->set_class_def(use_class);
|
||||
use_class->set_class_scope(class_scope);
|
||||
use_class->set_definition_scope(scope);
|
||||
set_scope_timescale(des, class_scope, pclass);
|
||||
|
||||
// Collect the properties, elaborate them, and add them to the
|
||||
// elaborated class definition.
|
||||
for (map<perm_string, class_type_t::prop_info_t>::iterator cur = use_type->properties.begin()
|
||||
; cur != use_type->properties.end() ; ++ cur) {
|
||||
|
||||
ivl_type_s*tmp = cur->second.type->elaborate_type(des, scope);
|
||||
ivl_assert(*pclass, tmp);
|
||||
if (debug_scopes) {
|
||||
cerr << pclass->get_fileline() << ": elaborate_scope_class: "
|
||||
<< " Property " << cur->first
|
||||
<< " type=" << *tmp << endl;
|
||||
}
|
||||
use_class->set_property(cur->first, cur->second.qual, tmp);
|
||||
|
||||
}
|
||||
|
||||
for (map<perm_string,PTask*>::iterator cur = pclass->tasks.begin()
|
||||
; cur != pclass->tasks.end() ; ++cur) {
|
||||
|
||||
hname_t use_name (cur->first);
|
||||
NetScope*method_scope = new NetScope(class_scope, use_name, NetScope::TASK);
|
||||
// Task methods are always automatic...
|
||||
method_scope->is_auto(true);
|
||||
method_scope->set_line(cur->second);
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << cur->second->get_fileline() << ": elaborate_scope_class: "
|
||||
<< "Elaborate method (task) scope "
|
||||
<< scope_path(method_scope) << endl;
|
||||
}
|
||||
|
||||
cur->second->elaborate_scope(des, method_scope);
|
||||
}
|
||||
|
||||
for (map<perm_string,PFunction*>::iterator cur = pclass->funcs.begin()
|
||||
; cur != pclass->funcs.end() ; ++cur) {
|
||||
|
||||
hname_t use_name (cur->first);
|
||||
NetScope*method_scope = new NetScope(class_scope, use_name, NetScope::FUNC);
|
||||
// Function methods are always automatic...
|
||||
method_scope->is_auto(true);
|
||||
method_scope->set_line(cur->second);
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << cur->second->get_fileline() << ": elaborate_scope_class: "
|
||||
<< "Elaborate method (function) scope "
|
||||
<< scope_path(method_scope) << endl;
|
||||
}
|
||||
|
||||
cur->second->elaborate_scope(des, method_scope);
|
||||
}
|
||||
|
||||
if (scope) {
|
||||
scope->add_class(use_class);
|
||||
|
||||
} else {
|
||||
des->add_class(use_class, pclass);
|
||||
}
|
||||
}
|
||||
|
||||
static void elaborate_scope_classes(Design*des, NetScope*scope,
|
||||
const map<perm_string,PClass*>&classes)
|
||||
const vector<PClass*>&classes)
|
||||
{
|
||||
for (map<perm_string,PClass*>::const_iterator cur = classes.begin()
|
||||
; cur != classes.end() ; ++ cur) {
|
||||
elaborate_scope_class(des, scope, cur->second);
|
||||
for (size_t idx = 0 ; idx < classes.size() ; idx += 1) {
|
||||
blend_class_constructors(classes[idx]);
|
||||
elaborate_scope_class(des, scope, classes[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
void elaborate_rootscope_classes(Design*des)
|
||||
{
|
||||
if (pform_classes.empty())
|
||||
return;
|
||||
|
||||
for (map<perm_string,PClass*>::iterator cur = pform_classes.begin()
|
||||
; cur != pform_classes.end() ; ++ cur) {
|
||||
blend_class_constructors(cur->second);
|
||||
elaborate_scope_class(des, 0, cur->second);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -354,6 +656,27 @@ static void elaborate_scope_events_(Design*des, NetScope*scope,
|
||||
}
|
||||
}
|
||||
|
||||
static void elaborate_scope_task(Design*des, NetScope*scope, PTask*task)
|
||||
{
|
||||
hname_t use_name( task->pscope_name() );
|
||||
|
||||
NetScope*task_scope = new NetScope(scope, use_name, NetScope::TASK);
|
||||
task_scope->is_auto(task->is_auto());
|
||||
task_scope->set_line(task);
|
||||
|
||||
if (scope==0) {
|
||||
set_scope_timescale(des, task_scope, task);
|
||||
des->add_root_task(task_scope, task);
|
||||
}
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << task->get_fileline() << ": elaborate_scope_task: "
|
||||
<< "Elaborate task scope " << scope_path(task_scope) << endl;
|
||||
}
|
||||
|
||||
task->elaborate_scope(des, task_scope);
|
||||
}
|
||||
|
||||
static void elaborate_scope_tasks(Design*des, NetScope*scope,
|
||||
const map<perm_string,PTask*>&tasks)
|
||||
{
|
||||
@@ -395,19 +718,32 @@ static void elaborate_scope_tasks(Design*des, NetScope*scope,
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
NetScope*task_scope = new NetScope(scope, use_name,
|
||||
NetScope::TASK);
|
||||
task_scope->is_auto((*cur).second->is_auto());
|
||||
task_scope->set_line((*cur).second);
|
||||
|
||||
if (debug_scopes)
|
||||
cerr << cur->second->get_fileline() << ": debug: "
|
||||
<< "Elaborate task scope " << scope_path(task_scope) << endl;
|
||||
(*cur).second->elaborate_scope(des, task_scope);
|
||||
elaborate_scope_task(des, scope, cur->second);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void elaborate_scope_func(Design*des, NetScope*scope, PFunction*task)
|
||||
{
|
||||
hname_t use_name( task->pscope_name() );
|
||||
|
||||
NetScope*task_scope = new NetScope(scope, use_name, NetScope::FUNC);
|
||||
task_scope->is_auto(task->is_auto());
|
||||
task_scope->set_line(task);
|
||||
|
||||
if (scope==0) {
|
||||
set_scope_timescale(des, task_scope, task);
|
||||
des->add_root_task(task_scope, task);
|
||||
}
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << task->get_fileline() << ": elaborate_scope_func: "
|
||||
<< "Elaborate task scope " << scope_path(task_scope) << endl;
|
||||
}
|
||||
|
||||
task->elaborate_scope(des, task_scope);
|
||||
}
|
||||
|
||||
static void elaborate_scope_funcs(Design*des, NetScope*scope,
|
||||
const map<perm_string,PFunction*>&funcs)
|
||||
{
|
||||
@@ -450,19 +786,33 @@ static void elaborate_scope_funcs(Design*des, NetScope*scope,
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
NetScope*func_scope = new NetScope(scope, use_name,
|
||||
NetScope::FUNC);
|
||||
func_scope->is_auto((*cur).second->is_auto());
|
||||
func_scope->set_line((*cur).second);
|
||||
|
||||
if (debug_scopes)
|
||||
cerr << cur->second->get_fileline() << ": debug: "
|
||||
<< "Elaborate function scope " << scope_path(func_scope) << endl;
|
||||
(*cur).second->elaborate_scope(des, func_scope);
|
||||
elaborate_scope_func(des, scope, cur->second);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void elaborate_rootscope_tasks(Design*des)
|
||||
{
|
||||
for (map<perm_string,PTaskFunc*>::iterator cur = pform_tasks.begin()
|
||||
; cur != pform_tasks.end() ; ++ cur) {
|
||||
|
||||
if (PTask*task = dynamic_cast<PTask*> (cur->second)) {
|
||||
elaborate_scope_task(des, 0, task);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (PFunction*func = dynamic_cast<PFunction*>(cur->second)) {
|
||||
elaborate_scope_func(des, 0, func);
|
||||
continue;
|
||||
}
|
||||
|
||||
cerr << cur->second->get_fileline() << ": internal error: "
|
||||
<< "elaborate_rootscope_tasks does not understand "
|
||||
<< "this object," << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
class generate_schemes_work_item_t : public elaborator_work_item_t {
|
||||
public:
|
||||
generate_schemes_work_item_t(Design*des__, NetScope*scope, Module*mod)
|
||||
@@ -495,12 +845,28 @@ class generate_schemes_work_item_t : public elaborator_work_item_t {
|
||||
Module*mod_;
|
||||
};
|
||||
|
||||
bool PPackage::elaborate_scope(Design*des, NetScope*scope)
|
||||
{
|
||||
if (debug_scopes) {
|
||||
cerr << get_fileline() << ": PPackage::elaborate_scope: "
|
||||
<< "Elaborate package " << scope_path(scope) << "." << endl;
|
||||
}
|
||||
|
||||
collect_scope_parameters_(des, scope, parameters);
|
||||
collect_scope_localparams_(des, scope, localparams);
|
||||
elaborate_scope_enumerations(des, scope, enum_sets);
|
||||
elaborate_scope_classes(des, scope, classes_lexical);
|
||||
elaborate_scope_funcs(des, scope, funcs);
|
||||
elaborate_scope_tasks(des, scope, tasks);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Module::elaborate_scope(Design*des, NetScope*scope,
|
||||
const replace_t&replacements)
|
||||
{
|
||||
if (debug_scopes) {
|
||||
cerr << get_fileline() << ": debug: Elaborate scope "
|
||||
<< scope_path(scope) << "." << endl;
|
||||
cerr << get_fileline() << ": Module::elaborate_scope: "
|
||||
<< "Elaborate " << scope_path(scope) << "." << endl;
|
||||
}
|
||||
|
||||
// Add the genvars to the scope.
|
||||
@@ -527,7 +893,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
||||
|
||||
elaborate_scope_enumerations(des, scope, enum_sets);
|
||||
|
||||
elaborate_scope_classes(des, scope, classes);
|
||||
assert(classes.size() == classes_lexical.size());
|
||||
elaborate_scope_classes(des, scope, classes_lexical);
|
||||
|
||||
// Run through the defparams for this module and save the result
|
||||
// in a table for later final override.
|
||||
@@ -549,7 +916,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope,
|
||||
delete[]attr;
|
||||
|
||||
// Generate schemes need to have their scopes elaborated, but
|
||||
// we cannot do that until defparams are run, so push it off
|
||||
// we can not do that until defparams are run, so push it off
|
||||
// into an elaborate work item.
|
||||
if (debug_scopes)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
@@ -685,8 +1052,10 @@ bool PGenerate::generate_scope_loop_(Design*des, NetScope*container)
|
||||
|
||||
// Check the generate block name.
|
||||
|
||||
// A generate "loop" can not have the same name as another scope object.
|
||||
const NetScope *child = container->child(hname_t(scope_name));
|
||||
// A generate "loop" can not have the same name as another
|
||||
// scope object. Find any scope with this name, not just an
|
||||
// exact match scope.
|
||||
const NetScope *child = container->child_byname(scope_name);
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: generate \"loop\" and ";
|
||||
child->print_type(cerr);
|
||||
@@ -1289,7 +1658,7 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
continue;
|
||||
}
|
||||
|
||||
cerr << get_fileline() << ": error: You cannot instantiate "
|
||||
cerr << get_fileline() << ": error: You can not instantiate "
|
||||
<< "module " << mod->mod_name() << " within itself." << endl;
|
||||
cerr << get_fileline() << ": : The offending instance is "
|
||||
<< get_name() << " within " << scope_path(scn) << "." << endl;
|
||||
@@ -1387,18 +1756,15 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
||||
// scope searches will continue into the parent scope.
|
||||
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE,
|
||||
bound_type_? true : false,
|
||||
mod->program_block);
|
||||
mod->program_block,
|
||||
mod->is_interface);
|
||||
my_scope->set_line(get_file(), mod->get_file(),
|
||||
get_lineno(), mod->get_lineno());
|
||||
my_scope->set_module_name(mod->mod_name());
|
||||
|
||||
instances[idx] = my_scope;
|
||||
|
||||
// Set time units and precision.
|
||||
my_scope->time_unit(mod->time_unit);
|
||||
my_scope->time_precision(mod->time_precision);
|
||||
my_scope->time_from_timescale(mod->time_from_timescale);
|
||||
des->set_precision(mod->time_precision);
|
||||
set_scope_timescale(des, my_scope, mod);
|
||||
|
||||
// Look for module parameter replacements. The "replace" map
|
||||
// maps parameter name to replacement expression that is
|
||||
@@ -1437,8 +1803,12 @@ void PGModule::elaborate_scope_mod_instances_(Design*des, Module*mod, NetScope*s
|
||||
// so the mapping into the replace list is much easier.
|
||||
if (parms_) {
|
||||
assert(overrides_ == 0);
|
||||
for (unsigned jdx = 0 ; jdx < nparms_ ; jdx += 1)
|
||||
replace[parms_[jdx].name] = parms_[jdx].parm;
|
||||
for (unsigned jdx = 0 ; jdx < nparms_ ; jdx += 1) {
|
||||
// No expression means that the parameter is not
|
||||
// replaced.
|
||||
if (parms_[jdx].parm)
|
||||
replace[parms_[jdx].name] = parms_[jdx].parm;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1668,6 +2038,17 @@ void PDelayStatement::elaborate_scope(Design*des, NetScope*scope) const
|
||||
statement_ -> elaborate_scope(des, scope);
|
||||
}
|
||||
|
||||
/*
|
||||
* Statements that contain a further statement but do not
|
||||
* intrinsically add a scope need to elaborate_scope the contained
|
||||
* statement.
|
||||
*/
|
||||
void PDoWhile::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
if (statement_)
|
||||
statement_ -> elaborate_scope(des, scope);
|
||||
}
|
||||
|
||||
/*
|
||||
* Statements that contain a further statement but do not
|
||||
* intrinsically add a scope need to elaborate_scope the contained
|
||||
@@ -1679,6 +2060,18 @@ void PEventStatement::elaborate_scope(Design*des, NetScope*scope) const
|
||||
statement_ -> elaborate_scope(des, scope);
|
||||
}
|
||||
|
||||
/*
|
||||
* The standard says that we create an implicit scope for foreach
|
||||
* loops, but that is just to hold the index variables, and we'll
|
||||
* handle them by creating unique names. So just jump into the
|
||||
* contained statement for scope elaboration.
|
||||
*/
|
||||
void PForeach::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
if (statement_)
|
||||
statement_ -> elaborate_scope(des, scope);
|
||||
}
|
||||
|
||||
/*
|
||||
* Statements that contain a further statement but do not
|
||||
* intrinsically add a scope need to elaborate_scope the contained
|
||||
|
||||
+367
-337
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2016 Stephen Williams (steve@icarus.com)
|
||||
* Copyright CERN 2012 / Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
@@ -25,9 +25,11 @@
|
||||
# include <iostream>
|
||||
|
||||
# include "Module.h"
|
||||
# include "PClass.h"
|
||||
# include "PExpr.h"
|
||||
# include "PGate.h"
|
||||
# include "PGenerate.h"
|
||||
# include "PPackage.h"
|
||||
# include "PTask.h"
|
||||
# include "PWire.h"
|
||||
# include "Statement.h"
|
||||
@@ -36,10 +38,10 @@
|
||||
# include "netmisc.h"
|
||||
# include "netclass.h"
|
||||
# include "netenum.h"
|
||||
# include "netstruct.h"
|
||||
# include "netvector.h"
|
||||
# include "netdarray.h"
|
||||
# include "netparray.h"
|
||||
# include "netqueue.h"
|
||||
# include "util.h"
|
||||
# include "ivl_assert.h"
|
||||
|
||||
@@ -71,6 +73,8 @@ static bool get_const_argument(NetExpr*exp, verinum&res)
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* This function is not currently used. */
|
||||
static bool get_const_argument(NetExpr*exp, long&res)
|
||||
{
|
||||
verinum tmp;
|
||||
@@ -79,6 +83,7 @@ static bool get_const_argument(NetExpr*exp, long&res)
|
||||
res = tmp.as_long();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void Statement::elaborate_sig(Design*, NetScope*) const
|
||||
{
|
||||
@@ -165,7 +170,13 @@ static void elaborate_sig_funcs(Design*des, NetScope*scope,
|
||||
continue;
|
||||
}
|
||||
|
||||
(*cur).second->elaborate_sig(des, fscope);
|
||||
if (debug_elaborate) {
|
||||
cerr << cur->second->get_fileline() << ": elaborate_sig_funcs: "
|
||||
<< "Elaborate function " << use_name
|
||||
<< " in " << scope_path(fscope) << endl;
|
||||
}
|
||||
|
||||
cur->second->elaborate_sig(des, fscope);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,6 +193,43 @@ static void elaborate_sig_tasks(Design*des, NetScope*scope,
|
||||
}
|
||||
}
|
||||
|
||||
static void elaborate_sig_classes(Design*des, NetScope*scope,
|
||||
const map<perm_string,PClass*>&classes)
|
||||
{
|
||||
for (map<perm_string,PClass*>::const_iterator cur = classes.begin()
|
||||
; cur != classes.end() ; ++ cur) {
|
||||
netclass_t*use_class = scope->find_class(cur->second->pscope_name());
|
||||
use_class->elaborate_sig(des, cur->second);
|
||||
}
|
||||
}
|
||||
|
||||
bool PPackage::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
bool flag = true;
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PPackage::elaborate_sig: "
|
||||
<< "Start package scope=" << scope_path(scope) << endl;
|
||||
}
|
||||
|
||||
flag = elaborate_sig_wires_(des, scope) && flag;
|
||||
|
||||
// After all the wires are elaborated, we are free to
|
||||
// elaborate the ports of the tasks defined within this
|
||||
// module. Run through them now.
|
||||
|
||||
elaborate_sig_funcs(des, scope, funcs);
|
||||
elaborate_sig_tasks(des, scope, tasks);
|
||||
elaborate_sig_classes(des, scope, classes);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PPackage::elaborate_sig: "
|
||||
<< "Done package scope=" << scope_path(scope)
|
||||
<< ", flag=" << flag << endl;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
@@ -262,6 +310,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
elaborate_sig_funcs(des, scope, funcs);
|
||||
elaborate_sig_tasks(des, scope, tasks);
|
||||
elaborate_sig_classes(des, scope, classes);
|
||||
|
||||
// initial and always blocks may contain begin-end and
|
||||
// fork-join blocks that can introduce scopes. Therefore, I
|
||||
@@ -278,6 +327,53 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
return flag;
|
||||
}
|
||||
|
||||
void netclass_t::elaborate_sig(Design*des, PClass*pclass)
|
||||
{
|
||||
for (map<perm_string,struct class_type_t::prop_info_t>::iterator cur = pclass->type->properties.begin()
|
||||
; cur != pclass->type->properties.end() ; ++ cur) {
|
||||
|
||||
if (! cur->second.qual.test_static())
|
||||
continue;
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << pclass->get_fileline() << ": netclass_t::elaborate_sig: "
|
||||
<< "Elaborate static property " << cur->first
|
||||
<< " as signal in scope " << scope_path(class_scope_)
|
||||
<< "." << endl;
|
||||
}
|
||||
|
||||
list<netrange_t> nil_list;
|
||||
ivl_type_t use_type = cur->second.type->elaborate_type(des, class_scope_);
|
||||
/* NetNet*sig = */ new NetNet(class_scope_, cur->first, NetNet::REG,
|
||||
nil_list, use_type);
|
||||
}
|
||||
|
||||
for (map<perm_string,PFunction*>::iterator cur = pclass->funcs.begin()
|
||||
; cur != pclass->funcs.end() ; ++ cur) {
|
||||
if (debug_elaborate) {
|
||||
cerr << cur->second->get_fileline() << ": netclass_t::elaborate_sig: "
|
||||
<< "Elaborate signals in function method " << cur->first << endl;
|
||||
}
|
||||
|
||||
NetScope*scope = class_scope_->child( hname_t(cur->first) );
|
||||
ivl_assert(*cur->second, scope);
|
||||
cur->second->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
for (map<perm_string,PTask*>::iterator cur = pclass->tasks.begin()
|
||||
; cur != pclass->tasks.end() ; ++ cur) {
|
||||
if (debug_elaborate) {
|
||||
cerr << cur->second->get_fileline() << ": netclass_t::elaborate_sig: "
|
||||
<< "Elaborate signals in task method " << cur->first << endl;
|
||||
}
|
||||
|
||||
NetScope*scope = class_scope_->child( hname_t(cur->first) );
|
||||
ivl_assert(*cur->second, scope);
|
||||
cur->second->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool PGate::elaborate_sig(Design*, NetScope*) const
|
||||
{
|
||||
return true;
|
||||
@@ -475,218 +571,73 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
elaborate_sig_wires_(des, scope);
|
||||
|
||||
/* Make sure the function has at least one input port. If it
|
||||
fails this test, print an error message. Keep going so we
|
||||
can find more errors. */
|
||||
if (ports_ == 0 && !gn_system_verilog()) {
|
||||
cerr << get_fileline() << ": error: Function " << fname
|
||||
<< " has no ports." << endl;
|
||||
cerr << get_fileline() << ": : Functions must have"
|
||||
<< " at least one input port." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
NetNet*ret_sig;
|
||||
if (gn_system_verilog() && (fname=="new" || fname=="new@")) {
|
||||
// Special case: this is a constructor, so the return
|
||||
// signal is also the first argument. For example, the
|
||||
// source code for the definition may be:
|
||||
// function new(...);
|
||||
// endfunction
|
||||
// In this case, the "@" port is the synthetic "this"
|
||||
// argument and we also use it as a return value at the
|
||||
// same time.
|
||||
ret_sig = scope->find_signal(perm_string::literal("@"));
|
||||
ivl_assert(*this, ret_sig);
|
||||
|
||||
NetNet*ret_sig = 0;
|
||||
netvector_t*ret_vec = 0;
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": PFunction::elaborate_sig: "
|
||||
<< "Scope " << scope_path(scope)
|
||||
<< " is a CONSTRUCTOR, so use \"this\" argument"
|
||||
<< " as return value." << endl;
|
||||
|
||||
/* Create the signals/variables of the return value and write
|
||||
them into the function scope. */
|
||||
switch (return_type_.type) {
|
||||
} else {
|
||||
ivl_type_t ret_type;
|
||||
|
||||
case PTF_REG:
|
||||
case PTF_REG_S:
|
||||
if (return_type_.range) {
|
||||
ivl_assert(*this, return_type_.range->size() == 1);
|
||||
pform_range_t&return_range = return_type_.range->front();
|
||||
|
||||
NetExpr*me = elab_and_eval(des, scope,
|
||||
return_range.first, -1,
|
||||
true);
|
||||
assert(me);
|
||||
NetExpr*le = elab_and_eval(des, scope,
|
||||
return_range.second, -1,
|
||||
true);
|
||||
assert(le);
|
||||
|
||||
long mnum = 0, lnum = 0;
|
||||
if ( ! get_const_argument(me, mnum) ) {
|
||||
cerr << me->get_fileline() << ": error: "
|
||||
"Unable to evaluate constant expression "
|
||||
<< *me << "." << endl;
|
||||
des->errors += 1;
|
||||
if (return_type_) {
|
||||
if (dynamic_cast<const struct void_type_t*> (return_type_)) {
|
||||
ret_type = 0;
|
||||
} else {
|
||||
ret_type = return_type_->elaborate_type(des, scope->parent());
|
||||
ivl_assert(*this, ret_type);
|
||||
}
|
||||
|
||||
if ( ! get_const_argument(le, lnum) ) {
|
||||
cerr << le->get_fileline() << ": error: "
|
||||
"Unable to evaluate constant expression "
|
||||
<< *le << "." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
vector<netrange_t> packed;
|
||||
packed.push_back(netrange_t(mnum, lnum));
|
||||
ret_vec = new netvector_t(packed, IVL_VT_LOGIC);
|
||||
ret_vec->set_signed(return_type_.type == PTF_REG_S);
|
||||
ret_vec->set_scalar(false);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
|
||||
} else {
|
||||
ret_vec = new netvector_t(IVL_VT_LOGIC);
|
||||
ret_vec->set_signed(return_type_.type == PTF_REG_S);
|
||||
ret_vec->set_scalar(true);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
netvector_t*tmp = new netvector_t(IVL_VT_LOGIC);
|
||||
tmp->set_scalar(true);
|
||||
ret_type = tmp;
|
||||
}
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
break;
|
||||
|
||||
case PTF_INTEGER:
|
||||
ret_vec = new netvector_t(IVL_VT_LOGIC, integer_width-1,0);
|
||||
ret_vec->set_signed(true);
|
||||
ret_vec->set_isint(true);
|
||||
ret_vec->set_scalar(false);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
break;
|
||||
|
||||
case PTF_TIME:
|
||||
ret_vec = new netvector_t(IVL_VT_LOGIC, 64-1,0);
|
||||
ret_vec->set_isint(false);
|
||||
ret_vec->set_scalar(false);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
break;
|
||||
|
||||
case PTF_REAL:
|
||||
case PTF_REALTIME:
|
||||
ret_vec = new netvector_t(IVL_VT_REAL);
|
||||
ret_vec->set_signed(true);
|
||||
ret_vec->set_isint(false);
|
||||
ret_vec->set_scalar(true);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
break;
|
||||
|
||||
case PTF_ATOM2:
|
||||
case PTF_ATOM2_S:
|
||||
long use_wid;
|
||||
{
|
||||
ivl_assert(*this, return_type_.range->size() == 1);
|
||||
pform_range_t&return_range = return_type_.range->front();
|
||||
NetExpr*me = elab_and_eval(des, scope,
|
||||
return_range.first, -1,
|
||||
true);
|
||||
ivl_assert(*this, me);
|
||||
NetExpr*le = elab_and_eval(des, scope,
|
||||
return_range.second, -1,
|
||||
true);
|
||||
ivl_assert(*this, le);
|
||||
|
||||
long mnum = 0, lnum = 0;
|
||||
if ( ! get_const_argument(me, mnum) ) {
|
||||
cerr << me->get_fileline() << ": error: "
|
||||
"Unable to evaluate constant expression "
|
||||
<< *me << "." << endl;
|
||||
des->errors += 1;
|
||||
if (ret_type) {
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PFunction::elaborate_sig: "
|
||||
<< "return type: " << *ret_type << endl;
|
||||
if (return_type_)
|
||||
return_type_->pform_dump(cerr, 8);
|
||||
}
|
||||
list<netrange_t> ret_unpacked;
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_unpacked, ret_type);
|
||||
|
||||
if ( ! get_const_argument(le, lnum) ) {
|
||||
cerr << le->get_fileline() << ": error: "
|
||||
"Unable to evaluate constant expression "
|
||||
<< *le << "." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
use_wid = mnum - lnum + 1;
|
||||
}
|
||||
ret_vec = new netvector_t(IVL_VT_BOOL, use_wid-1, 0);
|
||||
ret_vec->set_isint(true);
|
||||
ret_vec->set_scalar(false);
|
||||
ret_vec->set_signed(return_type_.type == PTF_ATOM2_S? true : false);
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, ret_vec);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
break;
|
||||
|
||||
case PTF_STRING:
|
||||
cerr << get_fileline() << ": sorry: String functions are not supported yet" << endl;
|
||||
break;
|
||||
|
||||
case PTF_VOID:
|
||||
// Void functions have no return value, so there is no
|
||||
// signal to create here.
|
||||
break;
|
||||
|
||||
default:
|
||||
if (ports_) {
|
||||
cerr << get_fileline() << ": internal error: I don't know "
|
||||
<< "how to deal with return type of function "
|
||||
<< scope->basename() << "." << endl;
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
} else {
|
||||
/* If we do not have any ports or a return type this
|
||||
* is probably a bad function definition. */
|
||||
cerr << get_fileline() << ": error: Bad definition for "
|
||||
<< "function " << scope->basename() << "?" << endl;
|
||||
return;
|
||||
ret_sig = 0;
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PFunction::elaborate_sig: "
|
||||
<< "Detected that function is void." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vector<NetNet*>ports (ports_? ports_->count() : 0);
|
||||
vector<NetNet*>ports;
|
||||
vector<NetExpr*>pdef;
|
||||
elaborate_sig_ports_(des, scope, ports, pdef);
|
||||
|
||||
if (ports_)
|
||||
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
|
||||
NetFuncDef*def = new NetFuncDef(scope, ret_sig, ports, pdef);
|
||||
|
||||
/* Parse the port name into the task name and the reg
|
||||
name. We know by design that the port name is given
|
||||
as two components: <func>.<port>. */
|
||||
|
||||
perm_string pname = (*ports_)[idx]->basename();
|
||||
|
||||
NetNet*tmp = scope->find_signal(pname);
|
||||
ports[idx] = 0;
|
||||
|
||||
if (tmp == 0) {
|
||||
cerr << get_fileline() << ": internal error: function "
|
||||
<< scope_path(scope) << " is missing port "
|
||||
<< pname << "." << endl;
|
||||
scope->dump(cerr);
|
||||
cerr << get_fileline() << ": Continuing..." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tmp->port_type() == NetNet::NOT_A_PORT) {
|
||||
cerr << get_fileline() << ": internal error: function "
|
||||
<< scope_path(scope) << " port " << pname
|
||||
<< " is a port but is not a port?" << endl;
|
||||
des->errors += 1;
|
||||
scope->dump(cerr);
|
||||
continue;
|
||||
}
|
||||
|
||||
ports[idx] = tmp;
|
||||
if (tmp->port_type() != NetNet::PINPUT) {
|
||||
cerr << tmp->get_fileline() << ": error: function "
|
||||
<< scope_path(scope) << " port " << pname
|
||||
<< " is not an input port." << endl;
|
||||
cerr << tmp->get_fileline() << ": : Function arguments "
|
||||
<< "must be input ports." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NetFuncDef*def = 0;
|
||||
if (ret_sig) def = new NetFuncDef(scope, ret_sig, ports);
|
||||
|
||||
assert(def);
|
||||
if (debug_elaborate)
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Attach function definition to scope "
|
||||
<< scope_path(scope) << "." << endl;
|
||||
cerr << get_fileline() << ": PFunction::elaborate_sig: "
|
||||
<< "Attach function definition " << scope_path(scope)
|
||||
<< " with ret_sig width=" << (ret_sig? ret_sig->vector_width() : 0)
|
||||
<< "." << endl;
|
||||
|
||||
scope->set_func_def(def);
|
||||
|
||||
@@ -710,28 +661,10 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
elaborate_sig_wires_(des, scope);
|
||||
|
||||
svector<NetNet*>ports (ports_? ports_->count() : 0);
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
|
||||
perm_string port_name = (*ports_)[idx]->basename();
|
||||
|
||||
/* Find the signal for the port. We know by definition
|
||||
that it is in the scope of the task, so look only in
|
||||
the scope. */
|
||||
NetNet*tmp = scope->find_signal(port_name);
|
||||
|
||||
if (tmp == 0) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Could not find port " << port_name
|
||||
<< " in scope " << scope_path(scope) << endl;
|
||||
scope->dump(cerr);
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
ports[idx] = tmp;
|
||||
}
|
||||
|
||||
NetTaskDef*def = new NetTaskDef(scope, ports);
|
||||
vector<NetNet*>ports;
|
||||
vector<NetExpr*>pdefs;
|
||||
elaborate_sig_ports_(des, scope, ports, pdefs);
|
||||
NetTaskDef*def = new NetTaskDef(scope, ports, pdefs);
|
||||
scope->set_task_def(def);
|
||||
|
||||
// Look for further signals in the sub-statement
|
||||
@@ -739,6 +672,94 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
|
||||
statement_->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
void PTaskFunc::elaborate_sig_ports_(Design*des, NetScope*scope,
|
||||
vector<NetNet*>&ports, vector<NetExpr*>&pdefs) const
|
||||
{
|
||||
if (ports_ == 0) {
|
||||
ports.clear();
|
||||
pdefs.clear();
|
||||
|
||||
/* Make sure the function has at least one input
|
||||
port. If it fails this test, print an error
|
||||
message. Keep going so we can find more errors. */
|
||||
if (scope->type()==NetScope::FUNC && !gn_system_verilog()) {
|
||||
cerr << get_fileline() << ": error: "
|
||||
<< "Function " << scope->basename()
|
||||
<< " has no ports." << endl;
|
||||
cerr << get_fileline() << ": : "
|
||||
<< "Functions must have at least one input port." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ports.resize(ports_->size());
|
||||
pdefs.resize(ports_->size());
|
||||
|
||||
for (size_t idx = 0 ; idx < ports_->size() ; idx += 1) {
|
||||
|
||||
perm_string port_name = ports_->at(idx).port->basename();
|
||||
|
||||
ports[idx] = 0;
|
||||
pdefs[idx] = 0;
|
||||
NetNet*tmp = scope->find_signal(port_name);
|
||||
NetExpr*tmp_def = 0;
|
||||
if (tmp == 0) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "task/function " << scope_path(scope)
|
||||
<< " is missing port " << port_name << "." << endl;
|
||||
scope->dump(cerr);
|
||||
cerr << get_fileline() << ": Continuing..." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the port has a default expression, elaborate
|
||||
// that expression here.
|
||||
if (ports_->at(idx).defe != 0) {
|
||||
if (tmp->port_type() == NetNet::PINPUT) {
|
||||
tmp_def = elab_and_eval(des, scope, ports_->at(idx).defe,
|
||||
-1, scope->need_const_func());
|
||||
if (tmp_def == 0) {
|
||||
cerr << get_fileline()
|
||||
<< ": error: Unable to evaluate "
|
||||
<< *ports_->at(idx).defe
|
||||
<< " as a port default expression." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
} else {
|
||||
cerr << get_fileline() << ": sorry: Default arguments "
|
||||
"for subroutine output or inout ports are not "
|
||||
"yet supported." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (tmp->port_type() == NetNet::NOT_A_PORT) {
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "task/function " << scope_path(scope)
|
||||
<< " port " << port_name
|
||||
<< " is a port but is not a port?" << endl;
|
||||
des->errors += 1;
|
||||
scope->dump(cerr);
|
||||
continue;
|
||||
}
|
||||
|
||||
ports[idx] = tmp;
|
||||
pdefs[idx] = tmp_def;
|
||||
if (scope->type()==NetScope::FUNC && tmp->port_type()!=NetNet::PINPUT) {
|
||||
cerr << tmp->get_fileline() << ": error: "
|
||||
<< "Function " << scope_path(scope)
|
||||
<< " port " << port_name
|
||||
<< " is not an input port." << endl;
|
||||
cerr << tmp->get_fileline() << ": : "
|
||||
<< "Function arguments must be input ports." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PBlock::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetScope*my_scope = scope;
|
||||
@@ -793,12 +814,24 @@ void PDelayStatement::elaborate_sig(Design*des, NetScope*scope) const
|
||||
statement_->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
void PDoWhile::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
if (statement_)
|
||||
statement_->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
void PEventStatement::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
if (statement_)
|
||||
statement_->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
void PForeach::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
if (statement_)
|
||||
statement_->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
void PForever::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
if (statement_)
|
||||
@@ -823,96 +856,11 @@ void PWhile::elaborate_sig(Design*des, NetScope*scope) const
|
||||
statement_->elaborate_sig(des, scope);
|
||||
}
|
||||
|
||||
static bool evaluate_ranges(Design*des, NetScope*scope,
|
||||
vector<netrange_t>&llist,
|
||||
const list<pform_range_t>&rlist)
|
||||
{
|
||||
bool bad_msb = false, bad_lsb = false;
|
||||
|
||||
for (list<pform_range_t>::const_iterator cur = rlist.begin()
|
||||
; cur != rlist.end() ; ++cur) {
|
||||
long use_msb, use_lsb;
|
||||
|
||||
NetExpr*texpr = elab_and_eval(des, scope, cur->first, -1, true);
|
||||
if (! eval_as_long(use_msb, texpr)) {
|
||||
cerr << cur->first->get_fileline() << ": error: "
|
||||
"Range expressions must be constant." << endl;
|
||||
cerr << cur->first->get_fileline() << " : "
|
||||
"This MSB expression violates the rule: "
|
||||
<< *cur->first << endl;
|
||||
des->errors += 1;
|
||||
bad_msb = true;
|
||||
}
|
||||
|
||||
delete texpr;
|
||||
|
||||
texpr = elab_and_eval(des, scope, cur->second, -1, true);
|
||||
if (! eval_as_long(use_lsb, texpr)) {
|
||||
cerr << cur->second->get_fileline() << ": error: "
|
||||
"Range expressions must be constant." << endl;
|
||||
cerr << cur->second->get_fileline() << " : "
|
||||
"This LSB expression violates the rule: "
|
||||
<< *cur->second << endl;
|
||||
des->errors += 1;
|
||||
bad_lsb = true;
|
||||
}
|
||||
|
||||
delete texpr;
|
||||
|
||||
llist.push_back(netrange_t(use_msb, use_lsb));
|
||||
}
|
||||
|
||||
return bad_msb | bad_lsb;
|
||||
}
|
||||
|
||||
static netclass_t* locate_class_type(Design*des, NetScope*scope,
|
||||
class_type_t*class_type)
|
||||
{
|
||||
netclass_t*use_class = scope->find_class(class_type->name);
|
||||
return use_class;
|
||||
}
|
||||
|
||||
static netstruct_t* elaborate_struct_type(Design*des, NetScope*scope,
|
||||
struct_type_t*struct_type)
|
||||
{
|
||||
netstruct_t*res = new netstruct_t;
|
||||
|
||||
res->packed(struct_type->packed_flag);
|
||||
|
||||
for (list<struct_member_t*>::iterator cur = struct_type->members->begin()
|
||||
; cur != struct_type->members->end() ; ++ cur) {
|
||||
|
||||
vector<netrange_t>packed_dimensions;
|
||||
|
||||
struct_member_t*curp = *cur;
|
||||
if (curp->range.get() && ! curp->range->empty()) {
|
||||
bool bad_range;
|
||||
bad_range = evaluate_ranges(des, scope, packed_dimensions, *curp->range);
|
||||
ivl_assert(*curp, !bad_range);
|
||||
} else {
|
||||
packed_dimensions.push_back(netrange_t(0,0));
|
||||
}
|
||||
|
||||
for (list<decl_assignment_t*>::iterator name = curp->names->begin()
|
||||
; name != curp->names->end() ; ++ name) {
|
||||
decl_assignment_t*namep = *name;
|
||||
|
||||
netstruct_t::member_t memb;
|
||||
memb.name = namep->name;
|
||||
memb.type = curp->type;
|
||||
memb.packed_dims = packed_dimensions;
|
||||
res->append_member(memb);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static ivl_type_s*elaborate_type(Design*des, NetScope*scope,
|
||||
data_type_t*pform_type)
|
||||
{
|
||||
if (struct_type_t*struct_type = dynamic_cast<struct_type_t*>(pform_type)) {
|
||||
netstruct_t*use_type = elaborate_struct_type(des, scope, struct_type);
|
||||
ivl_type_s*use_type = struct_type->elaborate_type(des, scope);
|
||||
return use_type;
|
||||
}
|
||||
|
||||
@@ -928,7 +876,7 @@ static netparray_t* elaborate_parray_type(Design*des, NetScope*scope,
|
||||
{
|
||||
|
||||
vector<netrange_t>packed_dimensions;
|
||||
bool bad_range = evaluate_ranges(des, scope, packed_dimensions, * data_type->packed_dims);
|
||||
bool bad_range = evaluate_ranges(des, scope, packed_dimensions, * data_type->dims);
|
||||
ivl_assert(*data_type, !bad_range);
|
||||
|
||||
ivl_type_s*element_type = elaborate_type(des, scope, data_type->base_type);
|
||||
@@ -968,6 +916,11 @@ bool test_ranges_eeq(const vector<netrange_t>&lef, const vector<netrange_t>&rig)
|
||||
*/
|
||||
NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
// This sets the vector or array dimension size that will
|
||||
// cause a warning. For now, these warnings are permanently
|
||||
// enabled.
|
||||
const long warn_dimension_size = 1 << 30;
|
||||
|
||||
NetNet::Type wtype = type_;
|
||||
bool is_implicit_scalar = false;
|
||||
if (wtype == NetNet::IMPLICIT) {
|
||||
@@ -985,7 +938,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
des->errors += error_cnt_;
|
||||
|
||||
// A signal can not have the same name as a scope object.
|
||||
const NetScope *child = scope->child(hname_t(name_));
|
||||
const NetScope *child = scope->child_byname(name_);
|
||||
if (child) {
|
||||
cerr << get_fileline() << ": error: signal and ";
|
||||
child->print_type(cerr);
|
||||
@@ -1001,7 +954,10 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
<< "'." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
// A signal can not have the same name as a parameter.
|
||||
// A signal can not have the same name as a parameter. Note
|
||||
// that we treat enumeration literals similar to parameters,
|
||||
// so if the name matches an enumeration literal, it will be
|
||||
// caught here.
|
||||
const NetExpr *ex_msb, *ex_lsb;
|
||||
const NetExpr *parm = scope->get_parameter(des, name_, ex_msb, ex_lsb);
|
||||
if (parm) {
|
||||
@@ -1020,10 +976,31 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
}
|
||||
|
||||
if (port_set_ || net_set_) {
|
||||
|
||||
if (warn_implicit_dimensions
|
||||
&& port_set_ && net_set_
|
||||
&& net_.empty() && !port_.empty()) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< "var/net declaration of " << basename()
|
||||
<< " inherits dimensions from port declaration." << endl;
|
||||
}
|
||||
|
||||
if (warn_implicit_dimensions
|
||||
&& port_set_ && net_set_
|
||||
&& port_.empty() && !net_.empty()) {
|
||||
cerr << get_fileline() << ": warning: "
|
||||
<< "Port declaration of " << basename()
|
||||
<< " inherits dimensions from var/net." << endl;
|
||||
}
|
||||
|
||||
bool bad_range = false;
|
||||
vector<netrange_t> plist, nlist;
|
||||
/* If they exist get the port definition MSB and LSB */
|
||||
if (port_set_ && !port_.empty()) {
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PWire::elaborate_sig: "
|
||||
<< "Evaluate ranges for port " << basename() << endl;
|
||||
}
|
||||
bad_range |= evaluate_ranges(des, scope, plist, port_);
|
||||
nlist = plist;
|
||||
/* An implicit port can have a range so note that here. */
|
||||
@@ -1034,13 +1011,19 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
/* If they exist get the net/etc. definition MSB and LSB */
|
||||
if (net_set_ && !net_.empty() && !bad_range) {
|
||||
nlist.clear();
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PWire::elaborate_sig: "
|
||||
<< "Evaluate ranges for net " << basename() << endl;
|
||||
}
|
||||
bad_range |= evaluate_ranges(des, scope, nlist, net_);
|
||||
}
|
||||
assert(net_set_ || net_.empty());
|
||||
|
||||
/* If we find errors here, then give up on this signal. */
|
||||
if (bad_range)
|
||||
return 0;
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": PWire::elaborate_sig: "
|
||||
<< "Calculated ranges for " << basename()
|
||||
<< ". Now check for consistency." << endl;
|
||||
}
|
||||
|
||||
/* We have a port size error */
|
||||
if (port_set_ && net_set_ && !test_ranges_eeq(plist, nlist)) {
|
||||
@@ -1088,7 +1071,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
packed_dimensions = nlist;
|
||||
wid = netrange_width(packed_dimensions);
|
||||
|
||||
if (wid > warn_dimension_size) {
|
||||
cerr << get_fileline() << ": warning: Vector size "
|
||||
"is greater than " << warn_dimension_size
|
||||
<< "." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned nattrib = 0;
|
||||
@@ -1097,7 +1084,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
|
||||
list<netrange_t>unpacked_dimensions;
|
||||
netdarray_t*netarray = 0;
|
||||
netdarray_t*netdarray = 0;
|
||||
|
||||
for (list<pform_range_t>::const_iterator cur = unpacked_.begin()
|
||||
; cur != unpacked_.end() ; ++cur) {
|
||||
@@ -1109,14 +1096,26 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
// put all the packed dimensions there.
|
||||
if (use_lidx==0 && use_ridx==0) {
|
||||
netvector_t*vec = new netvector_t(packed_dimensions, data_type_);
|
||||
vec->set_signed(get_signed());
|
||||
packed_dimensions.clear();
|
||||
ivl_assert(*this, netarray==0);
|
||||
netarray = new netdarray_t(vec);
|
||||
ivl_assert(*this, netdarray==0);
|
||||
netdarray = new netdarray_t(vec);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Special case: Detect the mark for a QUEUE
|
||||
// declaration, which is the dimensions [null:<nil>].
|
||||
if (use_ridx==0 && dynamic_cast<PENull*>(use_lidx)) {
|
||||
netvector_t*vec = new netvector_t(packed_dimensions, data_type_);
|
||||
vec->set_signed(get_signed());
|
||||
packed_dimensions.clear();
|
||||
ivl_assert(*this, netdarray==0);
|
||||
netdarray = new netqueue_t(vec);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Cannot handle dynamic arrays of arrays yet.
|
||||
ivl_assert(*this, netarray==0);
|
||||
ivl_assert(*this, netdarray==0);
|
||||
ivl_assert(*this, use_lidx && use_ridx);
|
||||
|
||||
NetExpr*lexp = elab_and_eval(des, scope, use_lidx, -1, true);
|
||||
@@ -1150,6 +1149,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
index_l = lval.as_long();
|
||||
index_r = rval.as_long();
|
||||
}
|
||||
if (abs(index_r - index_l) > warn_dimension_size) {
|
||||
cerr << get_fileline() << ": warning: Array dimension "
|
||||
"is greater than " << warn_dimension_size
|
||||
<< "." << endl;
|
||||
}
|
||||
|
||||
unpacked_dimensions.push_back(netrange_t(index_l, index_r));
|
||||
}
|
||||
@@ -1181,6 +1185,14 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
NetLogic*pull = 0;
|
||||
if (wtype == NetNet::SUPPLY0 || wtype == NetNet::SUPPLY1) {
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Generate a SUPPLY pull for the ";
|
||||
if (wtype == NetNet::SUPPLY0) cerr << "supply0";
|
||||
else cerr << "supply1";
|
||||
cerr << " net." << endl;
|
||||
}
|
||||
|
||||
NetLogic::TYPE pull_type = (wtype==NetNet::SUPPLY1)
|
||||
? NetLogic::PULLUP
|
||||
: NetLogic::PULLDOWN;
|
||||
@@ -1191,14 +1203,6 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
pull->pin(0).drive1(IVL_DR_SUPPLY);
|
||||
des->add_node(pull);
|
||||
wtype = NetNet::WIRE;
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: "
|
||||
<< "Generate a SUPPLY pull for the ";
|
||||
if (wtype == NetNet::SUPPLY0) cerr << "supply0";
|
||||
else cerr << "supply1";
|
||||
cerr << " net." << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1209,15 +1213,17 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
// should already have been elaborated. All we need to
|
||||
// do right now is locate the netclass_t object for the
|
||||
// class, and use that to build the net.
|
||||
netclass_t*use_type = locate_class_type(des, scope, class_type);
|
||||
// (No arrays of classes)
|
||||
list<netrange_t> use_unpacked;
|
||||
sig = new NetNet(scope, name_, wtype, use_unpacked, use_type);
|
||||
|
||||
ivl_assert(*this, class_type->save_elaborated_type);
|
||||
netclass_t*use_type = class_type->save_elaborated_type;
|
||||
|
||||
sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_type);
|
||||
|
||||
} else if (struct_type_t*struct_type = dynamic_cast<struct_type_t*>(set_data_type_)) {
|
||||
// If this is a struct type, then build the net with the
|
||||
// struct type.
|
||||
netstruct_t*use_type = elaborate_struct_type(des, scope, struct_type);
|
||||
ivl_type_s*tmp_type = struct_type->elaborate_type(des, scope);
|
||||
netstruct_t*use_type = dynamic_cast<netstruct_t*>(tmp_type);
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Create signal " << wtype;
|
||||
if (use_type->packed())
|
||||
@@ -1228,11 +1234,11 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
cerr << " in scope " << scope_path(scope) << endl;
|
||||
}
|
||||
|
||||
sig = new NetNet(scope, name_, wtype, use_type);
|
||||
sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_type);
|
||||
|
||||
} else if (enum_type_t*enum_type = dynamic_cast<enum_type_t*>(set_data_type_)) {
|
||||
list<named_pexpr_t>::const_iterator sample_name = enum_type->names->begin();
|
||||
netenum_t*use_enum = scope->enumeration_for_name(sample_name->name);
|
||||
const netenum_t*use_enum = scope->find_enumeration_for_name(sample_name->name);
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Create signal " << wtype
|
||||
@@ -1246,7 +1252,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
sig = new NetNet(scope, name_, wtype, unpacked_dimensions, use_enum);
|
||||
|
||||
|
||||
} else if (netarray) {
|
||||
} else if (netdarray) {
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Create signal " << wtype
|
||||
@@ -1256,7 +1262,7 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
ivl_assert(*this, packed_dimensions.empty());
|
||||
ivl_assert(*this, unpacked_dimensions.empty());
|
||||
sig = new NetNet(scope, name_, wtype, netarray);
|
||||
sig = new NetNet(scope, name_, wtype, netdarray);
|
||||
|
||||
} else if (parray_type_t*parray_type = dynamic_cast<parray_type_t*>(set_data_type_)) {
|
||||
// The pform gives us a parray_type_t for packed arrays
|
||||
@@ -1266,13 +1272,13 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
// The trick here is that the parray type has an
|
||||
// arbitrary sub-type, and not just a scalar bit...
|
||||
netparray_t*use_type = elaborate_parray_type(des, scope, parray_type);
|
||||
// Should not be getting packed dimensions other then
|
||||
// Should not be getting packed dimensions other than
|
||||
// through the parray type declaration.
|
||||
ivl_assert(*this, packed_dimensions.empty());
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << get_fileline() << ": debug: Create signal " << wtype
|
||||
<< " parray=" << use_type->packed_dimensions()
|
||||
<< " parray=" << use_type->static_dimensions()
|
||||
<< " " << name_ << unpacked_dimensions
|
||||
<< " in scope " << scope_path(scope) << endl;
|
||||
}
|
||||
@@ -1327,3 +1333,27 @@ NetNet* PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
|
||||
void Design::root_elaborate_sig(void)
|
||||
{
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++ cur) {
|
||||
|
||||
netclass_t*cur_class = cur->second;
|
||||
PClass*cur_pclass = class_to_pclass_[cur_class];
|
||||
|
||||
cur_class->elaborate_sig(this, cur_pclass);
|
||||
}
|
||||
|
||||
for (map<NetScope*,PTaskFunc*>::iterator cur = root_tasks_.begin()
|
||||
; cur != root_tasks_.end() ; ++ cur) {
|
||||
|
||||
if (debug_elaborate) {
|
||||
cerr << cur->second->get_fileline() << ": root_elaborate_sig: "
|
||||
<< "Elaborate_sig for root task/func " << scope_path(cur->first) << endl;
|
||||
}
|
||||
|
||||
cur->second->elaborate_sig(this, cur->first);
|
||||
}
|
||||
}
|
||||
|
||||
+210
-3
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2012-2016 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
|
||||
@@ -17,15 +17,81 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "pform_types.h"
|
||||
# include "netlist.h"
|
||||
# include "netclass.h"
|
||||
# include "netdarray.h"
|
||||
# include "netenum.h"
|
||||
# include "netqueue.h"
|
||||
# include "netparray.h"
|
||||
# include "netscalar.h"
|
||||
# include "netstruct.h"
|
||||
# include "netvector.h"
|
||||
# include "netmisc.h"
|
||||
# include <typeinfo>
|
||||
# include "ivl_assert.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*) const
|
||||
/*
|
||||
* Some types have a list of ranges that need to be elaborated. This
|
||||
* function elaborates the ranges referenced by "dims" into the vector
|
||||
* "ranges".
|
||||
*/
|
||||
static void elaborate_array_ranges(Design*des, NetScope*scope,
|
||||
vector<netrange_t>&ranges,
|
||||
const list<pform_range_t>*dims)
|
||||
{
|
||||
if (dims == 0)
|
||||
return;
|
||||
|
||||
for (list<pform_range_t>::const_iterator cur = dims->begin()
|
||||
; cur != dims->end() ; ++ cur) {
|
||||
|
||||
NetExpr*me = elab_and_eval(des, scope, cur->first, 0, true);
|
||||
|
||||
NetExpr*le = elab_and_eval(des, scope, cur->second, 0, true);
|
||||
|
||||
/* If elaboration failed for either expression, we
|
||||
should have already reported the error, so just
|
||||
skip the following evaluation to recover. */
|
||||
|
||||
long mnum = 0, lnum = 0;
|
||||
if ( me && ! eval_as_long(mnum, me) ) {
|
||||
assert(0);
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if ( le && ! eval_as_long(lnum, le) ) {
|
||||
assert(0);
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
ranges.push_back(netrange_t(mnum, lnum));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborations of types may vary depending on the scope that it is
|
||||
* done in, so keep a per-scope cache of the results.
|
||||
*/
|
||||
ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*scope)
|
||||
{
|
||||
Definitions*use_definitions = scope;
|
||||
if (use_definitions == 0)
|
||||
use_definitions = des;
|
||||
|
||||
map<Definitions*,ivl_type_s*>::iterator pos = cache_type_elaborate_.lower_bound(use_definitions);
|
||||
if (pos != cache_type_elaborate_.end() && pos->first == use_definitions)
|
||||
return pos->second;
|
||||
|
||||
ivl_type_s*tmp = elaborate_type_raw(des, scope);
|
||||
cache_type_elaborate_.insert(pos, pair<NetScope*,ivl_type_s*>(scope, tmp));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
ivl_type_s* data_type_t::elaborate_type_raw(Design*des, NetScope*) const
|
||||
{
|
||||
cerr << get_fileline() << ": internal error: "
|
||||
<< "Elaborate method not implemented for " << typeid(*this).name()
|
||||
@@ -34,9 +100,15 @@ ivl_type_s* data_type_t::elaborate_type(Design*des, NetScope*) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
ivl_type_s* atom2_type_t::elaborate_type(Design*des, NetScope*) const
|
||||
ivl_type_s* atom2_type_t::elaborate_type_raw(Design*des, NetScope*) const
|
||||
{
|
||||
switch (type_code) {
|
||||
case 64:
|
||||
if (signed_flag)
|
||||
return &netvector_t::atom2s64;
|
||||
else
|
||||
return &netvector_t::atom2u64;
|
||||
|
||||
case 32:
|
||||
if (signed_flag)
|
||||
return &netvector_t::atom2s32;
|
||||
@@ -62,3 +134,138 @@ ivl_type_s* atom2_type_t::elaborate_type(Design*des, NetScope*) const
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ivl_type_s* class_type_t::elaborate_type_raw(Design*, NetScope*) const
|
||||
{
|
||||
ivl_assert(*this, save_elaborated_type);
|
||||
return save_elaborated_type;
|
||||
}
|
||||
|
||||
/*
|
||||
* elaborate_type_raw for enumerations is actually mostly performed
|
||||
* during scope elaboration so that the enumeration literals are
|
||||
* available at the right time. At that time, the netenum_t* object is
|
||||
* stashed in the scope so that I can retrieve it here.
|
||||
*/
|
||||
ivl_type_s* enum_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
{
|
||||
ivl_assert(*this, scope);
|
||||
ivl_type_s*tmp = scope->enumeration_for_key(this);
|
||||
if (tmp) return tmp;
|
||||
|
||||
tmp = des->enumeration_for_key(this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
ivl_type_s* vector_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
{
|
||||
vector<netrange_t> packed;
|
||||
elaborate_array_ranges(des, scope, packed, pdims.get());
|
||||
|
||||
netvector_t*tmp = new netvector_t(packed, base_type);
|
||||
tmp->set_signed(signed_flag);
|
||||
tmp->set_isint(integer_flag);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
ivl_type_s* real_type_t::elaborate_type_raw(Design*, NetScope*) const
|
||||
{
|
||||
switch (type_code) {
|
||||
case REAL:
|
||||
return &netreal_t::type_real;
|
||||
case SHORTREAL:
|
||||
return &netreal_t::type_shortreal;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
ivl_type_s* string_type_t::elaborate_type_raw(Design*, NetScope*) const
|
||||
{
|
||||
return &netstring_t::type_string;
|
||||
}
|
||||
|
||||
ivl_type_s* parray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
{
|
||||
vector<netrange_t>packed;
|
||||
elaborate_array_ranges(des, scope, packed, dims.get());
|
||||
|
||||
ivl_type_t etype = base_type->elaborate_type(des, scope);
|
||||
|
||||
return new netparray_t(packed, etype);
|
||||
}
|
||||
|
||||
netstruct_t* struct_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
{
|
||||
netstruct_t*res = new netstruct_t;
|
||||
|
||||
res->packed(packed_flag);
|
||||
|
||||
if (union_flag)
|
||||
res->union_flag(true);
|
||||
|
||||
for (list<struct_member_t*>::iterator cur = members->begin()
|
||||
; cur != members->end() ; ++ cur) {
|
||||
|
||||
// Elaborate the type of the member.
|
||||
struct_member_t*curp = *cur;
|
||||
ivl_type_t mem_vec = curp->type->elaborate_type(des, scope);
|
||||
if (mem_vec == 0)
|
||||
continue;
|
||||
|
||||
// There may be several names that are the same type:
|
||||
// <data_type> name1, name2, ...;
|
||||
// Process all the member, and give them a type.
|
||||
for (list<decl_assignment_t*>::iterator name = curp->names->begin()
|
||||
; name != curp->names->end() ; ++ name) {
|
||||
decl_assignment_t*namep = *name;
|
||||
|
||||
netstruct_t::member_t memb;
|
||||
memb.name = namep->name;
|
||||
memb.net_type = mem_vec;
|
||||
res->append_member(des, memb);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
ivl_type_s* uarray_type_t::elaborate_type_raw(Design*des, NetScope*scope) const
|
||||
{
|
||||
|
||||
ivl_type_t btype = base_type->elaborate_type(des, scope);
|
||||
|
||||
assert(dims->size() >= 1);
|
||||
list<pform_range_t>::const_iterator cur = dims->begin();
|
||||
|
||||
// Special case: if the dimension is nil:nil, this is a
|
||||
// dynamic array. Note that we only know how to handle dynamic
|
||||
// arrays with 1 dimension at a time.
|
||||
if (cur->first==0 && cur->second==0) {
|
||||
assert(dims->size()==1);
|
||||
ivl_type_s*res = new netdarray_t(btype);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Special case: if the dimension is null:nil. this is a queue.
|
||||
if (cur->second==0 && dynamic_cast<PENull*>(cur->first)) {
|
||||
cerr << get_fileline() << ": sorry: "
|
||||
<< "SV queues inside classes are not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
|
||||
ivl_type_s*res = new netqueue_t(btype);
|
||||
return res;
|
||||
}
|
||||
|
||||
vector<netrange_t> dimensions;
|
||||
bool bad_range = evaluate_ranges(des, scope, dimensions, *dims);
|
||||
|
||||
if (bad_range) {
|
||||
cerr << get_fileline() << " : warning: "
|
||||
<< "Bad dimensions for type here." << endl;
|
||||
}
|
||||
|
||||
ivl_assert(*this, btype);
|
||||
ivl_type_s*res = new netuarray_t(dimensions, btype);
|
||||
return res;
|
||||
}
|
||||
|
||||
+1655
-326
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-2013 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,7 +26,9 @@
|
||||
* target.
|
||||
*/
|
||||
# include "target.h"
|
||||
# include "netclass.h"
|
||||
# include "netlist.h"
|
||||
# include "compiler.h"
|
||||
# include <typeinfo>
|
||||
# include <cassert>
|
||||
# include <cstring>
|
||||
@@ -165,6 +167,11 @@ bool NetSignExtend::emit_node(struct target_t*tgt) const
|
||||
return tgt->sign_extend(this);
|
||||
}
|
||||
|
||||
bool NetSubstitute::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->substitute(this);
|
||||
}
|
||||
|
||||
bool NetUReduce::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->ureduce(this);
|
||||
@@ -259,6 +266,17 @@ bool NetDisable::emit_proc(struct target_t*tgt) const
|
||||
return tgt->proc_disable(this);
|
||||
}
|
||||
|
||||
bool NetDoWhile::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
tgt->proc_do_while(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetDoWhile::emit_proc_recurse(struct target_t*tgt) const
|
||||
{
|
||||
proc_->emit_proc(tgt);
|
||||
}
|
||||
|
||||
bool NetForce::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->proc_force(this);
|
||||
@@ -270,6 +288,11 @@ bool NetForever::emit_proc(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetForLoop::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->proc_block(as_block_);
|
||||
}
|
||||
|
||||
bool NetFree::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
tgt->proc_free(this);
|
||||
@@ -316,6 +339,11 @@ bool NetWhile::emit_proc(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetWhile::emit_proc_recurse(struct target_t*tgt) const
|
||||
{
|
||||
proc_->emit_proc(tgt);
|
||||
}
|
||||
|
||||
void NetBlock::emit_recurse(struct target_t*tgt) const
|
||||
{
|
||||
if (last_ == 0)
|
||||
@@ -378,20 +406,32 @@ void NetRepeat::emit_recurse(struct target_t*tgt) const
|
||||
statement_->emit_proc(tgt);
|
||||
}
|
||||
|
||||
void netclass_t::emit_scope(struct target_t*tgt) const
|
||||
{
|
||||
class_scope_->emit_scope(tgt);
|
||||
}
|
||||
|
||||
void NetScope::emit_scope(struct target_t*tgt) const
|
||||
{
|
||||
if (debug_emit) {
|
||||
cerr << "NetScope::emit_scope: "
|
||||
<< "Emit scope " << scope_path(this) << endl;
|
||||
}
|
||||
|
||||
tgt->scope(this);
|
||||
|
||||
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_)
|
||||
tgt->event(cur);
|
||||
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++cur)
|
||||
; cur != classes_.end() ; ++cur) {
|
||||
cur->second->emit_scope(tgt);
|
||||
tgt->class_type(this, cur->second);
|
||||
}
|
||||
|
||||
for (list<netenum_t*>::const_iterator cur = enum_sets_.begin()
|
||||
for (map<const enum_type_t*,netenum_t*>::const_iterator cur = enum_sets_.begin()
|
||||
; cur != enum_sets_.end() ; ++cur)
|
||||
tgt->enumeration(this, *cur);
|
||||
tgt->enumeration(this, cur->second);
|
||||
|
||||
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
|
||||
; cur != children_.end() ; ++ cur )
|
||||
@@ -420,11 +460,20 @@ bool NetScope::emit_defs(struct target_t*tgt) const
|
||||
{
|
||||
bool flag = true;
|
||||
|
||||
if (debug_emit) {
|
||||
cerr << "NetScope::emit_defs: "
|
||||
<< "Emit definitions for " << scope_path(this) << endl;
|
||||
}
|
||||
|
||||
switch (type_) {
|
||||
case PACKAGE:
|
||||
case MODULE:
|
||||
for (map<hname_t,NetScope*>::const_iterator cur = children_.begin()
|
||||
; cur != children_.end() ; ++ cur )
|
||||
flag &= cur->second->emit_defs(tgt);
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++ cur)
|
||||
flag &= cur->second->emit_defs(tgt);
|
||||
break;
|
||||
|
||||
case FUNC:
|
||||
@@ -443,9 +492,9 @@ bool NetScope::emit_defs(struct target_t*tgt) const
|
||||
return flag;
|
||||
}
|
||||
|
||||
void NetWhile::emit_proc_recurse(struct target_t*tgt) const
|
||||
bool netclass_t::emit_defs(struct target_t*tgt) const
|
||||
{
|
||||
proc_->emit_proc(tgt);
|
||||
return class_scope_->emit_defs(tgt);
|
||||
}
|
||||
|
||||
int Design::emit(struct target_t*tgt) const
|
||||
@@ -455,11 +504,29 @@ int Design::emit(struct target_t*tgt) const
|
||||
if (tgt->start_design(this) == false)
|
||||
return -2;
|
||||
|
||||
// enumerate the scopes
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); ++ scope )
|
||||
(*scope)->emit_scope(tgt);
|
||||
for (map<NetScope*,PTaskFunc*>::const_iterator scope = root_tasks_.begin()
|
||||
; scope != root_tasks_.end() ; ++ scope) {
|
||||
scope->first->emit_scope(tgt);
|
||||
}
|
||||
|
||||
// enumerate package scopes
|
||||
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
|
||||
; scope != packages_.end() ; ++ scope) {
|
||||
scope->second->emit_scope(tgt);
|
||||
}
|
||||
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++cur) {
|
||||
const NetScope*use_scope = cur->second->class_scope();
|
||||
cur->second->emit_scope(tgt);
|
||||
tgt->class_type(use_scope, cur->second);
|
||||
}
|
||||
|
||||
// enumerate root scopes
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
|
||||
; scope != root_scopes_.end(); ++ scope ) {
|
||||
(*scope)->emit_scope(tgt);
|
||||
}
|
||||
|
||||
// emit nodes
|
||||
bool nodes_rc = true;
|
||||
@@ -479,8 +546,17 @@ int Design::emit(struct target_t*tgt) const
|
||||
|
||||
// emit task and function definitions
|
||||
bool tasks_rc = true;
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); ++ scope )
|
||||
for (map<NetScope*,PTaskFunc*>::const_iterator scope = root_tasks_.begin()
|
||||
; scope != root_tasks_.end() ; ++ scope)
|
||||
tasks_rc &= scope->first->emit_defs(tgt);
|
||||
for (map<perm_string,netclass_t*>::const_iterator cur = classes_.begin()
|
||||
; cur != classes_.end() ; ++cur)
|
||||
tasks_rc &= cur->second->emit_defs(tgt);
|
||||
for (map<perm_string,NetScope*>::const_iterator scope = packages_.begin()
|
||||
; scope != packages_.end() ; ++ scope )
|
||||
tasks_rc &= scope->second->emit_defs(tgt);
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
|
||||
; scope != root_scopes_.end(); ++ scope )
|
||||
tasks_rc &= (*scope)->emit_defs(tgt);
|
||||
|
||||
|
||||
@@ -491,6 +567,15 @@ int Design::emit(struct target_t*tgt) const
|
||||
for (const NetAnalogTop*idx = aprocs_ ; idx ; idx = idx->next_)
|
||||
proc_rc &= idx->emit(tgt);
|
||||
|
||||
if (nodes_rc == false)
|
||||
tgt->errors += 1;
|
||||
if (tasks_rc == false)
|
||||
tgt->errors += 1;
|
||||
if (proc_rc == false)
|
||||
tgt->errors += 1;
|
||||
if (branches_rc == false)
|
||||
tgt->errors += 1;
|
||||
|
||||
rc = tgt->end_design(this);
|
||||
|
||||
if (nodes_rc == false)
|
||||
@@ -498,7 +583,7 @@ int Design::emit(struct target_t*tgt) const
|
||||
if (tasks_rc == false)
|
||||
return -2;
|
||||
if (proc_rc == false)
|
||||
return -3;
|
||||
return -3;
|
||||
if (branches_rc == false)
|
||||
return -4;
|
||||
|
||||
@@ -510,6 +595,11 @@ void NetEAccess::expr_scan(struct expr_scan_t*tgt) const
|
||||
tgt->expr_access_func(this);
|
||||
}
|
||||
|
||||
void NetEArrayPattern::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_array_pattern(this);
|
||||
}
|
||||
|
||||
void NetEBinary::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_binary(this);
|
||||
@@ -550,6 +640,11 @@ void NetEEvent::expr_scan(struct expr_scan_t*tgt) const
|
||||
tgt->expr_event(this);
|
||||
}
|
||||
|
||||
void NetELast::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_last(this);
|
||||
}
|
||||
|
||||
void NetENetenum::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_netenum(this);
|
||||
@@ -585,6 +680,21 @@ void NetESFunc::expr_scan(struct expr_scan_t*tgt) const
|
||||
tgt->expr_sfunc(this);
|
||||
}
|
||||
|
||||
void NetEShallowCopy::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_scopy(this);
|
||||
}
|
||||
|
||||
void NetEShallowCopy::expr_scan_oper1(struct expr_scan_t*tgt) const
|
||||
{
|
||||
arg1_->expr_scan(tgt);
|
||||
}
|
||||
|
||||
void NetEShallowCopy::expr_scan_oper2(struct expr_scan_t*tgt) const
|
||||
{
|
||||
arg2_->expr_scan(tgt);
|
||||
}
|
||||
|
||||
void NetEUFunc::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_ufunc(this);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-1999 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1998-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
|
||||
@@ -44,6 +44,14 @@ verinum* PEBinary::eval_const(Design*des, NetScope*scope) const
|
||||
verinum*res;
|
||||
|
||||
switch (op_) {
|
||||
case 'p': {
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
res = new verinum(pow(*l, *r));
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '+': {
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
res = new verinum(*l + *r);
|
||||
@@ -261,7 +269,7 @@ verinum* PEUnary::eval_const(Design*des, NetScope*scope) const
|
||||
for (unsigned idx = 0 ; idx < val->len() ; idx += 1)
|
||||
tmp.set(idx, val->get(idx));
|
||||
|
||||
*val = v_not(tmp) + verinum(verinum::V1, 1);
|
||||
*val = -tmp;
|
||||
val->has_sign(true);
|
||||
return val;
|
||||
}
|
||||
|
||||
+795
-476
File diff suppressed because it is too large
Load Diff
+53
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2012 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2015 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
|
||||
@@ -274,7 +274,7 @@ NetNet* NetEBComp::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
|
||||
if (op_ == 'E' || op_ == 'N') {
|
||||
NetCaseCmp*gate = new NetCaseCmp(scope, scope->local_symbol(),
|
||||
width, op_=='E'?true:false);
|
||||
width, op_=='E'?NetCaseCmp::EEQ:NetCaseCmp::NEQ);
|
||||
gate->set_line(*this);
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
connect(gate->pin(1), lsig->pin(0));
|
||||
@@ -615,7 +615,8 @@ NetNet* NetEBShift::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
// to the amount left by the shift.
|
||||
NetPartSelect*psel = new NetPartSelect(lsig, shift<0? ushift : 0,
|
||||
part_width,
|
||||
NetPartSelect::VP);
|
||||
NetPartSelect::VP,
|
||||
signed_flag && right_flag);
|
||||
psel->set_line(*this);
|
||||
des->add_node(psel);
|
||||
|
||||
@@ -980,7 +981,10 @@ NetNet* NetECast::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
|
||||
switch (op()) {
|
||||
case 'v':
|
||||
isig = cast_to_int4(des, scope, isig, isig->vector_width());
|
||||
isig = cast_to_int4(des, scope, isig, expr_width());
|
||||
break;
|
||||
case '2':
|
||||
isig = cast_to_int2(des, scope, isig, expr_width());
|
||||
break;
|
||||
case 'r':
|
||||
isig = cast_to_real(des, scope, isig);
|
||||
@@ -1134,18 +1138,29 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
||||
if (sub->vector_width() == expr_width())
|
||||
return sub;
|
||||
|
||||
// The vector_width is not exactly right, so the source is
|
||||
// probably asking for padding. Create nodes to do sign
|
||||
// extension or 0 extension, depending on the has_sign() mode
|
||||
// of the expression.
|
||||
|
||||
netvector_t*net_vec = new netvector_t(expr_type(), expr_width()-1, 0);
|
||||
net_vec->set_signed(has_sign());
|
||||
NetNet*net = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, net_vec);
|
||||
net->set_line(*this);
|
||||
net->local_flag(true);
|
||||
if (has_sign()) {
|
||||
|
||||
// It may still happen that the expression is wider than the selection,
|
||||
// and there was no part select created earlier (size casting).
|
||||
if(expr_width() < sub->vector_width()) {
|
||||
NetPartSelect*sel = new NetPartSelect(sub, 0, expr_width(),
|
||||
NetPartSelect::VP, has_sign());
|
||||
sel->set_line(*this);
|
||||
des->add_node(sel);
|
||||
|
||||
connect(net->pin(0), sel->pin(0));
|
||||
|
||||
// The vector_width is not exactly right, so the source is
|
||||
// probably asking for padding. Create nodes to do sign
|
||||
// extension or 0 extension, depending on the has_sign() mode
|
||||
// of the expression.
|
||||
|
||||
} else if (has_sign()) {
|
||||
NetSignExtend*pad = new NetSignExtend(scope,
|
||||
scope->local_symbol(),
|
||||
expr_width());
|
||||
@@ -1162,7 +1177,6 @@ NetNet* NetESelect::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
||||
cat->set_line(*this);
|
||||
des->add_node(cat);
|
||||
|
||||
assert(expr_width() > sub->vector_width());
|
||||
unsigned pad_width = expr_width() - sub->vector_width();
|
||||
verinum pad((uint64_t)0, pad_width);
|
||||
NetConst*con = new NetConst(scope, scope->local_symbol(),
|
||||
@@ -1267,6 +1281,24 @@ NetNet* NetETernary::synthesize(Design *des, NetScope*scope, NetExpr*root)
|
||||
*/
|
||||
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);
|
||||
NetNet*tmp = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, tmp_vec);
|
||||
tmp->set_line(*this);
|
||||
tmp->local_flag(true);
|
||||
verinum tmp_val ((uint64_t)scope->genvar_tmp_val, net_->vector_width());
|
||||
NetConst*tmp_const = new NetConst(scope, scope->local_symbol(), tmp_val);
|
||||
tmp_const->set_line(*this);
|
||||
des->add_node(tmp_const);
|
||||
|
||||
connect(tmp->pin(0), tmp_const->pin(0));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
if (word_ == 0)
|
||||
return net_;
|
||||
|
||||
@@ -1306,16 +1338,16 @@ static NetEvWait* make_func_trigger(Design*des, NetScope*scope, NetExpr*root)
|
||||
NetEvWait*trigger = 0;
|
||||
|
||||
NexusSet*nset = root->nex_input(false);
|
||||
if (nset && (nset->count() > 0)) {
|
||||
if (nset && (nset->size() > 0)) {
|
||||
NetEvent*ev = new NetEvent(scope->local_symbol());
|
||||
ev->set_line(*root);
|
||||
|
||||
NetEvProbe*pr = new NetEvProbe(scope, scope->local_symbol(),
|
||||
ev, NetEvProbe::ANYEDGE,
|
||||
nset->count());
|
||||
nset->size());
|
||||
pr->set_line(*root);
|
||||
for (unsigned idx = 0 ; idx < nset->count() ; idx += 1)
|
||||
connect(nset[0][idx], pr->pin(idx));
|
||||
for (unsigned idx = 0 ; idx < nset->size() ; idx += 1)
|
||||
connect(nset->at(idx).lnk, pr->pin(idx));
|
||||
|
||||
des->add_node(pr);
|
||||
|
||||
@@ -1436,6 +1468,12 @@ NetNet* NetEUFunc::synthesize(Design*des, NetScope*scope, NetExpr*root)
|
||||
osig->local_flag(true);
|
||||
connect(net->pin(0), osig->pin(0));
|
||||
|
||||
if (debug_synth2) {
|
||||
cerr << get_fileline() << ": NetEUFunc::synthesize: "
|
||||
<< "result_sig_->vector_width()=" << result_sig_->vector_width()
|
||||
<< ", osig->vector_width()=" << osig->vector_width() << endl;
|
||||
}
|
||||
|
||||
/* Connect the pins to the arguments. */
|
||||
NetFuncDef*def = func_->func_def();
|
||||
for (unsigned idx = 0; idx < eparms.size(); idx += 1) {
|
||||
|
||||
+20
@@ -24,6 +24,8 @@
|
||||
# include "functor.h"
|
||||
# include "netlist.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
functor_t::~functor_t()
|
||||
{
|
||||
}
|
||||
@@ -52,6 +54,10 @@ void functor_t::lpm_compare(Design*, NetCompare*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_concat(Design*, NetConcat*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_const(Design*, NetConst*)
|
||||
{
|
||||
}
|
||||
@@ -84,6 +90,10 @@ void functor_t::lpm_mux(Design*, NetMux*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_part_select(Design*, NetPartSelect*)
|
||||
{
|
||||
}
|
||||
|
||||
void functor_t::lpm_pow(Design*, NetPow*)
|
||||
{
|
||||
}
|
||||
@@ -185,6 +195,11 @@ void NetCompare::functor_node(Design*des, functor_t*fun)
|
||||
fun->lpm_compare(des, this);
|
||||
}
|
||||
|
||||
void NetConcat::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_concat(des, this);
|
||||
}
|
||||
|
||||
void NetConst::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_const(des, this);
|
||||
@@ -225,6 +240,11 @@ void NetMux::functor_node(Design*des, functor_t*fun)
|
||||
fun->lpm_mux(des, this);
|
||||
}
|
||||
|
||||
void NetPartSelect::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_part_select(des, this);
|
||||
}
|
||||
|
||||
void NetPow::functor_node(Design*des, functor_t*fun)
|
||||
{
|
||||
fun->lpm_pow(des, this);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __functor_H
|
||||
#define __functor_H
|
||||
#ifndef IVL_functor_H
|
||||
#define IVL_functor_H
|
||||
/*
|
||||
* Copyright (c) 1999-2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-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
|
||||
@@ -57,6 +57,9 @@ struct functor_t {
|
||||
/* This method is called for each structural comparator. */
|
||||
virtual void lpm_compare(class Design*des, class NetCompare*);
|
||||
|
||||
/* This method is called for each structural concatenation. */
|
||||
virtual void lpm_concat(class Design*des, class NetConcat*);
|
||||
|
||||
/* This method is called for each structural constant. */
|
||||
virtual void lpm_const(class Design*des, class NetConst*);
|
||||
|
||||
@@ -81,6 +84,8 @@ struct functor_t {
|
||||
/* This method is called for each MUX. */
|
||||
virtual void lpm_mux(class Design*des, class NetMux*);
|
||||
|
||||
virtual void lpm_part_select(class Design*des, class NetPartSelect*);
|
||||
|
||||
/* This method is called for each power. */
|
||||
virtual void lpm_pow(class Design*des, class NetPow*);
|
||||
|
||||
@@ -100,4 +105,4 @@ struct proc_match_t {
|
||||
virtual int block(class NetBlock*);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_functor_H */
|
||||
|
||||
+39
-47
@@ -1,10 +1,10 @@
|
||||
.TH iverilog-vpi 1 "April 17th, 2009" "" "Version %M.%m.%n %E"
|
||||
.TH iverilog-vpi 1 "Jan 29th, 2017" "" "Version %M.%n%E"
|
||||
.SH NAME
|
||||
iverilog-vpi - Compile front end for VPI modules
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog-vpi
|
||||
[\-\-name=\fIname\fP]
|
||||
[options]
|
||||
\fIsourcefile\fP...
|
||||
|
||||
.SH DESCRIPTION
|
||||
@@ -15,9 +15,9 @@ list of C or C++ source files, and generates as output a linked VPI
|
||||
module. See the \fBvvp\fP(1) man page for a description of how the
|
||||
linked module is loaded by a simulation.
|
||||
|
||||
The output is named after the first source file. For example, if the
|
||||
first source file is named \fIfoo.c\fP, the output becomes
|
||||
\fIfoo.vpi\fP.
|
||||
By default the output is named after the first source file. For
|
||||
example, if the first source file is named \fIfoo.c\fP, the output
|
||||
becomes \fIfoo.vpi\fP.
|
||||
|
||||
.SH OPTIONS
|
||||
\fIiverilog\-vpi\fP accepts the following options:
|
||||
@@ -26,10 +26,15 @@ first source file is named \fIfoo.c\fP, the output becomes
|
||||
Include the named library in the link of the VPI module. This allows
|
||||
VPI modules to further reference external libraries.
|
||||
|
||||
.TP 8
|
||||
.B -L\fIdirectory\fP
|
||||
Add \fIdirectory\fP to the list of directories that will be searched
|
||||
for library files.
|
||||
|
||||
.TP 8
|
||||
.B -I\fIdirectory\fP
|
||||
Add \fIdirectory\fP to the list of directories that will be search for
|
||||
header files.
|
||||
Add \fIdirectory\fP to the list of directories that will be searched
|
||||
for header files.
|
||||
|
||||
.TP 8
|
||||
.B -D\fIdefine\fP
|
||||
@@ -41,46 +46,38 @@ Normally, the output VPI module will be named after the first source
|
||||
file passed to the command. This flag sets the name (without the .vpi
|
||||
suffix) of the output vpi module.
|
||||
|
||||
.TP 8
|
||||
.B --install-dir
|
||||
This flag causes the program to print the install directory for VPI
|
||||
modules, then exit. It is a convenience for makefiles or automated
|
||||
plug-in installers.
|
||||
|
||||
.TP 8
|
||||
.B --cflags, --ldflags and --ldlibs
|
||||
These flags provide compile time information.
|
||||
|
||||
.SH "PC-ONLY OPTIONS"
|
||||
|
||||
The PC port of \fIiverilog\-vpi\fP includes two special flags needed to
|
||||
support the more intractable development environment. These flags help
|
||||
the program locate parts that it needs.
|
||||
When built as a native Windows program (using the MinGW toolchain),
|
||||
by default \fIiverilog\-vpi\fP will attempt to locate the MinGW tools
|
||||
needed to compile a VPI module on the system path (as set by the PATH
|
||||
environment variable). As an alternative, the user may specify the
|
||||
location of the MinGW tools via the following option.
|
||||
|
||||
.TP 8
|
||||
.B -mingw=\fIpath\fP
|
||||
Tell the program the root of the Mingw compiler tool suite. The
|
||||
Tell the program the root of the MinGW compiler tool suite. The
|
||||
\fBvvp\fP runtime is compiled with this compiler, and this is the
|
||||
compiler that \fIiverilog\-vpi\fP expects to use to compile your source
|
||||
code. This is normally not needed, and if you do use it, it is only
|
||||
needed once. The compiler will save the \fIpath\fP in the registry for
|
||||
use later.
|
||||
compiler that \fIiverilog\-vpi\fP expects to use to compile your
|
||||
source code. If this option accompanies a list of files, it will
|
||||
apply to the current build only. If this option is provided on its
|
||||
own, \fIiverilog\-vpi\fP will save the \fIpath\fP in the registry
|
||||
and use that path in preference to the system path for subsequent
|
||||
operations, avoiding the need to specify it on the command line
|
||||
every time.
|
||||
|
||||
.SH "INFORMATIONAL OPTIONS"
|
||||
|
||||
\fIiverilog\-vpi\fP includes additional flags to let Makefile gurus
|
||||
peek at the configuration of the \fIiverilog\fP installation. This way,
|
||||
Makefiles can be written that handle complex VPI builds natively, and
|
||||
without hard-coding values that depend on the system and installation.
|
||||
If used at all, these options must be used one at a time, and without
|
||||
any other options or directives.
|
||||
|
||||
.TP 8
|
||||
.B -ivl=\fIpath\fP
|
||||
Set for the use during compilation the root if the Icarus Verilog
|
||||
install. This is the place where you installed Icarus Verilog when you
|
||||
ran the installer. This flag is also only needed once, and the path is
|
||||
stored in the registry for future use.
|
||||
|
||||
.SH "UNIX-ONLY OPTIONS"
|
||||
|
||||
The UNIX version of \fIiverilog\-vpi\fP includes additional flags to
|
||||
let Makefile gurus peek at the configuration of the \fIiverilog\fP
|
||||
installation. This way, Makefiles can be written that handle complex VPI
|
||||
builds natively, and without hard-coding values that depend on the
|
||||
system and installation. If used at all, these options must be
|
||||
used one at a time, and without any other options or directives.
|
||||
.B --install-dir
|
||||
Print the install directory for VPI modules.
|
||||
|
||||
.TP 8
|
||||
.B --cflags
|
||||
@@ -95,11 +92,6 @@ Print the linker flags (LDFLAGS) needed to link a VPI module.
|
||||
.B --ldlibs
|
||||
Print the libraries (LDLIBS) needed to link a VPI module.
|
||||
|
||||
.TP 8
|
||||
.B -m32
|
||||
On 64bit systems that support it (and support vvp32) this flag
|
||||
requests a 32bit vpi binary instead of the default 64bit binary.
|
||||
|
||||
.P
|
||||
Example GNU makefile that takes advantage of these flags:
|
||||
.IP "" 4
|
||||
@@ -123,12 +115,12 @@ Steve Williams ([email protected])
|
||||
|
||||
.SH SEE ALSO
|
||||
iverilog(1), vvp(1),
|
||||
.BR "<http://www.icarus.com/eda/verilog/>",
|
||||
.BR "<http://www.mingw.org>",
|
||||
.BR "<http://iverilog.icarus.com/>",
|
||||
.BR "<http://mingw-w64.yaxm.org/>",
|
||||
|
||||
.SH COPYRIGHT
|
||||
.nf
|
||||
Copyright \(co 2002\-2009 Stephen Williams
|
||||
Copyright \(co 2002\-2017 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
|
||||
+5
-1
@@ -35,6 +35,7 @@ CCSRC=
|
||||
CXSRC=
|
||||
OBJ=
|
||||
LIB=
|
||||
LIBDIR=
|
||||
OUT=
|
||||
INCOPT=
|
||||
DEFS=
|
||||
@@ -81,6 +82,9 @@ do
|
||||
-l*) LIB="$LIB $parm"
|
||||
;;
|
||||
|
||||
-L*) LIBDIR="$LIBDIR $parm"
|
||||
;;
|
||||
|
||||
-I*) INCOPT="$INCOPT $parm"
|
||||
;;
|
||||
|
||||
@@ -148,4 +152,4 @@ then
|
||||
fi
|
||||
|
||||
echo "Making $OUT from $OBJ..."
|
||||
exec $LD -o $OUT $LDFLAGS $OBJ $LIB $LDLIBS
|
||||
exec $LD -o $OUT $LDFLAGS $LIBDIR $OBJ $LIB $LDLIBS
|
||||
|
||||
@@ -125,6 +125,7 @@ ivl_lpm_enable
|
||||
ivl_lpm_file
|
||||
ivl_lpm_lineno
|
||||
ivl_lpm_name
|
||||
ivl_lpm_negedge
|
||||
ivl_lpm_q
|
||||
ivl_lpm_scope
|
||||
ivl_lpm_select
|
||||
@@ -141,6 +142,7 @@ ivl_lpm_width
|
||||
|
||||
ivl_lval_idx
|
||||
ivl_lval_mux
|
||||
ivl_lval_nest
|
||||
ivl_lval_part_off
|
||||
ivl_lval_property_idx
|
||||
ivl_lval_sel_type
|
||||
@@ -170,6 +172,11 @@ ivl_parameter_expr
|
||||
ivl_parameter_file
|
||||
ivl_parameter_lineno
|
||||
ivl_parameter_local
|
||||
ivl_parameter_lsb
|
||||
ivl_parameter_msb
|
||||
ivl_parameter_scope
|
||||
ivl_parameter_signed
|
||||
ivl_parameter_width
|
||||
|
||||
ivl_path_condit
|
||||
ivl_path_delay
|
||||
@@ -192,6 +199,8 @@ ivl_scope_attr_cnt
|
||||
ivl_scope_attr_val
|
||||
ivl_scope_basename
|
||||
ivl_scope_children
|
||||
ivl_scope_child
|
||||
ivl_scope_childs
|
||||
ivl_scope_class
|
||||
ivl_scope_classes
|
||||
ivl_scope_def
|
||||
@@ -313,6 +322,7 @@ ivl_type_packed_msb
|
||||
ivl_type_prop_name
|
||||
ivl_type_prop_type
|
||||
ivl_type_properties
|
||||
ivl_type_signed
|
||||
|
||||
ivl_udp_init
|
||||
ivl_udp_file
|
||||
|
||||
+6
-4
@@ -1,7 +1,7 @@
|
||||
#ifndef __ivl_alloc_H
|
||||
#define __ivl_alloc_H
|
||||
#ifndef IVL_ivl_alloc_H
|
||||
#define IVL_ivl_alloc_H
|
||||
/*
|
||||
* Copyright (C) 2010 Cary R. (cygcary@yahoo.com)
|
||||
* Copyright (C) 2010-2014 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
|
||||
@@ -26,6 +26,7 @@
|
||||
# include <stdio.h>
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
/*
|
||||
* Define a safer version of malloc().
|
||||
*/
|
||||
@@ -82,5 +83,6 @@
|
||||
} \
|
||||
__ivl_rtn; \
|
||||
})
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* IVL_ivl_alloc_H */
|
||||
|
||||
+4
-5
@@ -1,5 +1,7 @@
|
||||
#ifndef IVL_ivl_assert_H
|
||||
#define IVL_ivl_assert_H
|
||||
/*
|
||||
* Copyright (c) 2007-2010 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2007-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
|
||||
@@ -17,9 +19,6 @@
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ivl_assert_h
|
||||
#define __ivl_assert_h
|
||||
|
||||
# include <cstdlib>
|
||||
|
||||
#define ivl_assert(tok, expression) \
|
||||
@@ -32,4 +31,4 @@
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
#endif /* IVL_ivl_assert_H */
|
||||
|
||||
+106
-32
@@ -1,7 +1,7 @@
|
||||
#ifndef __ivl_target_H
|
||||
#define __ivl_target_H
|
||||
#ifndef IVL_ivl_target_H
|
||||
#define IVL_ivl_target_H
|
||||
/*
|
||||
* Copyright (c) 2000-2012 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2015 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
|
||||
@@ -20,10 +20,11 @@
|
||||
*/
|
||||
|
||||
# include <inttypes.h>
|
||||
# include <stddef.h>
|
||||
|
||||
/* Re the _CLASS define: clang++ wants this to be class to match the
|
||||
* definition, but clang (the C) compiler needs it to be a struct
|
||||
* since class is not defined in C. They are effecively both pointers
|
||||
* since class is not defined in C. They are effectively both pointers
|
||||
* to an object so everything works out. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -40,6 +41,12 @@
|
||||
# define __attribute__(x)
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus) && defined(_MSC_VER)
|
||||
# define ENUM_UNSIGNED_INT : unsigned int
|
||||
#else
|
||||
# define ENUM_UNSIGNED_INT
|
||||
#endif
|
||||
|
||||
_BEGIN_DECL
|
||||
|
||||
/*
|
||||
@@ -165,7 +172,7 @@ typedef struct ivl_branch_s *ivl_branch_t;
|
||||
typedef struct ivl_delaypath_s*ivl_delaypath_t;
|
||||
typedef struct ivl_design_s *ivl_design_t;
|
||||
typedef _CLASS ivl_discipline_s*ivl_discipline_t;
|
||||
typedef _CLASS netenum_t *ivl_enumtype_t;
|
||||
typedef const _CLASS netenum_t*ivl_enumtype_t;
|
||||
typedef struct ivl_event_s *ivl_event_t;
|
||||
typedef struct ivl_expr_s *ivl_expr_t;
|
||||
typedef struct ivl_island_s *ivl_island_t;
|
||||
@@ -200,7 +207,7 @@ typedef enum ivl_dis_domain_e {
|
||||
IVL_DIS_CONTINUOUS = 2
|
||||
} ivl_dis_domain_t;
|
||||
|
||||
typedef enum ivl_drive_e {
|
||||
typedef enum ivl_drive_e ENUM_UNSIGNED_INT {
|
||||
IVL_DR_HiZ = 0,
|
||||
IVL_DR_SMALL = 1,
|
||||
IVL_DR_MEDIUM = 2,
|
||||
@@ -227,11 +234,13 @@ typedef enum ivl_expr_type_e {
|
||||
IVL_EX_NEW = 23,
|
||||
IVL_EX_NULL = 22,
|
||||
IVL_EX_NUMBER = 5,
|
||||
IVL_EX_ARRAY_PATTERN = 26,
|
||||
IVL_EX_PROPERTY = 24,
|
||||
IVL_EX_REALNUM = 16,
|
||||
IVL_EX_SCOPE = 6,
|
||||
IVL_EX_SELECT = 7,
|
||||
IVL_EX_SFUNC = 8,
|
||||
IVL_EX_SHALLOWCOPY = 25,
|
||||
IVL_EX_SIGNAL = 9,
|
||||
IVL_EX_STRING = 10,
|
||||
IVL_EX_TERNARY = 11,
|
||||
@@ -240,7 +249,7 @@ typedef enum ivl_expr_type_e {
|
||||
IVL_EX_UNARY = 14
|
||||
} ivl_expr_type_t;
|
||||
|
||||
typedef enum ivl_select_type_e {
|
||||
typedef enum ivl_select_type_e ENUM_UNSIGNED_INT {
|
||||
IVL_SEL_OTHER = 0,
|
||||
IVL_SEL_IDX_UP = 1,
|
||||
IVL_SEL_IDX_DOWN = 2
|
||||
@@ -295,7 +304,10 @@ typedef enum ivl_lpm_type_e {
|
||||
IVL_LPM_CAST_INT2 = 35,
|
||||
IVL_LPM_CAST_REAL = 33,
|
||||
IVL_LPM_CONCAT = 16,
|
||||
IVL_LPM_CONCATZ = 36, /* Transparent concat */
|
||||
IVL_LPM_CMP_EEQ= 18, /* Case EQ (===) */
|
||||
IVL_LPM_CMP_EQX= 37, /* Wildcard EQ (==?) */
|
||||
IVL_LPM_CMP_EQZ= 38, /* casez EQ */
|
||||
IVL_LPM_CMP_EQ = 10,
|
||||
IVL_LPM_CMP_GE = 1,
|
||||
IVL_LPM_CMP_GT = 2,
|
||||
@@ -322,6 +334,7 @@ typedef enum ivl_lpm_type_e {
|
||||
IVL_LPM_SHIFTR = 7,
|
||||
IVL_LPM_SIGN_EXT=27,
|
||||
IVL_LPM_SUB = 8,
|
||||
IVL_LPM_SUBSTITUTE=39,
|
||||
/* IVL_LPM_RAM = 9, / obsolete */
|
||||
IVL_LPM_UFUNC = 14
|
||||
} ivl_lpm_type_t;
|
||||
@@ -338,7 +351,7 @@ typedef enum ivl_path_edge_e {
|
||||
|
||||
/* Processes are initial, always, or final blocks with a statement. This is
|
||||
the type of the ivl_process_t object. */
|
||||
typedef enum ivl_process_type_e {
|
||||
typedef enum ivl_process_type_e ENUM_UNSIGNED_INT {
|
||||
IVL_PR_INITIAL = 0,
|
||||
IVL_PR_ALWAYS = 1,
|
||||
IVL_PR_FINAL = 2
|
||||
@@ -352,7 +365,9 @@ typedef enum ivl_scope_type_e {
|
||||
IVL_SCT_TASK = 2,
|
||||
IVL_SCT_BEGIN = 3,
|
||||
IVL_SCT_FORK = 4,
|
||||
IVL_SCT_GENERATE= 5
|
||||
IVL_SCT_GENERATE= 5,
|
||||
IVL_SCT_PACKAGE = 6,
|
||||
IVL_SCT_CLASS = 7
|
||||
} ivl_scope_type_t;
|
||||
|
||||
/* Signals (ivl_signal_t) that are ports into the scope that contains
|
||||
@@ -397,6 +412,7 @@ typedef enum ivl_statement_type_e {
|
||||
IVL_ST_DELAY = 11,
|
||||
IVL_ST_DELAYX = 12,
|
||||
IVL_ST_DISABLE = 13,
|
||||
IVL_ST_DO_WHILE = 30,
|
||||
IVL_ST_FORCE = 14,
|
||||
IVL_ST_FOREVER = 15,
|
||||
IVL_ST_FORK = 16,
|
||||
@@ -421,7 +437,7 @@ typedef enum ivl_sfunc_as_task_e {
|
||||
|
||||
/* This is the type of a variable, and also used as the type for an
|
||||
expression. */
|
||||
typedef enum ivl_variable_type_e {
|
||||
typedef enum ivl_variable_type_e ENUM_UNSIGNED_INT {
|
||||
IVL_VT_VOID = 0, /* Not used */
|
||||
IVL_VT_NO_TYPE = 1, /* Place holder for missing/unknown type. */
|
||||
IVL_VT_REAL = 2,
|
||||
@@ -430,6 +446,7 @@ typedef enum ivl_variable_type_e {
|
||||
IVL_VT_STRING = 5,
|
||||
IVL_VT_DARRAY = 6, /* Array (esp. dynamic array) */
|
||||
IVL_VT_CLASS = 7, /* SystemVerilog class instances */
|
||||
IVL_VT_QUEUE = 8, /* SystemVerilog queue instances */
|
||||
IVL_VT_VECTOR = IVL_VT_LOGIC /* For compatibility */
|
||||
} ivl_variable_type_t;
|
||||
|
||||
@@ -770,7 +787,7 @@ extern unsigned ivl_event_lineno(ivl_event_t net);
|
||||
*
|
||||
* ivl_expr_net_type
|
||||
* This is used in some cases to carry more advanced type
|
||||
* descriptions. Over the long run, all type informatino will be
|
||||
* descriptions. Over the long run, all type information will be
|
||||
* moved into the ivl_type_t type description method.
|
||||
*
|
||||
* ivl_expr_width
|
||||
@@ -821,6 +838,20 @@ extern unsigned ivl_event_lineno(ivl_event_t net);
|
||||
* table. That number can be passed to ivl_type_prop_*() functions to
|
||||
* get details about the property.
|
||||
*
|
||||
* If the property is an array, then the ivl_expr_oper1() function
|
||||
* returns the canonical expression for accessing the element of the
|
||||
* property.
|
||||
*
|
||||
* - IVL_EX_NEW
|
||||
* This expression takes one or two operands. The first operand,
|
||||
* returned by ivl_expr_oper1() is the number of elements to create
|
||||
* for the dynamic array. The second operand, if present, is returned
|
||||
* by the ivl_expr_oper2() function. If this returns a non-nil
|
||||
* expression, it is the initial value to be written to the elements
|
||||
* of the array. If the expression is an IVL_EX_ARRAY_PATTERN, then
|
||||
* this is the very special case of a list of values to be written to
|
||||
* array elements.
|
||||
*
|
||||
* - IVL_EX_SELECT
|
||||
* This expression takes two operands, oper1 is the expression to
|
||||
* select from, and oper2 is the selection base. The ivl_expr_width
|
||||
@@ -829,9 +860,9 @@ extern unsigned ivl_event_lineno(ivl_event_t net);
|
||||
* conversion from signal units to vector units, so the result of
|
||||
* ivl_expr_oper1 should range from 0 to ivl_expr_width().
|
||||
*
|
||||
* This exprsesion is also used to implement string substrings. If the
|
||||
* This expression is also used to implement string substrings. If the
|
||||
* sub-expression (oper1) is IVL_VT_STRING, then the base expression
|
||||
* (oper2) is a charaster address, with 0 the first address of the
|
||||
* (oper2) is a character address, with 0 the first address of the
|
||||
* string, 1 the second, and so on. This is OPPOSITE how a part select
|
||||
* of a string cast to a vector works, to be aware. The size of the
|
||||
* expression is an even multiple of 8, and is 8 times the number of
|
||||
@@ -889,17 +920,17 @@ extern const char* ivl_expr_name(ivl_expr_t net);
|
||||
extern ivl_nature_t ivl_expr_nature(ivl_expr_t net);
|
||||
/* IVL_EX_BINARY IVL_EX_UNARY */
|
||||
extern char ivl_expr_opcode(ivl_expr_t net);
|
||||
/* IVL_EX_BINARY IVL_EX_UNARY, IVL_EX_MEMORY IVL_EX_TERNARY */
|
||||
/* IVL_EX_BINARY IVL_EX_UNARY, IVL_EX_MEMORY IVL_EX_NEW IVL_EX_TERNARY */
|
||||
extern ivl_expr_t ivl_expr_oper1(ivl_expr_t net);
|
||||
/* IVL_EX_BINARY IVL_EX_TERNARY */
|
||||
/* IVL_EX_BINARY IVL_EX_NEW IVL_EX_TERNARY */
|
||||
extern ivl_expr_t ivl_expr_oper2(ivl_expr_t net);
|
||||
/* IVL_EX_TERNARY */
|
||||
extern ivl_expr_t ivl_expr_oper3(ivl_expr_t net);
|
||||
/* and expression */
|
||||
extern ivl_parameter_t ivl_expr_parameter(ivl_expr_t net);
|
||||
/* IVL_EX_CONCAT IVL_EX_UFUNC */
|
||||
/* IVL_EX_ARRAY_PATTERN IVL_EX_CONCAT IVL_EX_UFUNC */
|
||||
extern ivl_expr_t ivl_expr_parm(ivl_expr_t net, unsigned idx);
|
||||
/* IVL_EX_CONCAT IVL_EX_SFUNC IVL_EX_UFUNC */
|
||||
/* IVL_EX_ARRAY_PATTERN IVL_EX_CONCAT IVL_EX_SFUNC IVL_EX_UFUNC */
|
||||
extern unsigned ivl_expr_parms(ivl_expr_t net);
|
||||
/* IVL_EX_CONCAT */
|
||||
extern unsigned ivl_expr_repeat(ivl_expr_t net);
|
||||
@@ -1248,7 +1279,7 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net);
|
||||
* width of the part. The ivl_lpm_q is the part end, and the
|
||||
* ivl_lpm_data(0) is the non-part end.
|
||||
*
|
||||
* - Comparisons (IVL_LPM_CMP_GT/GE/EQ/NE/EEQ/NEE)
|
||||
* - Comparisons (IVL_LPM_CMP_GT/GE/EQ/NE/EEQ/NEE/EQX/EQZ)
|
||||
* These devices have two inputs, available by the ivl_lpm_data()
|
||||
* function, and one output available by the ivl_lpm_q function. The
|
||||
* output width is always 1, but the ivl_lpm_width() returns the width
|
||||
@@ -1260,6 +1291,11 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net);
|
||||
* magnitude compare, the signedness does matter. In any case, the
|
||||
* result of the compare is always unsigned.
|
||||
*
|
||||
* The EQX and EQZ nodes are wildcard compares, where xz bits (EQX) or
|
||||
* z bits (EQZ) in the data(1) operand are treated as wildcards. no
|
||||
* bits in the data(0) operand are wild. This matches the
|
||||
* SystemVerilog convention for the ==? operator.
|
||||
*
|
||||
* - Mux Device (IVL_LPM_MUX)
|
||||
* The MUX device has a q output, a select input, and a number of data
|
||||
* inputs. The ivl_lpm_q output and the ivl_lpm_data inputs all have
|
||||
@@ -1309,7 +1345,7 @@ extern unsigned ivl_lpm_lineno(ivl_lpm_t net);
|
||||
* repeated to get the desired width. The ivl core assures that the
|
||||
* input vector is exactly ivl_lpm_width() / ivl_lpm_size() bits.
|
||||
*
|
||||
* - Sign Exend (IVL_LPM_SIGN_EXT)
|
||||
* - Sign Extend (IVL_LPM_SIGN_EXT)
|
||||
* This node takes a single input and generates a single output. The
|
||||
* input must be signed, and the output will be a vector sign extended
|
||||
* to the desired width. The ivl_lpm_width() value is the output
|
||||
@@ -1385,9 +1421,10 @@ extern ivl_nexus_t ivl_lpm_sync_set(ivl_lpm_t net);
|
||||
extern ivl_expr_t ivl_lpm_sset_value(ivl_lpm_t net);
|
||||
/* IVL_LPM_ARRAY */
|
||||
extern ivl_signal_t ivl_lpm_array(ivl_lpm_t net);
|
||||
/* IVL_LPM_PART */
|
||||
/* IVL_LPM_PART IVL_LPM_SUBSTITUTE */
|
||||
extern unsigned ivl_lpm_base(ivl_lpm_t net);
|
||||
/* IVL_LPM_FF */
|
||||
extern unsigned ivl_lpm_negedge(ivl_lpm_t net);
|
||||
extern ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net);
|
||||
/* IVL_LPM_UFUNC */
|
||||
extern ivl_scope_t ivl_lpm_define(ivl_lpm_t net);
|
||||
@@ -1395,12 +1432,14 @@ extern ivl_scope_t ivl_lpm_define(ivl_lpm_t net);
|
||||
extern ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net);
|
||||
/* IVL_LPM_ADD IVL_LPM_CONCAT IVL_LPM_FF IVL_LPM_PART IVL_LPM_MULT
|
||||
IVL_LPM_MUX IVL_LPM_POW IVL_LPM_SHIFTL IVL_LPM_SHIFTR IVL_LPM_SUB
|
||||
IVL_LPM_UFUNC */
|
||||
IVL_LPM_UFUNC IVL_LPM_SUBSTITUTE */
|
||||
extern ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx);
|
||||
/* IVL_LPM_ADD IVL_LPM_MULT IVL_LPM_POW IVL_LPM_SUB */
|
||||
/* IVL_LPM_ADD IVL_LPM_MULT IVL_LPM_POW IVL_LPM_SUB IVL_LPM_CMP_EQ
|
||||
IVL_LPM_CMP_EEQ IVL_LPM_CMP_EQX IVL_LPM_CMP_EQZ IVL_LPM_CMP_NEE */
|
||||
extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx);
|
||||
/* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_PART IVL_LPM_POW
|
||||
IVL_LPM_SUB IVL_LPM_UFUNC */
|
||||
IVL_LPM_SUB IVL_LPM_UFUNC IVL_LPM_CMP_EEQ IVL_LPM_CMP_EQX
|
||||
IVL_LPM_CMP_EQZ IVL_LPM_CMP_NEE IVL_LPM_SUBSTITUTE */
|
||||
extern ivl_nexus_t ivl_lpm_q(ivl_lpm_t net);
|
||||
extern ivl_drive_t ivl_lpm_drive0(ivl_lpm_t net);
|
||||
extern ivl_drive_t ivl_lpm_drive1(ivl_lpm_t net);
|
||||
@@ -1427,12 +1466,11 @@ extern const char*ivl_lpm_string(ivl_lpm_t net);
|
||||
* for the local part selecting I might to in the lval object, as
|
||||
* well as the target object width.
|
||||
*
|
||||
* ivl_lval_mux
|
||||
* If the l-value includes a bit select expression, this method
|
||||
* returns an ivl_expr_t that represents that
|
||||
* expression. Otherwise, it returns 0.
|
||||
* ivl_lval_mux (* obsolete *)
|
||||
*
|
||||
* (Should this be combined with ivl_lval_idx? -Ed)
|
||||
* ivl_lval_nest
|
||||
* If the l-value is an object more complex than a variable, then
|
||||
* this returns the nested l-value (and ivl_lval_sig==0).
|
||||
*
|
||||
* ivl_lval_sig
|
||||
* If the l-value is a variable, this method returns the signal
|
||||
@@ -1472,15 +1510,21 @@ extern const char*ivl_lpm_string(ivl_lpm_t net);
|
||||
* then the ivl_lval_idx expression must *not* be present.
|
||||
*
|
||||
* For array words, the ivl_lval_width is the width of the word.
|
||||
*
|
||||
* - Arrayed properties
|
||||
* If the l-value is a class property, then the ivl_lval_idx function
|
||||
* will return an expression if the property is in fact arrayed. The
|
||||
* expression is the canonical index for elements in the property.
|
||||
*/
|
||||
|
||||
extern unsigned ivl_lval_width(ivl_lval_t net);
|
||||
extern ivl_expr_t ivl_lval_mux(ivl_lval_t net); /* XXXX Obsolete? */
|
||||
extern ivl_expr_t ivl_lval_mux(ivl_lval_t net) __attribute__((deprecated)); /* XXXX Obsolete? */
|
||||
extern ivl_expr_t ivl_lval_idx(ivl_lval_t net);
|
||||
extern ivl_expr_t ivl_lval_part_off(ivl_lval_t net);
|
||||
extern ivl_select_type_t ivl_lval_sel_type(ivl_lval_t net);
|
||||
extern int ivl_lval_property_idx(ivl_lval_t net);
|
||||
extern ivl_signal_t ivl_lval_sig(ivl_lval_t net);
|
||||
extern ivl_lval_t ivl_lval_nest(ivl_lval_t net);
|
||||
|
||||
|
||||
/* NEXUS
|
||||
@@ -1602,6 +1646,18 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
|
||||
* Return the value of the parameter. This should be a simple
|
||||
* constant expression, an IVL_EX_STRING or IVL_EX_NUMBER.
|
||||
*
|
||||
* ivl_parameter_msb
|
||||
* ivl_parameter_lsb
|
||||
* Returns the MSB and LSB for the parameter. For a parameter without
|
||||
* a range the value is zero based and the width of the expression is
|
||||
* used to determine the MSB.
|
||||
*
|
||||
* ivl_parameter_width
|
||||
* return |MSB - LSB| + 1
|
||||
*
|
||||
* ivl_parameter_signed
|
||||
* Returns if the parameter was declared to be signed.
|
||||
*
|
||||
* ivl_parameter_local
|
||||
* Return whether parameter was local (localparam, implicit genvar etc)
|
||||
* or not.
|
||||
@@ -1613,9 +1669,13 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
|
||||
extern const char* ivl_parameter_basename(ivl_parameter_t net);
|
||||
extern ivl_scope_t ivl_parameter_scope(ivl_parameter_t net);
|
||||
extern ivl_expr_t ivl_parameter_expr(ivl_parameter_t net);
|
||||
extern int ivl_parameter_local(ivl_parameter_t net);
|
||||
extern int ivl_parameter_msb(ivl_parameter_t net);
|
||||
extern int ivl_parameter_lsb(ivl_parameter_t net);
|
||||
extern unsigned ivl_parameter_width(ivl_parameter_t net);
|
||||
extern int ivl_parameter_signed(ivl_parameter_t net);
|
||||
extern int ivl_parameter_local(ivl_parameter_t net);
|
||||
extern const char* ivl_parameter_file(ivl_parameter_t net);
|
||||
extern unsigned ivl_parameter_lineno(ivl_parameter_t net);
|
||||
extern unsigned ivl_parameter_lineno(ivl_parameter_t net);
|
||||
|
||||
|
||||
/* SCOPE
|
||||
@@ -1658,6 +1718,11 @@ extern unsigned ivl_parameter_lineno(ivl_parameter_t net);
|
||||
* If the scope has no children, this method will return 0 and
|
||||
* otherwise do nothing.
|
||||
*
|
||||
* ivl_scope_childs
|
||||
* ivl_scope_child
|
||||
* This is an alternative way of getting at the childs scopes of a
|
||||
* given scope.
|
||||
*
|
||||
* ivl_scope_def
|
||||
* Task definition scopes carry a task definition, in the form of
|
||||
* a statement. This method accesses that definition. The
|
||||
@@ -1759,6 +1824,8 @@ extern ivl_statement_t ivl_scope_def(ivl_scope_t net);
|
||||
extern const char* ivl_scope_def_file(ivl_scope_t net);
|
||||
extern unsigned ivl_scope_def_lineno(ivl_scope_t net);
|
||||
|
||||
extern size_t ivl_scope_childs(ivl_scope_t net);
|
||||
extern ivl_scope_t ivl_scope_child(ivl_scope_t net, size_t idx);
|
||||
extern unsigned ivl_scope_classes(ivl_scope_t net);
|
||||
extern ivl_type_t ivl_scope_class(ivl_scope_t net, unsigned idx);
|
||||
extern unsigned ivl_scope_enumerates(ivl_scope_t net);
|
||||
@@ -2232,6 +2299,10 @@ extern unsigned ivl_switch_lineno(ivl_switch_t net);
|
||||
* Return the type of the element of an array. This is only valid
|
||||
* for array types.
|
||||
*
|
||||
* ivl_type_signed
|
||||
* Return TRUE if the type represents a signed packed vector or
|
||||
* signed atomic type, and FALSE otherwise.
|
||||
*
|
||||
* SEMANTIC NOTES
|
||||
*
|
||||
* Class types have names and properties.
|
||||
@@ -2241,6 +2312,7 @@ extern ivl_type_t ivl_type_element(ivl_type_t net);
|
||||
extern unsigned ivl_type_packed_dimensions(ivl_type_t net);
|
||||
extern int ivl_type_packed_lsb(ivl_type_t net, unsigned dim);
|
||||
extern int ivl_type_packed_msb(ivl_type_t net, unsigned dim);
|
||||
extern int ivl_type_signed(ivl_type_t net);
|
||||
extern const char* ivl_type_name(ivl_type_t net);
|
||||
extern int ivl_type_properties(ivl_type_t net);
|
||||
extern const char* ivl_type_prop_name(ivl_type_t net, int idx);
|
||||
@@ -2277,4 +2349,6 @@ typedef const char* (*target_query_f) (const char*key);
|
||||
|
||||
_END_DECL
|
||||
|
||||
#endif
|
||||
#undef ENUM_UNSIGNED_INT
|
||||
|
||||
#endif /* IVL_ivl_target_H */
|
||||
|
||||
+16
-7
@@ -1,7 +1,7 @@
|
||||
#ifndef __ivl_target_priv_H
|
||||
#define __ivl_target_priv_H
|
||||
#ifndef IVL_ivl_target_priv_H
|
||||
#define IVL_ivl_target_priv_H
|
||||
/*
|
||||
* Copyright (c) 2008 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2008-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
|
||||
@@ -21,10 +21,13 @@
|
||||
|
||||
# include "ivl_target.h"
|
||||
# include <inttypes.h>
|
||||
# include <map>
|
||||
# include <vector>
|
||||
# include <ostream>
|
||||
# include <valarray>
|
||||
|
||||
class NetScope;
|
||||
|
||||
/*
|
||||
* This header has declarations related to the ivl_target.h API that
|
||||
* are not to be exported outside of the core via the ivl_target.h
|
||||
@@ -47,11 +50,17 @@ struct ivl_design_s {
|
||||
|
||||
ivl_process_t threads_;
|
||||
|
||||
ivl_scope_t *roots_;
|
||||
unsigned nroots_;
|
||||
// Keep arrays of root scopes.
|
||||
std::map<const NetScope*,ivl_scope_t> classes;
|
||||
std::map<const NetScope*,ivl_scope_t> root_tasks;
|
||||
std::vector<ivl_scope_t> packages;
|
||||
std::vector<ivl_scope_t> roots;
|
||||
|
||||
// This is used to implement the ivl_design_roots function.
|
||||
std::vector<ivl_scope_t> root_scope_list;
|
||||
|
||||
// Keep an array of constants objects.
|
||||
std::valarray<ivl_net_const_t> consts;
|
||||
std::vector<ivl_net_const_t> consts;
|
||||
|
||||
// Keep a handy array of all of the disciplines in the design.
|
||||
std::valarray<ivl_discipline_t> disciplines;
|
||||
@@ -82,4 +91,4 @@ struct ivl_island_s {
|
||||
|
||||
extern std::ostream& operator << (std::ostream&o, ivl_drive_t str);
|
||||
|
||||
#endif
|
||||
#endif /* IVL_ivl_target_priv_H */
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
|
||||
endif
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
O = main.o lexor.o
|
||||
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
#ifndef __globals_H
|
||||
#define __globals_H
|
||||
#ifndef IVL_globals_H
|
||||
#define IVL_globals_H
|
||||
/*
|
||||
* Copyright (c) 1999-2009 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-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
|
||||
@@ -22,11 +22,11 @@
|
||||
# include <stdio.h>
|
||||
|
||||
extern void reset_lexor(FILE*out, char*paths[]);
|
||||
extern void destroy_lexor();
|
||||
extern void destroy_lexor(void);
|
||||
extern void load_precompiled_defines(FILE*src);
|
||||
extern void define_macro(const char*name, const char*value, int keyword,
|
||||
int argc);
|
||||
extern void free_macros();
|
||||
extern void free_macros(void);
|
||||
extern void dump_precompiled_defines(FILE*out);
|
||||
|
||||
/* These variables contain the include directories to be searched when
|
||||
@@ -54,6 +54,6 @@ extern char dep_mode;
|
||||
extern int verbose_flag;
|
||||
|
||||
/* This is the entry to the lexer. */
|
||||
extern int yylex();
|
||||
extern int yylex(void);
|
||||
|
||||
#endif
|
||||
#endif /* IVL_globals_H */
|
||||
|
||||
+1
-1
@@ -95,7 +95,7 @@ keys, with their corresponding values, are:
|
||||
This is exactly the same as the "-Dname=<value>" described above.
|
||||
|
||||
I:<dir>
|
||||
This is exctly the same as "-I<dir>".
|
||||
This is exactly the same as "-I<dir>".
|
||||
|
||||
relative include:<flag>
|
||||
The <flag> can be "true" or "false". This enables "relative
|
||||
|
||||
+387
-385
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -1,5 +1,5 @@
|
||||
const char COPYRIGHT[] =
|
||||
"Copyright (c) 1999-2011 Stephen Williams ([email protected])";
|
||||
"Copyright (c) 1999-2011,2015 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
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 1998-2012 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2015 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
|
||||
@@ -91,6 +91,19 @@ static bool in_module = false;
|
||||
static bool in_UDP = false;
|
||||
bool in_celldefine = false;
|
||||
UCDriveType uc_drive = UCD_NONE;
|
||||
|
||||
/*
|
||||
* The parser sometimes needs to indicate to the lexor that the next
|
||||
* identifier needs to be understood in the context of a package. The
|
||||
* parser feeds back that left context with calls to the
|
||||
* lex_in_package_scope.
|
||||
*/
|
||||
static PPackage* in_package_scope = 0;
|
||||
void lex_in_package_scope(PPackage*pkg)
|
||||
{
|
||||
in_package_scope = pkg;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%x CCOMMENT
|
||||
@@ -121,9 +134,17 @@ TU [munpf]
|
||||
\n { yylloc.first_line += 1; }
|
||||
|
||||
/* C++ style comments start with / / and run to the end of the
|
||||
current line. These are very easy to handle. */
|
||||
current line. These are very easy to handle. The meta-comments
|
||||
format is a little more tricky to handle, but do what we can. */
|
||||
|
||||
"//".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
|
||||
/* The lexor detects "// synthesis translate_on/off" meta-comments,
|
||||
we handle them here by turning on/off a flag. The pform uses
|
||||
that flag to attach implicit attributes to "initial" and
|
||||
"always" statements. */
|
||||
|
||||
"//"{W}*"synthesis"{W}+"translate_on"{W}*\n { pform_mc_translate_on(true); }
|
||||
"//"{W}*"synthesis"{W}+"translate_off"{W}*\n { pform_mc_translate_on(false); }
|
||||
"//" { comment_enter = YY_START; BEGIN(LCOMMENT); }
|
||||
<LCOMMENT>. { yymore(); }
|
||||
<LCOMMENT>\n { yylloc.first_line += 1; BEGIN(comment_enter); }
|
||||
|
||||
@@ -216,6 +237,8 @@ TU [munpf]
|
||||
return STRING; }
|
||||
<CSTRING>. { yymore(); }
|
||||
|
||||
/* The UDP Table is a unique lexical environment. These are most
|
||||
tokens that we can expect in a table. */
|
||||
<UDPTABLE>\(\?0\) { return '_'; }
|
||||
<UDPTABLE>\(\?1\) { return '+'; }
|
||||
<UDPTABLE>\(\?[xX]\) { return '%'; }
|
||||
@@ -240,7 +263,7 @@ TU [munpf]
|
||||
<UDPTABLE>[xX] { return 'x'; }
|
||||
<UDPTABLE>[nN] { return 'n'; }
|
||||
<UDPTABLE>[pP] { return 'p'; }
|
||||
<UDPTABLE>[01\?\*\-] { return yytext[0]; }
|
||||
<UDPTABLE>[01\?\*\-:;] { return yytext[0]; }
|
||||
|
||||
<EDGES>"01" { return K_edge_descriptor; }
|
||||
<EDGES>"0x" { return K_edge_descriptor; }
|
||||
@@ -283,6 +306,10 @@ TU [munpf]
|
||||
in_UDP = false;
|
||||
break;
|
||||
|
||||
case K_table:
|
||||
BEGIN(UDPTABLE);
|
||||
break;
|
||||
|
||||
/* Translate these to checks if we already have or are
|
||||
* outside the declaration region. */
|
||||
case K_timeunit:
|
||||
@@ -297,6 +324,24 @@ TU [munpf]
|
||||
break;
|
||||
}
|
||||
|
||||
/* Special case: If this is part of a scoped name, then check
|
||||
the package for identifier details. For example, if the
|
||||
source file is foo::bar, the parse.y will note the
|
||||
PACKAGE_IDENTIFIER and "::" token and mark the
|
||||
"in_package_scope" variable. Then this lexor will see the
|
||||
identifier here and interpret it in the package scope. */
|
||||
if (in_package_scope) {
|
||||
if (rc == IDENTIFIER) {
|
||||
if (data_type_t*type = pform_test_type_identifier(in_package_scope, yylval.text)) {
|
||||
yylval.type_identifier.text = yylval.text;
|
||||
yylval.type_identifier.type = type;
|
||||
rc = TYPE_IDENTIFIER;
|
||||
}
|
||||
}
|
||||
in_package_scope = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* If this identifier names a discipline, then return this as
|
||||
a DISCIPLINE_IDENTIFIER and return the discipline as the
|
||||
value instead. */
|
||||
@@ -310,12 +355,22 @@ TU [munpf]
|
||||
}
|
||||
}
|
||||
|
||||
/* If this identifier names a previously declared package, then
|
||||
return this as a PACKAGE_IDENTIFIER instead. */
|
||||
if (rc == IDENTIFIER && gn_system_verilog()) {
|
||||
if (PPackage*pkg = pform_test_package_identifier(yylval.text)) {
|
||||
delete[]yylval.text;
|
||||
yylval.package = pkg;
|
||||
rc = PACKAGE_IDENTIFIER;
|
||||
}
|
||||
}
|
||||
|
||||
/* If this identifier names a previously declared type, then
|
||||
return this as a TYPE_IDENTIFIER instead. */
|
||||
if (rc == IDENTIFIER && gn_system_verilog()) {
|
||||
if (data_type_t*type = pform_test_type_identifier(yylval.text)) {
|
||||
delete[]yylval.text;
|
||||
yylval.data_type = type;
|
||||
yylval.type_identifier.text = yylval.text;
|
||||
yylval.type_identifier.type = type;
|
||||
rc = TYPE_IDENTIFIER;
|
||||
}
|
||||
}
|
||||
@@ -327,9 +382,16 @@ TU [munpf]
|
||||
\\[^ \t\b\f\r\n]+ {
|
||||
yylval.text = strdupnew(yytext+1);
|
||||
if (gn_system_verilog()) {
|
||||
if (data_type_t*type = pform_test_type_identifier(yylval.text)) {
|
||||
if (PPackage*pkg = pform_test_package_identifier(yylval.text)) {
|
||||
delete[]yylval.text;
|
||||
yylval.data_type = type;
|
||||
yylval.package = pkg;
|
||||
return PACKAGE_IDENTIFIER;
|
||||
}
|
||||
}
|
||||
if (gn_system_verilog()) {
|
||||
if (data_type_t*type = pform_test_type_identifier(yylval.text)) {
|
||||
yylval.type_identifier.text = yylval.text;
|
||||
yylval.type_identifier.type = type;
|
||||
return TYPE_IDENTIFIER;
|
||||
}
|
||||
}
|
||||
@@ -370,18 +432,28 @@ TU [munpf]
|
||||
return SYSTEM_IDENTIFIER; }
|
||||
|
||||
|
||||
\'[sS]?[dD][ \t]*[0-9][0-9_]* { yylval.number = make_unsized_dec(yytext);
|
||||
return BASED_NUMBER; }
|
||||
\'[sS]?[dD][ \t]*[xzXZ?]_* { yylval.number = make_undef_highz_dec(yytext);
|
||||
return BASED_NUMBER; }
|
||||
\'[sS]?[bB][ \t]*[0-1xzXZ_\?]+ { yylval.number = make_unsized_binary(yytext);
|
||||
return BASED_NUMBER; }
|
||||
\'[sS]?[oO][ \t]*[0-7xzXZ_\?]+ { yylval.number = make_unsized_octal(yytext);
|
||||
return BASED_NUMBER; }
|
||||
\'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ_\?]+ { yylval.number = make_unsized_hex(yytext);
|
||||
return BASED_NUMBER; }
|
||||
\'[sS]?[dD][ \t]*[0-9][0-9_]* {
|
||||
yylval.number = make_unsized_dec(yytext);
|
||||
return BASED_NUMBER;
|
||||
}
|
||||
\'[sS]?[dD][ \t]*[xzXZ?]_* {
|
||||
yylval.number = make_undef_highz_dec(yytext);
|
||||
return BASED_NUMBER;
|
||||
}
|
||||
\'[sS]?[bB][ \t]*[0-1xzXZ?][0-1xzXZ?_]* {
|
||||
yylval.number = make_unsized_binary(yytext);
|
||||
return BASED_NUMBER;
|
||||
}
|
||||
\'[sS]?[oO][ \t]*[0-7xzXZ?][0-7xzXZ?_]* {
|
||||
yylval.number = make_unsized_octal(yytext);
|
||||
return BASED_NUMBER;
|
||||
}
|
||||
\'[sS]?[hH][ \t]*[0-9a-fA-FxzXZ?][0-9a-fA-FxzXZ?_]* {
|
||||
yylval.number = make_unsized_hex(yytext);
|
||||
return BASED_NUMBER;
|
||||
}
|
||||
\'[01xzXZ] {
|
||||
if (generation_flag < GN_VER2005_SV) {
|
||||
if (!gn_system_verilog()) {
|
||||
cerr << yylloc.text << ":" << yylloc.first_line << ": warning: "
|
||||
<< "Using SystemVerilog 'N bit vector. Use at least "
|
||||
<< "-g2005-sv to remove this warning." << endl;
|
||||
@@ -392,14 +464,22 @@ TU [munpf]
|
||||
generation_flag = generation_save;
|
||||
return UNBASED_NUMBER; }
|
||||
|
||||
/* Decimal numbers are the usual. But watch out for the UDPTABLE
|
||||
mode, where there are no decimal numbers. Reject the match if we
|
||||
are in the UDPTABLE state. */
|
||||
[0-9][0-9_]* {
|
||||
yylval.number = make_unsized_dec(yytext);
|
||||
based_size = yylval.number->as_ulong();
|
||||
return DEC_NUMBER; }
|
||||
if (YY_START==UDPTABLE) {
|
||||
REJECT;
|
||||
} else {
|
||||
yylval.number = make_unsized_dec(yytext);
|
||||
based_size = yylval.number->as_ulong();
|
||||
return DEC_NUMBER;
|
||||
}
|
||||
}
|
||||
|
||||
/* This rule handles scaled time values for SystemVerilog. */
|
||||
[0-9][0-9_]*(\.[0-9][0-9_]*)?{TU}?s {
|
||||
if(generation_flag & (GN_VER2005_SV | GN_VER2009)) {
|
||||
if (gn_system_verilog()) {
|
||||
yylval.text = strdupnew(yytext);
|
||||
return TIME_LITERAL;
|
||||
} else REJECT; }
|
||||
@@ -572,6 +652,14 @@ TU [munpf]
|
||||
|GN_KEYWORDS_1364_2005
|
||||
|GN_KEYWORDS_1800_2005
|
||||
|GN_KEYWORDS_1800_2009;
|
||||
} else if (strcmp(word,"1800-2012") == 0) {
|
||||
lexor_keyword_mask = GN_KEYWORDS_1364_1995
|
||||
|GN_KEYWORDS_1364_2001
|
||||
|GN_KEYWORDS_1364_2001_CONFIG
|
||||
|GN_KEYWORDS_1364_2005
|
||||
|GN_KEYWORDS_1800_2005
|
||||
|GN_KEYWORDS_1800_2009
|
||||
|GN_KEYWORDS_1800_2012;
|
||||
} else if (strcmp(word,"VAMS-2.3") == 0) {
|
||||
lexor_keyword_mask = GN_KEYWORDS_1364_1995
|
||||
|GN_KEYWORDS_1364_2001
|
||||
@@ -735,16 +823,27 @@ TU [munpf]
|
||||
* lexor. The level characters are normally accepted as other things,
|
||||
* so the parser needs to switch my mode when it believes in needs to.
|
||||
*/
|
||||
void lex_start_table()
|
||||
{
|
||||
BEGIN(UDPTABLE);
|
||||
}
|
||||
|
||||
void lex_end_table()
|
||||
{
|
||||
BEGIN(INITIAL);
|
||||
}
|
||||
|
||||
static unsigned truncate_to_integer_width(verinum::V*bits, unsigned size)
|
||||
{
|
||||
if (size <= integer_width) return size;
|
||||
|
||||
verinum::V pad = bits[size-1];
|
||||
if (pad == verinum::V1) pad = verinum::V0;
|
||||
|
||||
for (unsigned idx = integer_width; idx < size; idx += 1) {
|
||||
if (bits[idx] != pad) {
|
||||
yywarn(yylloc, "Unsized numeric constant truncated to integer width.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
return integer_width;
|
||||
}
|
||||
|
||||
verinum*make_unsized_binary(const char*txt)
|
||||
{
|
||||
bool sign_flag = false;
|
||||
@@ -758,7 +857,7 @@ verinum*make_unsized_binary(const char*txt)
|
||||
ptr += 1;
|
||||
}
|
||||
|
||||
assert((tolower(*ptr) == 'b') || (generation_flag >= GN_VER2005_SV));
|
||||
assert((tolower(*ptr) == 'b') || gn_system_verilog());
|
||||
if (tolower(*ptr) == 'b') {
|
||||
ptr += 1;
|
||||
} else {
|
||||
@@ -802,6 +901,9 @@ verinum*make_unsized_binary(const char*txt)
|
||||
ptr += 1;
|
||||
}
|
||||
|
||||
if (gn_strict_expr_width_flag && (based_size == 0))
|
||||
size = truncate_to_integer_width(bits, size);
|
||||
|
||||
verinum*out = new verinum(bits, size, false);
|
||||
out->has_sign(sign_flag);
|
||||
out->is_single(single_flag);
|
||||
@@ -870,6 +972,9 @@ verinum*make_unsized_octal(const char*txt)
|
||||
ptr += 1;
|
||||
}
|
||||
|
||||
if (gn_strict_expr_width_flag && (based_size == 0))
|
||||
size = truncate_to_integer_width(bits, size);
|
||||
|
||||
verinum*out = new verinum(bits, size, false);
|
||||
out->has_sign(sign_flag);
|
||||
delete[]bits;
|
||||
@@ -947,6 +1052,9 @@ verinum*make_unsized_hex(const char*txt)
|
||||
ptr += 1;
|
||||
}
|
||||
|
||||
if (gn_strict_expr_width_flag && (based_size == 0))
|
||||
size = truncate_to_integer_width(bits, size);
|
||||
|
||||
verinum*out = new verinum(bits, size, false);
|
||||
out->has_sign(sign_flag);
|
||||
delete[]bits;
|
||||
@@ -1136,6 +1244,9 @@ verinum*make_unsized_dec(const char*ptr)
|
||||
number represents we do not check for extra bits. */
|
||||
// if (based_size > 0) { }
|
||||
|
||||
if (gn_strict_expr_width_flag && (based_size == 0))
|
||||
size = truncate_to_integer_width(bits, size);
|
||||
|
||||
verinum*res = new verinum(bits, size, false);
|
||||
res->has_sign(signed_flag);
|
||||
|
||||
|
||||
+8
-2
@@ -3,9 +3,11 @@
|
||||
* tokenType values are not initialized for the empty table entries.
|
||||
*/
|
||||
%define initializer-suffix ,0,0
|
||||
%language=C++
|
||||
%define class-name Lkwd
|
||||
|
||||
%{
|
||||
/* Command-line: gperf -o -i 1 -C -k 1-3,$ -L C -H keyword_hash -N check_identifier -tT lexor_keyword.gperf */
|
||||
/* Command-line: gperf -o -i 7 -C -k '1-4,6,9,$' -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf */
|
||||
|
||||
#include "config.h"
|
||||
#include "parse_misc.h"
|
||||
@@ -161,6 +163,7 @@ ifnone, GN_KEYWORDS_1364_1995, K_ifnone
|
||||
ignore_bins, GN_KEYWORDS_1800_2005, K_ignore_bins
|
||||
illegal_bins, GN_KEYWORDS_1800_2005, K_illegal_bins
|
||||
implies, GN_KEYWORDS_1800_2009, K_implies
|
||||
implements, GN_KEYWORDS_1800_2012, K_implements
|
||||
import, GN_KEYWORDS_1800_2005, K_import
|
||||
incdir, GN_KEYWORDS_1364_2001_CONFIG, K_incdir
|
||||
include, GN_KEYWORDS_1364_2001_CONFIG, K_include
|
||||
@@ -173,6 +176,7 @@ inside, GN_KEYWORDS_1800_2005, K_inside
|
||||
instance, GN_KEYWORDS_1364_2001_CONFIG, K_instance
|
||||
int, GN_KEYWORDS_1800_2005, K_int
|
||||
integer, GN_KEYWORDS_1364_1995, K_integer
|
||||
interconnect, GN_KEYWORDS_1800_2012, K_interconnect
|
||||
interface, GN_KEYWORDS_1800_2005, K_interface
|
||||
intersect, GN_KEYWORDS_1800_2005, K_intersect
|
||||
join, GN_KEYWORDS_1364_1995, K_join
|
||||
@@ -207,6 +211,7 @@ nand, GN_KEYWORDS_1364_1995, K_nand
|
||||
nature, GN_KEYWORDS_VAMS_2_3, K_nature
|
||||
negedge, GN_KEYWORDS_1364_1995, K_negedge
|
||||
net_resolution, GN_KEYWORDS_VAMS_2_3, K_net_resolution
|
||||
nettype, GN_KEYWORDS_1800_2012, K_nettype
|
||||
new, GN_KEYWORDS_1800_2005, K_new
|
||||
nexttime, GN_KEYWORDS_1800_2009, K_nexttime
|
||||
nmos, GN_KEYWORDS_1364_1995, K_nmos
|
||||
@@ -274,6 +279,7 @@ sin, GN_KEYWORDS_VAMS_2_3, K_sin
|
||||
sinh, GN_KEYWORDS_VAMS_2_3, K_sinh
|
||||
slew, GN_KEYWORDS_VAMS_2_3, K_slew
|
||||
small, GN_KEYWORDS_1364_1995, K_small
|
||||
soft, GN_KEYWORDS_1800_2012, K_soft
|
||||
solve, GN_KEYWORDS_1800_2005, K_solve
|
||||
specify, GN_KEYWORDS_1364_1995, K_specify
|
||||
specparam, GN_KEYWORDS_1364_1995, K_specparam
|
||||
@@ -358,7 +364,7 @@ int lexor_keyword_mask = 0;
|
||||
|
||||
int lexor_keyword_code(const char*str, unsigned nstr)
|
||||
{
|
||||
const struct lexor_keyword*rc = check_identifier(str, nstr);
|
||||
const struct lexor_keyword*rc = Lkwd::check_identifier(str, nstr);
|
||||
if (rc == 0)
|
||||
return IDENTIFIER;
|
||||
else if ((rc->mask & lexor_keyword_mask) == 0)
|
||||
|
||||
+4
-4
@@ -1,7 +1,7 @@
|
||||
#ifndef __lexor_keyword_H
|
||||
#define __lexor_keyword_H
|
||||
#ifndef IVL_lexor_keyword_H
|
||||
#define IVL_lexor_keyword_H
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-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
|
||||
@@ -21,4 +21,4 @@
|
||||
|
||||
extern int lexor_keyword_code (const char*str, unsigned len);
|
||||
|
||||
#endif
|
||||
#endif /* IVL_lexor_keyword_H */
|
||||
|
||||
@@ -27,6 +27,11 @@ LineInfo::LineInfo()
|
||||
{
|
||||
}
|
||||
|
||||
LineInfo::LineInfo(const LineInfo&that) :
|
||||
file_(that.file_), lineno_(that.lineno_)
|
||||
{
|
||||
}
|
||||
|
||||
LineInfo::~LineInfo()
|
||||
{
|
||||
}
|
||||
|
||||
+5
-4
@@ -1,7 +1,7 @@
|
||||
#ifndef __LineInfo_H
|
||||
#define __LineInfo_H
|
||||
#ifndef IVL_LineInfo_H
|
||||
#define IVL_LineInfo_H
|
||||
/*
|
||||
* Copyright (c) 1999-2011 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-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
|
||||
@@ -36,6 +36,7 @@ using namespace std;
|
||||
class LineInfo {
|
||||
public:
|
||||
LineInfo();
|
||||
LineInfo(const LineInfo&that);
|
||||
virtual ~LineInfo();
|
||||
|
||||
// Get a fully formatted file/lineno
|
||||
@@ -54,4 +55,4 @@ class LineInfo {
|
||||
unsigned lineno_;
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_LineInfo_H */
|
||||
|
||||
@@ -210,3 +210,5 @@ ostream& operator << (ostream&out, perm_string that)
|
||||
out << that.str();
|
||||
return out;
|
||||
}
|
||||
|
||||
const perm_string empty_perm_string = perm_string::literal("");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __StringHeap_H
|
||||
#define __StringHeap_H
|
||||
#ifndef IVL_StringHeap_H
|
||||
#define IVL_StringHeap_H
|
||||
/*
|
||||
* Copyright (c) 2002-2009 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2002-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
|
||||
@@ -52,6 +52,7 @@ class perm_string {
|
||||
const char*text_;
|
||||
};
|
||||
|
||||
extern const perm_string empty_perm_string;
|
||||
extern bool operator == (perm_string a, perm_string b);
|
||||
extern bool operator == (perm_string a, const char* b);
|
||||
extern bool operator != (perm_string a, perm_string b);
|
||||
@@ -120,4 +121,4 @@ class StringHeapLex : private StringHeap {
|
||||
StringHeapLex& operator= (const StringHeapLex&);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif /* IVL_StringHeap_H */
|
||||
|
||||
@@ -48,7 +48,7 @@ LDRELOCFLAGS = @LDRELOCFLAGS@
|
||||
LDTARGETFLAGS = @LDTARGETFLAGS@
|
||||
|
||||
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CFLAGS = @WARNING_FLAGS@ @CFLAGS@
|
||||
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||
|
||||
A = a_close.o a_compare_handles.o a_configure.o a_fetch_argc.o \
|
||||
a_fetch_argv.o a_fetch_dir.o a_fetch_fullname.o a_fetch_location.o \
|
||||
|
||||
@@ -69,9 +69,13 @@ int acc_configure(PLI_INT32 config_param, const char*value)
|
||||
fprintf(pli_trace, "acc_configure(config=%d, %s)\n",
|
||||
(int)config_param, value);
|
||||
}
|
||||
|
||||
#if 0
|
||||
vpi_printf("XXXX acc_configure(%d, %s)\n", (int)config_param,
|
||||
value);
|
||||
#else
|
||||
/* Parameter is not necessarily a string. */
|
||||
vpi_printf("XXXX acc_configure(%d, ...)\n", (int)config_param);
|
||||
#endif
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
# include <vpi_user.h>
|
||||
# include <veriuser.h>
|
||||
# include <acc_user.h>
|
||||
|
||||
/*
|
||||
* acc_fetch_argc implemented using VPI interface
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
# include <vpi_user.h>
|
||||
# include <veriuser.h>
|
||||
# include <acc_user.h>
|
||||
|
||||
/*
|
||||
* acc_fetch_argv implemented using VPI interface
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user