mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-23 14:27:01 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4907776eaa | ||
|
|
51dd41f81a | ||
|
|
e4ae832153 | ||
|
|
b3a3428b9a | ||
|
|
2abdcfcaa4 | ||
|
|
526b87cae3 | ||
|
|
9383b165a4 | ||
|
|
e827f8f8c1 | ||
|
|
965d928430 | ||
|
|
96936456da | ||
|
|
94647be1f0 | ||
|
|
e45230061e | ||
|
|
180bfc5e72 | ||
|
|
6d40326a2f | ||
|
|
0a630b60dd | ||
|
|
1e4ffc292d | ||
|
|
a579114ae2 | ||
|
|
8dfe16f6d2 | ||
|
|
d1dac0017d | ||
|
|
5e627c9adc | ||
|
|
98ba641e67 | ||
|
|
a70dd79cd8 | ||
|
|
a8ee786036 | ||
|
|
d16e8f7c94 | ||
|
|
4148a2a44c | ||
|
|
5f38591676 | ||
|
|
c10e572091 | ||
|
|
1ab8879100 | ||
|
|
2d498363d7 | ||
|
|
15059bbfdc | ||
|
|
9de786fc44 | ||
|
|
62cffe16f4 | ||
|
|
d3eb53e6b1 | ||
|
|
b631e6e704 | ||
|
|
ba3790dc2b | ||
|
|
f02f5be3cc | ||
|
|
7f67afe9d5 | ||
|
|
d76ad25778 | ||
|
|
21ba781604 | ||
|
|
95c8115fc7 | ||
|
|
49366d1334 | ||
|
|
e2b94947f5 | ||
|
|
efe05a77cb | ||
|
|
8bf434754f | ||
|
|
491df9c327 | ||
|
|
fca2e64808 | ||
|
|
6cd7c1a650 | ||
|
|
3dbc07f34d | ||
|
|
57b8ca191f | ||
|
|
9ee0210cac | ||
|
|
69cfdbdc54 | ||
|
|
76c0fe459c | ||
|
|
9ba1177a4d | ||
|
|
51fd249d8a | ||
|
|
050ec6f325 | ||
|
|
03d7448550 | ||
|
|
b3529d8593 | ||
|
|
112368c7de | ||
|
|
d1f0a0b0d7 | ||
|
|
b043445c80 | ||
|
|
fd371a3958 | ||
|
|
35619771dd | ||
|
|
bdc6cb8723 | ||
|
|
2d63705093 | ||
|
|
b108167441 | ||
|
|
9949040285 | ||
|
|
e8e0cd7cab | ||
|
|
f2d4966634 | ||
|
|
50bf2095df | ||
|
|
2003c5a21e | ||
|
|
bfd393c91c | ||
|
|
37ae777111 | ||
|
|
dd69872266 | ||
|
|
fbfc796647 | ||
|
|
8d3102388b | ||
|
|
ba309e60bb | ||
|
|
5472b27e1f | ||
|
|
e7fa56981a | ||
|
|
55ba131997 | ||
|
|
559f73c135 | ||
|
|
b97f9448e0 | ||
|
|
a7ae8adf9b | ||
|
|
896f1b0de1 | ||
|
|
ca55cadc6c | ||
|
|
324ba713e5 | ||
|
|
69ebd0c49e | ||
|
|
d60112d58b | ||
|
|
5807d6912e | ||
|
|
ec0e35b940 | ||
|
|
c8d67b904a | ||
|
|
c55adddb69 | ||
|
|
8e63f56caf | ||
|
|
9e223b9696 | ||
|
|
dd7472d125 | ||
|
|
0ef1ecab5e | ||
|
|
28719e8584 | ||
|
|
a0ed5e9e29 | ||
|
|
20b7a23bde | ||
|
|
33783385d2 | ||
|
|
914746f6f3 | ||
|
|
c6453a0854 | ||
|
|
413932e406 | ||
|
|
9531920685 | ||
|
|
4456937274 | ||
|
|
efef8fba85 | ||
|
|
177b6ffb6a | ||
|
|
1295058e5d | ||
|
|
b5b02269f1 | ||
|
|
60adfb845d | ||
|
|
a4c5ff0bd3 | ||
|
|
72f9dc5094 | ||
|
|
65f09337f6 | ||
|
|
8d2858c555 | ||
|
|
89acc41437 | ||
|
|
536068bdfb | ||
|
|
2d7380c03b | ||
|
|
27af95d402 | ||
|
|
17c891bc9c | ||
|
|
38ec4b7851 | ||
|
|
6f9ebb1e60 | ||
|
|
0fd5a79760 | ||
|
|
4288f3c6d0 | ||
|
|
d64295ed65 | ||
|
|
2f8a40b159 | ||
|
|
081a6a4088 | ||
|
|
c971448760 | ||
|
|
c275ef9482 | ||
|
|
8188c4c690 | ||
|
|
d482e341ae | ||
|
|
f2b9b8946f | ||
|
|
fa4a873628 | ||
|
|
a436bfc711 | ||
|
|
c2ab27541f | ||
|
|
5160021b48 | ||
|
|
f349449a49 | ||
|
|
de7f87853d | ||
|
|
6a02613fca | ||
|
|
3bb408faf2 | ||
|
|
4987970af4 | ||
|
|
d98720af4d | ||
|
|
793493d3ff | ||
|
|
36785997cb | ||
|
|
923a3ea537 | ||
|
|
8aca824c0f | ||
|
|
e6b25a4e20 | ||
|
|
d98b7ffb2e | ||
|
|
e617e4a98c | ||
|
|
1970e41041 | ||
|
|
e331b182a7 | ||
|
|
11b0cc5bf3 | ||
|
|
5b0c7be6b7 | ||
|
|
59ac435c71 | ||
|
|
57c3e86084 | ||
|
|
f0e0377a20 | ||
|
|
ae3198b505 | ||
|
|
d4525ddc16 | ||
|
|
19e8a92729 | ||
|
|
1bd1d287e4 | ||
|
|
4c8c14ceec | ||
|
|
df968687e4 | ||
|
|
973b4d9bcb | ||
|
|
2a60768ffe | ||
|
|
e56b77a43f | ||
|
|
9967bfcbfd | ||
|
|
2c4358c9ff | ||
|
|
be0b42f210 | ||
|
|
cf33bedc2d | ||
|
|
0b538ceed6 | ||
|
|
8d4c3a8620 | ||
|
|
700d51ff8a | ||
|
|
cceb2bd2c5 | ||
|
|
12033d7bd4 | ||
|
|
c96b0402be | ||
|
|
5068e3ea15 | ||
|
|
435f06bd21 | ||
|
|
534a656be8 | ||
|
|
d10da2121f | ||
|
|
43f28b53a3 | ||
|
|
995cd449c5 | ||
|
|
7fa531c5db | ||
|
|
df08760ef8 | ||
|
|
a7c773262e | ||
|
|
f58b124101 | ||
|
|
8eccb7b9a1 | ||
|
|
bc0ead2842 | ||
|
|
80570c7c78 | ||
|
|
ed831e7c32 | ||
|
|
074dcc934a | ||
|
|
9db45e398e | ||
|
|
4f40eb0a00 | ||
|
|
1dfbe0f7f2 | ||
|
|
c5f7e7837b | ||
|
|
faf33458fd | ||
|
|
0607970eca | ||
|
|
c4e069e505 | ||
|
|
7fd669fcc0 | ||
|
|
fad43d78b0 | ||
|
|
5aadc310f7 | ||
|
|
930e5137ac | ||
|
|
02ec36806c | ||
|
|
e88c3a20a2 | ||
|
|
5ff3bcc7fb | ||
|
|
4236b8a95e | ||
|
|
89fca07dc8 | ||
|
|
4eae8426a9 | ||
|
|
1b8034818c | ||
|
|
a503e2d91f | ||
|
|
65ae69843b | ||
|
|
1c99c629b1 | ||
|
|
edaa7df6d2 | ||
|
|
847448139c | ||
|
|
ee172bdccf | ||
|
|
5496a38499 | ||
|
|
8dab4c6b53 | ||
|
|
3e44a7121d | ||
|
|
d4f3349fe0 | ||
|
|
f2382e209a | ||
|
|
123e4c7f65 | ||
|
|
bb8785962f | ||
|
|
dba4f44598 | ||
|
|
ec9361ae22 | ||
|
|
906e7d9946 | ||
|
|
9628b4d047 | ||
|
|
46bb8c68fa | ||
|
|
a461a76bd5 | ||
|
|
368e2211e3 | ||
|
|
e9f1fd012c | ||
|
|
c34d5699ee | ||
|
|
468ffa4bd0 | ||
|
|
e49856fad4 | ||
|
|
ee81485582 | ||
|
|
8cf7b62933 | ||
|
|
cf1affff32 | ||
|
|
9a232d545d | ||
|
|
fc44f44879 | ||
|
|
ddba06904c | ||
|
|
a89f39f166 | ||
|
|
9b821c0dbd | ||
|
|
52b756a6fa | ||
|
|
7ef45769a7 | ||
|
|
fff6e88245 | ||
|
|
01d22e2005 | ||
|
|
691d31faac | ||
|
|
3190eda414 | ||
|
|
40daff0aed | ||
|
|
f7b3c720af | ||
|
|
2f4ec5a473 | ||
|
|
d21351405a | ||
|
|
1cb589fee0 | ||
|
|
8c30d217d5 | ||
|
|
86e9489530 | ||
|
|
07ece95383 | ||
|
|
2ed433b8c1 | ||
|
|
39b2928ad8 | ||
|
|
becae2cecd | ||
|
|
2231b830db | ||
|
|
2970b3c39b | ||
|
|
daa85f2479 | ||
|
|
2f8181f40a | ||
|
|
d1f0bcf620 | ||
|
|
933f4483b1 | ||
|
|
2e6cfd8c0d | ||
|
|
6abe797963 | ||
|
|
94a71fdee8 | ||
|
|
39df56fdcf | ||
|
|
1f0c274e82 | ||
|
|
693794552c | ||
|
|
da7956a797 | ||
|
|
1de5e6c848 | ||
|
|
ed792c5321 | ||
|
|
31c0a9dcd1 | ||
|
|
1c51e1787c | ||
|
|
178847fc53 | ||
|
|
7e7735ce21 | ||
|
|
537fe0547a | ||
|
|
9093877073 | ||
|
|
6927e0fa1f | ||
|
|
2418ab9063 | ||
|
|
2df976b4c6 | ||
|
|
c4c03e6be3 | ||
|
|
cee34f8a8a | ||
|
|
aa40930278 | ||
|
|
59c5759fdf | ||
|
|
f495c75faf | ||
|
|
fea68f7fe7 | ||
|
|
7521aa83f8 | ||
|
|
c26df174a1 | ||
|
|
b0230cf4d4 | ||
|
|
ca0a9faa90 | ||
|
|
af806ed9c3 | ||
|
|
2272843511 | ||
|
|
fdb5731b8b | ||
|
|
7c1401a2ba | ||
|
|
14150d6fba | ||
|
|
816aba993f | ||
|
|
60b2e89b1b | ||
|
|
64d795c53a | ||
|
|
ec07674d40 | ||
|
|
0a012c5d90 | ||
|
|
cd4b3b0f17 | ||
|
|
3dc73aa292 | ||
|
|
e561819179 | ||
|
|
855c2fe001 | ||
|
|
bc428cfe9b | ||
|
|
bdd0b455bd | ||
|
|
fff8278eb4 | ||
|
|
b6c3f94d52 | ||
|
|
6b7879c0b0 | ||
|
|
adcafb6f24 | ||
|
|
23d5b68153 | ||
|
|
aadf39a985 | ||
|
|
a95463ff81 | ||
|
|
fbe6fc315b | ||
|
|
63fb5ea03c | ||
|
|
800e9dd76a | ||
|
|
f4b8a4877f | ||
|
|
e312e99448 | ||
|
|
c96598a429 | ||
|
|
38d851f04e | ||
|
|
ddbb95870d | ||
|
|
d3d63c1b8b | ||
|
|
5e326cd90e | ||
|
|
1a3a3fbcfa | ||
|
|
d6420f9e0c | ||
|
|
2d5b48ce0a | ||
|
|
66b7b36bc5 | ||
|
|
d653a7e88d | ||
|
|
d4b7c835de | ||
|
|
31b1fb4ec4 | ||
|
|
bfe31e22bf | ||
|
|
e854ecd993 | ||
|
|
48b6b6f460 | ||
|
|
e7ddf21233 | ||
|
|
c6cf7e017b | ||
|
|
5e954e94fa | ||
|
|
4b7b32d385 | ||
|
|
a378efb398 | ||
|
|
0cfac55d8a | ||
|
|
008c2cf448 | ||
|
|
82bfbf41ea | ||
|
|
4a8b9e549a | ||
|
|
cadf4cfdef | ||
|
|
4641966349 | ||
|
|
6cc5dd93fe | ||
|
|
5f96dc9faf | ||
|
|
77da147629 | ||
|
|
1c4552e262 | ||
|
|
5b351599f0 | ||
|
|
c2feb162f2 | ||
|
|
7734ba99fc | ||
|
|
dccd7ec7e2 | ||
|
|
272dc749da | ||
|
|
01b858ef13 | ||
|
|
939a85054d | ||
|
|
004ecd08dd | ||
|
|
eb605694eb | ||
|
|
b810556d3f | ||
|
|
3a3e288f6f | ||
|
|
0ffb613229 | ||
|
|
2e4276f5c5 | ||
|
|
daad030ce6 | ||
|
|
5314ec373b | ||
|
|
03089bdbf3 | ||
|
|
253f3bc660 | ||
|
|
7b933eddd4 | ||
|
|
a9595fe6ba | ||
|
|
e8a222e783 | ||
|
|
0e797dc7bc | ||
|
|
f7162eb538 | ||
|
|
56b876afc4 | ||
|
|
957a464743 | ||
|
|
79248d0592 | ||
|
|
21ff80075a | ||
|
|
bad861dba3 | ||
|
|
5cb5a19819 | ||
|
|
996d4c76db | ||
|
|
565e4f1fed | ||
|
|
61195c5daa | ||
|
|
ccf4d4d7da | ||
|
|
cc5f7a64b0 | ||
|
|
71a404a546 | ||
|
|
ae418c6a6d | ||
|
|
2894c021e7 | ||
|
|
2321df4bfc | ||
|
|
96ca885aca | ||
|
|
bbdf03b457 | ||
|
|
b544b319fa | ||
|
|
536b79b667 | ||
|
|
4da0cc4c8c | ||
|
|
ad102e80de | ||
|
|
c8b18b998e | ||
|
|
1b0408ac8f | ||
|
|
222eaa0f88 | ||
|
|
d2188b8f6d | ||
|
|
2f6826247a | ||
|
|
4709c3e012 | ||
|
|
54e809ffa4 | ||
|
|
a9ce23d2e9 | ||
|
|
3ef65d1298 | ||
|
|
b43c543455 | ||
|
|
dc90f0d52d | ||
|
|
83dfce00d2 | ||
|
|
218693794d | ||
|
|
0c7a5874d4 | ||
|
|
2f241ae95b | ||
|
|
6827aef285 | ||
|
|
4f89e3a026 | ||
|
|
8352c91b0a | ||
|
|
a4d69e08da | ||
|
|
1c65ea08e8 | ||
|
|
d3daa997b5 | ||
|
|
bc91ec41f2 | ||
|
|
2b471d16f7 | ||
|
|
0555a5f182 | ||
|
|
bd459d5182 | ||
|
|
f003da6621 | ||
|
|
5903f0744c | ||
|
|
e7b3168466 | ||
|
|
bf664c67b4 | ||
|
|
8cfef65bd8 | ||
|
|
577554cca5 | ||
|
|
bf881fef0a | ||
|
|
031962ba32 | ||
|
|
ea2cef34ae | ||
|
|
7fa987e58d | ||
|
|
5c34f53e9c | ||
|
|
4b20ffc829 | ||
|
|
e157b3f9c5 | ||
|
|
b82a2d4773 | ||
|
|
c29b1639e1 | ||
|
|
5ee1b465e9 | ||
|
|
6e5b7e4a41 | ||
|
|
49a8d46885 | ||
|
|
639d3aad1e | ||
|
|
e3e4e648d7 | ||
|
|
3770dda0b8 | ||
|
|
7e2848b105 | ||
|
|
0d779098f0 | ||
|
|
17e93b7cbe | ||
|
|
52c1c051b0 | ||
|
|
ea33862632 | ||
|
|
cd7a313f56 | ||
|
|
218d74f7bb | ||
|
|
11058017df | ||
|
|
8126bdd384 | ||
|
|
2e3ce49400 | ||
|
|
04d32a4d4c | ||
|
|
f37213e7e6 | ||
|
|
2a29c4fd62 | ||
|
|
889b9bfe07 | ||
|
|
2356741169 | ||
|
|
3bd08e6212 | ||
|
|
d9b86d9b3a | ||
|
|
2a93dc00f6 | ||
|
|
a5298eef46 | ||
|
|
5e07cd7e6e | ||
|
|
4ace97a083 | ||
|
|
84b0ca822b | ||
|
|
1b7c876fd8 | ||
|
|
d958fd2c36 | ||
|
|
afb7a48b29 | ||
|
|
aff5b7fadf | ||
|
|
7733a0a620 | ||
|
|
78a2ef04a9 | ||
|
|
76295ac873 | ||
|
|
8df9bb3840 | ||
|
|
ea3048fb96 | ||
|
|
cb0a9b254e | ||
|
|
06b4f3cd58 | ||
|
|
ab6b9312f2 | ||
|
|
d88d876501 | ||
|
|
60229d96a5 | ||
|
|
789b278ec5 | ||
|
|
65c8722d72 | ||
|
|
6df92f7cca | ||
|
|
58f6755fa7 | ||
|
|
aa47ff5653 | ||
|
|
cdbf21a92d | ||
|
|
5b726e09af | ||
|
|
928cee9dab | ||
|
|
351485f066 | ||
|
|
11b9adfa40 | ||
|
|
d5642e6bdf | ||
|
|
d9568263a3 | ||
|
|
54ea845f34 | ||
|
|
3aa3d03397 | ||
|
|
f1cc9d865b | ||
|
|
299f6f8551 | ||
|
|
c75140592f | ||
|
|
59aa9052f8 | ||
|
|
92a44db0b8 | ||
|
|
58f5955687 | ||
|
|
2879ed4388 | ||
|
|
772a8b7dac | ||
|
|
bab0924d86 | ||
|
|
561a268c9c | ||
|
|
3b17456254 | ||
|
|
6035a7c143 | ||
|
|
77cadcdf22 | ||
|
|
e972f9c557 | ||
|
|
07b7bf3084 | ||
|
|
8ac644c746 | ||
|
|
5d1d99a89f | ||
|
|
2c1e36ae9a | ||
|
|
58f2fe73c8 | ||
|
|
2c129dfbfa | ||
|
|
aad7816949 | ||
|
|
15fa7246f2 | ||
|
|
882c46437c | ||
|
|
6495d0bd5d | ||
|
|
47060bfedd | ||
|
|
6fcbc0e59a | ||
|
|
1ef01b404e | ||
|
|
4987558a56 | ||
|
|
e4ddf1e8c0 | ||
|
|
9531aafaf2 | ||
|
|
aa9ab7e09c | ||
|
|
2be1b1a096 | ||
|
|
3878f3c770 | ||
|
|
6e01d390bf | ||
|
|
d18934d444 | ||
|
|
4b543de7f9 | ||
|
|
4e182ebf67 | ||
|
|
71bd810531 | ||
|
|
38ebbd23c7 | ||
|
|
9a1612b99b | ||
|
|
f354c43941 | ||
|
|
a49df16d44 | ||
|
|
004b377701 | ||
|
|
ff032fa18c | ||
|
|
20c0d8f3ba | ||
|
|
6b71345142 | ||
|
|
b21dba8fc4 | ||
|
|
1afad677e9 | ||
|
|
99b1cb0f74 | ||
|
|
c602d94cef | ||
|
|
7a752bd111 | ||
|
|
90de3904f4 | ||
|
|
08154ec4d1 | ||
|
|
a281675348 | ||
|
|
6d94f2ea55 | ||
|
|
06d5c8135c | ||
|
|
857ec1079a | ||
|
|
f2106416a7 | ||
|
|
380a52cde7 | ||
|
|
a6e0e34c6e | ||
|
|
d34045b904 | ||
|
|
fd4985cc62 | ||
|
|
d11ad87c4c | ||
|
|
9e63c88809 | ||
|
|
e6db4113a5 | ||
|
|
c37153b604 | ||
|
|
fd95cffad4 | ||
|
|
8188e8f3bf | ||
|
|
399b3be499 | ||
|
|
8d0cb2aa7f | ||
|
|
9e9326cc6d | ||
|
|
f45fd155c4 | ||
|
|
155eb70d65 | ||
|
|
963b0c5952 | ||
|
|
c2ce8bb26b | ||
|
|
60deeb0182 | ||
|
|
385a688830 | ||
|
|
e3dc9ca70b | ||
|
|
1222153cdf | ||
|
|
7e9095acf2 | ||
|
|
654ad4c97e | ||
|
|
66697ca6e9 | ||
|
|
aff8faf44d | ||
|
|
f78e014022 | ||
|
|
2b543ddf16 | ||
|
|
90d1877856 | ||
|
|
bd8eb7f2ca | ||
|
|
1507dcd56d | ||
|
|
6474c5c9f4 | ||
|
|
12d432d94d | ||
|
|
258013f99f | ||
|
|
f40ea15cce | ||
|
|
0aaf0218ca | ||
|
|
5adf99059d | ||
|
|
cc1e952d0b | ||
|
|
658706ad8b | ||
|
|
9c973efa9d | ||
|
|
ef47ea31fa | ||
|
|
22d392a75c | ||
|
|
0bf901e9bb | ||
|
|
badad63ab4 | ||
|
|
26546c1bd8 | ||
|
|
17ec5d7891 | ||
|
|
e6e0396ecb | ||
|
|
44748ea86b | ||
|
|
1e73cf82a6 | ||
|
|
59f820aacd | ||
|
|
edffdb5702 | ||
|
|
76a77fdd36 | ||
|
|
85991e88e8 | ||
|
|
486274cfa1 | ||
|
|
679c9c5bfe | ||
|
|
c4f57e74ee | ||
|
|
4c67de5ca7 | ||
|
|
411098117a | ||
|
|
c2f90ac911 | ||
|
|
21b0f4955e | ||
|
|
970c4950f4 | ||
|
|
feee40603c | ||
|
|
3a653c73e7 | ||
|
|
514bb4a6a9 | ||
|
|
aa3297a925 | ||
|
|
e58030498f | ||
|
|
a275133ff9 | ||
|
|
c62a53ad27 | ||
|
|
9ceaaa5faf | ||
|
|
e6eded243e | ||
|
|
d8706979ae | ||
|
|
5ca6991067 | ||
|
|
fc062c3b63 | ||
|
|
70daee399f | ||
|
|
7f8433148c | ||
|
|
5b7c1bc7e2 | ||
|
|
2935e28ffb | ||
|
|
94914382c2 | ||
|
|
1951a81a0b | ||
|
|
6fab2e3651 | ||
|
|
cd572a74ce | ||
|
|
eeb056b8d9 | ||
|
|
19c6bd2139 | ||
|
|
2de0597038 | ||
|
|
fbac08200d | ||
|
|
a4be33026d | ||
|
|
de4bfe4e4f | ||
|
|
62ef34ea04 | ||
|
|
9e63ed305d | ||
|
|
3b1cdaa9bf | ||
|
|
ae0788682a | ||
|
|
d3de1d9c33 | ||
|
|
ec48049a69 | ||
|
|
8f99365e9a | ||
|
|
74192632fa | ||
|
|
a94ca97d36 | ||
|
|
fe4546498b | ||
|
|
7930398a25 | ||
|
|
41e54499c9 | ||
|
|
d8761211a4 | ||
|
|
f00a6e5419 | ||
|
|
66785b7997 | ||
|
|
d0728add45 | ||
|
|
25d47ec6df | ||
|
|
83ee6fc818 | ||
|
|
2713694338 | ||
|
|
32088821c0 | ||
|
|
dcbb8d0780 | ||
|
|
b726395d1e | ||
|
|
929f0f5f00 | ||
|
|
e571dd90d8 | ||
|
|
26b755d544 | ||
|
|
79b2beb588 | ||
|
|
55af069fe8 | ||
|
|
f8d1e15a27 | ||
|
|
7638ec05e7 | ||
|
|
3c18663c3f | ||
|
|
b230bec586 | ||
|
|
a07b3dccc4 | ||
|
|
589422b505 | ||
|
|
dd56d9a17c | ||
|
|
68de9bf5d2 | ||
|
|
03afae4da4 | ||
|
|
2637566fe9 | ||
|
|
967eec5786 | ||
|
|
be4be5c650 | ||
|
|
ce489d8d84 | ||
|
|
d188e5cd2e | ||
|
|
a45803f00f | ||
|
|
9adbdcb7c5 | ||
|
|
b0f7c33ab1 | ||
|
|
27f7a00df0 | ||
|
|
222f15c293 | ||
|
|
ff2ec85b61 | ||
|
|
53f35b5284 | ||
|
|
844cfc5137 | ||
|
|
e3d6c29c8f | ||
|
|
fec6a10771 | ||
|
|
e549a2c5c3 | ||
|
|
e941e7e805 | ||
|
|
8f4afd53a6 | ||
|
|
9bb27b1e8d | ||
|
|
971cd51d76 | ||
|
|
de4c73abcb | ||
|
|
8f0c02c0fa | ||
|
|
04ada23119 | ||
|
|
46253ed873 | ||
|
|
1a9ab8ec84 | ||
|
|
47db309d30 | ||
|
|
7de4108bad | ||
|
|
9a5a00f836 | ||
|
|
07a427bf28 | ||
|
|
dfc9a9474a | ||
|
|
54206ef92b | ||
|
|
ddd43f1378 | ||
|
|
38ccb12eb0 | ||
|
|
ca3bf14fb6 | ||
|
|
982474899b | ||
|
|
ad6ff5562d | ||
|
|
d4cd1dbd27 | ||
|
|
3c1426e631 | ||
|
|
c3a1a9514f | ||
|
|
f56d763411 | ||
|
|
4ec91047dd | ||
|
|
0579ae08cd | ||
|
|
9074999666 | ||
|
|
0458ab5a53 | ||
|
|
4a3459c87c | ||
|
|
301cbe31ad | ||
|
|
165dd82bb2 | ||
|
|
9c3b3246c8 | ||
|
|
6416f8b90e | ||
|
|
e6eae5fd15 | ||
|
|
aa3a6dba4e | ||
|
|
dedae73761 | ||
|
|
d7f3d00f5c | ||
|
|
c2070777b2 | ||
|
|
42b34c2ce6 | ||
|
|
6fbfdd8f3f | ||
|
|
bee3acfd12 | ||
|
|
2e279b61dd | ||
|
|
8ab909a765 | ||
|
|
cca07fa42d | ||
|
|
5b81798205 | ||
|
|
a8a82df47d | ||
|
|
e62e1d89b6 | ||
|
|
c032186133 | ||
|
|
b89e138404 | ||
|
|
9f80ed32b6 | ||
|
|
c16a4a3950 | ||
|
|
90fa90a508 | ||
|
|
aaa734690f | ||
|
|
88da7804c4 | ||
|
|
8604f922a5 | ||
|
|
807a758f7c | ||
|
|
ef55086543 | ||
|
|
2001903c89 | ||
|
|
751e4e4c79 | ||
|
|
9d91b5db4c | ||
|
|
9a3c9507ed | ||
|
|
d71d52bfe9 | ||
|
|
8e30bc9f9e | ||
|
|
412518d1ca | ||
|
|
03afbf157b | ||
|
|
00b2d467e4 | ||
|
|
856829d299 | ||
|
|
2fafe6866f | ||
|
|
b9188ad0ca | ||
|
|
0ccb9139c9 | ||
|
|
18e402ddc8 | ||
|
|
b82d3165da | ||
|
|
91580d1fcc | ||
|
|
35d7384903 | ||
|
|
4539632f34 | ||
|
|
0651f246b2 | ||
|
|
6d0dee9341 | ||
|
|
c692f1708c | ||
|
|
d91733d32c | ||
|
|
cd7378ff3f | ||
|
|
c98ce4a029 | ||
|
|
d035a7e92c | ||
|
|
6db6359363 | ||
|
|
5c07a29e46 | ||
|
|
42d9094e9b | ||
|
|
1742231eba | ||
|
|
3178f886b7 | ||
|
|
cbc4a0ab52 | ||
|
|
cfd8cbf850 | ||
|
|
013b18b3dc | ||
|
|
db9f20b21a | ||
|
|
f611260089 | ||
|
|
e34e3a4875 | ||
|
|
aa8869a3c7 | ||
|
|
588931fcf2 | ||
|
|
07e49e215e | ||
|
|
1b84893ccb | ||
|
|
6445bb6915 | ||
|
|
db899bd1b5 | ||
|
|
c6dcc38fe0 | ||
|
|
b0a7909162 | ||
|
|
d7ae85a13a | ||
|
|
46ee38b466 | ||
|
|
bc6a958a50 | ||
|
|
0e751ad975 | ||
|
|
de94d09706 | ||
|
|
2f88a631df | ||
|
|
4e5dd49a37 | ||
|
|
8463dcc878 | ||
|
|
18bc2f65b3 | ||
|
|
b4e8ea5a0c | ||
|
|
06a8087cb5 | ||
|
|
a9dfef0f55 | ||
|
|
e4540c3d0d | ||
|
|
0cc8396244 | ||
|
|
946693ad4d | ||
|
|
f014d4c533 | ||
|
|
6a1e3f7e27 | ||
|
|
7ad66b0725 | ||
|
|
0341c0c727 | ||
|
|
20c8550139 | ||
|
|
39aa90ce59 | ||
|
|
6c67a64fc3 | ||
|
|
86032c0aa5 | ||
|
|
f243f694b4 | ||
|
|
276ae3e228 | ||
|
|
fe6756eb07 | ||
|
|
539e494bc0 | ||
|
|
1298656c22 | ||
|
|
c66d319d9c | ||
|
|
ae27165ffe | ||
|
|
32f1ca6f8b | ||
|
|
9ce2806710 | ||
|
|
3d4593d4d5 | ||
|
|
df5ae54ec7 | ||
|
|
fbee1b424d | ||
|
|
555017b525 | ||
|
|
1e170ee005 | ||
|
|
43501809b1 | ||
|
|
c0c67a101a | ||
|
|
1eb714e097 | ||
|
|
54a8e12856 | ||
|
|
6203f05ef9 | ||
|
|
703ad04067 | ||
|
|
778e96330d | ||
|
|
e3eb89fb12 | ||
|
|
166621bcb3 | ||
|
|
879a5a4cbe | ||
|
|
9faabfe995 | ||
|
|
6f23fa61ac | ||
|
|
30b6cf7821 | ||
|
|
6258011210 | ||
|
|
7557a46382 | ||
|
|
a0a91f358c | ||
|
|
0128286966 | ||
|
|
acd5e86e04 | ||
|
|
ab94b0a636 | ||
|
|
de6d696667 | ||
|
|
63946c4cfb | ||
|
|
475b603d15 | ||
|
|
096956cda9 | ||
|
|
3d3116d48b | ||
|
|
616360d751 | ||
|
|
7a5c30d297 | ||
|
|
9c5ab36a8b | ||
|
|
466656b167 | ||
|
|
5d6567cb02 | ||
|
|
c44c123ef5 | ||
|
|
4ecbf56e2b | ||
|
|
ed9a2c4b3f | ||
|
|
90751b9250 | ||
|
|
7d8011669d | ||
|
|
eb81062d85 | ||
|
|
8fbacc966e | ||
|
|
75801a12e3 | ||
|
|
9f1ce170e6 | ||
|
|
327c8826f4 | ||
|
|
fb0383d2bd | ||
|
|
28725d0d74 | ||
|
|
dac99b9374 | ||
|
|
1573477caf | ||
|
|
70a7513781 | ||
|
|
0277035496 | ||
|
|
33f462fdf6 | ||
|
|
639b9f346f | ||
|
|
447fee6f43 | ||
|
|
c9212a9a09 | ||
|
|
ea21fab379 | ||
|
|
4d090b64bd | ||
|
|
7e1e44e87a | ||
|
|
0a2a9dcd94 | ||
|
|
c9b4b66af2 | ||
|
|
7b6678b2a1 | ||
|
|
e79f62c5fa | ||
|
|
60046cc790 | ||
|
|
3fca25181a | ||
|
|
cbca31555d | ||
|
|
d5aa700b4b | ||
|
|
1db8319bce | ||
|
|
aa390f2a91 | ||
|
|
bd9e66d333 | ||
|
|
c34e318f8c | ||
|
|
4fc858b676 | ||
|
|
ac8b582b3d | ||
|
|
6f748d3d4f | ||
|
|
2854a524f0 | ||
|
|
985c34bfd9 | ||
|
|
63f97d8ec6 | ||
|
|
d2ac85e2c7 | ||
|
|
1b42f6232f | ||
|
|
4de141ab1d | ||
|
|
8ab2ec6f86 | ||
|
|
2fad8d4cff | ||
|
|
d94b0fe3c8 | ||
|
|
98956ef88f | ||
|
|
ac21d96bd8 | ||
|
|
c794aa02b8 | ||
|
|
dd564ab321 | ||
|
|
c0046e845e | ||
|
|
640767b748 | ||
|
|
d4eaede435 | ||
|
|
52bf4e613f | ||
|
|
9533a8dbdf | ||
|
|
774f78cd3e | ||
|
|
aca1dcf848 | ||
|
|
d24cd015b6 | ||
|
|
4d41525a91 | ||
|
|
b170a85fef | ||
|
|
90c6bc3a61 | ||
|
|
a4f6217a2f | ||
|
|
faff19af7b | ||
|
|
bc86bd4efa | ||
|
|
b4b18f3f30 | ||
|
|
1bcacf06d4 | ||
|
|
27178cedda | ||
|
|
6151d796a2 | ||
|
|
6ace9659e0 | ||
|
|
14942b4b43 | ||
|
|
9ede67ea63 | ||
|
|
cc74d2a6b0 | ||
|
|
ea779ac7dd | ||
|
|
693e9e5ad0 | ||
|
|
a1bc8ca6ca | ||
|
|
4e753a2c15 | ||
|
|
89314d4772 | ||
|
|
41f7ecacfc | ||
|
|
dd8da912f5 | ||
|
|
65ad911a2a | ||
|
|
37331d1c1b | ||
|
|
db2c842d15 | ||
|
|
c0e22a6533 | ||
|
|
bb87c368b8 | ||
|
|
76665b9404 | ||
|
|
a265ba2162 | ||
|
|
461a0fa2fb | ||
|
|
e51bbcb85a | ||
|
|
58ec62c895 | ||
|
|
843e1f9c44 | ||
|
|
45382144c3 | ||
|
|
e2f537628f | ||
|
|
91baa938e2 | ||
|
|
7fcaeacd65 | ||
|
|
2478d6f5d3 | ||
|
|
fbc1f6fb81 | ||
|
|
57aee7ca26 | ||
|
|
2fcfe9f2c3 | ||
|
|
2df2619029 | ||
|
|
9260d0d245 | ||
|
|
15becdaee4 | ||
|
|
80c9db3c88 | ||
|
|
c5d03d3a25 | ||
|
|
9e1570dc80 | ||
|
|
68da84e84a | ||
|
|
18ba73382e | ||
|
|
dabbfdb80a | ||
|
|
4eea8720a0 | ||
|
|
41239078a9 | ||
|
|
e375078dda | ||
|
|
da6b4c447f | ||
|
|
b72c0a0089 | ||
|
|
fbaf8f91bb | ||
|
|
329e943e4e | ||
|
|
31bd3e6056 | ||
|
|
15b94050ce | ||
|
|
c610699227 | ||
|
|
f0d2e20342 | ||
|
|
26a80005d6 | ||
|
|
5cf033a6ad | ||
|
|
e41ee7632d | ||
|
|
66a86433e7 | ||
|
|
2354a90e9f | ||
|
|
b7aaf51fbd | ||
|
|
5a885165b2 | ||
|
|
a748604418 | ||
|
|
e1a4e27173 | ||
|
|
2b06a293b6 | ||
|
|
472f98affe | ||
|
|
8114523be2 | ||
|
|
33ee1da817 | ||
|
|
301040a67a | ||
|
|
54b96ea7bd | ||
|
|
d0dfe2e7e7 | ||
|
|
fd8ceac170 | ||
|
|
a05d8c2823 | ||
|
|
626f418ab0 | ||
|
|
5792220dcb | ||
|
|
29d5d44f03 | ||
|
|
b2762f63a2 | ||
|
|
7d97f8a964 | ||
|
|
d3e63088d8 | ||
|
|
dddaa0ebcf | ||
|
|
ccbb1e5f5a | ||
|
|
3f1cd14f6c | ||
|
|
70abb2ce5c | ||
|
|
3f80bead1b | ||
|
|
93bb4283b8 | ||
|
|
5b5b31286b | ||
|
|
c5bde6560c | ||
|
|
cb4eb6236c | ||
|
|
d5e9e13555 | ||
|
|
3595b6d186 | ||
|
|
210010a390 | ||
|
|
99b3cc4464 | ||
|
|
9b6b081e38 | ||
|
|
b54ee3b1cd | ||
|
|
9fc4e1eddd | ||
|
|
73cca6ec39 | ||
|
|
58c2e12507 | ||
|
|
6dd80611a1 | ||
|
|
c2132039d2 | ||
|
|
d8d07eb129 | ||
|
|
f9768cd579 | ||
|
|
b6a15b2f4d | ||
|
|
5eca5d9948 | ||
|
|
f4a4ee00d0 | ||
|
|
cd94019733 | ||
|
|
d7fb47268f | ||
|
|
b4b5ac9944 | ||
|
|
df0b81d94d | ||
|
|
067d09720c | ||
|
|
870c35eece | ||
|
|
a82c178fd9 | ||
|
|
809bd18e66 | ||
|
|
4f0ffa2258 | ||
|
|
f45b17973c | ||
|
|
0bbea355c2 | ||
|
|
2be3507422 | ||
|
|
d6c946f390 | ||
|
|
96b6eb6b30 | ||
|
|
9cef973d9b | ||
|
|
88722a2831 | ||
|
|
d6b5c67313 | ||
|
|
4fed9d6532 | ||
|
|
28e0616543 | ||
|
|
6173e6b78a | ||
|
|
b5018cd994 | ||
|
|
f19a7c617d | ||
|
|
53d8cdd9f8 | ||
|
|
4bac5c06ba | ||
|
|
91a755d0e8 | ||
|
|
8cae7a4d44 | ||
|
|
11d1c45e45 | ||
|
|
5454a15b94 | ||
|
|
3ad0ec77ce | ||
|
|
3966e852ac | ||
|
|
83bfa9345f | ||
|
|
7d1d3847d8 | ||
|
|
a91c4f66ce | ||
|
|
ca2486ea61 | ||
|
|
24a2487c18 | ||
|
|
d68153dea3 | ||
|
|
89329fc0cc | ||
|
|
cba5a22714 | ||
|
|
1ce50993f0 | ||
|
|
2c0c934ad5 | ||
|
|
b6db8b63ec | ||
|
|
f1ab9e63fa | ||
|
|
12c574d5c9 | ||
|
|
af6f0c800f | ||
|
|
48f65cef40 | ||
|
|
b5a1d116fa | ||
|
|
b9339d3c60 | ||
|
|
0838dd24a4 | ||
|
|
9537fd7f0b | ||
|
|
95876feb46 | ||
|
|
19d817503d | ||
|
|
b6b364a09d | ||
|
|
f704d4d3ff | ||
|
|
450b9ab85c | ||
|
|
a1774bd3bd | ||
|
|
5aa69516bb | ||
|
|
c594dcec52 | ||
|
|
8126384726 | ||
|
|
96e6a9b02f | ||
|
|
d44ff4fd91 | ||
|
|
9a4ee873e1 | ||
|
|
597ed1681a | ||
|
|
bcd49b94dd | ||
|
|
422754f36f | ||
|
|
bfad382fd1 | ||
|
|
8941a594ee | ||
|
|
6bd8ab46d5 | ||
|
|
57f2ad6d15 | ||
|
|
33efeca0da | ||
|
|
be1888ed5f | ||
|
|
6ede18d41c | ||
|
|
d63e994ea5 | ||
|
|
700887d657 | ||
|
|
42674be38b | ||
|
|
fde7cd8f10 | ||
|
|
7ce713356e | ||
|
|
6511fc610b | ||
|
|
8dd4f77f3f | ||
|
|
004bfad348 | ||
|
|
ff90a5735d | ||
|
|
e6c0629626 | ||
|
|
01efffedfc | ||
|
|
74c219f171 | ||
|
|
bf10c5762a | ||
|
|
ca9abaf0c5 | ||
|
|
cfab250671 | ||
|
|
b1c0f7306d | ||
|
|
a156d8b8ce | ||
|
|
a7b7781fe9 | ||
|
|
21fe6afe8d | ||
|
|
48da46986b | ||
|
|
8d6239301f | ||
|
|
2e6807493f | ||
|
|
94cef20e49 | ||
|
|
c787a36af2 | ||
|
|
da0c4c7565 | ||
|
|
9c28f085d8 | ||
|
|
e9af0c7485 | ||
|
|
be54bfdc21 | ||
|
|
c6a6f4bc79 | ||
|
|
88ae1b7b3c | ||
|
|
f5d3b78653 | ||
|
|
68f1316eba | ||
|
|
e70e04d6e8 | ||
|
|
a3eb6868ea | ||
|
|
186759c95e | ||
|
|
8667b9a35d | ||
|
|
00defb0265 | ||
|
|
822a085d97 | ||
|
|
f23aec7f14 | ||
|
|
fb457128bf | ||
|
|
d126a414bd | ||
|
|
844fe3b9bc | ||
|
|
271855377f | ||
|
|
84020b16e3 | ||
|
|
c6035ab06e | ||
|
|
d94a40ecd9 | ||
|
|
c3be17ccae | ||
|
|
10dc978778 | ||
|
|
7f8f0eb65a | ||
|
|
c7107dc973 | ||
|
|
74eb544962 | ||
|
|
0696e3d558 | ||
|
|
714ca3542d | ||
|
|
7e27217dac | ||
|
|
4a7e14786c | ||
|
|
1ddb736f4c | ||
|
|
9ef49379f4 | ||
|
|
96213fe0ac | ||
|
|
d482da4803 | ||
|
|
4502da608d | ||
|
|
0976fd393b | ||
|
|
5882c6a481 | ||
|
|
52ea13819a | ||
|
|
048d044fdc | ||
|
|
9dda15a186 | ||
|
|
b094bbdcf4 | ||
|
|
eb708c1540 | ||
|
|
47a3b1f744 | ||
|
|
76b5d7e9e1 | ||
|
|
0071c9b0aa | ||
|
|
0ab42597d9 | ||
|
|
95ccc1e904 | ||
|
|
ea44866b2f | ||
|
|
6d4c6b56f6 | ||
|
|
f03ec88c2a | ||
|
|
e630ecdb0d | ||
|
|
eb27dc8db3 | ||
|
|
5cf7355c91 | ||
|
|
84bf0cee59 | ||
|
|
a18662ed13 | ||
|
|
3275d1f252 | ||
|
|
b14a0b885a | ||
|
|
e95a902b3d | ||
|
|
6733f7625b | ||
|
|
f7f61a8696 | ||
|
|
e1a6bb10de | ||
|
|
07bee5ca72 | ||
|
|
fa97ba0d9a | ||
|
|
bc95b02854 | ||
|
|
1893e7c8e5 | ||
|
|
0c04e2976b | ||
|
|
ac4fbb3e41 | ||
|
|
c98c24b9ff | ||
|
|
284c6fd85d | ||
|
|
3c8551ce90 | ||
|
|
65159a2733 | ||
|
|
007d702223 | ||
|
|
362b2aa604 | ||
|
|
de252965ac | ||
|
|
7349a6beaf | ||
|
|
828ca0ef9d | ||
|
|
f5049c2f14 | ||
|
|
f77c7f3d18 | ||
|
|
f75fb3cd95 | ||
|
|
8b9c26598a | ||
|
|
53600d3361 | ||
|
|
0dc5e5e29d | ||
|
|
eae9153b40 | ||
|
|
3d646aa92c | ||
|
|
b7c2bd4f72 | ||
|
|
b0a489fb7f | ||
|
|
01b9d5e023 | ||
|
|
6fa9415482 | ||
|
|
c159ff3134 | ||
|
|
efa5338e3b | ||
|
|
6dcf880482 | ||
|
|
b5fbb82ba1 | ||
|
|
ba8465abd2 | ||
|
|
0964dd99c5 | ||
|
|
a6a78f5776 | ||
|
|
23f73390a4 | ||
|
|
d55a890fdd | ||
|
|
84de8f2b93 | ||
|
|
08dac488c1 | ||
|
|
f2cff31b6e | ||
|
|
7c3f5c9fae | ||
|
|
aa16e82102 | ||
|
|
ddd3566d50 | ||
|
|
ec82af0c74 | ||
|
|
78bb3d6f09 | ||
|
|
54dab22042 | ||
|
|
9756cb6382 | ||
|
|
9fa0f95003 | ||
|
|
a624021a2e | ||
|
|
928df5caf7 | ||
|
|
5796524f06 | ||
|
|
b761a105b3 | ||
|
|
364ffc9024 | ||
|
|
712080f7e0 | ||
|
|
b906f4c0a1 | ||
|
|
d48bb4d744 | ||
|
|
d67ad166cd | ||
|
|
4e286ea86b | ||
|
|
a9be4e009f | ||
|
|
2f05d4b227 | ||
|
|
0b68639f7d | ||
|
|
5f09e01a44 | ||
|
|
6a98764b3b | ||
|
|
853c1f4387 | ||
|
|
b99c5aa394 | ||
|
|
349be0f169 | ||
|
|
4f28f6a770 | ||
|
|
fcf64c0c38 | ||
|
|
da8d59757e | ||
|
|
a02cfe0f1b | ||
|
|
f3255121a2 | ||
|
|
608555ce7e | ||
|
|
ec8b6e126e | ||
|
|
a697157257 | ||
|
|
ec070ee65b | ||
|
|
02f5ccd5d9 | ||
|
|
361d4f2147 | ||
|
|
c09a148cd9 | ||
|
|
b274dada85 | ||
|
|
c6a937e2e7 | ||
|
|
5840368f2d | ||
|
|
dee52dd2d0 | ||
|
|
a0e3b3386d | ||
|
|
6535b48c1c | ||
|
|
4d3611c5f1 | ||
|
|
77c4c88a4c | ||
|
|
4291866b9f | ||
|
|
8aef782411 | ||
|
|
0aa033ddf3 | ||
|
|
edba542c7a | ||
|
|
0e5289b022 | ||
|
|
6be3be0f16 | ||
|
|
03d188fc52 | ||
|
|
6e1e658922 | ||
|
|
a87575a76e | ||
|
|
336624c7b9 | ||
|
|
71660fbaa5 | ||
|
|
dd79885f6d | ||
|
|
51ffeb7c06 | ||
|
|
912749342c | ||
|
|
4bb91c4f98 | ||
|
|
400580179f | ||
|
|
c9d6b5431d | ||
|
|
51db00fb44 | ||
|
|
e20acfc9f9 | ||
|
|
a3fe753826 | ||
|
|
03aebd7525 | ||
|
|
fd5c0cfa28 | ||
|
|
357a0ff23e | ||
|
|
1a22f37d92 | ||
|
|
a5890b914f | ||
|
|
b397b10104 | ||
|
|
5de8e0555c | ||
|
|
91b01cd67e | ||
|
|
9c6b17c887 | ||
|
|
000d187c94 | ||
|
|
989e9d4d94 | ||
|
|
40ef704cc3 | ||
|
|
7c9fe0c173 | ||
|
|
dddbeb957a | ||
|
|
fd0cb30a4d | ||
|
|
125c631091 | ||
|
|
443dc7853f | ||
|
|
a5400d7212 | ||
|
|
da09d4c6e6 | ||
|
|
ace6b0a767 | ||
|
|
7d494fd3d5 | ||
|
|
cd1524e6ca | ||
|
|
a0526cdd32 | ||
|
|
4dd5f97a96 | ||
|
|
1ca6fe5519 | ||
|
|
6b2c604124 | ||
|
|
e42775ea7f | ||
|
|
a8c4729cf5 | ||
|
|
c200c0c20e | ||
|
|
4b174fd996 | ||
|
|
dbf5509f4f | ||
|
|
ec4f8c80d5 | ||
|
|
c8319bcc02 | ||
|
|
7bf480be9a | ||
|
|
2d3e85d941 | ||
|
|
ab6c8cb4b8 | ||
|
|
33c7c47f73 | ||
|
|
64d7b1cee5 | ||
|
|
0cebef872a | ||
|
|
65f835f3eb | ||
|
|
8309c1f673 | ||
|
|
e85347bf8b | ||
|
|
86a4512848 | ||
|
|
82831ea9a5 | ||
|
|
98c145c3b6 | ||
|
|
a50fe36ef8 | ||
|
|
7cbd710f7b | ||
|
|
39ef2b7605 | ||
|
|
da4901bb17 | ||
|
|
f28f5e01e5 | ||
|
|
e00aedd99b | ||
|
|
9d1a81ce2c | ||
|
|
cfed3933fa | ||
|
|
659624c71f | ||
|
|
6e0b77a8da | ||
|
|
54bb59ae99 | ||
|
|
cac941b272 | ||
|
|
0be48388c2 | ||
|
|
d8970752b6 | ||
|
|
08f0f5a1f7 | ||
|
|
f8162be8c3 | ||
|
|
f50074de50 | ||
|
|
9866fd01bd | ||
|
|
d1ad10c90f | ||
|
|
0045d7d1bf | ||
|
|
4a74ae1795 | ||
|
|
4d0b840c26 | ||
|
|
0c7335a77d | ||
|
|
7e8a538c20 | ||
|
|
aca5afa95c | ||
|
|
7793a49854 | ||
|
|
6bfbcbdcf7 | ||
|
|
bf72f39fe9 | ||
|
|
fa23dafdae | ||
|
|
9572ddd7e8 | ||
|
|
1ff36dc892 | ||
|
|
bf9a8f5021 | ||
|
|
0c4bea473c | ||
|
|
649428962e | ||
|
|
cc5ddc0b6b | ||
|
|
b624b6002e | ||
|
|
af35736e04 | ||
|
|
58b5b583a7 | ||
|
|
9e385e6947 | ||
|
|
560c003e03 | ||
|
|
1d045eea0d | ||
|
|
7a0e73ef3d | ||
|
|
5d20dd63ec | ||
|
|
ab9a853d52 | ||
|
|
82c0a2ebac | ||
|
|
75e78e86d3 | ||
|
|
a75326e2e0 | ||
|
|
b3e430c751 | ||
|
|
faa3a62259 | ||
|
|
438605fad5 | ||
|
|
9505b586bf | ||
|
|
40e7bc2450 | ||
|
|
a9aaca1ffa | ||
|
|
ce61d12f60 | ||
|
|
874bab10e4 | ||
|
|
21194c909a | ||
|
|
96a50d635d | ||
|
|
8c9e0bafa9 | ||
|
|
b3bb79992a | ||
|
|
4e92501864 | ||
|
|
d83fb10774 | ||
|
|
5a6cca33a0 | ||
|
|
b2f6953259 | ||
|
|
b1f1f74920 | ||
|
|
2adea8de48 | ||
|
|
859318becd | ||
|
|
55fb219503 | ||
|
|
b01316ce12 | ||
|
|
1921e19635 | ||
|
|
990df42407 | ||
|
|
924b4e0062 | ||
|
|
0e43dfb285 | ||
|
|
46621d3c83 | ||
|
|
fa95f7ff3b | ||
|
|
e45546e6f3 | ||
|
|
d79d48ffeb | ||
|
|
467ecf5b33 | ||
|
|
9f3e64e11a | ||
|
|
56954356db | ||
|
|
6466d02eda | ||
|
|
7a149a6943 | ||
|
|
acf3a4ec16 | ||
|
|
5c4b87675f | ||
|
|
83d3a60d5c | ||
|
|
3e4eb17b15 | ||
|
|
1075b28f26 | ||
|
|
943527c526 | ||
|
|
d350620315 | ||
|
|
6fc556cefc | ||
|
|
73283768a5 | ||
|
|
ce7d64f427 | ||
|
|
84b70be7ee | ||
|
|
3924c51097 | ||
|
|
4bb1bd4315 | ||
|
|
0164ad78be | ||
|
|
36e1eab3f4 | ||
|
|
177fa4062b | ||
|
|
821c68696d | ||
|
|
a3217db7b2 | ||
|
|
42dab181cd | ||
|
|
98d71de50f | ||
|
|
c596e1cda1 | ||
|
|
706f2ffc89 | ||
|
|
a7054a91e5 | ||
|
|
ad44b411fb | ||
|
|
f7fa2f1f4d | ||
|
|
2fcab15704 | ||
|
|
cfbad49d33 | ||
|
|
9dbcb32808 | ||
|
|
1b69bb5d2f | ||
|
|
2326672b3a | ||
|
|
393a76d57a | ||
|
|
4b3b41cd79 | ||
|
|
eab5793dda | ||
|
|
6cf2ddf541 | ||
|
|
ad6bbe539f | ||
|
|
f12864f69e | ||
|
|
b61c89c104 | ||
|
|
0def3c9983 | ||
|
|
9e5dc17c1d | ||
|
|
36d36d99f3 | ||
|
|
de985ac3fd | ||
|
|
245905aeda | ||
|
|
ac6caaf29e | ||
|
|
3734b5e7f1 | ||
|
|
789efb9832 | ||
|
|
c7bc35ad75 | ||
|
|
5071ce8575 | ||
|
|
64ff74df37 | ||
|
|
181066311b | ||
|
|
20ad433f8c | ||
|
|
494b5ff1ee | ||
|
|
cbd501b865 | ||
|
|
41384a0e41 | ||
|
|
3854e12024 | ||
|
|
ff55af1e9e | ||
|
|
bdf643ddb1 | ||
|
|
d46465845c | ||
|
|
dd75595082 | ||
|
|
a73cfbc2b5 | ||
|
|
21c844363a | ||
|
|
3109906514 | ||
|
|
606eb2b3cd | ||
|
|
e99059e001 | ||
|
|
cefbb635c1 | ||
|
|
b2b8b89cd8 | ||
|
|
92760f2c5f | ||
|
|
176be94be9 | ||
|
|
9fda809fa6 | ||
|
|
3c8d598eed | ||
|
|
f2068e83d4 | ||
|
|
5976e7078c | ||
|
|
da9a84ed84 | ||
|
|
03b635604a | ||
|
|
167f94bdbf | ||
|
|
4507351d48 | ||
|
|
0253f92e7e | ||
|
|
432d4efc9b | ||
|
|
749c3eb5a7 | ||
|
|
e933b56507 | ||
|
|
0c5ce9dfec | ||
|
|
acde444439 | ||
|
|
298a352cbd | ||
|
|
356552faad | ||
|
|
5e1e79b3c4 | ||
|
|
2996d2eb19 | ||
|
|
16023cbbd6 | ||
|
|
77927972e5 | ||
|
|
d762a320dc | ||
|
|
a9e54e7553 | ||
|
|
8b8a3d83e0 | ||
|
|
3fbbd4080a | ||
|
|
e79a371f76 | ||
|
|
c507379f09 | ||
|
|
47031767fa | ||
|
|
af5e68448c | ||
|
|
c1c88f87c6 | ||
|
|
a9b5c9c037 | ||
|
|
03b428b6cb | ||
|
|
271a835305 | ||
|
|
a3c3019a04 | ||
|
|
f063bf833f | ||
|
|
2002c03cef | ||
|
|
b8be5e80cd | ||
|
|
c29e11ed36 | ||
|
|
e35ed6e91c | ||
|
|
794ce68a6c | ||
|
|
31aa85ce7d | ||
|
|
15c2b0317d | ||
|
|
820d8b9edc | ||
|
|
a3a0f5f432 | ||
|
|
a98b5023a8 | ||
|
|
645c8913f1 | ||
|
|
066284d5c2 | ||
|
|
2802601c44 | ||
|
|
962a77c6b8 | ||
|
|
ca801574e3 | ||
|
|
606c1d38bb | ||
|
|
147ee59940 | ||
|
|
2e3fc89831 | ||
|
|
82bccd335d | ||
|
|
bfc05e2d71 | ||
|
|
c8135595be | ||
|
|
d5658d4180 | ||
|
|
8356e6a51f | ||
|
|
fbf55b9df4 | ||
|
|
176e6d09ca | ||
|
|
b72d1c297d | ||
|
|
f5b9c26735 | ||
|
|
d8141252e9 | ||
|
|
ed86dee65d | ||
|
|
f535cd3077 | ||
|
|
537757a7b9 | ||
|
|
4fb354776e | ||
|
|
1583b1e84a | ||
|
|
45ff04ecb6 | ||
|
|
ef08e43cf2 | ||
|
|
e17f7f5146 | ||
|
|
8654412844 | ||
|
|
140533db50 | ||
|
|
00cacae2a3 | ||
|
|
7e0b0d7328 | ||
|
|
1be77d68ce | ||
|
|
c5a5a11b7f | ||
|
|
becc7cb56a | ||
|
|
629a02cccf | ||
|
|
f28b97ebfd | ||
|
|
c5234e95cd | ||
|
|
b825f8d2b2 | ||
|
|
eb08253ed0 | ||
|
|
7b79fd98e5 | ||
|
|
6d5fcf5853 | ||
|
|
bc284ee6d8 | ||
|
|
260b4166c1 | ||
|
|
b59cc5ff6d | ||
|
|
5c89fb71ae | ||
|
|
3baa8c0445 | ||
|
|
ce589da58a | ||
|
|
0bb9359c05 | ||
|
|
54140dadcf | ||
|
|
60c22aefeb | ||
|
|
69a2331791 | ||
|
|
29cfd8ccfe | ||
|
|
bf67f386de | ||
|
|
a2f07011c1 | ||
|
|
0bd6cf7b6f | ||
|
|
cd8e491028 | ||
|
|
e773ccfe49 | ||
|
|
83de770387 | ||
|
|
b3a8098506 | ||
|
|
05407f488f | ||
|
|
85d53ebbf4 | ||
|
|
e4139f4819 | ||
|
|
45c935af45 | ||
|
|
cfbfd9ec1d | ||
|
|
ae209a144f | ||
|
|
64837efac5 | ||
|
|
8d73df2b04 | ||
|
|
59117c2e42 | ||
|
|
e23dd57c9d | ||
|
|
0e20be774e | ||
|
|
c3ae00ae49 | ||
|
|
a7328ecce1 | ||
|
|
15a952a143 | ||
|
|
3154f07817 | ||
|
|
4e700bffb8 | ||
|
|
7b2d4c9ef6 | ||
|
|
da828a218f | ||
|
|
13ef84bc35 | ||
|
|
c7b36322f6 | ||
|
|
8cc89a3a1f | ||
|
|
b8c5aff0cb | ||
|
|
fb0c387b12 | ||
|
|
1628045b55 | ||
|
|
608e5a4dbb | ||
|
|
30787fd49e | ||
|
|
1e231c3338 | ||
|
|
370549a19a | ||
|
|
39c39f0162 | ||
|
|
bcaa122fb9 | ||
|
|
96403de903 | ||
|
|
ab5cad18de | ||
|
|
b1c548a981 | ||
|
|
039769dbaf | ||
|
|
a76d6dc352 | ||
|
|
7eab75ded1 | ||
|
|
ef9c7c4a30 | ||
|
|
4c54e070ed | ||
|
|
80c609853a | ||
|
|
eeabc7234c | ||
|
|
79b740284a | ||
|
|
ab7b353ace | ||
|
|
3b82a15521 | ||
|
|
97d972ebb3 | ||
|
|
5f5081827d | ||
|
|
6b7b4e700a | ||
|
|
baac893d22 | ||
|
|
d680e594ed | ||
|
|
42adc49e57 | ||
|
|
4a2168b352 | ||
|
|
44d4660fe8 | ||
|
|
45d4117c02 | ||
|
|
ae837a6347 | ||
|
|
426fc18d10 | ||
|
|
2531ed89cd | ||
|
|
566d5c9a93 | ||
|
|
a033c331b6 | ||
|
|
066b534307 | ||
|
|
64cabd8074 | ||
|
|
a0db52c69f | ||
|
|
7bbedd1b55 | ||
|
|
0340256b4c | ||
|
|
c4bd8b1463 | ||
|
|
a2d465804f | ||
|
|
3c5d32637c | ||
|
|
c93cb71162 | ||
|
|
c3960f8e6a | ||
|
|
96d04bb5a0 | ||
|
|
1f1bfd0eab | ||
|
|
8cdf51f913 | ||
|
|
1f3eedcfd7 | ||
|
|
541f269c20 | ||
|
|
68a7ddefd3 | ||
|
|
3961c68928 | ||
|
|
832b795826 | ||
|
|
7a6be47603 | ||
|
|
81536481cc | ||
|
|
6e703c5744 | ||
|
|
82e8e51736 | ||
|
|
905529081d | ||
|
|
4159c98c58 | ||
|
|
e40efec4bd | ||
|
|
e418625457 | ||
|
|
4b82d26f5e | ||
|
|
63a02d1c0a | ||
|
|
bf42772995 | ||
|
|
b75221e9bf | ||
|
|
1e9a54d134 | ||
|
|
ff0b59ff6b | ||
|
|
b3a5a0e5ab | ||
|
|
e002b1c1c4 | ||
|
|
7009dc8d9b | ||
|
|
e28b7f06c5 | ||
|
|
b6e1d63cb0 | ||
|
|
5a279dbdc8 | ||
|
|
3ad3a2ab57 | ||
|
|
5361efe8ed | ||
|
|
2f2657b765 | ||
|
|
19a7f3faeb | ||
|
|
f480943649 | ||
|
|
f3019ff5a0 | ||
|
|
33ee5c26b0 | ||
|
|
1e9184f0f9 | ||
|
|
19251f7a79 | ||
|
|
b79da2c4d6 | ||
|
|
e68ba4c73a | ||
|
|
39ffe91230 | ||
|
|
150fc6f3ee | ||
|
|
a7411eb00d | ||
|
|
660fd7c1d4 | ||
|
|
53772db66d | ||
|
|
93dd08bdf5 | ||
|
|
176d707e0a | ||
|
|
34dade1b65 | ||
|
|
4e815f8565 | ||
|
|
e69a3ed934 | ||
|
|
77d63aba74 | ||
|
|
de8c725890 | ||
|
|
d4b2958e50 | ||
|
|
8669b372e0 | ||
|
|
61991e6367 | ||
|
|
bdcb813727 | ||
|
|
e6f1510a40 | ||
|
|
224af78463 | ||
|
|
983bf5cbab | ||
|
|
96bcf6eac4 | ||
|
|
0872ad34cf | ||
|
|
5aee3b866a | ||
|
|
3ce86f5664 | ||
|
|
23e5394fb4 | ||
|
|
be7ac7a2ca | ||
|
|
a616cfd0c2 | ||
|
|
e85b669307 | ||
|
|
bc6dfeb4a9 | ||
|
|
bf96986c38 | ||
|
|
26cfbb2b7b | ||
|
|
35fc2a609d | ||
|
|
f05b13c630 | ||
|
|
4d8954be4c | ||
|
|
1d0a9871c2 | ||
|
|
2292751fc3 | ||
|
|
a6524e47e2 | ||
|
|
02b9aa9163 | ||
|
|
754adce4a4 | ||
|
|
f3fdf70b56 | ||
|
|
38db6fde0c | ||
|
|
4f804577f9 | ||
|
|
44a182d92c | ||
|
|
91d65d0e4e | ||
|
|
a88f030b52 | ||
|
|
4537de8120 | ||
|
|
100bdedac3 | ||
|
|
914ad85e63 | ||
|
|
b3c2ad0a65 | ||
|
|
2e12635494 | ||
|
|
4325b787c0 | ||
|
|
4e3c702cc7 | ||
|
|
213cb1b08a | ||
|
|
b7569f4d70 | ||
|
|
e328cf9fed | ||
|
|
78af3dbdc0 | ||
|
|
372674b4c0 | ||
|
|
8d0f7e1594 | ||
|
|
558fea33fb | ||
|
|
de5930f7d8 | ||
|
|
e09a14aa44 | ||
|
|
d45c7c58df | ||
|
|
b5e0f46229 | ||
|
|
12229e4826 | ||
|
|
8f88525819 | ||
|
|
a225fe304d | ||
|
|
0f9eb13245 | ||
|
|
06437b7fba | ||
|
|
ba910c0fac | ||
|
|
28278d3c09 | ||
|
|
2bf7653ab9 | ||
|
|
cb39b3b65c | ||
|
|
3e3757bde7 | ||
|
|
8b4befd4fc | ||
|
|
972e9c866b | ||
|
|
f758010f01 | ||
|
|
8057faccc1 | ||
|
|
3f952a2fd2 | ||
|
|
eb71c70c99 | ||
|
|
2a44cf70b1 | ||
|
|
431b16639d | ||
|
|
014e68b62f | ||
|
|
31291f5d8a | ||
|
|
a52b34cb64 | ||
|
|
3ca55bf327 | ||
|
|
9bb2cee686 | ||
|
|
4f3bdd9f38 | ||
|
|
efe41c2435 | ||
|
|
f855cb19b8 | ||
|
|
861ed55879 | ||
|
|
35e0dcdd3d | ||
|
|
a72a8607e6 | ||
|
|
904747acf5 | ||
|
|
4d40a336c0 | ||
|
|
32e9c8049a | ||
|
|
bb24624979 | ||
|
|
506bc87e82 | ||
|
|
986885bd70 | ||
|
|
73c4893ef7 | ||
|
|
62c9f39297 | ||
|
|
8b5f62a5e5 | ||
|
|
aec5841c7f | ||
|
|
c997c090a1 | ||
|
|
0ab60cd3c3 | ||
|
|
ae23a8f6bf | ||
|
|
46e868d313 | ||
|
|
8dfa322b8b | ||
|
|
2f2f08b02f | ||
|
|
102fd24dd2 | ||
|
|
66cf3ec8fa | ||
|
|
57b0d9691e | ||
|
|
7c6f496765 | ||
|
|
67e72ce77e | ||
|
|
c97692d715 | ||
|
|
66f83f3b08 | ||
|
|
3765bdd3ac | ||
|
|
39bcdfb7b4 | ||
|
|
57cd770650 | ||
|
|
3194b0c53a | ||
|
|
9e8005f7b7 | ||
|
|
41ce198a1f | ||
|
|
05e30ed43b | ||
|
|
09cd582cc5 | ||
|
|
235781ce08 | ||
|
|
70aeb980d8 | ||
|
|
d0d6189874 | ||
|
|
8205d0fcc9 | ||
|
|
60d068a33e | ||
|
|
e1a4b457c2 | ||
|
|
86e18226eb | ||
|
|
7fa2975c24 | ||
|
|
d39190243b | ||
|
|
0550287658 | ||
|
|
82947a9343 | ||
|
|
b7fb806611 | ||
|
|
6a236061de | ||
|
|
898639d7bf | ||
|
|
6322400b83 | ||
|
|
9b7341889d | ||
|
|
0653f859bc | ||
|
|
48ff66cbce | ||
|
|
1b2a6f8bed | ||
|
|
c6cf665c4a | ||
|
|
19c84ff9a2 | ||
|
|
15398a8f58 | ||
|
|
9d2e22576e | ||
|
|
3ffb3c7011 | ||
|
|
cac4c8d5ce | ||
|
|
f40d006c26 | ||
|
|
e6c36597eb | ||
|
|
141808b787 | ||
|
|
003f103408 | ||
|
|
ce66498c88 | ||
|
|
bf30a0bc07 | ||
|
|
f8e6d782e1 | ||
|
|
7a8135c703 | ||
|
|
311e1ce9ee | ||
|
|
9bce21ddb7 | ||
|
|
c4e438d4ba | ||
|
|
a2da2d59df | ||
|
|
56a4236576 | ||
|
|
2443c655f2 | ||
|
|
ae1d5227de | ||
|
|
5769bbe15e | ||
|
|
6dbf7333c8 | ||
|
|
4352ce6753 | ||
|
|
29a50a52ca | ||
|
|
d25690cc8e |
+11
@@ -2,14 +2,25 @@ lexor_keyword.cc
|
||||
parse.h
|
||||
parse.cc
|
||||
parse.cc.output
|
||||
parse.output
|
||||
syn-rules.cc
|
||||
syn-rules.cc.output
|
||||
syn-rules.output
|
||||
lexor.cc
|
||||
iverilog-vpi
|
||||
iverilog-vpi.pdf
|
||||
iverilog-vpi.ps
|
||||
ivl
|
||||
ivl.exp
|
||||
dep
|
||||
configure
|
||||
Makefile
|
||||
check
|
||||
check.cc
|
||||
config.status
|
||||
config.log
|
||||
config.cache
|
||||
autom4te.cache
|
||||
config.h
|
||||
_pli_types.h
|
||||
dosify
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: Attrib.cc,v 1.1 2000/12/04 17:37:03 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Attrib.cc,v 1.6 2004/02/20 18:53:33 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "Attrib.h"
|
||||
# include <assert.h>
|
||||
|
||||
@@ -34,23 +36,8 @@ Attrib::~Attrib()
|
||||
delete[] list_;
|
||||
}
|
||||
|
||||
void Attrib::set_attributes(const map<string,string>&attr)
|
||||
{
|
||||
assert(list_ == 0);
|
||||
|
||||
nlist_ = attr.size();
|
||||
list_ = new cell_[nlist_];
|
||||
|
||||
map<string,string>::const_iterator idx;
|
||||
unsigned jdx;
|
||||
for (idx = attr.begin(), jdx = 0 ; idx != attr.end() ; idx ++, jdx++) {
|
||||
struct cell_*tmp = list_ + jdx;
|
||||
tmp->key = (*idx).first;
|
||||
tmp->val = (*idx).second;
|
||||
}
|
||||
}
|
||||
|
||||
string Attrib::attribute(const string&key) const
|
||||
const verinum& Attrib::attribute(perm_string key) const
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < nlist_ ; idx += 1) {
|
||||
|
||||
@@ -58,10 +45,11 @@ string Attrib::attribute(const string&key) const
|
||||
return list_[idx].val;
|
||||
}
|
||||
|
||||
return "";
|
||||
static const verinum null;
|
||||
return null;
|
||||
}
|
||||
|
||||
void Attrib::attribute(const string&key, const string&value)
|
||||
void Attrib::attribute(perm_string key, const verinum&value)
|
||||
{
|
||||
unsigned idx;
|
||||
|
||||
@@ -90,7 +78,7 @@ bool Attrib::has_compat_attributes(const Attrib&that) const
|
||||
|
||||
for (idx = 0 ; idx < that.nlist_ ; idx += 1) {
|
||||
|
||||
string tmp = attribute(that.list_[idx].key);
|
||||
verinum tmp = attribute(that.list_[idx].key);
|
||||
if (tmp != that.list_[idx].val)
|
||||
return false;
|
||||
}
|
||||
@@ -98,18 +86,18 @@ bool Attrib::has_compat_attributes(const Attrib&that) const
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned Attrib::size() const
|
||||
unsigned Attrib::attr_cnt() const
|
||||
{
|
||||
return nlist_;
|
||||
}
|
||||
|
||||
string Attrib::key(unsigned idx) const
|
||||
perm_string Attrib::attr_key(unsigned idx) const
|
||||
{
|
||||
assert(idx < nlist_);
|
||||
return list_[idx].key;
|
||||
}
|
||||
|
||||
string Attrib::value(unsigned idx) const
|
||||
const verinum& Attrib::attr_value(unsigned idx) const
|
||||
{
|
||||
assert(idx < nlist_);
|
||||
return list_[idx].val;
|
||||
@@ -118,6 +106,31 @@ string Attrib::value(unsigned idx) const
|
||||
|
||||
/*
|
||||
* $Log: Attrib.cc,v $
|
||||
* Revision 1.6 2004/02/20 18:53:33 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.5 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.4 2002/05/26 01:39:02 steve
|
||||
* Carry Verilog 2001 attributes with processes,
|
||||
* all the way through to the ivl_target API.
|
||||
*
|
||||
* Divide signal reference counts between rval
|
||||
* and lval references.
|
||||
*
|
||||
* Revision 1.3 2002/05/23 03:08:50 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.2 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.1 2000/12/04 17:37:03 steve
|
||||
* Add Attrib class for holding NetObj attributes.
|
||||
*
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: Attrib.h,v 1.1 2000/12/04 17:37:03 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Attrib.h,v 1.5 2004/02/20 18:53:33 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
# include <map>
|
||||
# include "StringHeap.h"
|
||||
# include "verinum.h"
|
||||
|
||||
/*
|
||||
* This class keeps a map of key/value pairs. The map can be set from
|
||||
@@ -35,21 +35,21 @@ class Attrib {
|
||||
Attrib();
|
||||
~Attrib();
|
||||
|
||||
void set_attributes(const map<string,string>&attr);
|
||||
string attribute(const string&key) const;
|
||||
void attribute(const string&key, const string&value);
|
||||
const verinum&attribute(perm_string key) const;
|
||||
void attribute(perm_string key, const verinum&value);
|
||||
bool has_compat_attributes(const Attrib&that) const;
|
||||
|
||||
|
||||
/* Provide a means of iterating over the entries in the map. */
|
||||
unsigned size() const;
|
||||
string key(unsigned idx) const;
|
||||
string value(unsigned idx) const;
|
||||
unsigned attr_cnt() const;
|
||||
perm_string attr_key(unsigned idx) const;
|
||||
const verinum& attr_value(unsigned idx) const;
|
||||
|
||||
|
||||
private:
|
||||
struct cell_ {
|
||||
string key;
|
||||
string val;
|
||||
perm_string key;
|
||||
verinum val;
|
||||
};
|
||||
|
||||
unsigned nlist_;
|
||||
@@ -62,6 +62,27 @@ class Attrib {
|
||||
|
||||
/*
|
||||
* $Log: Attrib.h,v $
|
||||
* Revision 1.5 2004/02/20 18:53:33 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.4 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.3 2002/05/26 01:39:02 steve
|
||||
* Carry Verilog 2001 attributes with processes,
|
||||
* all the way through to the ivl_target API.
|
||||
*
|
||||
* Divide signal reference counts between rval
|
||||
* and lval references.
|
||||
*
|
||||
* Revision 1.2 2002/05/23 03:08:50 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.1 2000/12/04 17:37:03 steve
|
||||
* Add Attrib class for holding NetObj attributes.
|
||||
*
|
||||
|
||||
@@ -16,7 +16,7 @@ compilation tools you are using. Specifically, I need to know:
|
||||
- Operating system and processor type,
|
||||
- Compiler w/ version,
|
||||
- Library version, and
|
||||
- anything else you think relevent.
|
||||
- anything else you think relevant.
|
||||
|
||||
Be aware that I do not have at my disposal a porting lab. I have the
|
||||
alpha on my desk, and the Linux/Intel box with a logic analyzer and
|
||||
@@ -110,6 +110,24 @@ program and include a GPL license statement if you can. Your test
|
||||
program may find its way into the test suite, and the notices will
|
||||
make it all nice and legal.
|
||||
|
||||
RESEARCHING EXISTING/PAST BUGS, AND FILING REPORTS
|
||||
|
||||
The URL <http://www.icarus.com/cgi-bin/ivl-bugs> is the main bug
|
||||
tracking system. Once you believe you have found a bug, you may browse
|
||||
the bugs database for existing bugs that may be related to yours. You
|
||||
might find that your bug has already been fixed in a later release or
|
||||
snapshot. If that's the case, then you are set.
|
||||
|
||||
The bug database supports basic keyword searches, and you can
|
||||
optionally limit your search to active bugs, or fixed bugs. You may
|
||||
also browse the bug database, just to get an idea what is still
|
||||
broken. You may for example find a related bug that explains your
|
||||
symptom.
|
||||
|
||||
The root page of the bug report database describes how to submit your
|
||||
completed bug report. You may submit it via the web form, or via
|
||||
e-mail.
|
||||
|
||||
HOW TO SEND PATCHES
|
||||
|
||||
Bug reports with patches are very welcome, especially if they are
|
||||
@@ -130,7 +148,7 @@ patch is for, I will ask for clarification before applying it.)
|
||||
|
||||
COPYRIGHT ISSUES
|
||||
|
||||
Icarus Verilog is Copyright (c) 1998-1999 Stephen Williams except
|
||||
Icarus Verilog is Copyright (c) 1998-2003 Stephen Williams except
|
||||
where otherwise noted. Minor patches are covered as derivative works
|
||||
(or editorial comment or whatever the appropriate legal term is) and
|
||||
folded into the rest of ivl. However, if a submission can reasonably
|
||||
@@ -141,8 +159,15 @@ then falls under the "otherwise noted" category.
|
||||
I must insist that any copyright material submitted for inclusion
|
||||
include the GPL license notice as shown in the rest of the source.
|
||||
|
||||
$Id: BUGS.txt,v 1.2 1999/08/06 04:05:28 steve Exp $
|
||||
|
||||
$Id: BUGS.txt,v 1.4 2003/02/19 04:36:31 steve Exp $
|
||||
$Log: BUGS.txt,v $
|
||||
Revision 1.4 2003/02/19 04:36:31 steve
|
||||
Notes on hte bug database.
|
||||
|
||||
Revision 1.3 2003/01/30 16:23:07 steve
|
||||
Spelling fixes.
|
||||
|
||||
Revision 1.2 1999/08/06 04:05:28 steve
|
||||
Handle scope of parameters.
|
||||
|
||||
|
||||
@@ -0,0 +1,279 @@
|
||||
/*
|
||||
* Copyright (c) 2001 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: HName.cc,v 1.5 2002/11/02 03:27:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "HName.h"
|
||||
# include <iostream>
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
hname_t::hname_t()
|
||||
{
|
||||
item_ = 0;
|
||||
count_ = 0;
|
||||
}
|
||||
|
||||
hname_t::hname_t(const char*text)
|
||||
{
|
||||
item_ = strdup(text);
|
||||
count_ = 1;
|
||||
}
|
||||
|
||||
hname_t::hname_t(const hname_t&that)
|
||||
{
|
||||
count_ = that.count_;
|
||||
switch (count_) {
|
||||
case 0:
|
||||
item_ = 0;
|
||||
break;
|
||||
case 1:
|
||||
item_ = strdup(that.item_);
|
||||
break;
|
||||
default:
|
||||
array_ = new char*[count_];
|
||||
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
|
||||
array_[idx] = strdup(that.array_[idx]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hname_t::~hname_t()
|
||||
{
|
||||
switch (count_) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
free(item_);
|
||||
break;
|
||||
default:
|
||||
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
|
||||
free(array_[idx]);
|
||||
delete[]array_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned hname_t::component_count() const
|
||||
{
|
||||
return count_;
|
||||
}
|
||||
|
||||
void hname_t::append(const char*text)
|
||||
{
|
||||
char**tmp;
|
||||
|
||||
switch (count_) {
|
||||
case 0:
|
||||
count_ = 1;
|
||||
item_ = strdup(text);
|
||||
break;
|
||||
case 1:
|
||||
count_ = 2;
|
||||
tmp = new char*[2];
|
||||
tmp[0] = item_;
|
||||
tmp[1] = strdup(text);
|
||||
array_ = tmp;
|
||||
break;
|
||||
default:
|
||||
tmp = new char*[count_+1];
|
||||
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
|
||||
tmp[idx] = array_[idx];
|
||||
delete[]array_;
|
||||
array_ = tmp;
|
||||
array_[count_] = strdup(text);
|
||||
count_ += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void hname_t::prepend(const char*text)
|
||||
{
|
||||
char**tmp;
|
||||
|
||||
switch (count_) {
|
||||
case 0:
|
||||
count_ = 1;
|
||||
item_ = strdup(text);
|
||||
break;
|
||||
case 1:
|
||||
count_ = 2;
|
||||
tmp = new char*[2];
|
||||
tmp[0] = strdup(text);
|
||||
tmp[1] = item_;
|
||||
array_ = tmp;
|
||||
break;
|
||||
default:
|
||||
tmp = new char*[count_+1];
|
||||
tmp[0] = strdup(text);
|
||||
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
|
||||
tmp[idx+1] = array_[idx];
|
||||
delete[]array_;
|
||||
array_ = tmp;
|
||||
count_ += 1;
|
||||
}
|
||||
}
|
||||
|
||||
char* hname_t::remove_tail_name()
|
||||
{
|
||||
if (count_ == 0)
|
||||
return 0;
|
||||
|
||||
if (count_ == 1) {
|
||||
char*tmp = item_;
|
||||
count_ = 0;
|
||||
item_ = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
if (count_ == 2) {
|
||||
char*tmp1 = array_[0];
|
||||
char*tmp2 = array_[1];
|
||||
delete[]array_;
|
||||
count_ = 1;
|
||||
item_ = tmp1;
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
char*tmpo = array_[count_-1];
|
||||
char**tmpa = new char*[count_-1];
|
||||
for (unsigned idx = 0 ; idx < count_-1 ; idx += 1)
|
||||
tmpa[idx] = array_[idx];
|
||||
|
||||
delete[]array_;
|
||||
array_ = tmpa;
|
||||
count_ -= 1;
|
||||
return tmpo;
|
||||
}
|
||||
|
||||
const char* hname_t::peek_name(unsigned idx) const
|
||||
{
|
||||
if (idx >= count_)
|
||||
return 0;
|
||||
|
||||
if (count_ == 1)
|
||||
return item_;
|
||||
|
||||
return array_[idx];
|
||||
}
|
||||
|
||||
const char* hname_t::peek_tail_name() const
|
||||
{
|
||||
switch (count_) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
return item_;
|
||||
default:
|
||||
return array_[count_-1];
|
||||
}
|
||||
}
|
||||
|
||||
bool operator < (const hname_t&l, const hname_t&r)
|
||||
{
|
||||
unsigned idx = 0;
|
||||
const char*lc = l.peek_name(idx);
|
||||
const char*rc = r.peek_name(idx);
|
||||
|
||||
while (lc && rc) {
|
||||
int cmp = strcmp(lc, rc);
|
||||
if (cmp < 0)
|
||||
return true;
|
||||
if (cmp > 0)
|
||||
return false;
|
||||
idx += 1;
|
||||
lc = l.peek_name(idx);
|
||||
rc = r.peek_name(idx);
|
||||
}
|
||||
|
||||
if (lc && !rc)
|
||||
return false;
|
||||
if (rc && !lc)
|
||||
return true;
|
||||
|
||||
// Must be ==
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator == (const hname_t&l, const hname_t&r)
|
||||
{
|
||||
unsigned idx = 0;
|
||||
const char*lc = l.peek_name(idx);
|
||||
const char*rc = r.peek_name(idx);
|
||||
|
||||
while (lc && rc) {
|
||||
int cmp = strcmp(lc, rc);
|
||||
if (cmp != 0)
|
||||
return false;
|
||||
idx += 1;
|
||||
lc = l.peek_name(idx);
|
||||
rc = r.peek_name(idx);
|
||||
}
|
||||
|
||||
if (lc || rc)
|
||||
return false;
|
||||
|
||||
// Must be ==
|
||||
return true;
|
||||
}
|
||||
|
||||
ostream& operator<< (ostream&out, const hname_t&that)
|
||||
{
|
||||
switch (that.count_) {
|
||||
case 0:
|
||||
out << "";
|
||||
return out;
|
||||
case 1:
|
||||
out << that.item_;
|
||||
return out;
|
||||
|
||||
default:
|
||||
out << that.array_[0];
|
||||
for (unsigned idx = 1 ; idx < that.count_ ; idx += 1)
|
||||
out << "." << that.array_[idx];
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: HName.cc,v $
|
||||
* Revision 1.5 2002/11/02 03:27:52 steve
|
||||
* Allow named events to be referenced by
|
||||
* hierarchical names.
|
||||
*
|
||||
* Revision 1.4 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.3 2002/01/05 04:36:06 steve
|
||||
* include malloc.h only when available.
|
||||
*
|
||||
* Revision 1.2 2001/12/18 04:52:45 steve
|
||||
* Include config.h for namespace declaration.
|
||||
*
|
||||
* Revision 1.1 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
#ifndef __HName_H
|
||||
#define __HName_H
|
||||
/*
|
||||
* Copyright (c) 2001 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: HName.h,v 1.4 2002/11/02 03:27:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <iostream>
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ > 2
|
||||
using namespace std;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This class represents a Verilog hierarchical name. A hierarchical
|
||||
* name is an ordered list of simple names.
|
||||
*/
|
||||
|
||||
class hname_t {
|
||||
|
||||
public:
|
||||
hname_t ();
|
||||
explicit hname_t (const char*text);
|
||||
hname_t (const hname_t&that);
|
||||
~hname_t();
|
||||
|
||||
// This method adds a name to the end of the hierarchical
|
||||
// path. This becomes a new base name.
|
||||
void append(const char*text);
|
||||
|
||||
// This method adds a name to the *front* of the hierarchical
|
||||
// path. The base name remains the same, unless this is the
|
||||
// only component.
|
||||
void prepend(const char*text);
|
||||
|
||||
// This method removes the tail name from the hierarchy, and
|
||||
// returns a pointer to that tail name. That tail name now
|
||||
// must be removed by the caller.
|
||||
char* remove_tail_name();
|
||||
|
||||
// Return the given component in the hierarchical name. If the
|
||||
// idx is too large, return 0.
|
||||
const char*peek_name(unsigned idx) const;
|
||||
const char*peek_tail_name() const;
|
||||
|
||||
// Return the number of components in the hierarchical
|
||||
// name. If this is a simple name, this will return 1.
|
||||
unsigned component_count() const;
|
||||
|
||||
friend ostream& operator<< (ostream&, const hname_t&);
|
||||
|
||||
private:
|
||||
union {
|
||||
char**array_;
|
||||
char* item_;
|
||||
};
|
||||
unsigned count_;
|
||||
|
||||
private: // not implemented
|
||||
hname_t& operator= (const hname_t&);
|
||||
};
|
||||
|
||||
extern bool operator < (const hname_t&, const hname_t&);
|
||||
extern bool operator == (const hname_t&, const hname_t&);
|
||||
|
||||
/*
|
||||
* $Log: HName.h,v $
|
||||
* Revision 1.4 2002/11/02 03:27:51 steve
|
||||
* Allow named events to be referenced by
|
||||
* hierarchical names.
|
||||
*
|
||||
* Revision 1.3 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2002/06/14 03:25:51 steve
|
||||
* Compiler portability.
|
||||
*
|
||||
* Revision 1.1 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+35
-6
@@ -16,12 +16,19 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: LineInfo.cc,v 1.1 2000/11/30 17:31:42 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: LineInfo.cc,v 1.4 2003/01/17 05:49:03 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include <cstdio>
|
||||
# include <sstream>
|
||||
|
||||
LineInfo::LineInfo()
|
||||
: file_(0), lineno_(0)
|
||||
{
|
||||
}
|
||||
|
||||
LineInfo::~LineInfo()
|
||||
{
|
||||
@@ -29,9 +36,11 @@ LineInfo::~LineInfo()
|
||||
|
||||
string LineInfo::get_line() const
|
||||
{
|
||||
char buf[8];
|
||||
sprintf(buf, "%u", lineno_);
|
||||
return string(file_? file_ : "") + ":" + buf;
|
||||
ostringstream buf;
|
||||
buf << (file_? file_ : "") << ":" << lineno_;
|
||||
|
||||
string res = buf.str();
|
||||
return res;
|
||||
}
|
||||
|
||||
void LineInfo::set_line(const LineInfo&that)
|
||||
@@ -40,8 +49,28 @@ void LineInfo::set_line(const LineInfo&that)
|
||||
lineno_ = that.lineno_;
|
||||
}
|
||||
|
||||
void LineInfo::set_file(const char*f)
|
||||
{
|
||||
file_ = f;
|
||||
}
|
||||
|
||||
void LineInfo::set_lineno(unsigned n)
|
||||
{
|
||||
lineno_ = n;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: LineInfo.cc,v $
|
||||
* Revision 1.4 2003/01/17 05:49:03 steve
|
||||
* Use stringstream in place of sprintf.
|
||||
*
|
||||
* Revision 1.3 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.1 2000/11/30 17:31:42 steve
|
||||
* Change LineInfo to store const C strings.
|
||||
*
|
||||
|
||||
+11
-5
@@ -18,8 +18,8 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: LineInfo.h,v 1.5 2000/11/30 17:31:42 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: LineInfo.h,v 1.7 2003/01/17 05:49:03 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
@@ -35,15 +35,15 @@
|
||||
|
||||
class LineInfo {
|
||||
public:
|
||||
LineInfo() : file_(0), lineno_(0) { }
|
||||
LineInfo();
|
||||
~LineInfo();
|
||||
|
||||
string get_line() const;
|
||||
|
||||
void set_line(const LineInfo&that);
|
||||
|
||||
void set_file(const char*f) { file_ = f; }
|
||||
void set_lineno(unsigned n) { lineno_ = n; }
|
||||
void set_file(const char*f);
|
||||
void set_lineno(unsigned n);
|
||||
|
||||
private:
|
||||
const char* file_;
|
||||
@@ -52,6 +52,12 @@ class LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: LineInfo.h,v $
|
||||
* Revision 1.7 2003/01/17 05:49:03 steve
|
||||
* Use stringstream in place of sprintf.
|
||||
*
|
||||
* Revision 1.6 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.5 2000/11/30 17:31:42 steve
|
||||
* Change LineInfo to store const C strings.
|
||||
*
|
||||
|
||||
+178
-87
@@ -16,12 +16,16 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.95 2001/03/25 05:59:46 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.168 2004/10/04 01:10:51 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.3
|
||||
# This version string is only used in the version message printed
|
||||
# by the compiler. It reflects the assigned version number for the
|
||||
# product as a whole. Most components also print the CVS Name: token
|
||||
# in order to get a more automatic version stamp as well.
|
||||
VERSION = 0.7
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -33,10 +37,13 @@ VPATH = $(srcdir)
|
||||
|
||||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
includedir = $(prefix)/include
|
||||
includedir = @includedir@
|
||||
mandir = @mandir@
|
||||
|
||||
libdir64 = @libdir64@
|
||||
|
||||
dllib=@DLLIB@
|
||||
rdynamic=@rdynamic@
|
||||
strip_dynamic=@strip_dynamic@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
@@ -45,97 +52,115 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
STRIP = @STRIP@
|
||||
LEX = @LEX@
|
||||
YACC = @YACC@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)
|
||||
LDFLAGS = @LDFLAGS@
|
||||
CPPFLAGS = @ident_support@ @DEFS@ -I. -I$(srcdir) @CPPFLAGS@
|
||||
CXXFLAGS = -Wall @CXXFLAGS@
|
||||
PICFLAGS = @PICFLAG@
|
||||
LDFLAGS = @rdynamic@ @LDFLAGS@
|
||||
|
||||
# The TARGETS variable lists the target modules that can be build and
|
||||
# installed. Some of them depend on external things, so are only
|
||||
# compiled if the prerequisites are installed.
|
||||
TARGETS = tgt-null
|
||||
ifeq ('@HAVE_IPAL@','yes')
|
||||
TARGETS += tgt-pal
|
||||
|
||||
all: dep ivl@EXEEXT@
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
||||
for dir in ivlpp tgt-verilog tgt-stub; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
cd driver ; $(MAKE) VERSION=$(VERSION) $@
|
||||
|
||||
# In the windows world, the installer will need a dosify program to
|
||||
# dosify text files.
|
||||
ifeq (@WIN32@,yes)
|
||||
all: dep dosify.exe
|
||||
dosify.exe: dosify.c
|
||||
$(CC) -o dosify.exe dosify.c
|
||||
endif
|
||||
|
||||
|
||||
all: ivl@EXEEXT@
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) all); done
|
||||
cd vvm ; $(MAKE) all
|
||||
cd vpi ; $(MAKE) all
|
||||
cd ivlpp ; $(MAKE) all
|
||||
cd driver ; $(MAKE) all
|
||||
cd tgt-verilog ; $(MAKE) all
|
||||
cd tgt-stub ; $(MAKE) all
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) all); done
|
||||
|
||||
# This rule rules the compiler in the trivial hello.vl program to make
|
||||
# sure the basics were compiled properly.
|
||||
check: all
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) check); done
|
||||
driver/iverilog -Ccheck.conf -ocheck -tvvm-check -B./ivlpp examples/hello.vl
|
||||
$(CXX) -o check $(rdynamic) -fno-exceptions -I$(srcdir) -I$(srcdir)/vvm -I$(srcdir)/vpip -Lvvm -Lvpip check.cc -lvvm -lvpip $(dllib)
|
||||
./check | grep 'Hello, World'
|
||||
test -r check.conf || cp $(srcdir)/check.conf .
|
||||
driver/iverilog -B. -BPivlpp -tcheck -ocheck.vvp $(srcdir)/examples/hello.vl
|
||||
vvp/vvp -M- -M./vpi ./check.vvp | grep 'Hello, World'
|
||||
|
||||
clean:
|
||||
rm -f *.o parse.cc parse.cc.output parse.h dep/*.d lexor.cc lexor_keyword.cc ivl@EXEEXT@ libivl.a
|
||||
cd vvm ; $(MAKE) clean
|
||||
cd vpi ; $(MAKE) clean
|
||||
cd driver ; $(MAKE) clean
|
||||
cd ivlpp ; $(MAKE) clean
|
||||
cd tgt-verilog ; $(MAKE) clean
|
||||
cd tgt-stub ; $(MAKE) clean
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) clean); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) clean); done
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
||||
for dir in vpi ivlpp tgt-verilog tgt-stub driver; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
rm -f *.o parse.cc parse.cc.output parse.h lexor.cc
|
||||
rm -f lexor_keyword.cc libivl.a libvpi.a iverilog-vpi syn-rules.cc*
|
||||
rm -rf dep ivl@EXEEXT@
|
||||
|
||||
distclean: clean
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) distclean); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) distclean); done
|
||||
rm -f vvm/Makefile
|
||||
rm -f vpi/Makefile
|
||||
rm -f ivlpp/Makefile
|
||||
rm -f driver/Makefile
|
||||
rm -f config.status config.cache config.log
|
||||
rm -f Makefile
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
||||
for dir in vpi ivlpp tgt-verilog tgt-stub driver; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
rm -f Makefile config.status config.log config.cache config.h
|
||||
|
||||
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-vvm.o t-xnf.o
|
||||
FF = nodangle.o synth.o syn-rules.o xnfio.o
|
||||
TT = t-dll.o t-dll-api.o t-dll-expr.o t-dll-proc.o t-xnf.o
|
||||
FF = cprop.o nodangle.o synth.o synth2.o syn-rules.o xnfio.o
|
||||
|
||||
O = main.o cprop.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
|
||||
O = main.o async.o design_dump.o dup_expr.o elaborate.o elab_expr.o \
|
||||
elab_lval.o elab_net.o elab_anet.o elab_pexpr.o elab_scope.o \
|
||||
elab_sig.o emit.o eval.o eval_rconst.o \
|
||||
elab_sig.o emit.o eval.o eval_attrib.o \
|
||||
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
||||
mangle.o netlist.o netmisc.o net_assign.o \
|
||||
net_design.o net_event.o net_force.o net_link.o net_modulo.o net_proc.o \
|
||||
net_scope.o net_udp.o pad_to_width.o \
|
||||
load_module.o netlist.o netmisc.o net_assign.o \
|
||||
net_design.o net_event.o net_expr.o net_force.o net_func.o \
|
||||
net_link.o net_modulo.o net_nex_input.o net_nex_output.o \
|
||||
net_proc.o net_scope.o net_udp.o net_variable.o pad_to_width.o \
|
||||
parse.o parse_misc.o pform.o pform_dump.o \
|
||||
set_width.o \
|
||||
verinum.o verireal.o target.o targets.o util.o \
|
||||
Attrib.o LineInfo.o Module.o PDelays.o PEvent.o \
|
||||
set_width.o symbol_search.o sync.o sys_funcs.o \
|
||||
verinum.o verireal.o target.o targets.o \
|
||||
Attrib.o HName.o LineInfo.o Module.o PData.o PDelays.o PEvent.o \
|
||||
PExpr.o PGate.o \
|
||||
PTask.o PFunction.o PWire.o Statement.o \
|
||||
PTask.o PUdp.o PFunction.o PWire.o Statement.o StringHeap.o \
|
||||
$(FF) $(TT)
|
||||
|
||||
Makefile: Makefile.in config.status
|
||||
Makefile: Makefile.in config.h.in config.status
|
||||
./config.status
|
||||
|
||||
|
||||
ifeq (@CYGWIN@,yes)
|
||||
ifeq (@WIN32@,yes)
|
||||
# Under Windows (mingw) I need to make the ivl.exe in two steps.
|
||||
# The first step makes an ivl.exe that dlltool can use to make an
|
||||
# export and import library, and the last link makes a, ivl.exe
|
||||
# that really exports the things that the import library imports.
|
||||
ivl@EXEEXT@: $O ivl.def
|
||||
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
|
||||
dlltool --dllname ivl@EXEEXT@ --def ivl.def \
|
||||
--output-lib libivl.a --output-exp ivl.exp
|
||||
# $(CXX) -o ivl@EXEEXT@ -Wl,--base-file,ivl.base ivl.exp $O $(dllib)
|
||||
# dlltool --dllname ivl@EXEEXT@ --base-file ivl.base \
|
||||
# --output-exp ivl.exp --def ivl.def
|
||||
$(CXX) -o ivl@EXEEXT@ ivl.exp $O $(dllib)
|
||||
$(CXX) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
|
||||
else
|
||||
ivl@EXEEXT@: $O
|
||||
$(CXX) $(CXXFLAGS) $(rdynamic) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
|
||||
$(CXX) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
|
||||
|
||||
endif
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
SUBDIRS += driver-vpi
|
||||
else
|
||||
all: dep iverilog-vpi
|
||||
|
||||
iverilog-vpi: iverilog-vpi.sh
|
||||
sed -e 's;@SHARED@;@shared@;' -e 's;@PIC@;@PICFLAG@;' \
|
||||
-e 's;@INCLUDEDIR@;@includedir@;' \
|
||||
-e 's;@LIBDIR64@;@libdir64@;' \
|
||||
-e 's;@VPIDIR1@;@vpidir1@;' -e 's;@VPIDIR2@;@vpidir2@;' \
|
||||
-e 's;@LIBDIR@;@libdir@;' $< > $@
|
||||
chmod +x $@
|
||||
endif
|
||||
|
||||
dep:
|
||||
mkdir dep
|
||||
|
||||
%.o: %.cc
|
||||
@[ -d dep ] || mkdir dep
|
||||
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep/$*.d
|
||||
|
||||
@@ -144,58 +169,124 @@ lexor.o: lexor.cc parse.h
|
||||
|
||||
parse.o: parse.cc
|
||||
|
||||
parse.h parse.cc: $(srcdir)/parse.y
|
||||
bison --verbose -t -p VL -d $(srcdir)/parse.y -o parse.cc
|
||||
mv parse.cc.h parse.h
|
||||
parse.cc: $(srcdir)/parse.y
|
||||
$(YACC) --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
|
||||
|
||||
parse.h: parse.cc
|
||||
mv parse.cc.h parse.h 2>/dev/null || mv parse.hh parse.h
|
||||
|
||||
syn-rules.cc: $(srcdir)/syn-rules.y
|
||||
bison --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
|
||||
$(YACC) --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
|
||||
|
||||
lexor.cc: $(srcdir)/lexor.lex
|
||||
flex -PVL -s -olexor.cc $(srcdir)/lexor.lex
|
||||
$(LEX) -PVL -s -olexor.cc $(srcdir)/lexor.lex
|
||||
|
||||
lexor_keyword.o: lexor_keyword.cc
|
||||
lexor_keyword.o: lexor_keyword.cc parse.h
|
||||
|
||||
lexor_keyword.cc: lexor_keyword.gperf
|
||||
gperf -o -i 7 -C -k 1-3,$$ -L ANSI-C -H keyword_hash -N check_identifier -t $(srcdir)/lexor_keyword.gperf > lexor_keyword.cc || (rm -f lexor_keyword.cc ; false)
|
||||
|
||||
iverilog-vpi.ps: $(srcdir)/iverilog-vpi.man
|
||||
man -t $(srcdir)/iverilog-vpi.man > iverilog-vpi.ps
|
||||
|
||||
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/iverilog.conf $(includedir)/ivl_target.h $(includedir)/vpi_user.h
|
||||
cd vvm ; $(MAKE) install
|
||||
cd vpi ; $(MAKE) install
|
||||
cd ivlpp ; $(MAKE) install
|
||||
cd driver ; $(MAKE) install
|
||||
for tgt in $(SUBDIRS); do (cd $$tgt ; $(MAKE) install); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) install); done
|
||||
iverilog-vpi.pdf: iverilog-vpi.ps
|
||||
ps2pdf iverilog-vpi.ps iverilog-vpi.pdf
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
INSTALL_DOC = $(prefix)/iverilog-vpi.pdf $(mandir)/man1/iverilog-vpi.1
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
all: dep iverilog-vpi.pdf
|
||||
else
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog-vpi.1
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
endif
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/sqrt-virtex.v $(prefix)/QUICK_START.txt
|
||||
else
|
||||
WIN32_INSTALL = $(bindir)/iverilog-vpi
|
||||
endif
|
||||
|
||||
XNF_INSTALL = $(libdir)/ivl/xnf.conf $(libdir)/ivl/xnf-s.conf
|
||||
|
||||
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(includedir)/ivl_target.h $(includedir)/_pli_types.h $(includedir)/vpi_user.h $(includedir)/acc_user.h $(includedir)/veriuser.h $(WIN32_INSTALL) $(INSTALL_DOC) $(XNF_INSTALL)
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
||||
for dir in vpi ivlpp driver; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
|
||||
$(bindir)/iverilog-vpi: ./iverilog-vpi
|
||||
$(INSTALL_SCRIPT) ./iverilog-vpi $(bindir)/iverilog-vpi
|
||||
|
||||
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
|
||||
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(libdir)/ivl/ivl@EXEEXT@
|
||||
$(STRIP) $(libdir)/ivl/ivl@EXEEXT@
|
||||
$(STRIP) $(strip_dynamic) $(libdir)/ivl/ivl@EXEEXT@
|
||||
|
||||
$(libdir)/ivl/iverilog.conf: $(srcdir)/iverilog.conf
|
||||
$(INSTALL_DATA) $(srcdir)/iverilog.conf $(libdir)/ivl/iverilog.conf
|
||||
$(libdir)/ivl/xnf-s.conf: $(srcdir)/xnf-s.conf
|
||||
$(INSTALL_DATA) $(srcdir)/xnf-s.conf $(libdir)/ivl/xnf-s.conf
|
||||
|
||||
$(libdir)/ivl/xnf.conf: $(srcdir)/xnf.conf
|
||||
$(INSTALL_DATA) $(srcdir)/xnf.conf $(libdir)/ivl/xnf.conf
|
||||
|
||||
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
|
||||
$(INSTALL_DATA) $(srcdir)/ivl_target.h $(includedir)/ivl_target.h
|
||||
|
||||
$(includedir)/_pli_types.h: _pli_types.h
|
||||
$(INSTALL_DATA) $< $(includedir)/_pli_types.h
|
||||
|
||||
$(includedir)/vpi_user.h: $(srcdir)/vpi_user.h
|
||||
$(INSTALL_DATA) $(srcdir)/vpi_user.h $(includedir)/vpi_user.h
|
||||
|
||||
$(includedir)/acc_user.h: $(srcdir)/acc_user.h
|
||||
$(INSTALL_DATA) $(srcdir)/acc_user.h $(includedir)/acc_user.h
|
||||
|
||||
$(includedir)/veriuser.h: $(srcdir)/veriuser.h
|
||||
$(INSTALL_DATA) $(srcdir)/veriuser.h $(includedir)/veriuser.h
|
||||
|
||||
$(mandir)/man1/iverilog-vpi.1: $(srcdir)/iverilog-vpi.man
|
||||
$(INSTALL_DATA) $(srcdir)/iverilog-vpi.man $(mandir)/man1/iverilog-vpi.1
|
||||
|
||||
$(prefix)/iverilog-vpi.pdf: iverilog-vpi.pdf
|
||||
$(INSTALL_DATA) iverilog-vpi.pdf $(prefix)/iverilog-vpi.pdf
|
||||
|
||||
# In windows installations, put a few examples and the quick_start
|
||||
# into the destination directory.
|
||||
ifeq (@MINGW32@,yes)
|
||||
$(prefix)/hello.vl: $(srcdir)/examples/hello.vl
|
||||
./dosify.exe $(srcdir)/examples/hello.vl tmp.vl
|
||||
mv tmp.vl $(prefix)/hello.vl
|
||||
|
||||
$(prefix)/sqrt.vl: $(srcdir)/examples/sqrt.vl
|
||||
./dosify.exe $(srcdir)/examples/sqrt.vl tmp.vl
|
||||
mv tmp.vl $(prefix)/sqrt.vl
|
||||
|
||||
$(prefix)/sqrt-virtex.v: $(srcdir)/examples/sqrt-virtex.v
|
||||
./dosify.exe $(srcdir)/examples/sqrt-virtex.v tmp.vl
|
||||
mv tmp.vl $(prefix)/sqrt-virtex.v
|
||||
|
||||
$(prefix)/QUICK_START.txt: $(srcdir)/QUICK_START.txt
|
||||
./dosify.exe $(srcdir)/QUICK_START.txt tmp.txt
|
||||
mv tmp.txt $(prefix)/QUICK_START.txt
|
||||
endif
|
||||
|
||||
installdirs: mkinstalldirs
|
||||
$(srcdir)/mkinstalldirs $(bindir) $(includedir) $(libdir)/ivl
|
||||
$(srcdir)/mkinstalldirs $(bindir) $(includedir) $(libdir)/ivl \
|
||||
$(mandir) $(mandir)/man1
|
||||
|
||||
uninstall:
|
||||
rm -f $(libdir)/ivl/ivl@EXEEXT@
|
||||
rm -f $(bindir)/verilog
|
||||
rm -f $(bindir)/gverilog@EXEEXT@
|
||||
rm -f $(includedir)/ivl_target.h
|
||||
rm -f $(includedir)/vpi_user.h
|
||||
cd driver ; $(MAKE) uninstall
|
||||
cd vpi ; $(MAKE) uninstall
|
||||
cd vvm ; $(MAKE) uninstall
|
||||
cd ivlpp ; $(MAKE) uninstall
|
||||
for tgt in $(SUBDIRS); do (cd $$tgt ; $(MAKE) uninstall); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) uninstall); done
|
||||
for dir in $(SUBDIRS); do (cd $$dir ; $(MAKE) $@); done
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) $@); done
|
||||
for dir in vpi ivlpp driver; \
|
||||
do (cd $$dir ; $(MAKE) $@); done
|
||||
for f in xnf.conf xnf-s.conf ivl; \
|
||||
do rm -f $(libdir)/ivl/$$f; done
|
||||
-rmdir $(libdir)/ivl
|
||||
for f in verilog iverilog-vpi gverilog@EXEEXT@; \
|
||||
do rm -f $(bindir)/$$f; done
|
||||
for f in ivl_target.h vpi_user.h _pli_types.h acc_user.h veriuser.h; \
|
||||
do rm -f $(includedir)/$$f; done
|
||||
rm -f $(mandir)/man1/iverilog-vpi.1
|
||||
|
||||
|
||||
-include $(patsubst %.o, dep/%.d, $O)
|
||||
-include $(patsubst %.o, dep/%.d, vpithunk.o)
|
||||
|
||||
@@ -16,21 +16,26 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Module.cc,v 1.14 2000/11/15 20:31:05 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Module.cc,v 1.25 2004/10/04 01:10:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "Module.h"
|
||||
# include "PGate.h"
|
||||
# include "PWire.h"
|
||||
# include <assert.h>
|
||||
|
||||
Module::Module(const string&name, const svector<Module::port_t*>*pp)
|
||||
: name_(name)
|
||||
/* n is a permallocated string. */
|
||||
Module::Module(perm_string n)
|
||||
: name_(n)
|
||||
{
|
||||
if (pp)
|
||||
ports_ = *pp;
|
||||
default_nettype = NetNet::NONE;
|
||||
}
|
||||
|
||||
Module::~Module()
|
||||
{
|
||||
}
|
||||
|
||||
void Module::add_gate(PGate*gate)
|
||||
@@ -38,19 +43,19 @@ void Module::add_gate(PGate*gate)
|
||||
gates_.push_back(gate);
|
||||
}
|
||||
|
||||
void Module::add_task(const string&name, PTask*task)
|
||||
void Module::add_task(perm_string name, PTask*task)
|
||||
{
|
||||
tasks_[name] = task;
|
||||
}
|
||||
|
||||
void Module::add_function(const string &name, PFunction *func)
|
||||
void Module::add_function(perm_string name, PFunction *func)
|
||||
{
|
||||
funcs_[name] = func;
|
||||
}
|
||||
|
||||
PWire* Module::add_wire(PWire*wire)
|
||||
{
|
||||
PWire*&ep = wires_[wire->name()];
|
||||
PWire*&ep = wires_[wire->path()];
|
||||
if (ep) return ep;
|
||||
|
||||
assert(ep == 0);
|
||||
@@ -65,46 +70,56 @@ void Module::add_behavior(PProcess*b)
|
||||
|
||||
unsigned Module::port_count() const
|
||||
{
|
||||
return ports_.count();
|
||||
return ports.count();
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the array of PEIdent object that are at this port of the
|
||||
* module. If the port is internally unconnected, return an empty
|
||||
* array.
|
||||
* array.
|
||||
*/
|
||||
const svector<PEIdent*>& Module::get_port(unsigned idx) const
|
||||
{
|
||||
assert(idx < ports_.count());
|
||||
assert(idx < ports.count());
|
||||
static svector<PEIdent*> zero;
|
||||
|
||||
if (ports_[idx])
|
||||
return ports_[idx]->expr;
|
||||
if (ports[idx])
|
||||
return ports[idx]->expr;
|
||||
else
|
||||
return zero;
|
||||
}
|
||||
|
||||
unsigned Module::find_port(const string&name) const
|
||||
unsigned Module::find_port(const char*name) const
|
||||
{
|
||||
assert(name != "");
|
||||
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1)
|
||||
if (ports_[idx]->name == name)
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
if (ports[idx] == 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. */
|
||||
continue;
|
||||
}
|
||||
assert(ports[idx]);
|
||||
if (ports[idx]->name == name)
|
||||
return idx;
|
||||
}
|
||||
|
||||
return ports_.count();
|
||||
return ports.count();
|
||||
}
|
||||
|
||||
|
||||
PWire* Module::get_wire(const string&name) const
|
||||
PWire* Module::get_wire(const hname_t&name) const
|
||||
{
|
||||
map<string,PWire*>::const_iterator obj = wires_.find(name);
|
||||
map<hname_t,PWire*>::const_iterator obj = wires_.find(name);
|
||||
if (obj == wires_.end())
|
||||
return 0;
|
||||
else
|
||||
return (*obj).second;
|
||||
}
|
||||
|
||||
PGate* Module::get_gate(const string&name)
|
||||
PGate* Module::get_gate(perm_string name)
|
||||
{
|
||||
for (list<PGate*>::iterator cur = gates_.begin()
|
||||
; cur != gates_.end()
|
||||
@@ -117,7 +132,7 @@ PGate* Module::get_gate(const string&name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const map<string,PWire*>& Module::get_wires() const
|
||||
const map<hname_t,PWire*>& Module::get_wires() const
|
||||
{
|
||||
return wires_;
|
||||
}
|
||||
@@ -135,6 +150,41 @@ const list<PProcess*>& Module::get_behaviors() const
|
||||
|
||||
/*
|
||||
* $Log: Module.cc,v $
|
||||
* Revision 1.25 2004/10/04 01:10:51 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.24 2004/06/13 04:56:53 steve
|
||||
* Add support for the default_nettype directive.
|
||||
*
|
||||
* Revision 1.23 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.22 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.21 2003/04/02 03:00:14 steve
|
||||
* Cope with empty module ports while binding by name.
|
||||
*
|
||||
* Revision 1.20 2003/03/06 04:37:12 steve
|
||||
* lex_strings.add module names earlier.
|
||||
*
|
||||
* Revision 1.19 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.18 2002/05/19 23:37:28 steve
|
||||
* Parse port_declaration_lists from the 2001 Standard.
|
||||
*
|
||||
* Revision 1.17 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.16 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
*
|
||||
* Revision 1.15 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.14 2000/11/15 20:31:05 steve
|
||||
* Fix warning about temporaries.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __Module_H
|
||||
#define __Module_H
|
||||
/*
|
||||
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2004 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,15 +18,19 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Module.h,v 1.21 2000/11/05 06:05:59 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Module.h,v 1.37 2004/06/13 04:56:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include "HName.h"
|
||||
# include "named.h"
|
||||
# include <string>
|
||||
# include "LineInfo.h"
|
||||
# include "netlist.h"
|
||||
class PData;
|
||||
class PEvent;
|
||||
class PExpr;
|
||||
class PEIdent;
|
||||
@@ -44,7 +48,7 @@ class NetScope;
|
||||
* therefore the handle for grasping the described circuit.
|
||||
*/
|
||||
|
||||
class Module {
|
||||
class Module : public LineInfo {
|
||||
|
||||
/* The module ports are in general a vector of port_t
|
||||
objects. Each port has a name and an ordered list of
|
||||
@@ -53,25 +57,41 @@ class Module {
|
||||
the port. */
|
||||
public:
|
||||
struct port_t {
|
||||
string name;
|
||||
perm_string name;
|
||||
svector<PEIdent*> expr;
|
||||
};
|
||||
|
||||
public:
|
||||
explicit Module(const string&name, const svector<port_t*>*);
|
||||
/* The name passed here is the module name, not the instance
|
||||
name. This make must be a permallocated string. */
|
||||
explicit Module(perm_string name);
|
||||
~Module();
|
||||
|
||||
NetNet::Type default_nettype;
|
||||
|
||||
/* The module has parameters that are evaluated when the
|
||||
module is elaborated. During parsing, I put the parameters
|
||||
into this map. */
|
||||
map<string,PExpr*>parameters;
|
||||
map<string,PExpr*>localparams;
|
||||
struct param_expr_t {
|
||||
PExpr*expr;
|
||||
PExpr*msb;
|
||||
PExpr*lsb;
|
||||
bool signed_flag;
|
||||
};
|
||||
map<perm_string,param_expr_t>parameters;
|
||||
map<perm_string,param_expr_t>localparams;
|
||||
|
||||
|
||||
/* specparams are simpler then other params, in that they have
|
||||
no type information. They are merely constant
|
||||
expressions. */
|
||||
map<perm_string,PExpr*>specparams;
|
||||
|
||||
/* The module also has defparam assignments which don't create
|
||||
new parameters within the module, but may be used to set
|
||||
values within this module (when instantiated) or in other
|
||||
instantiated modules. */
|
||||
map<string,PExpr*>defparms;
|
||||
map<hname_t,PExpr*>defparms;
|
||||
|
||||
/* Parameters may be overridden at instantiation time;
|
||||
the overrides do not contain explicit parameter names,
|
||||
@@ -79,16 +99,25 @@ class Module {
|
||||
appear in the instantiated module. Therefore a
|
||||
list of names in module-order is needed to pass from
|
||||
a parameter-index to its name. */
|
||||
list<string> param_names;
|
||||
list<perm_string> param_names;
|
||||
|
||||
/* This is an array of port descriptors, which is in turn a
|
||||
named array of PEident pointers. */
|
||||
svector<port_t*> ports;
|
||||
|
||||
/* Keep a table of named events declared in the module. */
|
||||
map<string,PEvent*>events;
|
||||
map<perm_string,PEvent*>events;
|
||||
|
||||
/* Keep a table of datum variables declared in the module. */
|
||||
map<hname_t,PData*>datum;
|
||||
|
||||
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;
|
||||
|
||||
const string&get_name() const { return name_; }
|
||||
perm_string mod_name() const { return name_; }
|
||||
|
||||
void add_gate(PGate*gate);
|
||||
|
||||
@@ -98,19 +127,19 @@ class Module {
|
||||
PWire* add_wire(PWire*wire);
|
||||
|
||||
void add_behavior(PProcess*behave);
|
||||
void add_task(const string&name, PTask*def);
|
||||
void add_function(const string&name, PFunction*def);
|
||||
void add_task(perm_string name, PTask*def);
|
||||
void add_function(perm_string name, PFunction*def);
|
||||
|
||||
unsigned port_count() const;
|
||||
const svector<PEIdent*>& get_port(unsigned idx) const;
|
||||
unsigned find_port(const string&) const;
|
||||
unsigned find_port(const char*name) const;
|
||||
|
||||
// Find a wire by name. This is used for connecting gates to
|
||||
// existing wires, etc.
|
||||
PWire* get_wire(const string&name) const;
|
||||
PGate* get_gate(const string&name);
|
||||
PWire* get_wire(const hname_t&name) const;
|
||||
PGate* get_gate(perm_string name);
|
||||
|
||||
const map<string,PWire*>& get_wires() const;
|
||||
const map<hname_t,PWire*>& get_wires() const;
|
||||
const list<PGate*>& get_gates() const;
|
||||
const list<PProcess*>& get_behaviors() const;
|
||||
|
||||
@@ -122,17 +151,13 @@ class Module {
|
||||
bool elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
const string name_;
|
||||
perm_string name_;
|
||||
|
||||
/* This is an array of port descriptors, which is in turn a
|
||||
named array of PEident pointers. */
|
||||
svector<port_t*> ports_;
|
||||
|
||||
map<string,PWire*> wires_;
|
||||
map<hname_t,PWire*> wires_;
|
||||
list<PGate*> gates_;
|
||||
list<PProcess*> behaviors_;
|
||||
map<string,PTask*> tasks_;
|
||||
map<string,PFunction*> funcs_;
|
||||
map<perm_string,PTask*> tasks_;
|
||||
map<perm_string,PFunction*> funcs_;
|
||||
|
||||
private: // Not implemented
|
||||
Module(const Module&);
|
||||
@@ -142,86 +167,45 @@ class Module {
|
||||
|
||||
/*
|
||||
* $Log: Module.h,v $
|
||||
* Revision 1.21 2000/11/05 06:05:59 steve
|
||||
* Handle connectsion to internally unconnected modules (PR#38)
|
||||
* Revision 1.37 2004/06/13 04:56:53 steve
|
||||
* Add support for the default_nettype directive.
|
||||
*
|
||||
* Revision 1.20 2000/07/22 22:09:03 steve
|
||||
* Parse and elaborate timescale to scopes.
|
||||
* Revision 1.36 2004/05/25 19:21:06 steve
|
||||
* More identifier lists use perm_strings.
|
||||
*
|
||||
* Revision 1.19 2000/05/16 04:05:15 steve
|
||||
* Module ports are really special PEIdent
|
||||
* expressions, because a name can be used
|
||||
* many places in the port list.
|
||||
* Revision 1.35 2004/02/20 18:53:33 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.18 2000/05/02 16:27:38 steve
|
||||
* Move signal elaboration to a seperate pass.
|
||||
* Revision 1.34 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.17 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
* Revision 1.33 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.16 2000/03/12 17:09:40 steve
|
||||
* Support localparam.
|
||||
* Revision 1.32 2003/06/20 00:53:19 steve
|
||||
* Module attributes from the parser
|
||||
* through to elaborated form.
|
||||
*
|
||||
* Revision 1.15 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
* Revision 1.31 2003/06/13 19:10:45 steve
|
||||
* Properly manage real variables in subscopes.
|
||||
*
|
||||
* Revision 1.14 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
* Revision 1.30 2003/03/06 04:37:12 steve
|
||||
* lex_strings.add module names earlier.
|
||||
*
|
||||
* Revision 1.13 2000/01/09 20:37:57 steve
|
||||
* Careful with wires connected to multiple ports.
|
||||
* Revision 1.29 2003/02/27 06:45:11 steve
|
||||
* specparams as far as pform.
|
||||
*
|
||||
* Revision 1.12 2000/01/09 05:50:48 steve
|
||||
* Support named parameter override lists.
|
||||
* Revision 1.28 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
* Revision 1.11 1999/12/11 05:45:41 steve
|
||||
* Fix support for attaching attributes to primitive gates.
|
||||
* Revision 1.27 2002/08/19 02:39:16 steve
|
||||
* Support parameters with defined ranges.
|
||||
*
|
||||
* Revision 1.10 1999/11/27 19:07:57 steve
|
||||
* Support the creation of scopes.
|
||||
*
|
||||
* Revision 1.9 1999/08/23 16:48:39 steve
|
||||
* Parameter overrides support from Peter Monta
|
||||
* AND and XOR support wide expressions.
|
||||
*
|
||||
* Revision 1.8 1999/08/04 02:13:02 steve
|
||||
* Elaborate module ports that are concatenations of
|
||||
* module signals.
|
||||
*
|
||||
* Revision 1.7 1999/08/03 04:14:49 steve
|
||||
* Parse into pform arbitrarily complex module
|
||||
* port declarations.
|
||||
*
|
||||
* Revision 1.6 1999/07/31 19:14:47 steve
|
||||
* Add functions up to elaboration (Ed Carter)
|
||||
*
|
||||
* Revision 1.5 1999/07/03 02:12:51 steve
|
||||
* Elaborate user defined tasks.
|
||||
*
|
||||
* Revision 1.4 1999/06/15 03:44:53 steve
|
||||
* Get rid of the STL vector template.
|
||||
*
|
||||
* Revision 1.3 1999/02/21 17:01:57 steve
|
||||
* Add support for module parameters.
|
||||
*
|
||||
* Revision 1.2 1999/01/25 05:45:56 steve
|
||||
* Add the LineInfo class to carry the source file
|
||||
* location of things. PGate, Statement and PProcess.
|
||||
*
|
||||
* elaborate handles module parameter mismatches,
|
||||
* missing or incorrect lvalues for procedural
|
||||
* assignment, and errors are propogated to the
|
||||
* top of the elaboration call tree.
|
||||
*
|
||||
* Attach line numbers to processes, gates and
|
||||
* assignment statements.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:28:52 steve
|
||||
* Introduce verilog to CVS.
|
||||
* Revision 1.26 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.25 2002/05/19 23:37:28 steve
|
||||
* Parse port_declaration_lists from the 2001 Standard.
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PData.cc,v 1.2 2003/11/10 20:11:01 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "PData.h"
|
||||
|
||||
PData::PData(const hname_t&h)
|
||||
: hname_(h)
|
||||
{
|
||||
}
|
||||
|
||||
PData::~PData()
|
||||
{
|
||||
}
|
||||
|
||||
const hname_t&PData::name() const
|
||||
{
|
||||
return hname_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PData.cc,v $
|
||||
* Revision 1.2 2003/11/10 20:11:01 steve
|
||||
* missing include of config.h
|
||||
*
|
||||
* Revision 1.1 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
#ifndef __PData_H
|
||||
#define __PData_H
|
||||
/*
|
||||
* Copyright (c) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PData.h,v 1.1 2003/01/26 21:15:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "HName.h"
|
||||
# include "netlist.h"
|
||||
# include "LineInfo.h"
|
||||
|
||||
/*
|
||||
* The PData object represents declaration of atomic datum such as
|
||||
* real and realtime variables. These are variables that cannot be bit
|
||||
* or part selected, but can be used in expressions.
|
||||
*/
|
||||
|
||||
class PData : public LineInfo {
|
||||
|
||||
public:
|
||||
PData(const hname_t&hname);
|
||||
~PData();
|
||||
|
||||
// Return a hierarchical name.
|
||||
const hname_t&name() const;
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
map<string,PExpr*> attributes;
|
||||
|
||||
private:
|
||||
hname_t hname_;
|
||||
|
||||
private:
|
||||
PData(const PData&);
|
||||
PData& operator= (const PData&);
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: PData.h,v $
|
||||
* Revision 1.1 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+82
-32
@@ -16,24 +16,31 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PDelays.cc,v 1.4 2001/01/20 02:15:50 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PDelays.cc,v 1.11 2003/06/21 01:21:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "PDelays.h"
|
||||
# include "PExpr.h"
|
||||
# include "verinum.h"
|
||||
|
||||
PDelays::PDelays()
|
||||
{
|
||||
delete_flag_ = true;
|
||||
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
|
||||
delay_[idx] = 0;
|
||||
}
|
||||
|
||||
PDelays::~PDelays()
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
|
||||
delete delay_[idx];
|
||||
if (delete_flag_) {
|
||||
for (unsigned idx = 0 ; idx < 3 ; idx += 1)
|
||||
delete delay_[idx];
|
||||
}
|
||||
}
|
||||
|
||||
void PDelays::set_delay(PExpr*del)
|
||||
@@ -41,57 +48,74 @@ void PDelays::set_delay(PExpr*del)
|
||||
assert(del);
|
||||
assert(delay_[0] == 0);
|
||||
delay_[0] = del;
|
||||
delete_flag_ = true;
|
||||
}
|
||||
|
||||
|
||||
void PDelays::set_delays(const svector<PExpr*>*del)
|
||||
void PDelays::set_delays(const svector<PExpr*>*del, bool df)
|
||||
{
|
||||
assert(del);
|
||||
assert(del->count() <= 3);
|
||||
for (unsigned idx = 0 ; idx < del->count() ; idx += 1)
|
||||
delay_[idx] = (*del)[idx];
|
||||
|
||||
delete_flag_ = df;
|
||||
}
|
||||
|
||||
static unsigned long calculate_val(Design*des, const NetScope*scope,
|
||||
static unsigned long calculate_val(Design*des, NetScope*scope,
|
||||
const PExpr*expr)
|
||||
{
|
||||
assert(expr);
|
||||
unsigned long val;
|
||||
|
||||
int shift = scope->time_unit() - des->get_precision();
|
||||
|
||||
if (verireal*dr = expr->eval_rconst(des, scope)) {
|
||||
val = dr->as_long(shift);
|
||||
delete dr;
|
||||
|
||||
} else {
|
||||
verinum*dv = expr->eval_const(des, scope->name());
|
||||
if (dv == 0) {
|
||||
cerr << expr->get_line() << ": sorry: non-constant "
|
||||
<< "delays not supported here: " << *expr << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(dv);
|
||||
val = dv->as_ulong();
|
||||
val = des->scale_to_precision(val, scope);
|
||||
delete dv;
|
||||
NetExpr*dex = expr->elaborate_expr(des, scope);
|
||||
if (NetExpr*tmp = dex->eval_tree()) {
|
||||
delete dex;
|
||||
dex = tmp;
|
||||
}
|
||||
|
||||
return val;
|
||||
/* If the delay expression is a real constant or vector
|
||||
constant, then evaluate it, scale it to the local time
|
||||
units, and return an adjusted value. */
|
||||
|
||||
if (NetECReal*tmp = dynamic_cast<NetECReal*>(dex)) {
|
||||
verireal fn = tmp->value();
|
||||
|
||||
int shift = scope->time_unit() - des->get_precision();
|
||||
long delay = fn.as_long(shift);
|
||||
if (delay < 0)
|
||||
delay = 0;
|
||||
|
||||
delete tmp;
|
||||
return delay;
|
||||
}
|
||||
|
||||
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(dex)) {
|
||||
verinum fn = tmp->value();
|
||||
|
||||
unsigned long delay =
|
||||
des->scale_to_precision(fn.as_ulong(), scope);
|
||||
|
||||
delete tmp;
|
||||
return delay;
|
||||
}
|
||||
|
||||
/* Oops, cannot evaluate down to a constant. Error message. */
|
||||
delete dex;
|
||||
|
||||
cerr << expr->get_line() << ": sorry: non-constant "
|
||||
<< "delays not supported here: " << *expr << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void PDelays::eval_delays(Design*des, const string&path,
|
||||
void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
int shift = scope->time_unit() - des->get_precision();
|
||||
|
||||
|
||||
if (delay_[0]) {
|
||||
rise_time = calculate_val(des, scope, delay_[0]);
|
||||
@@ -122,6 +146,32 @@ void PDelays::eval_delays(Design*des, const string&path,
|
||||
|
||||
/*
|
||||
* $Log: PDelays.cc,v $
|
||||
* Revision 1.11 2003/06/21 01:21:42 steve
|
||||
* Harmless fixup of warnings.
|
||||
*
|
||||
* Revision 1.10 2003/02/08 19:49:21 steve
|
||||
* Calculate delay statement delays using elaborated
|
||||
* expressions instead of pre-elaborated expression
|
||||
* trees.
|
||||
*
|
||||
* Remove the eval_pexpr methods from PExpr.
|
||||
*
|
||||
* Revision 1.9 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.8 2001/12/29 20:19:31 steve
|
||||
* Do not delete delay expressions of UDP instances.
|
||||
*
|
||||
* Revision 1.7 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.6 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.5 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.4 2001/01/20 02:15:50 steve
|
||||
* apologize for not supporting non-constant delays.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PDelays_H
|
||||
#define __PDelays_H
|
||||
/*
|
||||
* Copyright (c) 1999 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2002 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,20 +18,22 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PDelays.h,v 1.3 2001/01/16 02:44:17 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PDelays.h,v 1.7 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
# include <string>
|
||||
# include <iostream>
|
||||
|
||||
#ifdef HAVE_IOSFWD
|
||||
# include <iosfwd>
|
||||
#else
|
||||
class ostream;
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ > 2
|
||||
using namespace std;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class Design;
|
||||
class NetScope;
|
||||
class PExpr;
|
||||
|
||||
/*
|
||||
@@ -44,10 +46,13 @@ class PDelays {
|
||||
PDelays();
|
||||
~PDelays();
|
||||
|
||||
/* Set the delay expressions. If the delete_flag is true, then
|
||||
this object takes ownership of the expressions, and will
|
||||
delete it in the destructor. */
|
||||
void set_delay(PExpr*);
|
||||
void set_delays(const svector<PExpr*>*del);
|
||||
void set_delays(const svector<PExpr*>*del, bool delete_flag=true);
|
||||
|
||||
void eval_delays(Design*des, const string&path,
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const;
|
||||
@@ -56,6 +61,7 @@ class PDelays {
|
||||
|
||||
private:
|
||||
PExpr* delay_[3];
|
||||
bool delete_flag_;
|
||||
|
||||
private: // not implemented
|
||||
PDelays(const PDelays&);
|
||||
@@ -66,6 +72,18 @@ ostream& operator << (ostream&o, const PDelays&);
|
||||
|
||||
/*
|
||||
* $Log: PDelays.h,v $
|
||||
* Revision 1.7 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.6 2002/06/14 03:25:51 steve
|
||||
* Compiler portability.
|
||||
*
|
||||
* Revision 1.5 2001/12/29 20:19:31 steve
|
||||
* Do not delete delay expressions of UDP instances.
|
||||
*
|
||||
* Revision 1.4 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.3 2001/01/16 02:44:17 steve
|
||||
* Use the iosfwd header if available.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 200Stephen Williams ([email protected])
|
||||
* Copyright (c) 2004 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
|
||||
@@ -16,13 +16,15 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PEvent.cc,v 1.1 2000/04/01 19:31:57 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PEvent.cc,v 1.5 2004/02/19 06:57:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PEvent.h"
|
||||
|
||||
PEvent::PEvent(const string&n)
|
||||
PEvent::PEvent(perm_string n)
|
||||
: name_(n)
|
||||
{
|
||||
}
|
||||
@@ -31,13 +33,29 @@ PEvent::~PEvent()
|
||||
{
|
||||
}
|
||||
|
||||
string PEvent::name() const
|
||||
perm_string PEvent::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PEvent.cc,v $
|
||||
* Revision 1.5 2004/02/19 06:57:10 steve
|
||||
* Memory and Event names use perm_string.
|
||||
*
|
||||
* Revision 1.4 2003/03/01 06:25:30 steve
|
||||
* Add the lex_strings string handler, and put
|
||||
* scope names and system task/function names
|
||||
* into this table. Also, permallocate event
|
||||
* names from the beginning.
|
||||
*
|
||||
* Revision 1.3 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.1 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PEvent_H
|
||||
#define __PEvent_H
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000-2004 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,11 +18,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PEvent.h,v 1.4 2001/01/16 02:44:18 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PEvent.h,v 1.9 2004/02/19 06:57:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "StringHeap.h"
|
||||
# include <string>
|
||||
|
||||
class Design;
|
||||
@@ -30,20 +31,23 @@ class NetScope;
|
||||
|
||||
/*
|
||||
* The PEvent class represents event objects. These are things that
|
||||
* are declared in Verilog as ``event foo;''
|
||||
* are declared in Verilog as ``event foo;'' The name passed to the
|
||||
* constructor is the "foo" part of the declaration.
|
||||
*/
|
||||
class PEvent : public LineInfo {
|
||||
|
||||
public:
|
||||
explicit PEvent(const string&name);
|
||||
// The name is a perm-allocated string. It is the simple name
|
||||
// of the event, without any scope.
|
||||
explicit PEvent(perm_string name);
|
||||
~PEvent();
|
||||
|
||||
string name() const;
|
||||
perm_string name() const;
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
perm_string name_;
|
||||
|
||||
private: // not implemented
|
||||
PEvent(const PEvent&);
|
||||
@@ -52,6 +56,25 @@ class PEvent : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: PEvent.h,v $
|
||||
* Revision 1.9 2004/02/19 06:57:10 steve
|
||||
* Memory and Event names use perm_string.
|
||||
*
|
||||
* Revision 1.8 2003/03/01 06:25:30 steve
|
||||
* Add the lex_strings string handler, and put
|
||||
* scope names and system task/function names
|
||||
* into this table. Also, permallocate event
|
||||
* names from the beginning.
|
||||
*
|
||||
* Revision 1.7 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.6 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.5 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.4 2001/01/16 02:44:18 steve
|
||||
* Use the iosfwd header if available.
|
||||
*
|
||||
|
||||
@@ -16,10 +16,14 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PExpr.cc,v 1.23 2001/01/14 23:04:55 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PExpr.cc,v 1.35 2004/10/04 01:10:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "Module.h"
|
||||
# include <typeinfo>
|
||||
@@ -42,37 +46,34 @@ bool PExpr::is_constant(Module*) const
|
||||
return false;
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_net(Design*des, const string&path, unsigned,
|
||||
unsigned long,
|
||||
unsigned long,
|
||||
unsigned long,
|
||||
Link::strength_t,
|
||||
Link::strength_t) const
|
||||
{
|
||||
cerr << get_line() << ": error: Unable to elaborate `"
|
||||
<< *this << "' as gates." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_lnet(Design*des, const string&path) const
|
||||
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*, bool) const
|
||||
{
|
||||
cerr << get_line() << ": error: expression not valid in assign l-value: "
|
||||
<< *this << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
|
||||
: op_(op), left_(l), right_(r)
|
||||
{
|
||||
}
|
||||
|
||||
PEBinary::~PEBinary()
|
||||
{
|
||||
}
|
||||
|
||||
bool PEBinary::is_constant(Module*mod) const
|
||||
{
|
||||
return left_->is_constant(mod) && right_->is_constant(mod);
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(const char*n, const svector<PExpr *> &parms)
|
||||
: name_(n), parms_(parms)
|
||||
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
|
||||
: path_(n), parms_(parms)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(const char*n)
|
||||
: name_(n)
|
||||
PECallFunction::PECallFunction(const hname_t&n)
|
||||
: path_(n)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -138,8 +139,8 @@ bool PEFNumber::is_constant(Module*) const
|
||||
return true;
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(const string&s)
|
||||
: text_(s), msb_(0), lsb_(0), idx_(0)
|
||||
PEIdent::PEIdent(const hname_t&s)
|
||||
: path_(s), msb_(0), lsb_(0), idx_(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -147,25 +148,34 @@ PEIdent::~PEIdent()
|
||||
{
|
||||
}
|
||||
|
||||
string PEIdent::name() const
|
||||
const hname_t& PEIdent::path() const
|
||||
{
|
||||
return text_;
|
||||
return path_;
|
||||
}
|
||||
|
||||
/*
|
||||
* An identifier can be in a constant expresion if (and only if) it is
|
||||
* An identifier can be in a constant expression if (and only if) it is
|
||||
* a parameter.
|
||||
*/
|
||||
bool PEIdent::is_constant(Module*mod) const
|
||||
{
|
||||
map<string,PExpr*>::const_iterator cur;
|
||||
if (mod == 0) return false;
|
||||
|
||||
cur = mod->parameters.find(text_);
|
||||
if (cur != mod->parameters.end()) return true;
|
||||
/* This is a work-around for map not matching < even when
|
||||
there is a perm_string operator that can do the comprare.
|
||||
|
||||
cur = mod->localparams.find(text_);
|
||||
if (cur != mod->localparams.end()) return true;
|
||||
The real fix is to make the path_ carry perm_strings. */
|
||||
perm_string tmp = perm_string::literal(path_.peek_name(0));
|
||||
|
||||
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->parameters.find(tmp);
|
||||
if (cur != mod->parameters.end()) return true;
|
||||
}
|
||||
|
||||
{ map<perm_string,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->localparams.find(tmp);
|
||||
if (cur != mod->localparams.end()) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -200,13 +210,14 @@ bool PENumber::is_constant(Module*) const
|
||||
return true;
|
||||
}
|
||||
|
||||
PEString::PEString(const string&s)
|
||||
PEString::PEString(char*s)
|
||||
: text_(s)
|
||||
{
|
||||
}
|
||||
|
||||
PEString::~PEString()
|
||||
{
|
||||
delete[]text_;
|
||||
}
|
||||
|
||||
string PEString::value() const
|
||||
@@ -251,6 +262,44 @@ bool PEUnary::is_constant(Module*m) const
|
||||
|
||||
/*
|
||||
* $Log: PExpr.cc,v $
|
||||
* Revision 1.35 2004/10/04 01:10:51 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.34 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.33 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.32 2002/11/09 19:20:48 steve
|
||||
* Port expressions for output ports are lnets, not nets.
|
||||
*
|
||||
* Revision 1.31 2002/08/19 02:39:16 steve
|
||||
* Support parameters with defined ranges.
|
||||
*
|
||||
* Revision 1.30 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.29 2001/12/30 21:32:03 steve
|
||||
* Support elaborate_net for PEString objects.
|
||||
*
|
||||
* Revision 1.28 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.27 2001/11/08 05:15:50 steve
|
||||
* Remove string paths from PExpr elaboration.
|
||||
*
|
||||
* Revision 1.26 2001/11/07 04:26:46 steve
|
||||
* elaborate_lnet uses scope instead of string path.
|
||||
*
|
||||
* Revision 1.25 2001/11/06 06:11:55 steve
|
||||
* Support more real arithmetic in delay constants.
|
||||
*
|
||||
* Revision 1.24 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.23 2001/01/14 23:04:55 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
|
||||
@@ -18,14 +18,13 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PExpr.h,v 1.48 2001/01/14 23:04:55 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PExpr.h,v 1.66 2004/10/04 01:10:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
# include "netlist.h"
|
||||
# include "verinum.h"
|
||||
# include "verireal.h"
|
||||
# include "LineInfo.h"
|
||||
|
||||
class Design;
|
||||
@@ -51,8 +50,11 @@ class PExpr : public LineInfo {
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
// Procedural elaboration of the expression.
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
|
||||
// Procedural elaboration of the expression. Set the
|
||||
// bare_memory_ok flag if the result is allowed to be a
|
||||
// NetEMemory without an index.
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
bool sys_task_arg =false) const;
|
||||
|
||||
// Elaborate expressions that are the r-value of parameter
|
||||
// assignments. This elaboration follows the restrictions of
|
||||
@@ -62,7 +64,7 @@ class PExpr : public LineInfo {
|
||||
|
||||
// This method elaborate the expression as gates, for use in a
|
||||
// continuous assign or other wholly structural context.
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
@@ -77,7 +79,8 @@ class PExpr : public LineInfo {
|
||||
|
||||
// This method elaborates the expression as gates, but
|
||||
// restricted for use as l-values of continuous assignments.
|
||||
virtual NetNet* elaborate_lnet(Design*des, const string&path) const;
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
||||
bool implicit_net_ok =false) const;
|
||||
|
||||
// Expressions that can be in the l-value of procedural
|
||||
// assignments can be elaborated with this method.
|
||||
@@ -86,12 +89,7 @@ class PExpr : public LineInfo {
|
||||
// This attempts to evaluate a constant expression, and return
|
||||
// a verinum as a result. If the expression cannot be
|
||||
// evaluated, return 0.
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
|
||||
// This attempts to evaluate a constant expression as a
|
||||
// decimal floating point. This is used when calculating delay
|
||||
// constants.
|
||||
virtual verireal* eval_rconst(const Design*, const NetScope*) const;
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
|
||||
// This method returns true if that expression is the same as
|
||||
// this expression. This method is used for comparing
|
||||
@@ -101,7 +99,7 @@ class PExpr : public LineInfo {
|
||||
// Return true if this expression is a valid constant
|
||||
// expression. the Module pointer is needed to find parameter
|
||||
// identifiers and any other module specific interpretations
|
||||
// of expresions.
|
||||
// of expressions.
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
private: // not implemented
|
||||
@@ -123,15 +121,17 @@ class PEConcat : public PExpr {
|
||||
// continuous assignments.
|
||||
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
|
||||
|
||||
virtual NetNet* elaborate_lnet(Design*des, const string&path) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
||||
bool implicit_net_ok =false) const;
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetEConcat*elaborate_pexpr(Design*des, NetScope*) const;
|
||||
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
|
||||
virtual bool is_constant(Module*) const;
|
||||
@@ -160,7 +160,7 @@ class PEEvent : public PExpr {
|
||||
|
||||
edge_t type() const;
|
||||
PExpr* expr() const;
|
||||
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
private:
|
||||
@@ -182,15 +182,13 @@ class PEFNumber : public PExpr {
|
||||
/* The eval_const method as applied to a floating point number
|
||||
gets the *integer* value of the number. This accounts for
|
||||
any rounding that is needed to get the value. */
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
|
||||
/* This method returns the full floating point value. */
|
||||
virtual verireal* eval_rconst(const Design*, const NetScope*) const;
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
|
||||
/* A PEFNumber is a constant, so this returns true. */
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
@@ -202,7 +200,7 @@ class PEFNumber : public PExpr {
|
||||
class PEIdent : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEIdent(const string&s);
|
||||
explicit PEIdent(const hname_t&s);
|
||||
~PEIdent();
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
@@ -211,13 +209,14 @@ class PEIdent : public PExpr {
|
||||
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
|
||||
|
||||
// Identifiers are allowed (with restrictions) is assign l-values.
|
||||
virtual NetNet* elaborate_lnet(Design*des, const string&path) const;
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope,
|
||||
bool implicit_net_ok =false) const;
|
||||
|
||||
// Identifiers are also allowed as procedural assignment l-values.
|
||||
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
|
||||
|
||||
// Structural r-values are OK.
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
@@ -225,7 +224,8 @@ class PEIdent : public PExpr {
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
|
||||
// Elaborate the PEIdent as a port to a module. This method
|
||||
@@ -233,12 +233,12 @@ class PEIdent : public PExpr {
|
||||
NetNet* elaborate_port(Design*des, NetScope*sc) const;
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
verinum* eval_const(const Design*des, const string&path) const;
|
||||
verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
|
||||
string name() const;
|
||||
const hname_t& path() const;
|
||||
|
||||
private:
|
||||
string text_;
|
||||
hname_t path_;
|
||||
|
||||
public:
|
||||
// Use these to support bit- and part-select operators.
|
||||
@@ -249,11 +249,24 @@ class PEIdent : public PExpr {
|
||||
// expression.
|
||||
PExpr*idx_;
|
||||
|
||||
NetNet* elaborate_net_ram_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_ram_(Design*des, NetScope*scope,
|
||||
NetMemory*mem, unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
|
||||
NetNet* elaborate_net_bitmux_(Design*des, NetScope*scope,
|
||||
NetNet*sig,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
|
||||
private:
|
||||
NetAssign_* elaborate_mem_lval_(Design*des, NetScope*scope,
|
||||
NetMemory*mem) const;
|
||||
|
||||
};
|
||||
|
||||
class PENumber : public PExpr {
|
||||
@@ -265,16 +278,19 @@ class PENumber : public PExpr {
|
||||
const verinum& value() const;
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
|
||||
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
|
||||
virtual bool is_the_same(const PExpr*that) const;
|
||||
virtual bool is_constant(Module*) const;
|
||||
@@ -283,21 +299,37 @@ class PENumber : public PExpr {
|
||||
verinum*const value_;
|
||||
};
|
||||
|
||||
/*
|
||||
* This represents a string constant in an expression.
|
||||
*
|
||||
* The s parameter to the PEString constructor is a C string that this
|
||||
* class instance will take for its own. The caller should not delete
|
||||
* the string, the destructor will do it.
|
||||
*/
|
||||
class PEString : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEString(const string&s);
|
||||
explicit PEString(char*s);
|
||||
~PEString();
|
||||
|
||||
string value() const;
|
||||
virtual void dump(ostream&) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetEConst*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
verinum* PEString::eval_const(const Design*, const NetScope*) const;
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
private:
|
||||
const string text_;
|
||||
char*text_;
|
||||
};
|
||||
|
||||
class PEUnary : public PExpr {
|
||||
@@ -307,16 +339,17 @@ class PEUnary : public PExpr {
|
||||
~PEUnary();
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetEUnary*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
@@ -328,22 +361,23 @@ class PEUnary : public PExpr {
|
||||
class PEBinary : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEBinary(char op, PExpr*l, PExpr*r)
|
||||
: op_(op), left_(l), right_(r) { }
|
||||
explicit PEBinary(char op, PExpr*l, PExpr*r);
|
||||
~PEBinary();
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetEBinary*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetEBinary*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
|
||||
private:
|
||||
char op_;
|
||||
@@ -352,42 +386,42 @@ class PEBinary : public PExpr {
|
||||
|
||||
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
|
||||
|
||||
NetNet* elaborate_net_add_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_bit_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_bit_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_cmp_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_cmp_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_div_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_div_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_mod_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_mod_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_log_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_log_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_mul_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_mul_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_shift_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_shift_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
@@ -407,16 +441,17 @@ class PETernary : public PExpr {
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetETernary*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetETernary*elaborate_expr(Design*des, NetScope*,
|
||||
bool sys_task_arg =false) const;
|
||||
virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
|
||||
private:
|
||||
PExpr*expr_;
|
||||
@@ -426,219 +461,98 @@ class PETernary : public PExpr {
|
||||
|
||||
/*
|
||||
* This class represents a parsed call to a function, including calls
|
||||
* to system functions.
|
||||
* to system functions. The parameters in the parms list are the
|
||||
* expressions that are passed as input to the ports of the function.
|
||||
*/
|
||||
class PECallFunction : public PExpr {
|
||||
public:
|
||||
explicit PECallFunction(const char*n, const svector<PExpr *> &parms);
|
||||
explicit PECallFunction(const char*n);
|
||||
explicit PECallFunction(const hname_t&n, const svector<PExpr *> &parms);
|
||||
explicit PECallFunction(const hname_t&n);
|
||||
~PECallFunction();
|
||||
|
||||
virtual void dump(ostream &) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay,
|
||||
Link::strength_t drive0,
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope,
|
||||
bool sys_task_arg =false) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
hname_t path_;
|
||||
svector<PExpr *> parms_;
|
||||
|
||||
bool check_call_matches_definition_(Design*des, NetScope*dscope) const;
|
||||
|
||||
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: PExpr.h,v $
|
||||
* Revision 1.48 2001/01/14 23:04:55 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
* Revision 1.66 2004/10/04 01:10:51 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Allow parameters to be referenced by hierarchical name.
|
||||
* Revision 1.65 2003/02/08 19:49:21 steve
|
||||
* Calculate delay statement delays using elaborated
|
||||
* expressions instead of pre-elaborated expression
|
||||
* trees.
|
||||
*
|
||||
* Revision 1.47 2000/12/16 19:03:30 steve
|
||||
* Evaluate <= and ?: in parameter expressions (PR#81)
|
||||
* Remove the eval_pexpr methods from PExpr.
|
||||
*
|
||||
* Revision 1.46 2000/12/10 22:01:35 steve
|
||||
* Support decimal constants in behavioral delays.
|
||||
* Revision 1.64 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.45 2000/12/06 06:31:09 steve
|
||||
* Check lvalue of procedural continuous assign (PR#29)
|
||||
* Revision 1.63 2002/11/09 19:20:48 steve
|
||||
* Port expressions for output ports are lnets, not nets.
|
||||
*
|
||||
* Revision 1.44 2000/09/17 21:26:15 steve
|
||||
* Add support for modulus (Eric Aardoom)
|
||||
* Revision 1.62 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.43 2000/09/09 15:21:26 steve
|
||||
* move lval elaboration to PExpr virtual methods.
|
||||
* Revision 1.61 2002/06/04 05:38:43 steve
|
||||
* Add support for memory words in l-value of
|
||||
* blocking assignments, and remove the special
|
||||
* NetAssignMem class.
|
||||
*
|
||||
* Revision 1.42 2000/09/07 22:38:13 steve
|
||||
* Support unary + and - in constants.
|
||||
* Revision 1.60 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Revision 1.41 2000/06/30 15:50:20 steve
|
||||
* Allow unary operators in constant expressions.
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.40 2000/06/13 05:22:16 steve
|
||||
* Support concatenation in parameter expressions.
|
||||
* Revision 1.59 2002/04/23 03:53:59 steve
|
||||
* Add support for non-constant bit select.
|
||||
*
|
||||
* Revision 1.39 2000/06/01 02:31:39 steve
|
||||
* Parameters can be strings.
|
||||
* Revision 1.58 2002/04/14 03:55:25 steve
|
||||
* Precalculate unary - if possible.
|
||||
*
|
||||
* Revision 1.38 2000/05/16 04:05:15 steve
|
||||
* Module ports are really special PEIdent
|
||||
* expressions, because a name can be used
|
||||
* many places in the port list.
|
||||
* Revision 1.57 2002/04/13 02:33:17 steve
|
||||
* Detect missing indices to memories (PR#421)
|
||||
*
|
||||
* Revision 1.37 2000/05/07 04:37:56 steve
|
||||
* Carry strength values from Verilog source to the
|
||||
* pform and netlist for gates.
|
||||
* Revision 1.56 2002/03/09 04:02:26 steve
|
||||
* Constant expressions are not l-values for task ports.
|
||||
*
|
||||
* Change vvm constants to use the driver_t to drive
|
||||
* a constant value. This works better if there are
|
||||
* multiple drivers on a signal.
|
||||
* Revision 1.55 2002/03/09 02:10:22 steve
|
||||
* Add the NetUserFunc netlist node.
|
||||
*
|
||||
* Revision 1.36 2000/05/04 03:37:58 steve
|
||||
* Add infrastructure for system functions, move
|
||||
* $time to that structure and add $random.
|
||||
* Revision 1.54 2001/12/30 21:32:03 steve
|
||||
* Support elaborate_net for PEString objects.
|
||||
*
|
||||
* Revision 1.35 2000/04/12 04:23:57 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
* Revision 1.53 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Handle named events within the mix of net events
|
||||
* and edges. As a unified lot they get caught together.
|
||||
* wait statements are broken into more complex statements
|
||||
* that include a conditional.
|
||||
* Revision 1.52 2001/11/08 05:15:50 steve
|
||||
* Remove string paths from PExpr elaboration.
|
||||
*
|
||||
* Do not generate NetPEvent or NetNEvent objects in
|
||||
* elaboration. NetEvent, NetEvWait and NetEvProbe
|
||||
* take over those functions in the netlist.
|
||||
*
|
||||
* Revision 1.34 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.33 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
* Revision 1.32 2000/03/12 18:22:11 steve
|
||||
* Binary and unary operators in parameter expressions.
|
||||
*
|
||||
* Revision 1.31 2000/03/12 04:35:22 steve
|
||||
* Allow parameter identifiers in parameter expressions.
|
||||
*
|
||||
* Revision 1.30 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.29 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.28 2000/02/16 03:58:27 steve
|
||||
* Fix up width matching in structural bitwise operators.
|
||||
*
|
||||
* Revision 1.27 2000/01/13 03:35:35 steve
|
||||
* Multiplication all the way to simulation.
|
||||
*
|
||||
* Revision 1.26 1999/12/16 03:46:39 steve
|
||||
* Structural logical or.
|
||||
*
|
||||
* Revision 1.25 1999/11/21 00:13:08 steve
|
||||
* Support memories in continuous assignments.
|
||||
*
|
||||
* Revision 1.24 1999/11/14 20:24:28 steve
|
||||
* Add support for the LPM_CLSHIFT device.
|
||||
*
|
||||
* Revision 1.23 1999/11/05 21:45:19 steve
|
||||
* Fix NetConst being set to zero width, and clean
|
||||
* up elaborate_set_cmp_ for NetEBinary.
|
||||
*
|
||||
* Revision 1.22 1999/10/31 20:08:24 steve
|
||||
* Include subtraction in LPM_ADD_SUB device.
|
||||
*
|
||||
* Revision 1.21 1999/10/31 04:11:27 steve
|
||||
* Add to netlist links pin name and instance number,
|
||||
* and arrange in vvm for pin connections by name
|
||||
* and instance number.
|
||||
*
|
||||
* Revision 1.20 1999/09/25 02:57:29 steve
|
||||
* Parse system function calls.
|
||||
*
|
||||
* Revision 1.19 1999/09/15 04:17:52 steve
|
||||
* separate assign lval elaboration for error checking.
|
||||
*
|
||||
* Revision 1.18 1999/08/31 22:38:29 steve
|
||||
* Elaborate and emit to vvm procedural functions.
|
||||
*
|
||||
* Revision 1.17 1999/08/01 21:18:55 steve
|
||||
* elaborate rise/fall/decay for continuous assign.
|
||||
*
|
||||
* Revision 1.16 1999/07/31 19:14:47 steve
|
||||
* Add functions up to elaboration (Ed Carter)
|
||||
*
|
||||
* Revision 1.15 1999/07/22 02:05:20 steve
|
||||
* is_constant method for PEConcat.
|
||||
*
|
||||
* Revision 1.14 1999/07/17 19:50:59 steve
|
||||
* netlist support for ternary operator.
|
||||
*
|
||||
* Revision 1.13 1999/06/16 03:13:29 steve
|
||||
* More syntax parse with sorry stubs.
|
||||
*
|
||||
* Revision 1.12 1999/06/15 02:50:02 steve
|
||||
* Add lexical support for real numbers.
|
||||
*
|
||||
* Revision 1.11 1999/06/10 04:03:52 steve
|
||||
* Add support for the Ternary operator,
|
||||
* Add support for repeat concatenation,
|
||||
* Correct some seg faults cause by elaboration
|
||||
* errors,
|
||||
* Parse the casex anc casez statements.
|
||||
*
|
||||
* Revision 1.10 1999/06/09 03:00:05 steve
|
||||
* Add support for procedural concatenation expression.
|
||||
*
|
||||
* Revision 1.9 1999/05/16 05:08:42 steve
|
||||
* Redo constant expression detection to happen
|
||||
* after parsing.
|
||||
*
|
||||
* Parse more operators and expressions.
|
||||
*
|
||||
* Revision 1.8 1999/05/10 00:16:57 steve
|
||||
* Parse and elaborate the concatenate operator
|
||||
* in structural contexts, Replace vector<PExpr*>
|
||||
* and list<PExpr*> with svector<PExpr*>, evaluate
|
||||
* constant expressions with parameters, handle
|
||||
* memories as lvalues.
|
||||
*
|
||||
* Parse task declarations, integer types.
|
||||
*
|
||||
* Revision 1.7 1999/05/01 02:57:52 steve
|
||||
* Handle much more complex event expressions.
|
||||
*
|
||||
* Revision 1.6 1999/04/29 02:16:26 steve
|
||||
* Parse OR of event expressions.
|
||||
*
|
||||
* Revision 1.5 1999/04/19 01:59:36 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.4 1998/11/11 00:01:51 steve
|
||||
* Check net ranges in declarations.
|
||||
*
|
||||
* Revision 1.3 1998/11/09 18:55:33 steve
|
||||
* Add procedural while loops,
|
||||
* Parse procedural for loops,
|
||||
* Add procedural wait statements,
|
||||
* Add constant nodes,
|
||||
* Add XNOR logic gate,
|
||||
* Make vvm output look a bit prettier.
|
||||
*
|
||||
* Revision 1.2 1998/11/07 17:05:05 steve
|
||||
* Handle procedural conditional, and some
|
||||
* of the conditional expressions.
|
||||
*
|
||||
* Elaborate signals and identifiers differently,
|
||||
* allowing the netlist to hold signal information.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:28:54 steve
|
||||
* Introduce verilog to CVS.
|
||||
* Revision 1.51 2001/11/07 04:26:46 steve
|
||||
* elaborate_lnet uses scope instead of string path.
|
||||
*
|
||||
* Revision 1.50 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*/
|
||||
#endif
|
||||
|
||||
+21
-7
@@ -16,15 +16,18 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PFunction.cc,v 1.4 2001/01/13 22:20:08 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PFunction.cc,v 1.7 2004/05/31 23:34:36 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
#include "PTask.h"
|
||||
|
||||
PFunction::PFunction()
|
||||
: out_(0), ports_(0), statement_(0)
|
||||
PFunction::PFunction(perm_string name)
|
||||
: name_(name), ports_(0), statement_(0)
|
||||
{
|
||||
return_type_.type = PTF_NONE;
|
||||
}
|
||||
|
||||
PFunction::~PFunction()
|
||||
@@ -44,14 +47,25 @@ void PFunction::set_statement(Statement*s)
|
||||
statement_ = s;
|
||||
}
|
||||
|
||||
void PFunction::set_output(PWire*o)
|
||||
void PFunction::set_return(PTaskFuncArg t)
|
||||
{
|
||||
assert(out_ == 0);
|
||||
out_ = o;
|
||||
return_type_ = t;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PFunction.cc,v $
|
||||
* Revision 1.7 2004/05/31 23:34:36 steve
|
||||
* Rewire/generalize parsing an elaboration of
|
||||
* function return values to allow for better
|
||||
* speed and more type support.
|
||||
*
|
||||
* Revision 1.6 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.5 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.4 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2004 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
|
||||
@@ -16,16 +16,18 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PGate.cc,v 1.9 2000/05/06 15:41:56 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PGate.cc,v 1.16 2004/02/18 17:11:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PGate.h"
|
||||
# include "PExpr.h"
|
||||
# include "verinum.h"
|
||||
# include <assert.h>
|
||||
|
||||
PGate::PGate(const string&name,
|
||||
PGate::PGate(perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
const svector<PExpr*>*del)
|
||||
: name_(name), pins_(pins)
|
||||
@@ -35,7 +37,7 @@ PGate::PGate(const string&name,
|
||||
str1_ = STRONG;
|
||||
}
|
||||
|
||||
PGate::PGate(const string&name,
|
||||
PGate::PGate(perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
PExpr*del)
|
||||
: name_(name), pins_(pins)
|
||||
@@ -45,7 +47,7 @@ PGate::PGate(const string&name,
|
||||
str1_ = STRONG;
|
||||
}
|
||||
|
||||
PGate::PGate(const string&name, svector<PExpr*>*pins)
|
||||
PGate::PGate(perm_string name, svector<PExpr*>*pins)
|
||||
: name_(name), pins_(pins)
|
||||
{
|
||||
str0_ = STRONG;
|
||||
@@ -88,22 +90,22 @@ void PGate::elaborate_scope(Design*, NetScope*) const
|
||||
* parameters. This method understands how to handle the different
|
||||
* numbers of expressions.
|
||||
*/
|
||||
void PGate::eval_delays(Design*des, const string&path,
|
||||
void PGate::eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const
|
||||
{
|
||||
delay_.eval_delays(des, path, rise_time, fall_time, decay_time);
|
||||
delay_.eval_delays(des, scope, rise_time, fall_time, decay_time);
|
||||
}
|
||||
|
||||
PGAssign::PGAssign(svector<PExpr*>*pins)
|
||||
: PGate("", pins)
|
||||
: PGate(perm_string(), pins)
|
||||
{
|
||||
assert(pins->count() == 2);
|
||||
}
|
||||
|
||||
PGAssign::PGAssign(svector<PExpr*>*pins, svector<PExpr*>*dels)
|
||||
: PGate("", pins, dels)
|
||||
: PGate(perm_string(), pins, dels)
|
||||
{
|
||||
assert(pins->count() == 2);
|
||||
}
|
||||
@@ -112,14 +114,14 @@ PGAssign::~PGAssign()
|
||||
{
|
||||
}
|
||||
|
||||
PGBuiltin::PGBuiltin(Type t, const string&name,
|
||||
PGBuiltin::PGBuiltin(Type t, perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
svector<PExpr*>*del)
|
||||
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PGBuiltin::PGBuiltin(Type t, const string&name,
|
||||
PGBuiltin::PGBuiltin(Type t, perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
PExpr*del)
|
||||
: PGate(name, pins, del), type_(t), msb_(0), lsb_(0)
|
||||
@@ -140,16 +142,22 @@ void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
|
||||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
PGModule::PGModule(const string&type, const string&name, svector<PExpr*>*pins)
|
||||
: PGate(name, pins), type_(type), overrides_(0), pins_(0),
|
||||
PGModule::PGModule(perm_string type, perm_string name, svector<PExpr*>*pins)
|
||||
: PGate(name, pins), overrides_(0), pins_(0),
|
||||
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
PGModule::PGModule(const string&type, const string&name,
|
||||
PGModule::PGModule(perm_string type, perm_string name,
|
||||
named<PExpr*>*pins, unsigned npins)
|
||||
: PGate(name, 0), type_(type), overrides_(0), pins_(pins),
|
||||
: PGate(name, 0), overrides_(0), pins_(pins),
|
||||
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
PGModule::~PGModule()
|
||||
{
|
||||
}
|
||||
|
||||
@@ -176,8 +184,35 @@ void PGModule::set_range(PExpr*msb, PExpr*lsb)
|
||||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
perm_string PGModule::get_type()
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PGate.cc,v $
|
||||
* Revision 1.16 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.15 2003/03/06 04:37:12 steve
|
||||
* lex_strings.add module names earlier.
|
||||
*
|
||||
* Revision 1.14 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.13 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.12 2001/10/21 00:42:47 steve
|
||||
* Module types in pform are char* instead of string.
|
||||
*
|
||||
* Revision 1.11 2001/10/19 01:55:32 steve
|
||||
* Method to get the type_ member
|
||||
*
|
||||
* Revision 1.10 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.9 2000/05/06 15:41:56 steve
|
||||
* Carry assignment strength to pform.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PGate_H
|
||||
#define __PGate_H
|
||||
/*
|
||||
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2004 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,11 +18,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PGate.h,v 1.18 2000/05/06 15:41:56 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PGate.h,v 1.29 2004/10/04 01:10:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include "named.h"
|
||||
# include "LineInfo.h"
|
||||
# include "PDelays.h"
|
||||
@@ -49,23 +50,23 @@ class Module;
|
||||
* strength of the 1 drive.
|
||||
*/
|
||||
class PGate : public LineInfo {
|
||||
|
||||
|
||||
public:
|
||||
enum strength_t { HIGHZ, WEAK, PULL, STRONG, SUPPLY };
|
||||
|
||||
explicit PGate(const string&name, svector<PExpr*>*pins,
|
||||
explicit PGate(perm_string name, svector<PExpr*>*pins,
|
||||
const svector<PExpr*>*del);
|
||||
|
||||
explicit PGate(const string&name, svector<PExpr*>*pins,
|
||||
explicit PGate(perm_string name, svector<PExpr*>*pins,
|
||||
PExpr*del);
|
||||
|
||||
explicit PGate(const string&name, svector<PExpr*>*pins);
|
||||
explicit PGate(perm_string name, svector<PExpr*>*pins);
|
||||
|
||||
virtual ~PGate();
|
||||
|
||||
const string& get_name() const { return name_; }
|
||||
perm_string get_name() const { return name_; }
|
||||
|
||||
void eval_delays(Design*des, const string&path,
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const;
|
||||
@@ -79,21 +80,21 @@ class PGate : public LineInfo {
|
||||
void strength0(strength_t);
|
||||
void strength1(strength_t);
|
||||
|
||||
map<string,string> attributes;
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*des, const string&path) const;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
protected:
|
||||
const svector<PExpr*>* get_pins() const { return pins_; }
|
||||
const svector<PExpr*>& get_pins() const { return *pins_; }
|
||||
|
||||
void dump_pins(ostream&out) const;
|
||||
void dump_delays(ostream&out) const;
|
||||
|
||||
private:
|
||||
const string name_;
|
||||
perm_string name_;
|
||||
PDelays delay_;
|
||||
svector<PExpr*>*pins_;
|
||||
|
||||
@@ -116,7 +117,7 @@ class PGAssign : public PGate {
|
||||
~PGAssign();
|
||||
|
||||
void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*des, const string&path) const;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
};
|
||||
@@ -141,10 +142,10 @@ class PGBuiltin : public PGate {
|
||||
TRANIF1, RTRANIF0, RTRANIF1 };
|
||||
|
||||
public:
|
||||
explicit PGBuiltin(Type t, const string&name,
|
||||
explicit PGBuiltin(Type t, perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
svector<PExpr*>*del);
|
||||
explicit PGBuiltin(Type t, const string&name,
|
||||
explicit PGBuiltin(Type t, perm_string name,
|
||||
svector<PExpr*>*pins,
|
||||
PExpr*del);
|
||||
~PGBuiltin();
|
||||
@@ -153,7 +154,7 @@ class PGBuiltin : public PGate {
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*, const string&path) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
Type type_;
|
||||
@@ -171,17 +172,21 @@ class PGBuiltin : public PGate {
|
||||
class PGModule : public PGate {
|
||||
|
||||
public:
|
||||
// The name is the *instance* name of the gate.
|
||||
|
||||
// If the binding of ports is by position, this constructor
|
||||
// builds everything all at once.
|
||||
explicit PGModule(const string&type, const string&name,
|
||||
explicit PGModule(perm_string type, perm_string name,
|
||||
svector<PExpr*>*pins);
|
||||
|
||||
// If the binding of ports is by name, this constructor takes
|
||||
// the bindings and stores them for later elaboration.
|
||||
explicit PGModule(const string&type, const string&name,
|
||||
explicit PGModule(perm_string type, perm_string name,
|
||||
named<PExpr*>*pins, unsigned npins);
|
||||
|
||||
|
||||
~PGModule();
|
||||
|
||||
// Parameter overrides can come as an ordered list, or a set
|
||||
// of named expressions.
|
||||
void set_parameters(svector<PExpr*>*o);
|
||||
@@ -192,12 +197,16 @@ class PGModule : public PGate {
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*, const string&path) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
// This returns the module name of this module. It is a
|
||||
// permallocated string.
|
||||
perm_string get_type();
|
||||
|
||||
private:
|
||||
string type_;
|
||||
perm_string type_;
|
||||
svector<PExpr*>*overrides_;
|
||||
named<PExpr*>*pins_;
|
||||
unsigned npins_;
|
||||
@@ -210,15 +219,52 @@ class PGModule : public PGate {
|
||||
PExpr*msb_;
|
||||
PExpr*lsb_;
|
||||
|
||||
void elaborate_mod_(Design*, Module*mod, const string&path) const;
|
||||
void elaborate_sudp_(Design*, PUdp *udp, const string&path) const;
|
||||
void elaborate_cudp_(Design*, PUdp *udp, const string&path) const;
|
||||
void elaborate_mod_(Design*, Module*mod, NetScope*scope) const;
|
||||
void elaborate_udp_(Design*, PUdp *udp, NetScope*scope) const;
|
||||
void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const;
|
||||
bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: PGate.h,v $
|
||||
* Revision 1.29 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.28 2004/03/08 00:47:44 steve
|
||||
* primitive ports can bind bi name.
|
||||
*
|
||||
* Revision 1.27 2004/02/20 18:53:33 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.26 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.25 2003/03/06 04:37:12 steve
|
||||
* lex_strings.add module names earlier.
|
||||
*
|
||||
* Revision 1.24 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.23 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.22 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.21 2001/10/21 00:42:47 steve
|
||||
* Module types in pform are char* instead of string.
|
||||
*
|
||||
* Revision 1.20 2001/10/19 01:55:32 steve
|
||||
* Method to get the type_ member
|
||||
*
|
||||
* Revision 1.19 2001/04/22 23:09:45 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.18 2000/05/06 15:41:56 steve
|
||||
* Carry assignment strength to pform.
|
||||
*
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PTask.cc,v 1.4 2001/01/13 22:20:08 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PTask.cc,v 1.7 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PTask.h"
|
||||
|
||||
PTask::PTask()
|
||||
@@ -40,13 +42,22 @@ void PTask::set_ports(svector<PWire*>*p)
|
||||
void PTask::set_statement(Statement*s)
|
||||
{
|
||||
assert(statement_ == 0);
|
||||
assert(s != 0);
|
||||
statement_ = s;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: PTask.cc,v $
|
||||
* Revision 1.7 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.6 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.5 2001/04/19 03:04:47 steve
|
||||
* Spurious assert of empty statemnt.
|
||||
*
|
||||
* Revision 1.4 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
|
||||
@@ -18,17 +18,33 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PTask.h,v 1.10 2001/01/13 22:20:08 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PTask.h,v 1.13 2004/05/31 23:34:36 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include <string>
|
||||
class Design;
|
||||
class NetScope;
|
||||
class PWire;
|
||||
class Statement;
|
||||
class PExpr;
|
||||
|
||||
enum PTaskFuncEnum {
|
||||
PTF_NONE,
|
||||
PTF_REG,
|
||||
PTF_INTEGER,
|
||||
PTF_REAL,
|
||||
PTF_REALTIME,
|
||||
PTF_TIME
|
||||
};
|
||||
|
||||
struct PTaskFuncArg {
|
||||
PTaskFuncEnum type;
|
||||
svector<PExpr*>*range;
|
||||
};
|
||||
|
||||
/*
|
||||
* The PTask holds the parsed definitions of a task.
|
||||
@@ -52,7 +68,7 @@ class PTask : public LineInfo {
|
||||
void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
// Elaborate the statement to finish off the task definition.
|
||||
void elaborate(Design*des, const string&path) const;
|
||||
void elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
void dump(ostream&, unsigned) const;
|
||||
|
||||
@@ -69,16 +85,18 @@ class PTask : public LineInfo {
|
||||
* The function is similar to a task (in this context) but there is a
|
||||
* single output port and a set of input ports. The output port is the
|
||||
* function return value.
|
||||
*
|
||||
* The output value is not elaborated until elaborate_sig.
|
||||
*/
|
||||
class PFunction : public LineInfo {
|
||||
|
||||
public:
|
||||
explicit PFunction();
|
||||
explicit PFunction(perm_string name);
|
||||
~PFunction();
|
||||
|
||||
void set_ports(svector<PWire *>*p);
|
||||
void set_statement(Statement *s);
|
||||
void set_output(PWire*);
|
||||
void set_return(PTaskFuncArg t);
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
@@ -91,13 +109,25 @@ class PFunction : public LineInfo {
|
||||
void dump(ostream&, unsigned) const;
|
||||
|
||||
private:
|
||||
PWire*out_;
|
||||
perm_string name_;
|
||||
PTaskFuncArg return_type_;
|
||||
svector<PWire *> *ports_;
|
||||
Statement *statement_;
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: PTask.h,v $
|
||||
* Revision 1.13 2004/05/31 23:34:36 steve
|
||||
* Rewire/generalize parsing an elaboration of
|
||||
* function return values to allow for better
|
||||
* speed and more type support.
|
||||
*
|
||||
* Revision 1.12 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.11 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.10 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PUdp.cc,v 1.3 2004/03/08 00:47:44 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "PUdp.h"
|
||||
|
||||
PUdp::PUdp(perm_string n, unsigned nports)
|
||||
: ports(nports), sequential(false), initial(verinum::Vx), name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
unsigned PUdp::find_port(const char*name)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
|
||||
if (ports[idx] == name)
|
||||
return idx;
|
||||
}
|
||||
|
||||
return ports.count();
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PUdp.cc,v $
|
||||
* Revision 1.3 2004/03/08 00:47:44 steve
|
||||
* primitive ports can bind bi name.
|
||||
*
|
||||
* Revision 1.2 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.1 2003/07/15 05:07:13 steve
|
||||
* Move PUdp constructor into compiled file.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef __PUdp_H
|
||||
#define __PUdp_H
|
||||
/*
|
||||
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2004 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,25 +18,22 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PUdp.h,v 1.4 2000/02/23 02:56:53 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PUdp.h,v 1.12 2004/03/08 00:47:44 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <map>
|
||||
# include "StringHeap.h"
|
||||
# include "svector.h"
|
||||
# include <string>
|
||||
# include "verinum.h"
|
||||
|
||||
svector<string>::svector<string>(unsigned size)
|
||||
: nitems_(size), items_(new string[size])
|
||||
{
|
||||
}
|
||||
class PExpr;
|
||||
|
||||
/*
|
||||
* This class represents a parsed UDP. This is a much simpler object
|
||||
* then a module or macromodule.
|
||||
*
|
||||
* - all ports are scaler,
|
||||
* - all ports are scalar,
|
||||
* - pin 0 (the first port) is always output,
|
||||
* and the remaining pins are input.
|
||||
*
|
||||
@@ -51,15 +48,16 @@ svector<string>::svector<string>(unsigned size)
|
||||
* the current output.
|
||||
*
|
||||
* If the UDP is sequential, the "initial" member is taken to be the
|
||||
* intial value assigned in the source, or 'x' if none is given.
|
||||
* initial value assigned in the source, or 'x' if none is given.
|
||||
*/
|
||||
class PUdp {
|
||||
|
||||
public:
|
||||
explicit PUdp(const string&n, unsigned nports)
|
||||
: ports(nports), sequential(false), initial(verinum::Vx), name_(n) { }
|
||||
explicit PUdp(perm_string n, unsigned nports);
|
||||
|
||||
svector<string>ports;
|
||||
unsigned find_port(const char*name);
|
||||
|
||||
bool sequential;
|
||||
|
||||
svector<string>tinput;
|
||||
@@ -68,12 +66,12 @@ class PUdp {
|
||||
|
||||
verinum::V initial;
|
||||
|
||||
map<string,string> attributes;
|
||||
map<string,PExpr*> attributes;
|
||||
|
||||
void dump(ostream&out) const;
|
||||
|
||||
perm_string name_;
|
||||
private:
|
||||
const string name_;
|
||||
|
||||
private: // Not implemented
|
||||
PUdp(const PUdp&);
|
||||
@@ -82,6 +80,35 @@ class PUdp {
|
||||
|
||||
/*
|
||||
* $Log: PUdp.h,v $
|
||||
* Revision 1.12 2004/03/08 00:47:44 steve
|
||||
* primitive ports can bind bi name.
|
||||
*
|
||||
* Revision 1.11 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.10 2003/07/15 05:07:13 steve
|
||||
* Move PUdp constructor into compiled file.
|
||||
*
|
||||
* Revision 1.9 2003/07/15 03:49:22 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.8 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.7 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.6 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.5 2001/04/22 23:09:45 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.4 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
||||
@@ -16,16 +16,34 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PWire.cc,v 1.5 2001/01/06 02:29:35 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PWire.cc,v 1.10 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "PWire.h"
|
||||
# include <assert.h>
|
||||
|
||||
PWire::PWire(const string&n, NetNet::Type t, NetNet::PortType pt)
|
||||
: name_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0)
|
||||
PWire::PWire(const hname_t&n, NetNet::Type t, NetNet::PortType pt)
|
||||
: hname_(n), type_(t), port_type_(pt), signed_(false), isint_(false),
|
||||
lidx_(0), ridx_(0)
|
||||
{
|
||||
if (t == NetNet::INTEGER) {
|
||||
type_ = NetNet::REG;
|
||||
signed_ = true;
|
||||
isint_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
PWire::PWire(char*n, NetNet::Type t, NetNet::PortType pt)
|
||||
: hname_(n), type_(t), port_type_(pt), signed_(false), isint_(false),
|
||||
lidx_(0), ridx_(0)
|
||||
{
|
||||
if (t == NetNet::INTEGER) {
|
||||
type_ = NetNet::REG;
|
||||
signed_ = true;
|
||||
isint_ = true;
|
||||
}
|
||||
}
|
||||
|
||||
NetNet::Type PWire::get_wire_type() const
|
||||
@@ -33,6 +51,11 @@ NetNet::Type PWire::get_wire_type() const
|
||||
return type_;
|
||||
}
|
||||
|
||||
const hname_t& PWire::path() const
|
||||
{
|
||||
return hname_;
|
||||
}
|
||||
|
||||
bool PWire::set_wire_type(NetNet::Type t)
|
||||
{
|
||||
assert(t != NetNet::IMPLICIT);
|
||||
@@ -45,6 +68,10 @@ bool PWire::set_wire_type(NetNet::Type t)
|
||||
if (t == NetNet::REG) { type_ = t; return true; }
|
||||
return false;
|
||||
case NetNet::REG:
|
||||
if (t == NetNet::INTEGER) {
|
||||
isint_ = true;
|
||||
return true;
|
||||
}
|
||||
if (t == NetNet::REG) return true;
|
||||
return false;
|
||||
default:
|
||||
@@ -91,6 +118,11 @@ bool PWire::get_signed() const
|
||||
return signed_;
|
||||
}
|
||||
|
||||
bool PWire::get_isint() const
|
||||
{
|
||||
return isint_;
|
||||
}
|
||||
|
||||
void PWire::set_range(PExpr*m, PExpr*l)
|
||||
{
|
||||
msb_ = svector<PExpr*>(msb_,m);
|
||||
@@ -108,6 +140,23 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
|
||||
|
||||
/*
|
||||
* $Log: PWire.cc,v $
|
||||
* Revision 1.10 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.9 2002/06/21 04:59:35 steve
|
||||
* Carry integerness throughout the compilation.
|
||||
*
|
||||
* Revision 1.8 2002/01/26 05:28:28 steve
|
||||
* Detect scalar/vector declarion mismatch.
|
||||
*
|
||||
* Revision 1.7 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.6 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.5 2001/01/06 02:29:35 steve
|
||||
* Support arrays of integers.
|
||||
*
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PWire.h,v 1.10 2001/01/16 02:44:18 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PWire.h,v 1.17 2004/02/20 18:53:33 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
@@ -38,16 +38,22 @@ class Design;
|
||||
|
||||
/*
|
||||
* Wires include nets, registers and ports. A net or register becomes
|
||||
* a port by declaration, so ports are not seperate. The module
|
||||
* a port by declaration, so ports are not separate. The module
|
||||
* identifies a port by keeping it in its port list.
|
||||
*
|
||||
* The hname parameter to the constructor is a hierarchical name. It
|
||||
* is an array of strings starting with the root, running towards
|
||||
* the base name, and terminated by a null pointer. The environment
|
||||
* allocates the memory for me.
|
||||
*/
|
||||
class PWire : public LineInfo {
|
||||
|
||||
public:
|
||||
PWire(const string&n, NetNet::Type t, NetNet::PortType pt);
|
||||
PWire(const hname_t&hname, NetNet::Type t, NetNet::PortType pt);
|
||||
PWire(char*name, NetNet::Type t, NetNet::PortType pt);
|
||||
|
||||
|
||||
const string&name() const { return name_; }
|
||||
// Return a hierarchical name.
|
||||
const hname_t&path() const;
|
||||
|
||||
NetNet::Type get_wire_type() const;
|
||||
bool set_wire_type(NetNet::Type);
|
||||
@@ -57,12 +63,13 @@ class PWire : public LineInfo {
|
||||
|
||||
void set_signed(bool flag);
|
||||
bool get_signed() const;
|
||||
bool get_isint() const;
|
||||
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
void set_memory_idx(PExpr*ldx, PExpr*rdx);
|
||||
|
||||
map<string,string> attributes;
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
// Write myself to the specified stream.
|
||||
void dump(ostream&out) const;
|
||||
@@ -70,10 +77,11 @@ class PWire : public LineInfo {
|
||||
void elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
hname_t hname_;
|
||||
NetNet::Type type_;
|
||||
NetNet::PortType port_type_;
|
||||
bool signed_;
|
||||
bool isint_; // original type of integer
|
||||
|
||||
// These members hold expressions for the bit width of the
|
||||
// wire. If they do not exist, the wire is 1 bit wide.
|
||||
@@ -92,6 +100,34 @@ class PWire : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: PWire.h,v $
|
||||
* Revision 1.17 2004/02/20 18:53:33 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.16 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.15 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
* Revision 1.14 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.13 2002/06/21 04:59:35 steve
|
||||
* Carry integerness throughout the compilation.
|
||||
*
|
||||
* Revision 1.12 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.11 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.10 2001/01/16 02:44:18 steve
|
||||
* Use the iosfwd header if available.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
|
||||
* Getting Started with Icarus Verilog
|
||||
|
||||
Icarus Verilog is a Verilog compiler. It is suitable for use as a
|
||||
simulator, and, to some degree, synthesizer. Icarus Verilog runs under
|
||||
Linux and a variety of UNIX systems, as well as Windows as a command
|
||||
line tool, so the instructions are generally applicable to all
|
||||
environments. Note that this is only a quick start. For more detailed
|
||||
documentation, see the manual page for the iverilog command.
|
||||
|
||||
|
||||
* Hello, World!
|
||||
|
||||
The first thing you want to do as a user is learn how to compile and
|
||||
execute even the most trivial design. For the purposes of simulation,
|
||||
we use as our example *the* most trivial simulation:
|
||||
|
||||
module main;
|
||||
|
||||
initial
|
||||
begin
|
||||
$display("Hello, World");
|
||||
$finish ;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
By a text editor (or copy hello.vl from the Icarus Verilog examples
|
||||
directory) arrange for this program to be in a text file, "hello.vl".
|
||||
Next, compile this program with a command like this:
|
||||
|
||||
% iverilog -o hello hello.vl
|
||||
|
||||
The results of this compile are placed into the file "hello", as the
|
||||
"-o" flag tells the compiler where to place the compiled result. Next,
|
||||
execute the compiled program like so:
|
||||
|
||||
% vvp hello
|
||||
Hello, World
|
||||
|
||||
And there it is, the program has been executed. So what happened? The
|
||||
first step, the "iverilog" command, read and interpreted the source
|
||||
file, then generated a compiled result. The compiled form may be
|
||||
selected by command line switches, but the default form is the VVP
|
||||
format, which is actually run by the "vvp" command.
|
||||
|
||||
The "iverilog" and "vvp" commands are the only commands that users
|
||||
use to invoke Icarus Verilog. What the compiler actually does is
|
||||
controlled by command line switches. In our little example, we asked
|
||||
the compiler to compile the source program to the default vvp form,
|
||||
which is in turn executed by the vvp program.
|
||||
|
||||
|
||||
* Windows Install
|
||||
|
||||
The easiest way to install under Windows is to get a precompiled
|
||||
installer for the version you wish to install. Icarus Verilog is
|
||||
distributed for Windows users as a self-installing .exe. Just execute
|
||||
the installer and follow the instructions. During the install, take
|
||||
note of the directory where the program is installed: for example,
|
||||
C:\iverilog is a good place to install.
|
||||
|
||||
Once the binary is installed, you need to add the bin directory to
|
||||
your execution path. The executables you need are in C:\iverilog\bin,
|
||||
where the "C:\iverilog" part is actually the root of where you
|
||||
installed the package. The programs are in the bin subdirectory. Put
|
||||
this directory in your PATH environment variable, and the above
|
||||
commands become accessible to you at the command line prompt, or even
|
||||
in batch files.
|
||||
|
||||
|
||||
* Linux Install
|
||||
|
||||
Under Linux, the install is even easier. For RedHat and Mandrake based
|
||||
systems, there is the appropriate RPM file. Just install the package
|
||||
with the "rpm -U <file>" command. Debian users should get Icarus
|
||||
Verilog packages from the main Debian software site.
|
||||
|
||||
|
||||
* Install From Source
|
||||
|
||||
In this case, see README.txt and other documentation that comes with
|
||||
the source.
|
||||
+261
-153
@@ -1,5 +1,5 @@
|
||||
THE ICARUS VERILOG COMPILATION SYSTEM
|
||||
September 17, 2000
|
||||
THE ICARUS VERILOG COMPILATION SYSTEM
|
||||
Copyright 2000-2003 Stephen Williams
|
||||
|
||||
|
||||
1.0 What is ICARUS Verilog?
|
||||
@@ -9,15 +9,18 @@ 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>.
|
||||
|
||||
|
||||
Icarus Verilog is not aimed at being a simulator in the traditional
|
||||
sense, but a compiler that generates code employed by back-end
|
||||
tools. These back- end tools currently include a simulator written in
|
||||
C++ called VVM and an XNF (Xilinx Netlist Format) generator. See
|
||||
"vvm.txt" and "xnf.txt" for further details on these back-end
|
||||
processors. In the future, backends are expected for EDIF/LPM,
|
||||
tools. These back-end tools currently include a simulator engine
|
||||
called VVP, an XNF (Xilinx Netlist Format) generator and an EDIF FPGA
|
||||
netlist generator. In the future, backends are expected for EDIF/LPM,
|
||||
structural Verilog, VHDL, etc.
|
||||
|
||||
For instructions on how to run Icarus Verilog,
|
||||
see the ``iverilog'' man page.
|
||||
|
||||
|
||||
2.0 Building/Installing Icarus Verilog From Source
|
||||
|
||||
If you are starting from source, the build process is designed to be
|
||||
@@ -26,15 +29,17 @@ system and C/C++ compilation should be able to build the source
|
||||
distribution with little effort. Some actual programming skills are
|
||||
not required, but helpful in case of problems.
|
||||
|
||||
If you are building for Windows, see the mingw.txt file.
|
||||
|
||||
2.1 Compile Time Prerequisites
|
||||
|
||||
You need the following software to compile Icarus Verilog from source
|
||||
on a UNIX-like system:
|
||||
|
||||
- GNU Make
|
||||
The Makefiles use some GNU extensions to, so a basic POSIX
|
||||
The Makefiles use some GNU extensions, so a basic POSIX
|
||||
make will not work. Linux systems typically come with a
|
||||
satisfactory make. BSD based systems (i.e. NetBSD, FreeBSD)
|
||||
satisfactory make. BSD based systems (i.e., NetBSD, FreeBSD)
|
||||
typically have GNU make as the gmake program.
|
||||
|
||||
- ISO C++ Compiler
|
||||
@@ -54,6 +59,22 @@ on a UNIX-like system:
|
||||
A version problem with this program is the most common cause
|
||||
of difficulty. See the Icarus Verilog FAQ.
|
||||
|
||||
- readline 4.2
|
||||
On Linux systems, this usually means the readline-devel
|
||||
rpm. In any case, it is the development headers of readline
|
||||
that are needed.
|
||||
|
||||
- termcap
|
||||
The readline library in turn uses termcap.
|
||||
|
||||
If you are building from CVS, you will also need software to generate
|
||||
the configure scripts.
|
||||
|
||||
- autoconf 2.53
|
||||
This generates configure scripts from configure.in. The 2.53
|
||||
or later versions are known to work, autoconf 2.13 is
|
||||
reported to *not* work.
|
||||
|
||||
2.2 Compilation
|
||||
|
||||
Unpack the tar-ball and cd into the verilog-######### directory
|
||||
@@ -63,15 +84,70 @@ with the commands:
|
||||
./configure
|
||||
make
|
||||
|
||||
2.3 Installation
|
||||
Normally, this command automatically figures out everything it needs
|
||||
to know. It generally works pretty well. There are a few flags to the
|
||||
configure script that modify its behavior:
|
||||
|
||||
--without-ipal
|
||||
This turns off support for Icarus PAL, whether ipal
|
||||
libraries are installed or not.
|
||||
|
||||
--prefix=<root>
|
||||
The default is /usr/local, which causes the tool suite to
|
||||
be compiled for install in /usr/local/bin,
|
||||
/usr/local/share/ivl, etc.
|
||||
|
||||
I recommend that if you are configuring for precompiled
|
||||
binaries, use --prefix=/usr. On Solaris systems, it is
|
||||
common to use --prefix=/opt. You can configure for a non-root
|
||||
install with --prefix=$HOME.
|
||||
|
||||
--enable-vvp32 (experimental)
|
||||
If compiling on AMD64 systems, this enables the
|
||||
compilation of 32bit compatible vvp (vvp32) and the vpi
|
||||
modules that match.
|
||||
|
||||
2.2.1 Special AMD64 Instructions
|
||||
|
||||
(The Icarus Verilog RPM for x86_64 is build using these instructions.)
|
||||
|
||||
If you are building for Linux/AMD64 (a.k.a x86_64) then to get the
|
||||
most out of your install, first make sure you have both 64bit and
|
||||
32bit development libraries installed. Then configure with this
|
||||
somewhat more compilcated command:
|
||||
|
||||
./configure libdir64='$(prefix)/lib64' vpidir1=vpi64 vpidir2=. --enable-vvp32
|
||||
|
||||
This reflects the convention on AMD64 systems that 64bit libraries go
|
||||
into lib64 directories. The "--enable-vvp32" also turns on 32bit
|
||||
compatibility files. A 32bit version of vvp (vvp32) will be created,
|
||||
as well as 32bit versions of the development libraries and bundled VPI
|
||||
libraries.
|
||||
|
||||
2.3 (Optional) Testing
|
||||
|
||||
To run a simple test before installation, execute
|
||||
|
||||
make check
|
||||
|
||||
The commands printed by this run might help you in running Icarus
|
||||
Verilog on your own Verilog sources before the package is installed
|
||||
by root.
|
||||
|
||||
2.4 Installation
|
||||
|
||||
Now install the files in an appropriate place. (The makefiles by
|
||||
default install in /usr/local unless you specify a different prefix
|
||||
with the --prefix=<path> flag to the configure command.) Do this as
|
||||
root.
|
||||
with the --prefix=<path> flag to the configure command.) You may need
|
||||
to do this as root to gain access to installation directories.
|
||||
|
||||
make install
|
||||
|
||||
2.5 Uninstallation
|
||||
|
||||
The generated Makefiles also include the uninstall target. This should
|
||||
remove all the files that ``make install'' creates.
|
||||
|
||||
3.0 How Icarus Verilog Works
|
||||
|
||||
This tool includes a parser which reads in Verilog (plus extensions)
|
||||
@@ -91,15 +167,15 @@ only sees a single input file. See ivlpp/ivlpp.txt for details.
|
||||
|
||||
3.2 Parse
|
||||
|
||||
The verilog compiler starts by parsing the verilog source file. The
|
||||
output of the parse in a list of Module objects in PFORM. The pform
|
||||
The Verilog compiler starts by parsing the Verilog source file. The
|
||||
output of the parse is a list of Module objects in "pform". The pform
|
||||
(see pform.h) is mostly a direct reflection of the compilation
|
||||
step. There may be dangling references, and it is not yet clear which
|
||||
module is the root.
|
||||
|
||||
One can see a human readable version of the final PFORM by using the
|
||||
One can see a human readable version of the final pform by using the
|
||||
``-P <path>'' flag to the compiler. This will cause iverilog to dump
|
||||
the PFORM into the file named <path>.
|
||||
the pform into the file named <path>.
|
||||
|
||||
3.3 Elaboration
|
||||
|
||||
@@ -114,10 +190,10 @@ The elaborate() function performs the elaboration.
|
||||
|
||||
One can see a human readable version of the final, elaborated and
|
||||
optimized netlist by using the ``-N <path>'' flag to the compiler. If
|
||||
elaboration succeeds, the final netlist (i.e. after optimizations but
|
||||
elaboration succeeds, the final netlist (i.e., after optimizations but
|
||||
before code generation) will be dumped into the file named <path>.
|
||||
|
||||
Elaboration is actually performed it two steps: scopes and parameters
|
||||
Elaboration is actually performed in two steps: scopes and parameters
|
||||
first, followed by the structural and behavioral elaboration.
|
||||
|
||||
3.3.1 Scope Elaboration
|
||||
@@ -146,19 +222,19 @@ simply passing through the pform.
|
||||
|
||||
This is actually a collection of processing steps that perform
|
||||
optimizations that do not depend on the target technology. Examples of
|
||||
some useful transformations would be,
|
||||
some useful transformations are
|
||||
|
||||
- eliminate null effect circuitry,
|
||||
- eliminate null effect circuitry
|
||||
- combinational reduction
|
||||
- Constant propagation
|
||||
- constant propagation
|
||||
|
||||
The actual functions performed are specified on the ivl command line by
|
||||
the -F flags (See below).
|
||||
the -F flags (see below).
|
||||
|
||||
3.5 Code Generation
|
||||
|
||||
This step takes the design netlist and uses it to drive the code
|
||||
generator. (See target.h.) This may require transforming the
|
||||
generator (see target.h). This may require transforming the
|
||||
design to suit the technology.
|
||||
|
||||
The emit() method of the Design class performs this step. It runs
|
||||
@@ -170,7 +246,10 @@ command line.
|
||||
|
||||
3.6 ATTRIBUTES
|
||||
|
||||
The parser accepts as an extension to Verilog the $attribute module
|
||||
NOTE: The $attribute syntax will soon be deprecated in favor of the
|
||||
Verilog-2001 attribute syntax, which is cleaner and standardized.
|
||||
|
||||
The parser accepts, as an extension to Verilog, the $attribute module
|
||||
item. The syntax of the $attribute item is:
|
||||
|
||||
$attribute (<identifier>, <key>, <value>);
|
||||
@@ -198,6 +277,11 @@ between processing steps. Processing steps that are aware of others
|
||||
may place attributes on netlist objects to communicate information to
|
||||
later steps.
|
||||
|
||||
Icarus Verilog also accepts the Verilog 2001 syntax for
|
||||
attributes. They have the same general meaning as with the $attribute
|
||||
syntax, but they are attached to objects by position instead of by
|
||||
name. Also, the key is a Verilog identifier instead of a string.
|
||||
|
||||
4.0 Running iverilog
|
||||
|
||||
The preferred way to invoke the compiler is with the iverilog(1)
|
||||
@@ -205,89 +289,15 @@ command. This program invokes the preprocessor (ivlpp) and the
|
||||
compiler (ivl) with the proper command line options to get the job
|
||||
done in a friendly way. See the iverilog(1) man page for usage details.
|
||||
|
||||
4.1 Running IVL Directly (not recommended)
|
||||
|
||||
The ivl command is the compiler driver, that invokes the parser,
|
||||
optimization functions and the code generator, but not the preprocessor.
|
||||
|
||||
Usage: ivl <options>... file
|
||||
ivl -h
|
||||
|
||||
-F <name>
|
||||
Use this flag to request an optimization function be applied
|
||||
to the netlist before it is sent to the target output
|
||||
stage. Any number of -F options may be given, to specify a
|
||||
variety of processing steps. The steps will be applied in
|
||||
order, with the output of one uses as the input to the next.
|
||||
|
||||
The function is specified by name. Use the "ivl -h" command to
|
||||
get a list of configured function names.
|
||||
|
||||
-m <module>
|
||||
Cause a named VPI module to be included in the module
|
||||
list. This parameter appends the named module to the end of
|
||||
the VPI_MODULE_LIST. This is an ordered list of modules to be
|
||||
loaded into the simulation at runtime.
|
||||
|
||||
This list can also be set with -fVPI_MODULE_LIST=<list> which
|
||||
sets the list completely. Then, -m after this will append
|
||||
module names to the list sp specified. The default list
|
||||
includes "system".
|
||||
|
||||
-N <file>
|
||||
Dump the elaborated netlist to the named file. The netlist is
|
||||
the folly elaborated netlist, after all the function modules
|
||||
are applied and right before the output generator is
|
||||
called. This is an aid for debugging the compiler, and the
|
||||
output generator in particular.
|
||||
|
||||
-o <file>
|
||||
Normally, the generated result is sent to standard
|
||||
output. Use the -o flag to specify an output file for the
|
||||
generated result.
|
||||
|
||||
-P <file>
|
||||
Write the PForm of the parsed input to the specified file.
|
||||
The pform is the compiler's understanding of the input after
|
||||
parsing and before elaboration. This is an aid for debugging
|
||||
the compiler.
|
||||
|
||||
-p <assign>
|
||||
Use this flag to set a parameter value. The format of the
|
||||
assignment is <key>=<value> where key is any string up to the
|
||||
first '=', and <value> is the rest of the option. If the '='
|
||||
is omitted, then the key is assigned the empty string.
|
||||
|
||||
The useful keys are defined by the functions and the target in
|
||||
use. These assignments are specifically useful for passing
|
||||
target specific information to the target back-end, or
|
||||
options/parameters to optimization functions, if any are defined.
|
||||
|
||||
-s <module>
|
||||
Normally, ivl will elaborate the only module in the source
|
||||
file. If there are multiple modules, use this option to select
|
||||
the module to be used as the top-level module.
|
||||
|
||||
-T [min|typ|max]
|
||||
Normally, ivl will select typ values from min:type:max
|
||||
expressions and print a warning. This flag tells the compiler
|
||||
exactly which value to choose, and suppresses the warning.
|
||||
|
||||
-t <name>
|
||||
Select the output format for the compiled result. Use the
|
||||
"ivl -h" command to get a list of configured targets.
|
||||
|
||||
-v
|
||||
Print version and copyright information for ivl.
|
||||
|
||||
4.2 EXAMPLES
|
||||
4.1 EXAMPLES
|
||||
|
||||
Example: Compiling "hello.vl"
|
||||
|
||||
------------------------ hello.vl ----------------------------
|
||||
module main();
|
||||
|
||||
initial
|
||||
|
||||
initial
|
||||
begin
|
||||
$display("Hi there");
|
||||
$finish ;
|
||||
@@ -297,7 +307,7 @@ endmodule
|
||||
|
||||
--------------------------------------------------------------
|
||||
|
||||
Insure that "iverilog" is on your search path, and the vpi library
|
||||
Ensure that "iverilog" is on your search path, and the vpi library
|
||||
is available.
|
||||
|
||||
To compile the program:
|
||||
@@ -318,65 +328,156 @@ by the compiler. See the iverilog(1) man page.
|
||||
|
||||
Icarus Verilog is in development - as such it still only supports a
|
||||
(growing) subset of Verilog. Below is a description of some of the
|
||||
currently unsupported verilog features. This list is not exhaustive,
|
||||
currently unsupported Verilog features. This list is not exhaustive,
|
||||
and does not account for errors in the compiler. See the Icarus
|
||||
Verilog web page for the current state of support for Verilog, and in
|
||||
particular, browse the bug report database for reported unsupported
|
||||
constructs.
|
||||
|
||||
- block disable not supported, i.e.:
|
||||
|
||||
begin : foo
|
||||
[...]
|
||||
disable foo; // sorry
|
||||
[...]
|
||||
end
|
||||
|
||||
- Functions in structural contexts are not supported.
|
||||
|
||||
assign foo = user_function(a,b); // sorry
|
||||
always @(a or b) foo = user_function(a,b); // OK
|
||||
|
||||
- real data types not supported. This includes real and
|
||||
realtime. However, floating point constants in delay expressions
|
||||
are supported so that `timescale works properly.
|
||||
|
||||
- System functions are supported, but the compiler presumes that
|
||||
they return 32 bits. This is the typical case.
|
||||
- System functions are supported, but the return value is a little
|
||||
tricky. See SYSTEM FUNCTION TABLE FILES in the iverilog man page.
|
||||
|
||||
- Specify blocks are parsed but ignored in general.
|
||||
|
||||
- trireg is not supported. tri0 and tri1 are supported.
|
||||
|
||||
- tran primitives, i.e. tran, tranif1, tranif0, rtran, rtranif1
|
||||
and rtranif0 are not supported.
|
||||
|
||||
- Net delays, of the form "wire #N foo;" do not work. Delays in
|
||||
every other context do work properly, including the V2001 form
|
||||
"wire #5 foo = bar;"
|
||||
|
||||
- Event controls inside non-blocking assignments are not supported.
|
||||
i.e.: a <= @(posedge clk) b;
|
||||
|
||||
- Macro arguments are not supported. `define macros are supported,
|
||||
but they cannot take arguments.
|
||||
|
||||
5.1 Nonstandard Constructs or Behaviors
|
||||
|
||||
Icarus Verilog includes some features that are not part of the
|
||||
IEEE1364 standard, but have well defined meaning, and also sometimes
|
||||
gives nonstandard (but extended) meanings to some features of the
|
||||
language that are defined.
|
||||
|
||||
$is_signed(<expr>)
|
||||
This system function returns 1 if the expression contained is
|
||||
signed, or 0 otherwise. This is mostly of use for compiler
|
||||
regression tests.
|
||||
|
||||
$sizeof(<expr>)
|
||||
$bits(<expr>)
|
||||
The $bits system function returns the size in bits of the
|
||||
expression that is its argument. The result of this
|
||||
function is undefined if the argument doesn't have a
|
||||
self-determined size.
|
||||
|
||||
The $sizeof function is deprecated in favor of $bits, which is
|
||||
the same thing, but included in the SystemVerilog definition.
|
||||
|
||||
$simtime
|
||||
The $simtime system function returns as a 64bit value the
|
||||
simulation time, unscaled by the time units of local
|
||||
scope. This is different from the $time and $stime functions
|
||||
which return the scaled times. This function is added for
|
||||
regression testing of the compiler and run time, but can be
|
||||
used by applications who really want the simulation time.
|
||||
|
||||
Note that the simulation time can be confusing if there are
|
||||
lots of different `timescales within a design. It is not in
|
||||
general possible to predict what the simulation precision will
|
||||
turn out to be.
|
||||
|
||||
$mti_random()
|
||||
$mti_dist_uniform
|
||||
These functions are similar to the IEEE1364 standard $random
|
||||
functions, but they use the Mersenne Twister (MT19937)
|
||||
algorithm. This is considered an excellent random number
|
||||
generator, but does not generate the same sequence as the
|
||||
standardized $random.
|
||||
|
||||
Builtin system functions
|
||||
|
||||
Certain of the system functions have well defined meanings, so
|
||||
can theoretically be evaluated at compile time, instead of
|
||||
using runtime VPI code. Doing so means that VPI cannot
|
||||
override the definitions of functions handled in this
|
||||
manner. On the other hand, this makes them synthesizable, and
|
||||
also allows for more aggressive constant propagation. The
|
||||
functions handled in this manner are:
|
||||
|
||||
$bits
|
||||
$signed
|
||||
$sizeof
|
||||
$unsigned
|
||||
|
||||
Implementations of these system functions in VPI modules will
|
||||
be ignored.
|
||||
|
||||
Preprocessing Library Modules
|
||||
|
||||
Icarus Verilog does preprocess modules that are loaded from
|
||||
libraries via the -y mechanism. However, the only macros
|
||||
defined during compilation of that file are those that it
|
||||
defines itself (or includes) or that are defined on the
|
||||
command line or command file.
|
||||
|
||||
Specifically, macros defined in the non-library source files
|
||||
are not remembered when the library module is loaded. This is
|
||||
intentional. If it were otherwise, then compilation results
|
||||
might vary depending on the order that libraries are loaded,
|
||||
and that is too unpredictable.
|
||||
|
||||
It is said that some commercial compilers do allow macro
|
||||
definitions to span library modules. That's just plain weird.
|
||||
|
||||
Width in %t Time Formats
|
||||
|
||||
Standard Verilog does not allow width fields in the %t formats
|
||||
of display strings. For example, this is illegal:
|
||||
|
||||
$display("Time is %0t", %time);
|
||||
|
||||
Standard Verilog instead relies on the $timeformat to
|
||||
completely specify the format.
|
||||
|
||||
Icarus Verilog allows the programmer to specify the field
|
||||
width. The "%t" format in Icarus Verilog works exactly as it
|
||||
does in standard Verilog. However, if the programmer chooses
|
||||
to specify a minimum width (i.e., "%5t"), then for that display
|
||||
Icarus Verilog will override the $timeformat minimum width and
|
||||
use the explicit minimum width.
|
||||
|
||||
vpiScope iterator on vpiScope objects.
|
||||
|
||||
In the VPI, the normal way to iterate over vpiScope objects
|
||||
contained within a vpiScope object, is the vpiInternalScope
|
||||
iterator. Icarus Verilog adds support for the vpiScope
|
||||
iterator of a vpiScope object, that iterates over *everything*
|
||||
the is contained in the current scope. This is useful in cases
|
||||
where one wants to iterate over all the objects in a scope
|
||||
without iterating over all the contained types explicitly.
|
||||
|
||||
time 0 race resolution.
|
||||
|
||||
Combinational logic is routinely modeled using always
|
||||
blocks. However, this can lead to race conditions if the
|
||||
inputs to the combinational block are initialized in initial
|
||||
statements. Icarus Verilog slightly modifies time 0 scheduling
|
||||
by arranging for always statements with ANYEDGE sensitivity
|
||||
lists to be scheduled before any other threads. This causes
|
||||
combinational always blocks to be triggered when the values in
|
||||
the sensitivity list are initialized by initial threads.
|
||||
|
||||
6.0 CREDITS
|
||||
|
||||
Except where otherwise noted, Icarus Verilog, ivl and ivlpp are
|
||||
Copyright Stephen Williams. The proper notices are in the head of each
|
||||
file. However, I have early on received aid in the form of fixes,
|
||||
Verilog guidance, and especially testing from many people, including
|
||||
(in alphabetical order):
|
||||
|
||||
Eric Aardoom <[email protected]>
|
||||
Stephan I. Boettcher <[email protected]>
|
||||
Ed Carter <[email protected]>
|
||||
Larry Doolittle <[email protected]>
|
||||
Guy Hutchison <[email protected]>
|
||||
Ales Hvezda <[email protected]>
|
||||
Yasuhisa Kato <[email protected]>
|
||||
James Lee <[email protected]>
|
||||
Peter Monta <[email protected]>
|
||||
Daniel H. Nelsen <[email protected]>
|
||||
Stefan Petersen <[email protected]>
|
||||
Jason Schonberg <[email protected]>
|
||||
Stuart Sutherland <[email protected]>
|
||||
Stephen Tell <[email protected]>
|
||||
Stefan Theide <[email protected]>
|
||||
Steve Wilson <[email protected]>
|
||||
|
||||
and others. Testers in particular include a larger community of people
|
||||
interested in a GPL Verilog for Linux. Special thanks to Steve Wilson
|
||||
for collecting and organizing the test suite code for all those testers.
|
||||
Verilog guidance, and especially testing from many people. Testers in
|
||||
particular include a larger community of people interested in a GPL
|
||||
Verilog for Linux.
|
||||
|
||||
|
||||
6.1 PORT MAINTAINERS
|
||||
@@ -390,14 +491,17 @@ removed from the list) send e-mail to me.
|
||||
FreeBSD/{Intel,alpha}
|
||||
Ying-Chieh Liao <[email protected]>
|
||||
|
||||
Linux/{alpha,Intel} (RPMS)
|
||||
Linux/{alpha,AMD64,Intel} (RPMS)
|
||||
Stephen Williams <[email protected]>
|
||||
|
||||
Linux/* (.debs)
|
||||
Hamish Moffatt <[email protected]>
|
||||
|
||||
Macintosh -- MacO/S
|
||||
Yasuhisa Kato <ykato@mac.com>
|
||||
Yasuhisa Kato <kato@y.email.ne.jp>
|
||||
|
||||
Mac O/S X
|
||||
Timothy J. Wood <[email protected]>
|
||||
|
||||
NetBSD/*
|
||||
Dan McMahill <[email protected]>
|
||||
@@ -408,15 +512,19 @@ removed from the list) send e-mail to me.
|
||||
Cygwin32/*
|
||||
Venkat Iyer <[email protected]>
|
||||
|
||||
Mingw32
|
||||
Venkat Iyer <[email protected]>
|
||||
|
||||
(+) These are not the only systems where Icarus Verilog has been run,
|
||||
just the systems where precompiled binaries are publicly available.
|
||||
|
||||
|
||||
6.2 TEST SUITE MANAGER
|
||||
|
||||
Steve Wilson <stevew@home.com> or <[email protected]> has taken on
|
||||
the large task of managing the test suite. He has maintained the
|
||||
regression test scripts, the driver list, received submissions from
|
||||
myself and others, and has written a great many tests on his own. Any
|
||||
compiler writer, for any language, will tell you that the test suite
|
||||
is at least as important as the compiler code itself.
|
||||
Steve Wilson <stevew@ka6s.com> has taken on the large task of managing
|
||||
the test suite. He has maintained the regression test scripts, the
|
||||
driver list, received submissions from myself and others, and has
|
||||
written a great many tests on his own. Any compiler writer, for any
|
||||
language, will tell you that the test suite is at least as important
|
||||
as the compiler code itself.
|
||||
|
||||
|
||||
+63
-102
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Statement.cc,v 1.22 2000/07/26 05:08:07 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Statement.cc,v 1.29 2004/02/18 17:11:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "Statement.h"
|
||||
# include "PExpr.h"
|
||||
|
||||
@@ -30,17 +32,19 @@ Statement::~Statement()
|
||||
PAssign_::PAssign_(PExpr*lval, PExpr*ex)
|
||||
: event_(0), lval_(lval), rval_(ex)
|
||||
{
|
||||
delay_ = 0;
|
||||
}
|
||||
|
||||
PAssign_::PAssign_(PExpr*lval, PExpr*de, PExpr*ex)
|
||||
: event_(0), lval_(lval), rval_(ex)
|
||||
{
|
||||
if (de) delay_.set_delay(de);
|
||||
delay_ = de;
|
||||
}
|
||||
|
||||
PAssign_::PAssign_(PExpr*lval, PEventStatement*ev, PExpr*ex)
|
||||
: event_(ev), lval_(lval), rval_(ex)
|
||||
{
|
||||
delay_ = 0;
|
||||
}
|
||||
|
||||
PAssign_::~PAssign_()
|
||||
@@ -82,7 +86,7 @@ PAssignNB::~PAssignNB()
|
||||
{
|
||||
}
|
||||
|
||||
PBlock::PBlock(const string&n, BL_TYPE t, const svector<Statement*>&st)
|
||||
PBlock::PBlock(perm_string n, BL_TYPE t, const svector<Statement*>&st)
|
||||
: name_(n), bl_type_(t), list_(st)
|
||||
{
|
||||
}
|
||||
@@ -103,11 +107,20 @@ PBlock::~PBlock()
|
||||
delete list_[idx];
|
||||
}
|
||||
|
||||
PCallTask::PCallTask(const string&n, const svector<PExpr*>&p)
|
||||
: name_(n), parms_(p)
|
||||
PCallTask::PCallTask(const hname_t&n, const svector<PExpr*>&p)
|
||||
: path_(n), parms_(p)
|
||||
{
|
||||
}
|
||||
|
||||
PCallTask::~PCallTask()
|
||||
{
|
||||
}
|
||||
|
||||
const hname_t& PCallTask::path() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
|
||||
PCase::PCase(NetCase::TYPE t, PExpr*ex, svector<PCase::Item*>*l)
|
||||
: type_(t), expr_(ex), items_(l)
|
||||
{
|
||||
@@ -165,7 +178,7 @@ PDelayStatement::~PDelayStatement()
|
||||
{
|
||||
}
|
||||
|
||||
PDisable::PDisable(const string&sc)
|
||||
PDisable::PDisable(const hname_t&sc)
|
||||
: scope_(sc)
|
||||
{
|
||||
}
|
||||
@@ -177,6 +190,7 @@ PDisable::~PDisable()
|
||||
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
|
||||
: expr_(ee), statement_(0)
|
||||
{
|
||||
assert(expr_.count() > 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -186,6 +200,11 @@ PEventStatement::PEventStatement(PEEvent*ee)
|
||||
expr_[0] = ee;
|
||||
}
|
||||
|
||||
PEventStatement::PEventStatement(void)
|
||||
: statement_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PEventStatement::~PEventStatement()
|
||||
{
|
||||
// delete the events and the statement?
|
||||
@@ -217,6 +236,17 @@ PForever::~PForever()
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
PForStatement::PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
|
||||
PExpr*n2, PExpr*e2, Statement*st)
|
||||
: name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2),
|
||||
statement_(st)
|
||||
{
|
||||
}
|
||||
|
||||
PForStatement::~PForStatement()
|
||||
{
|
||||
}
|
||||
|
||||
PProcess::~PProcess()
|
||||
{
|
||||
delete statement_;
|
||||
@@ -243,7 +273,7 @@ PRepeat::~PRepeat()
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
PTrigger::PTrigger(const string&e)
|
||||
PTrigger::PTrigger(const hname_t&e)
|
||||
: event_(e)
|
||||
{
|
||||
}
|
||||
@@ -252,6 +282,11 @@ PTrigger::~PTrigger()
|
||||
{
|
||||
}
|
||||
|
||||
PWhile::PWhile(PExpr*e1, Statement*st)
|
||||
: cond_(e1), statement_(st)
|
||||
{
|
||||
}
|
||||
|
||||
PWhile::~PWhile()
|
||||
{
|
||||
delete cond_;
|
||||
@@ -260,105 +295,31 @@ PWhile::~PWhile()
|
||||
|
||||
/*
|
||||
* $Log: Statement.cc,v $
|
||||
* Revision 1.22 2000/07/26 05:08:07 steve
|
||||
* Parse disable statements to pform.
|
||||
* Revision 1.29 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.21 2000/05/11 23:37:26 steve
|
||||
* Add support for procedural continuous assignment.
|
||||
* Revision 1.28 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.20 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
* Revision 1.27 2002/04/21 22:31:02 steve
|
||||
* Redo handling of assignment internal delays.
|
||||
* Leave it possible for them to be calculated
|
||||
* at run time.
|
||||
*
|
||||
* Revision 1.19 2000/04/12 04:23:57 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
* Revision 1.26 2002/04/21 04:59:07 steve
|
||||
* Add support for conbinational events by finding
|
||||
* the inputs to expressions and some statements.
|
||||
* Get case and assignment statements working.
|
||||
*
|
||||
* Handle named events within the mix of net events
|
||||
* and edges. As a unified lot they get caught together.
|
||||
* wait statements are broken into more complex statements
|
||||
* that include a conditional.
|
||||
* Revision 1.25 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Do not generate NetPEvent or NetNEvent objects in
|
||||
* elaboration. NetEvent, NetEvWait and NetEvProbe
|
||||
* take over those functions in the netlist.
|
||||
*
|
||||
* Revision 1.18 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
* Revision 1.17 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.16 1999/09/29 18:36:02 steve
|
||||
* Full case support
|
||||
*
|
||||
* Revision 1.15 1999/09/22 02:00:48 steve
|
||||
* assignment with blocking event delay.
|
||||
*
|
||||
* Revision 1.14 1999/09/04 19:11:46 steve
|
||||
* Add support for delayed non-blocking assignments.
|
||||
*
|
||||
* Revision 1.13 1999/09/02 01:59:27 steve
|
||||
* Parse non-blocking assignment delays.
|
||||
*
|
||||
* Revision 1.12 1999/07/12 00:59:36 steve
|
||||
* procedural blocking assignment delays.
|
||||
*
|
||||
* Revision 1.11 1999/06/24 04:24:18 steve
|
||||
* Handle expression widths for EEE and NEE operators,
|
||||
* add named blocks and scope handling,
|
||||
* add registers declared in named blocks.
|
||||
*
|
||||
* Revision 1.10 1999/06/19 21:06:16 steve
|
||||
* Elaborate and supprort to vvm the forever
|
||||
* and repeat statements.
|
||||
*
|
||||
* Revision 1.9 1999/06/15 05:38:39 steve
|
||||
* Support case expression lists.
|
||||
*
|
||||
* Revision 1.8 1999/06/13 23:51:16 steve
|
||||
* l-value part select for procedural assignments.
|
||||
*
|
||||
* Revision 1.7 1999/06/06 20:45:38 steve
|
||||
* Add parse and elaboration of non-blocking assignments,
|
||||
* Replace list<PCase::Item*> with an svector version,
|
||||
* Add integer support.
|
||||
*
|
||||
* Revision 1.6 1999/05/10 00:16:58 steve
|
||||
* Parse and elaborate the concatenate operator
|
||||
* in structural contexts, Replace vector<PExpr*>
|
||||
* and list<PExpr*> with svector<PExpr*>, evaluate
|
||||
* constant expressions with parameters, handle
|
||||
* memories as lvalues.
|
||||
*
|
||||
* Parse task declarations, integer types.
|
||||
*
|
||||
* Revision 1.5 1999/02/03 04:20:11 steve
|
||||
* Parse and elaborate the Verilog CASE statement.
|
||||
*
|
||||
* Revision 1.4 1999/01/25 05:45:56 steve
|
||||
* Add the LineInfo class to carry the source file
|
||||
* location of things. PGate, Statement and PProcess.
|
||||
*
|
||||
* elaborate handles module parameter mismatches,
|
||||
* missing or incorrect lvalues for procedural
|
||||
* assignment, and errors are propogated to the
|
||||
* top of the elaboration call tree.
|
||||
*
|
||||
* Attach line numbers to processes, gates and
|
||||
* assignment statements.
|
||||
*
|
||||
* Revision 1.3 1998/11/11 03:13:04 steve
|
||||
* Handle while loops.
|
||||
*
|
||||
* Revision 1.2 1998/11/07 17:05:05 steve
|
||||
* Handle procedural conditional, and some
|
||||
* of the conditional expressions.
|
||||
*
|
||||
* Elaborate signals and identifiers differently,
|
||||
* allowing the netlist to hold signal information.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:28:55 steve
|
||||
* Introduce verilog to CVS.
|
||||
* Revision 1.24 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.23 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*/
|
||||
|
||||
|
||||
+93
-145
@@ -18,14 +18,16 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Statement.h,v 1.29 2000/09/09 15:21:26 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Statement.h,v 1.40 2004/02/20 18:53:33 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
# include "svector.h"
|
||||
# include "StringHeap.h"
|
||||
# include "PDelays.h"
|
||||
# include "PExpr.h"
|
||||
# include "HName.h"
|
||||
# include "LineInfo.h"
|
||||
class PExpr;
|
||||
class Statement;
|
||||
@@ -55,6 +57,8 @@ class PProcess : public LineInfo {
|
||||
Type type() const { return type_; }
|
||||
Statement*statement() { return statement_; }
|
||||
|
||||
map<perm_string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -74,7 +78,7 @@ class Statement : public LineInfo {
|
||||
virtual ~Statement() =0;
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
};
|
||||
|
||||
@@ -96,7 +100,7 @@ class PAssign_ : public Statement {
|
||||
protected:
|
||||
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
|
||||
|
||||
PDelays delay_;
|
||||
PExpr* delay_;
|
||||
PEventStatement*event_;
|
||||
|
||||
private:
|
||||
@@ -113,11 +117,9 @@ class PAssign : public PAssign_ {
|
||||
~PAssign();
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
NetProc*assign_to_memory_(class NetMemory*, PExpr*,
|
||||
Design*des, const string&path) const;
|
||||
};
|
||||
|
||||
class PAssignNB : public PAssign_ {
|
||||
@@ -128,11 +130,11 @@ class PAssignNB : public PAssign_ {
|
||||
~PAssignNB();
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
NetProc*assign_to_memory_(class NetMemory*, PExpr*,
|
||||
Design*des, const string&path) const;
|
||||
Design*des, NetScope*scope) const;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -147,22 +149,20 @@ class PBlock : public Statement {
|
||||
public:
|
||||
enum BL_TYPE { BL_SEQ, BL_PAR };
|
||||
|
||||
explicit PBlock(const string&n, BL_TYPE t, const svector<Statement*>&st);
|
||||
explicit PBlock(perm_string n, BL_TYPE t, const svector<Statement*>&st);
|
||||
explicit PBlock(BL_TYPE t, const svector<Statement*>&st);
|
||||
explicit PBlock(BL_TYPE t);
|
||||
~PBlock();
|
||||
|
||||
BL_TYPE bl_type() const { return bl_type_; }
|
||||
|
||||
//unsigned size() const { return list_.count(); }
|
||||
//const Statement*stat(unsigned idx) const { return list_[idx]; }
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
perm_string name_;
|
||||
const BL_TYPE bl_type_;
|
||||
svector<Statement*>list_;
|
||||
};
|
||||
@@ -170,9 +170,10 @@ class PBlock : public Statement {
|
||||
class PCallTask : public Statement {
|
||||
|
||||
public:
|
||||
explicit PCallTask(const string&n, const svector<PExpr*>&parms);
|
||||
explicit PCallTask(const hname_t&n, const svector<PExpr*>&parms);
|
||||
~PCallTask();
|
||||
|
||||
string name() const { return name_; }
|
||||
const hname_t& path() const;
|
||||
|
||||
unsigned nparms() const { return parms_.count(); }
|
||||
|
||||
@@ -187,13 +188,13 @@ class PCallTask : public Statement {
|
||||
}
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
NetProc* elaborate_sys(Design*des, const string&path) const;
|
||||
NetProc* elaborate_usr(Design*des, const string&path) const;
|
||||
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
|
||||
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
|
||||
|
||||
const string name_;
|
||||
hname_t path_;
|
||||
svector<PExpr*> parms_;
|
||||
};
|
||||
|
||||
@@ -208,7 +209,7 @@ class PCase : public Statement {
|
||||
PCase(NetCase::TYPE, PExpr*ex, svector<Item*>*);
|
||||
~PCase();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
@@ -229,7 +230,7 @@ class PCAssign : public Statement {
|
||||
explicit PCAssign(PExpr*l, PExpr*r);
|
||||
~PCAssign();
|
||||
|
||||
virtual NetCAssign* elaborate(Design*des, const string&path) const;
|
||||
virtual NetCAssign* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -243,7 +244,7 @@ class PCondit : public Statement {
|
||||
PCondit(PExpr*ex, Statement*i, Statement*e);
|
||||
~PCondit();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
@@ -263,7 +264,7 @@ class PDeassign : public Statement {
|
||||
explicit PDeassign(PExpr*l);
|
||||
~PDeassign();
|
||||
|
||||
virtual NetDeassign* elaborate(Design*des, const string&path) const;
|
||||
virtual NetDeassign* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -277,7 +278,7 @@ class PDelayStatement : public Statement {
|
||||
~PDelayStatement();
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
@@ -287,19 +288,19 @@ class PDelayStatement : public Statement {
|
||||
|
||||
|
||||
/*
|
||||
* This represends the parsing of a disable <scope> statement.
|
||||
* This represents the parsing of a disable <scope> statement.
|
||||
*/
|
||||
class PDisable : public Statement {
|
||||
|
||||
public:
|
||||
explicit PDisable(const string&sc);
|
||||
explicit PDisable(const hname_t&sc);
|
||||
~PDisable();
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
string scope_;
|
||||
hname_t scope_;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -308,6 +309,7 @@ class PDisable : public Statement {
|
||||
*
|
||||
* @name <statement>;
|
||||
* @(expr) <statement>;
|
||||
* @* <statement>;
|
||||
*/
|
||||
class PEventStatement : public Statement {
|
||||
|
||||
@@ -315,18 +317,22 @@ class PEventStatement : public Statement {
|
||||
|
||||
explicit PEventStatement(const svector<PEEvent*>&ee);
|
||||
explicit PEventStatement(PEEvent*ee);
|
||||
// Make an @* statement.
|
||||
explicit PEventStatement(void);
|
||||
|
||||
~PEventStatement();
|
||||
|
||||
void set_statement(Statement*st);
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
// This method is used to elaborate, but attach a previously
|
||||
// elaborated statement to the event.
|
||||
NetProc* elaborate_st(Design*des, const string&path, NetProc*st) const;
|
||||
NetProc* elaborate_st(Design*des, NetScope*scope, NetProc*st) const;
|
||||
|
||||
NetProc* elaborate_wait(Design*des, NetScope*scope, NetProc*st) const;
|
||||
|
||||
private:
|
||||
svector<PEEvent*>expr_;
|
||||
@@ -339,7 +345,7 @@ class PForce : public Statement {
|
||||
explicit PForce(PExpr*l, PExpr*r);
|
||||
~PForce();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -352,7 +358,7 @@ class PForever : public Statement {
|
||||
explicit PForever(Statement*s);
|
||||
~PForever();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
@@ -364,12 +370,10 @@ class PForStatement : public Statement {
|
||||
|
||||
public:
|
||||
PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
|
||||
PExpr*n2, PExpr*e2, Statement*st)
|
||||
: name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2),
|
||||
statement_(st)
|
||||
{ }
|
||||
PExpr*n2, PExpr*e2, Statement*st);
|
||||
~PForStatement();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
@@ -396,7 +400,7 @@ class PRepeat : public Statement {
|
||||
explicit PRepeat(PExpr*expr, Statement*s);
|
||||
~PRepeat();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
@@ -411,7 +415,7 @@ class PRelease : public Statement {
|
||||
explicit PRelease(PExpr*l);
|
||||
~PRelease();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -425,24 +429,23 @@ class PRelease : public Statement {
|
||||
class PTrigger : public Statement {
|
||||
|
||||
public:
|
||||
explicit PTrigger(const string&ev);
|
||||
explicit PTrigger(const hname_t&ev);
|
||||
~PTrigger();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
string event_;
|
||||
hname_t event_;
|
||||
};
|
||||
|
||||
class PWhile : public Statement {
|
||||
|
||||
public:
|
||||
PWhile(PExpr*e1, Statement*st)
|
||||
: cond_(e1), statement_(st) { }
|
||||
PWhile(PExpr*e1, Statement*st);
|
||||
~PWhile();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
@@ -453,6 +456,50 @@ class PWhile : public Statement {
|
||||
|
||||
/*
|
||||
* $Log: Statement.h,v $
|
||||
* Revision 1.40 2004/02/20 18:53:33 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.39 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.38 2003/05/19 02:50:58 steve
|
||||
* Implement the wait statement behaviorally instead of as nets.
|
||||
*
|
||||
* Revision 1.37 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.36 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.35 2002/06/04 05:38:44 steve
|
||||
* Add support for memory words in l-value of
|
||||
* blocking assignments, and remove the special
|
||||
* NetAssignMem class.
|
||||
*
|
||||
* Revision 1.34 2002/05/26 01:39:02 steve
|
||||
* Carry Verilog 2001 attributes with processes,
|
||||
* all the way through to the ivl_target API.
|
||||
*
|
||||
* Divide signal reference counts between rval
|
||||
* and lval references.
|
||||
*
|
||||
* Revision 1.33 2002/04/21 22:31:02 steve
|
||||
* Redo handling of assignment internal delays.
|
||||
* Leave it possible for them to be calculated
|
||||
* at run time.
|
||||
*
|
||||
* Revision 1.32 2002/04/21 04:59:07 steve
|
||||
* Add support for conbinational events by finding
|
||||
* the inputs to expressions and some statements.
|
||||
* Get case and assignment statements working.
|
||||
*
|
||||
* Revision 1.31 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.30 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.29 2000/09/09 15:21:26 steve
|
||||
* move lval elaboration to PExpr virtual methods.
|
||||
*
|
||||
@@ -480,104 +527,5 @@ class PWhile : public Statement {
|
||||
* Do not generate NetPEvent or NetNEvent objects in
|
||||
* elaboration. NetEvent, NetEvWait and NetEvProbe
|
||||
* take over those functions in the netlist.
|
||||
*
|
||||
* Revision 1.23 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
* Revision 1.22 2000/03/11 03:25:51 steve
|
||||
* Locate scopes in statements.
|
||||
*
|
||||
* Revision 1.21 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.20 1999/09/29 18:36:02 steve
|
||||
* Full case support
|
||||
*
|
||||
* Revision 1.19 1999/09/22 02:00:48 steve
|
||||
* assignment with blocking event delay.
|
||||
*
|
||||
* Revision 1.18 1999/09/15 01:55:06 steve
|
||||
* Elaborate non-blocking assignment to memories.
|
||||
*
|
||||
* Revision 1.17 1999/09/04 19:11:46 steve
|
||||
* Add support for delayed non-blocking assignments.
|
||||
*
|
||||
* Revision 1.16 1999/09/02 01:59:27 steve
|
||||
* Parse non-blocking assignment delays.
|
||||
*
|
||||
* Revision 1.15 1999/07/12 00:59:36 steve
|
||||
* procedural blocking assignment delays.
|
||||
*
|
||||
* Revision 1.14 1999/07/03 02:12:51 steve
|
||||
* Elaborate user defined tasks.
|
||||
*
|
||||
* Revision 1.13 1999/06/24 04:24:18 steve
|
||||
* Handle expression widths for EEE and NEE operators,
|
||||
* add named blocks and scope handling,
|
||||
* add registers declared in named blocks.
|
||||
*
|
||||
* Revision 1.12 1999/06/19 21:06:16 steve
|
||||
* Elaborate and supprort to vvm the forever
|
||||
* and repeat statements.
|
||||
*
|
||||
* Revision 1.11 1999/06/15 05:38:39 steve
|
||||
* Support case expression lists.
|
||||
*
|
||||
* Revision 1.10 1999/06/13 23:51:16 steve
|
||||
* l-value part select for procedural assignments.
|
||||
*
|
||||
* Revision 1.9 1999/06/06 20:45:38 steve
|
||||
* Add parse and elaboration of non-blocking assignments,
|
||||
* Replace list<PCase::Item*> with an svector version,
|
||||
* Add integer support.
|
||||
*
|
||||
* Revision 1.8 1999/05/10 00:16:58 steve
|
||||
* Parse and elaborate the concatenate operator
|
||||
* in structural contexts, Replace vector<PExpr*>
|
||||
* and list<PExpr*> with svector<PExpr*>, evaluate
|
||||
* constant expressions with parameters, handle
|
||||
* memories as lvalues.
|
||||
*
|
||||
* Parse task declarations, integer types.
|
||||
*
|
||||
* Revision 1.7 1999/04/29 02:16:26 steve
|
||||
* Parse OR of event expressions.
|
||||
*
|
||||
* Revision 1.6 1999/02/03 04:20:11 steve
|
||||
* Parse and elaborate the Verilog CASE statement.
|
||||
*
|
||||
* Revision 1.5 1999/01/25 05:45:56 steve
|
||||
* Add the LineInfo class to carry the source file
|
||||
* location of things. PGate, Statement and PProcess.
|
||||
*
|
||||
* elaborate handles module parameter mismatches,
|
||||
* missing or incorrect lvalues for procedural
|
||||
* assignment, and errors are propogated to the
|
||||
* top of the elaboration call tree.
|
||||
*
|
||||
* Attach line numbers to processes, gates and
|
||||
* assignment statements.
|
||||
*
|
||||
* Revision 1.4 1998/11/11 03:13:04 steve
|
||||
* Handle while loops.
|
||||
*
|
||||
* Revision 1.3 1998/11/09 18:55:33 steve
|
||||
* Add procedural while loops,
|
||||
* Parse procedural for loops,
|
||||
* Add procedural wait statements,
|
||||
* Add constant nodes,
|
||||
* Add XNOR logic gate,
|
||||
* Make vvm output look a bit prettier.
|
||||
*
|
||||
* Revision 1.2 1998/11/07 17:05:05 steve
|
||||
* Handle procedural conditional, and some
|
||||
* of the conditional expressions.
|
||||
*
|
||||
* Elaborate signals and identifiers differently,
|
||||
* allowing the netlist to hold signal information.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:28:56 steve
|
||||
* Introduce verilog to CVS.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
+206
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: StringHeap.cc,v 1.6 2004/02/18 17:11:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "StringHeap.h"
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
|
||||
StringHeap::StringHeap()
|
||||
{
|
||||
cell_base_ = 0;
|
||||
cell_ptr_ = HEAPCELL;
|
||||
cell_count_ = 0;
|
||||
}
|
||||
|
||||
StringHeap::~StringHeap()
|
||||
{
|
||||
// This is a planned memory leak. The string heap is intended
|
||||
// to hold permanently-allocated strings.
|
||||
}
|
||||
|
||||
const char* StringHeap::add(const char*text)
|
||||
{
|
||||
unsigned len = strlen(text);
|
||||
assert((len+1) <= HEAPCELL);
|
||||
|
||||
unsigned rem = HEAPCELL - cell_ptr_;
|
||||
if (rem < (len+1)) {
|
||||
cell_base_ = (char*)malloc(HEAPCELL);
|
||||
cell_ptr_ = 0;
|
||||
cell_count_ += 1;
|
||||
assert(cell_base_ != 0);
|
||||
}
|
||||
|
||||
char*res = cell_base_ + cell_ptr_;
|
||||
memcpy(res, text, len);
|
||||
cell_ptr_ += len;
|
||||
cell_base_[cell_ptr_++] = 0;
|
||||
|
||||
assert(cell_ptr_ <= HEAPCELL);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
perm_string StringHeap::make(const char*text)
|
||||
{
|
||||
return perm_string(add(text));
|
||||
}
|
||||
|
||||
|
||||
StringHeapLex::StringHeapLex()
|
||||
{
|
||||
hit_count_ = 0;
|
||||
add_count_ = 0;
|
||||
|
||||
for (unsigned idx = 0 ; idx < HASH_SIZE ; idx += 1)
|
||||
hash_table_[idx] = 0;
|
||||
}
|
||||
|
||||
StringHeapLex::~StringHeapLex()
|
||||
{
|
||||
}
|
||||
|
||||
unsigned StringHeapLex::add_hit_count() const
|
||||
{
|
||||
return hit_count_;
|
||||
}
|
||||
|
||||
unsigned StringHeapLex::add_count() const
|
||||
{
|
||||
return add_count_;
|
||||
}
|
||||
|
||||
static unsigned hash_string(const char*text)
|
||||
{
|
||||
unsigned h = 0;
|
||||
|
||||
while (*text) {
|
||||
h = (h << 4) ^ (h >> 28) ^ *text;
|
||||
text += 1;
|
||||
}
|
||||
return h;
|
||||
}
|
||||
|
||||
const char* StringHeapLex::add(const char*text)
|
||||
{
|
||||
unsigned hash_value = hash_string(text) % HASH_SIZE;
|
||||
|
||||
/* If we easily find the string in the hash table, then return
|
||||
that and be done. */
|
||||
if (hash_table_[hash_value]
|
||||
&& (strcmp(hash_table_[hash_value], text) == 0)) {
|
||||
hit_count_ += 1;
|
||||
return hash_table_[hash_value];
|
||||
}
|
||||
|
||||
/* The existing hash entry is not a match. Replace it with the
|
||||
newly allocated value, and return the new pointer as the
|
||||
result to the add. */
|
||||
const char*res = StringHeap::add(text);
|
||||
hash_table_[hash_value] = res;
|
||||
add_count_ += 1;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
perm_string StringHeapLex::make(const char*text)
|
||||
{
|
||||
return perm_string(add(text));
|
||||
}
|
||||
|
||||
perm_string StringHeapLex::make(const string&text)
|
||||
{
|
||||
return perm_string(add(text.c_str()));
|
||||
}
|
||||
|
||||
bool operator == (perm_string a, const char*b)
|
||||
{
|
||||
if (a.str() == b)
|
||||
return true;
|
||||
|
||||
if (! (a.str() && b))
|
||||
return false;
|
||||
|
||||
if (strcmp(a.str(), b) == 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator == (perm_string a, perm_string b)
|
||||
{
|
||||
return a == b.str();
|
||||
}
|
||||
|
||||
bool operator != (perm_string a, const char*b)
|
||||
{
|
||||
return ! (a == b);
|
||||
}
|
||||
|
||||
bool operator != (perm_string a, perm_string b)
|
||||
{
|
||||
return ! (a == b);
|
||||
}
|
||||
|
||||
bool operator < (perm_string a, perm_string b)
|
||||
{
|
||||
if (b.str() && !a.str())
|
||||
return true;
|
||||
|
||||
if (b.str() == a.str())
|
||||
return false;
|
||||
|
||||
if (strcmp(a.str(), b.str()) < 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: StringHeap.cc,v $
|
||||
* Revision 1.6 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.5 2003/03/01 06:25:30 steve
|
||||
* Add the lex_strings string handler, and put
|
||||
* scope names and system task/function names
|
||||
* into this table. Also, permallocate event
|
||||
* names from the beginning.
|
||||
*
|
||||
* Revision 1.4 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.3 2003/01/16 21:44:46 steve
|
||||
* Keep some debugging status.
|
||||
*
|
||||
* Revision 1.2 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.1 2002/08/04 19:13:16 steve
|
||||
* dll uses StringHeap for named items.
|
||||
*
|
||||
*/
|
||||
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
#ifndef __StringHeap_H
|
||||
#define __StringHeap_H
|
||||
/*
|
||||
* Copyright (c) 2002-2004 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: StringHeap.h,v 1.5 2004/02/18 17:11:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include <string>
|
||||
|
||||
class perm_string {
|
||||
|
||||
public:
|
||||
perm_string() : text_(0) { }
|
||||
perm_string(const perm_string&that) : text_(that.text_) { }
|
||||
~perm_string() { }
|
||||
|
||||
perm_string& operator = (const perm_string&that)
|
||||
{ text_ = that.text_; return *this; }
|
||||
|
||||
const char*str() const { return text_; }
|
||||
operator const char* () const { return str(); }
|
||||
|
||||
// This is an escape for making perm_string objects out of
|
||||
// literals. For example, per_string::literal("Label"); Please
|
||||
// do *not* cheat and pass arbitrary const char* items here.
|
||||
static perm_string literal(const char*t) { return perm_string(t); }
|
||||
|
||||
private:
|
||||
friend class StringHeap;
|
||||
friend class StringHeapLex;
|
||||
perm_string(const char*t) : text_(t) { };
|
||||
|
||||
private:
|
||||
const char*text_;
|
||||
};
|
||||
|
||||
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);
|
||||
extern bool operator != (perm_string a, const char* b);
|
||||
extern bool operator > (perm_string a, perm_string b);
|
||||
extern bool operator < (perm_string a, perm_string b);
|
||||
extern bool operator >= (perm_string a, perm_string b);
|
||||
extern bool operator <= (perm_string a, perm_string b);
|
||||
|
||||
/*
|
||||
* The string heap is a way to permanently allocate strings
|
||||
* efficiently. They only take up the space of the string characters
|
||||
* and the terminating nul, there is no malloc overhead.
|
||||
*/
|
||||
class StringHeap {
|
||||
|
||||
public:
|
||||
StringHeap();
|
||||
~StringHeap();
|
||||
|
||||
const char*add(const char*);
|
||||
perm_string make(const char*);
|
||||
|
||||
private:
|
||||
enum { HEAPCELL = 0x10000 };
|
||||
|
||||
char*cell_base_;
|
||||
unsigned cell_ptr_;
|
||||
unsigned cell_count_;
|
||||
|
||||
private: // not implemented
|
||||
StringHeap(const StringHeap&);
|
||||
StringHeap& operator= (const StringHeap&);
|
||||
};
|
||||
|
||||
/*
|
||||
* A lexical string heap is a string heap that makes an effort to
|
||||
* return the same pointer for identical strings. This saves further
|
||||
* space by not allocating duplicate strings, so in a system with lots
|
||||
* of identifiers, this can theoretically save more space.
|
||||
*/
|
||||
class StringHeapLex : private StringHeap {
|
||||
|
||||
public:
|
||||
StringHeapLex();
|
||||
~StringHeapLex();
|
||||
|
||||
const char*add(const char*);
|
||||
perm_string make(const char*);
|
||||
perm_string make(const string&);
|
||||
|
||||
unsigned add_count() const;
|
||||
unsigned add_hit_count() const;
|
||||
|
||||
private:
|
||||
enum { HASH_SIZE = 4096 };
|
||||
const char*hash_table_[HASH_SIZE];
|
||||
|
||||
unsigned add_count_;
|
||||
unsigned hit_count_;
|
||||
|
||||
private: // not implemented
|
||||
StringHeapLex(const StringHeapLex&);
|
||||
StringHeapLex& operator= (const StringHeapLex&);
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: StringHeap.h,v $
|
||||
* Revision 1.5 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.4 2003/03/01 06:25:30 steve
|
||||
* Add the lex_strings string handler, and put
|
||||
* scope names and system task/function names
|
||||
* into this table. Also, permallocate event
|
||||
* names from the beginning.
|
||||
*
|
||||
* Revision 1.3 2003/01/16 21:44:46 steve
|
||||
* Keep some debugging status.
|
||||
*
|
||||
* Revision 1.2 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.1 2002/08/04 19:13:16 steve
|
||||
* dll uses StringHeap for named items.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
#ifndef PLI_TYPES
|
||||
#define PLI_TYPES
|
||||
/*
|
||||
* Copyright (c) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: _pli_types.h.in,v 1.7 2003/11/12 02:38:44 steve Exp $"
|
||||
#endif
|
||||
|
||||
# undef HAVE_INTTYPES_H
|
||||
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
|
||||
/*
|
||||
* If the host environment has the stdint.h header file,
|
||||
* then use that to size our PLI types.
|
||||
*/
|
||||
#ifndef __STDC_FORMAT_MACROS
|
||||
# define __STDC_FORMAT_MACROS
|
||||
#endif
|
||||
|
||||
# include <inttypes.h>
|
||||
typedef uint64_t PLI_UINT64;
|
||||
typedef int64_t PLI_INT64;
|
||||
typedef uint32_t PLI_UINT32;
|
||||
typedef int32_t PLI_INT32;
|
||||
|
||||
typedef signed short PLI_INT16;
|
||||
typedef unsigned short PLI_UINT16;
|
||||
typedef signed char PLI_BYTE8;
|
||||
typedef unsigned char PLI_UBYTE8;
|
||||
|
||||
# define PLI_UINT64_FMT PRIu64
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* If we do not have the c99 stdint.h header file, then use
|
||||
* configure detection to guess the pli types ourselves.
|
||||
*/
|
||||
|
||||
# define SIZEOF_UNSIGNED_LONG_LONG 8
|
||||
# define SIZEOF_UNSIGNED_LONG 8
|
||||
# define SIZEOF_UNSIGNED 4
|
||||
|
||||
#if SIZEOF_UNSIGNED >= 8
|
||||
typedef unsigned PLI_UINT64;
|
||||
typedef int PLI_INT64;
|
||||
# define PLI_UINT64_FMT "u"
|
||||
#else
|
||||
# if SIZEOF_UNSIGNED_LONG >= 8
|
||||
typedef unsigned long PLI_UINT64;
|
||||
typedef long PLI_INT64;
|
||||
# define PLI_UINT64_FMT "lu"
|
||||
# else
|
||||
# if SIZEOF_UNSIGNED_LONG_LONG > SIZEOF_UNSIGNED_LONG
|
||||
typedef unsigned long long PLI_UINT64;
|
||||
typedef long long PLI_INT64;
|
||||
# define PLI_UINT64_FMT "llu"
|
||||
# else
|
||||
typedef unsigned long PLI_UINT64;
|
||||
typedef long PLI_INT64;
|
||||
# define PLI_UINT64_FMT "lu"
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef signed int PLI_INT32;
|
||||
typedef unsigned int PLI_UINT32;
|
||||
typedef signed short PLI_INT16;
|
||||
typedef unsigned short PLI_UINT16;
|
||||
typedef signed char PLI_BYTE8;
|
||||
typedef unsigned char PLI_UBYTE8;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* $Log: _pli_types.h.in,v $
|
||||
* Revision 1.7 2003/11/12 02:38:44 steve
|
||||
* Clean up manual definitions of PLI_UINT64_FMT.
|
||||
*
|
||||
* Revision 1.6 2003/11/08 20:06:21 steve
|
||||
* Spelling fixes in comments.
|
||||
*
|
||||
* Revision 1.5 2003/10/29 03:28:27 steve
|
||||
* Add the PLU_UINT64_FMT string for formatting output.
|
||||
*
|
||||
* Revision 1.4 2003/10/29 03:23:12 steve
|
||||
* Portably handle time format of VCD prints.
|
||||
*
|
||||
* Revision 1.3 2003/10/02 21:30:06 steve
|
||||
* Use configured TIME_FMT in vcd dump printf.
|
||||
*
|
||||
* Revision 1.2 2003/10/02 19:33:44 steve
|
||||
* Put libraries in libdir64.
|
||||
*
|
||||
* Revision 1.1 2003/09/30 01:33:13 steve
|
||||
* Add PLI_UINT64 to _pli_types.h.
|
||||
*
|
||||
* Revision 1.2 2003/05/26 04:39:16 steve
|
||||
* Typo type name.
|
||||
*
|
||||
* Revision 1.1 2003/02/17 06:39:47 steve
|
||||
* Add at least minimal implementations for several
|
||||
* acc_ functions. Add support for standard ACC
|
||||
* string handling.
|
||||
*
|
||||
* Add the _pli_types.h header file to carry the
|
||||
* IEEE1364-2001 standard PLI type declarations.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+354
@@ -0,0 +1,354 @@
|
||||
#ifndef __acc_user_H
|
||||
#define __acc_user_H
|
||||
/*
|
||||
* Copyright (c) 2002 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: acc_user.h,v 1.20 2003/12/17 15:45:07 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This header file contains the definitions and declarations needed
|
||||
* by an Icarus Verilog user using acc_ routines.
|
||||
*
|
||||
* NOTE: Icarus Verilog does not support acc_ routines. This is just a
|
||||
* stub. The functions that are implemented here are actually
|
||||
* implemented using VPI routines.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define EXTERN_C_START extern "C" {
|
||||
# define EXTERN_C_END }
|
||||
#else
|
||||
# define EXTERN_C_START
|
||||
# define EXTERN_C_END
|
||||
# define bool int
|
||||
#endif
|
||||
|
||||
EXTERN_C_START
|
||||
|
||||
# include "_pli_types.h"
|
||||
|
||||
/*
|
||||
* This is a declaration of the "handle" type that is compatible with
|
||||
* the vpiHandle from vpi_user.h. The libveriuser library implements
|
||||
* the acc handle type as a vpiHandle, to prevent useless indirection.
|
||||
*/
|
||||
typedef struct __vpiHandle *handle;
|
||||
|
||||
/* OBJECT TYPES */
|
||||
#define accModule 20
|
||||
#define accScope 21
|
||||
#define accNet 25
|
||||
#define accReg 30
|
||||
#define accIntegerParam 200
|
||||
#define accRealParam 202
|
||||
#define accStringParam 204
|
||||
#define accParameter 220
|
||||
#define accTopModule 224
|
||||
#define accModuleInstance 226
|
||||
#define accWire 260
|
||||
#define accNamedEvent 280
|
||||
#define accIntegerVar 281
|
||||
#define accRealVar 282
|
||||
#define accTimeVar 283
|
||||
#define accIntVar accIntegerVar
|
||||
#define accScalar 300
|
||||
#define accVector 302
|
||||
#define accUnknown 412
|
||||
#define accConstant 600
|
||||
|
||||
/* type VALUES FOR t_setval_delay STRUCTURE */
|
||||
#define accNoDelay 0
|
||||
#define accInertialDelay 1
|
||||
#define accTransportDelay 2
|
||||
#define accPureTransportDelay 3
|
||||
#define accForceFlag 4
|
||||
#define accReleaseFlag 5
|
||||
|
||||
/* type VALUES FOR t_setval_value STRUCTURE */
|
||||
#define accBinStrVal 1
|
||||
#define accOctStrVal 2
|
||||
#define accDecStrVal 3
|
||||
#define accHexStrVal 4
|
||||
#define accScalarVal 5
|
||||
#define accIntVal 6
|
||||
#define accRealVal 7
|
||||
#define accStringVal 8
|
||||
#define accVectorVal 9
|
||||
|
||||
/* Scalar values */
|
||||
#define acc0 0
|
||||
#define acc1 1
|
||||
#define accX 2
|
||||
#define accZ 3
|
||||
|
||||
/* type VALUES FOR t_acc_time STRUCTURE */
|
||||
#define accTime 1
|
||||
#define accSimTime 2
|
||||
#define accRealTime 3
|
||||
|
||||
/* reason codes */
|
||||
#define logic_value_change 1
|
||||
#define strength_value_change 2
|
||||
#define real_value_change 3
|
||||
#define vector_value_change 4
|
||||
#define event_value_change 5
|
||||
#define integer_value_change 6
|
||||
#define time_value_change 7
|
||||
#define sregister_value_change 8
|
||||
#define vregister_value_change 9
|
||||
#define realtime_value_change 10
|
||||
|
||||
/* VCL strength values */
|
||||
#define vclSupply 7
|
||||
#define vclStrong 6
|
||||
#define vclPull 5
|
||||
#define vclLarge 4
|
||||
#define vclWeak 3
|
||||
#define vclMedium 2
|
||||
#define vclSmall 1
|
||||
#define vclHighZ 0
|
||||
|
||||
/* Constants used by acc_vcl_add */
|
||||
#define vcl_verilog_logic 2
|
||||
#define VCL_VERILOG_LOGIC vcl_verilog_logic
|
||||
#define vcl_verilog_strength 3
|
||||
#define VCL_VERILOG_STRENGTH vcl_verilog_strength
|
||||
|
||||
typedef struct t_acc_time {
|
||||
int type;
|
||||
int low, high;
|
||||
double real;
|
||||
} s_acc_time, *p_acc_time;
|
||||
|
||||
typedef struct t_setval_delay {
|
||||
s_acc_time time;
|
||||
int model;
|
||||
} s_setval_delay, *p_setval_delay;
|
||||
|
||||
typedef struct t_acc_vecval {
|
||||
int aval;
|
||||
int bval;
|
||||
} s_acc_vecval, *p_acc_vecval;
|
||||
|
||||
typedef struct t_setval_value {
|
||||
int format;
|
||||
union {
|
||||
char*str;
|
||||
int scalar;
|
||||
int integer;
|
||||
double real;
|
||||
p_acc_vecval vector;
|
||||
} value;
|
||||
} s_setval_value, *p_setval_value, s_acc_value, *p_acc_value;
|
||||
|
||||
typedef struct t_strengths {
|
||||
PLI_UBYTE8 logic_value;
|
||||
PLI_UBYTE8 strength1;
|
||||
PLI_UBYTE8 strength2;
|
||||
} s_strengths, *p_strengths;
|
||||
|
||||
typedef struct t_vc_record {
|
||||
PLI_INT32 vc_reason;
|
||||
PLI_INT32 vc_hightime;
|
||||
PLI_INT32 vc_lowtime;
|
||||
void* user_data;
|
||||
union {
|
||||
PLI_UBYTE8 logic_value;
|
||||
double real_value;
|
||||
handle vector_handle;
|
||||
s_strengths strengths_s;
|
||||
} out_value;
|
||||
} s_vc_record, *p_vc_record;
|
||||
|
||||
|
||||
typedef struct t_location {
|
||||
PLI_INT32 line_no;
|
||||
const char*filename;
|
||||
} s_location, *p_location;
|
||||
|
||||
extern int acc_error_flag;
|
||||
|
||||
extern int acc_initialize(void);
|
||||
|
||||
extern void acc_close(void);
|
||||
|
||||
/*
|
||||
* This is the acc_configure command, and the config_param
|
||||
* codes that are accepted.
|
||||
*/
|
||||
extern int acc_configure(PLI_INT32 config_param, const char*value);
|
||||
#define accEnableArgs 6
|
||||
#define accDevelopmentVersion 11
|
||||
|
||||
extern int acc_fetch_argc(void);
|
||||
extern char**acc_fetch_argv(void);
|
||||
|
||||
extern PLI_INT32 acc_fetch_direction(handle obj);
|
||||
/* XXXX FIXME: Values returned by acc_fetch_direction */
|
||||
# define accInout 2
|
||||
|
||||
extern char* acc_fetch_fullname(handle obj);
|
||||
|
||||
extern int acc_fetch_location(p_location loc, handle obj);
|
||||
|
||||
extern char* acc_fetch_name(handle obj);
|
||||
extern char* acc_fetch_defname(handle obj);
|
||||
|
||||
extern double acc_fetch_paramval(handle obj);
|
||||
|
||||
extern double acc_fetch_tfarg(PLI_INT32);
|
||||
extern double acc_fetch_itfarg(PLI_INT32, handle);
|
||||
extern PLI_INT32 acc_fetch_tfarg_int(PLI_INT32);
|
||||
extern PLI_INT32 acc_fetch_itfarg_int(PLI_INT32, handle);
|
||||
extern char* acc_fetch_tfarg_str(PLI_INT32);
|
||||
extern char* acc_fetch_itfarg_str(PLI_INT32, handle);
|
||||
|
||||
typedef struct t_timescale_info {
|
||||
PLI_INT16 unit;
|
||||
PLI_INT16 precision;
|
||||
} s_timescale_info, *p_timescale_info;
|
||||
extern void acc_fetch_timescale_info(handle obj, p_timescale_info info);
|
||||
|
||||
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_range(handle object, int *msb, int *lsb);
|
||||
extern char* acc_fetch_type_str(PLI_INT32 type);
|
||||
|
||||
extern char* acc_fetch_value(handle obj, const char*fmt, s_acc_value*value);
|
||||
|
||||
extern handle acc_handle_by_name(const char*name, handle scope);
|
||||
extern handle acc_handle_hiconn(handle port_ref_handle);
|
||||
extern handle acc_handle_object(const char*name);
|
||||
extern handle acc_handle_parent(handle obj);
|
||||
extern handle acc_handle_scope(handle obj);
|
||||
extern handle acc_handle_simulated_net(handle net);
|
||||
|
||||
extern handle acc_handle_tfarg(int n);
|
||||
extern handle acc_handle_tfinst(void);
|
||||
|
||||
extern PLI_INT32 acc_compare_handles(handle, handle);
|
||||
|
||||
extern handle acc_next(PLI_INT32 *, handle, handle);
|
||||
extern handle acc_next_bit(handle ref, handle bit);
|
||||
extern handle acc_next_port(handle ref, handle bit);
|
||||
extern handle acc_next_scope(handle, handle);
|
||||
extern handle acc_next_topmod(handle prev_topmod);
|
||||
|
||||
extern int acc_object_in_typelist(handle object, PLI_INT32*typelist);
|
||||
extern int acc_object_of_type(handle object, PLI_INT32 type);
|
||||
|
||||
extern char*acc_product_version(void);
|
||||
|
||||
extern char*acc_set_scope(handle ref, ...);
|
||||
|
||||
extern int acc_set_value(handle obj, p_setval_value value,
|
||||
p_setval_delay delay);
|
||||
|
||||
extern void acc_vcl_add(handle obj, PLI_INT32(*consumer)(p_vc_record),
|
||||
void*data, PLI_INT32 vcl_flag);
|
||||
extern void acc_vcl_delete(handle obj, PLI_INT32(*consumer)(p_vc_record),
|
||||
void*data, PLI_INT32 vcl_flag);
|
||||
|
||||
extern char* acc_version(void);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
/*
|
||||
* $Log: acc_user.h,v $
|
||||
* Revision 1.20 2003/12/17 15:45:07 steve
|
||||
* Add acc_set_scope function.
|
||||
*
|
||||
* Revision 1.19 2003/10/10 02:57:45 steve
|
||||
* Some PLI1 stubs.
|
||||
*
|
||||
* Revision 1.18 2003/06/13 19:23:41 steve
|
||||
* Add a bunch more PLI1 routines.
|
||||
*
|
||||
* Revision 1.17 2003/06/04 01:56:20 steve
|
||||
* 1) Adds configure logic to clean up compiler warnings
|
||||
* 2) adds acc_compare_handle, acc_fetch_range, acc_next_scope and
|
||||
* tf_isetrealdelay, acc_handle_scope
|
||||
* 3) makes acc_next reentrant
|
||||
* 4) adds basic vpiWire type support
|
||||
* 5) fills in some acc_object_of_type() and acc_fetch_{full}type()
|
||||
* 6) add vpiLeftRange/RigthRange to signals
|
||||
*
|
||||
* Revision 1.16 2003/05/30 04:18:31 steve
|
||||
* Add acc_next function.
|
||||
*
|
||||
* Revision 1.15 2003/05/29 02:35:41 steve
|
||||
* acc_fetch_type supports module.
|
||||
*
|
||||
* Revision 1.14 2003/05/29 02:21:45 steve
|
||||
* Implement acc_fetch_defname and its infrastructure in vvp.
|
||||
*
|
||||
* Revision 1.13 2003/05/24 03:02:04 steve
|
||||
* Add implementation of acc_handle_by_name.
|
||||
*
|
||||
* Revision 1.12 2003/05/18 00:16:35 steve
|
||||
* Add PLI_TRACE tracing of PLI1 modules.
|
||||
*
|
||||
* Add tf_isetdelay and friends, and add
|
||||
* callback return values for acc_vcl support.
|
||||
*
|
||||
* Revision 1.11 2003/04/24 18:57:05 steve
|
||||
* Add acc_fetch_fulltype function.
|
||||
*
|
||||
* Revision 1.10 2003/04/20 02:48:39 steve
|
||||
* Support value change callbacks.
|
||||
*
|
||||
* Revision 1.9 2003/04/12 18:57:13 steve
|
||||
* More acc_ function stubs.
|
||||
*
|
||||
* Revision 1.8 2003/03/13 04:35:09 steve
|
||||
* Add a bunch of new acc_ and tf_ functions.
|
||||
*
|
||||
* Revision 1.7 2003/02/17 06:39:47 steve
|
||||
* Add at least minimal implementations for several
|
||||
* acc_ functions. Add support for standard ACC
|
||||
* string handling.
|
||||
*
|
||||
* Add the _pli_types.h header file to carry the
|
||||
* IEEE1364-2001 standard PLI type declarations.
|
||||
*
|
||||
* Revision 1.6 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.5 2002/06/11 15:19:12 steve
|
||||
* Add acc_fetch_argc/argv/version (mruff)
|
||||
*
|
||||
* Revision 1.4 2002/06/07 02:58:58 steve
|
||||
* Add a bunch of acc/tf functions. (mruff)
|
||||
*
|
||||
* Revision 1.3 2002/06/02 19:03:29 steve
|
||||
* Add acc_handle_tfarg and acc_next_topmode
|
||||
*
|
||||
* Revision 1.2 2002/05/30 02:06:05 steve
|
||||
* Implement acc_product_version.
|
||||
*
|
||||
* Revision 1.1 2002/05/23 03:46:42 steve
|
||||
* Add the acc_user.h header file.
|
||||
*
|
||||
*/
|
||||
|
||||
#endif
|
||||
Vendored
+207
@@ -0,0 +1,207 @@
|
||||
# AX_CPP_IDENT
|
||||
# ------------
|
||||
# Check if the C compiler supports #ident
|
||||
# Define and substitute ident_support if so.
|
||||
#
|
||||
# It would be simpler and more consistent with the rest of the autoconf
|
||||
# structure to AC_DEFINE(HAVE_CPP_IDENT) instead of
|
||||
# ident_support='-DHAVE_CVS_IDENT=1' and AC_SUBST(ident_support), but that
|
||||
# change would require all C files in the icarus top level directory to
|
||||
# put #include <config.h> before the #ifdef HAVE_CVS_IDENT (and change
|
||||
# HAVE_CVS_IDENT to HAVE_CPP_IDENT). That would also remove all special
|
||||
# ident_support handling from the Makefile. Manyana.
|
||||
#
|
||||
AC_DEFUN([AX_CPP_IDENT],
|
||||
[AC_CACHE_CHECK([for ident support in C compiler], ax_cv_cpp_ident,
|
||||
[AC_TRY_COMPILE([
|
||||
#ident "$Id: aclocal.m4,v 1.6 2004/10/04 01:10:52 steve Exp $"
|
||||
],[while (0) {}],
|
||||
[AS_VAR_SET(ax_cv_cpp_ident, yes)],
|
||||
[AS_VAR_SET(ax_cv_cpp_ident, no)])])
|
||||
if test $ax_cv_cpp_ident = yes; then
|
||||
ident_support='-DHAVE_CVS_IDENT=1'
|
||||
fi
|
||||
AC_SUBST(ident_support)
|
||||
])# AC_CPP_IDENT
|
||||
|
||||
|
||||
# _AX_C_UNDERSCORES_MATCH_IFELSE(PATTERN, ACTION-IF-MATCH, ACTION-IF-NOMATCH)
|
||||
# ------------------------------
|
||||
# Sub-macro for AX_C_UNDERSCORES_LEADING and AX_C_UNDERSCORES_TRAILING.
|
||||
# Unwarranted assumptions:
|
||||
# - the object file produced by AC_COMPILE_IFELSE is called "conftest.$ac_objext"
|
||||
# - the nm(1) utility is available, and its name is "nm".
|
||||
AC_DEFUN([_AX_C_UNDERSCORES_MATCH_IF],
|
||||
[AC_COMPILE_IFELSE([void underscore(void){}],
|
||||
[AS_IF([nm conftest.$ac_objext|grep $1 >/dev/null 2>/dev/null],[$2],[$3])],
|
||||
[AC_MSG_ERROR([underscore test crashed])]
|
||||
)])
|
||||
|
||||
|
||||
# AX_C_UNDERSCORES_LEADING
|
||||
# ---------------------------------
|
||||
# Check if symbol names in object files produced by C compiler have
|
||||
# leading underscores. Define NEED_LU if so.
|
||||
AC_DEFUN([AX_C_UNDERSCORES_LEADING],
|
||||
[AC_CACHE_CHECK([for leading underscores], ax_cv_c_underscores_leading,
|
||||
[_AX_C_UNDERSCORES_MATCH_IF([_underscore],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_leading, yes)],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_leading, no)])])
|
||||
if test $ax_cv_c_underscores_leading = yes -a "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; then
|
||||
AC_DEFINE(NEED_LU)
|
||||
fi
|
||||
])# AX_C_UNDERSCORES_LEADING
|
||||
|
||||
|
||||
# AX_C_UNDERSCORES_TRAILING
|
||||
# ---------------------------------
|
||||
# Check if symbol names in object files produced by C compiler have
|
||||
# trailing underscores. Define NEED_TU if so.
|
||||
AC_DEFUN([AX_C_UNDERSCORES_TRAILING],
|
||||
[AC_CACHE_CHECK([for trailing underscores], ax_cv_c_underscores_trailing,
|
||||
[_AX_C_UNDERSCORES_MATCH_IF([underscore_],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_trailing, yes)],
|
||||
[AS_VAR_SET(ax_cv_c_underscores_trailing, no)])])
|
||||
if test $ax_cv_c_underscores_trailing = yes; then
|
||||
AC_DEFINE(NEED_TU)
|
||||
fi
|
||||
])# AX_C_UNDERSCORES_TRAILING
|
||||
|
||||
# AX_WIN32
|
||||
# --------
|
||||
# Combined check for several flavors of Microsoft Windows so
|
||||
# their "issues" can be dealt with
|
||||
AC_DEFUN([AX_WIN32],
|
||||
[AC_CYGWIN
|
||||
AC_MINGW32
|
||||
WIN32=no
|
||||
AC_MSG_CHECKING([for Microsoft Windows])
|
||||
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
|
||||
then
|
||||
WIN32=yes
|
||||
fi
|
||||
AC_SUBST(MINGW32)
|
||||
AC_SUBST(WIN32)
|
||||
AC_MSG_RESULT($WIN32)
|
||||
])# AX_WIN32
|
||||
|
||||
# AX_LD_EXTRALIBS
|
||||
# ---------------
|
||||
# mingw needs to link with libiberty.a, but cygwin alone can't tolerate it
|
||||
AC_DEFUN([AX_LD_EXTRALIBS],
|
||||
[AC_MSG_CHECKING([for extra libs needed])
|
||||
EXTRALIBS=
|
||||
case "${host}" in
|
||||
*-*-cygwin* )
|
||||
if test "$MINGW32" = "yes"; then
|
||||
EXTRALIBS="-liberty"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(EXTRALIBS)
|
||||
AC_MSG_RESULT($EXTRALIBS)
|
||||
])# AX_LD_EXTRALIBS
|
||||
|
||||
# AX_LD_SHAREDLIB_OPTS
|
||||
# --------------------
|
||||
# linker options when building a shared library
|
||||
AC_DEFUN([AX_LD_SHAREDLIB_OPTS],
|
||||
[AC_MSG_CHECKING([for shared library link flag])
|
||||
shared=-shared
|
||||
case "${host}" in
|
||||
*-*-cygwin*)
|
||||
shared="-shared -Wl,--enable-auto-image-base"
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
shared="-b"
|
||||
;;
|
||||
|
||||
*-*-darwin1.[0123])
|
||||
shared="-bundle -undefined suppress"
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
shared="-bundle -undefined suppress -flat_namespace"
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(shared)
|
||||
AC_MSG_RESULT($shared)
|
||||
])# AX_LD_SHAREDLIB_OPTS
|
||||
|
||||
# AX_C_PICFLAG
|
||||
# ------------
|
||||
# The -fPIC flag is used to tell the compiler to make position
|
||||
# independent code. It is needed when making shared objects.
|
||||
AC_DEFUN([AX_C_PICFLAG],
|
||||
[AC_MSG_CHECKING([for flag to make position independent code])
|
||||
PICFLAG=-fPIC
|
||||
case "${host}" in
|
||||
|
||||
*-*-cygwin*)
|
||||
PICFLAG=
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
PICFLAG=+z
|
||||
;;
|
||||
|
||||
esac
|
||||
AC_SUBST(PICFLAG)
|
||||
AC_MSG_RESULT($PICFLAG)
|
||||
])# AX_C_PICFLAG
|
||||
|
||||
# AX_LD_RDYNAMIC
|
||||
# --------------
|
||||
# The -rdynamic flag is used by iverilog when compiling the target,
|
||||
# to know how to export symbols of the main program to loadable modules
|
||||
# that are brought in by -ldl
|
||||
AC_DEFUN([AX_LD_RDYNAMIC],
|
||||
[AC_MSG_CHECKING([for -rdynamic compiler flag])
|
||||
rdynamic=-rdynamic
|
||||
case "${host}" in
|
||||
|
||||
*-*-netbsd*)
|
||||
rdynamic="-Wl,--export-dynamic"
|
||||
;;
|
||||
|
||||
*-*-openbsd*)
|
||||
rdynamic="-Wl,--export-dynamic"
|
||||
;;
|
||||
|
||||
*-*-solaris*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-cygwin*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
rdynamic="-E"
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
rdynamic="-Wl,-all_load"
|
||||
strip_dynamic="-SX"
|
||||
;;
|
||||
|
||||
esac
|
||||
AC_SUBST(rdynamic)
|
||||
AC_MSG_RESULT($rdynamic)
|
||||
AC_SUBST(strip_dynamic)
|
||||
# since we didn't tell them we're "checking", no good place to tell the answer
|
||||
# AC_MSG_RESULT($strip_dynamic)
|
||||
])# AX_LD_RDYNAMIC
|
||||
|
||||
# AX_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
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2002 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: async.cc,v 1.7 2004/01/18 23:26:54 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "functor.h"
|
||||
# include "netlist.h"
|
||||
# include <assert.h>
|
||||
|
||||
bool NetAssign::is_asynchronous()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetCondit::is_asynchronous()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* NetEvWait statements come from statements of the form @(...) in the
|
||||
* Verilog source. These event waits are considered asynchronous if
|
||||
* all of the events in the list are ANYEDGE, and all the inputs to
|
||||
* the statement are included in the sensitivity list. If any of the
|
||||
* events are posedge or negedge, the statement is synchronous
|
||||
* (i.e. an edge-triggered flip-flop) and if any of the inputs are
|
||||
* unaccounted for in the sensitivity list then the statement is a
|
||||
* latch.
|
||||
*/
|
||||
bool NetEvWait::is_asynchronous()
|
||||
{
|
||||
/* The "sense" set contains the set of Nexa that are in the
|
||||
sensitivity list. We also require that the events are all
|
||||
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_();
|
||||
if (tmp == 0) {
|
||||
delete sense;
|
||||
return false;
|
||||
}
|
||||
|
||||
sense->add(*tmp);
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
NexusSet*inputs = statement_->nex_input();
|
||||
|
||||
if (! sense->contains(*inputs)) {
|
||||
delete sense;
|
||||
delete inputs;
|
||||
return false;
|
||||
}
|
||||
|
||||
delete sense;
|
||||
delete inputs;
|
||||
|
||||
/* If it passes all the other tests, then this statement is
|
||||
asynchronous. */
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetProc::is_asynchronous()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool NetProcTop::is_asynchronous()
|
||||
{
|
||||
if (type_ == NetProcTop::KINITIAL)
|
||||
return false;
|
||||
|
||||
return statement_->is_asynchronous();
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: async.cc,v $
|
||||
* Revision 1.7 2004/01/18 23:26:54 steve
|
||||
* The is_combinational function really need not recurse.
|
||||
*
|
||||
* Revision 1.6 2003/12/20 00:33:39 steve
|
||||
* More thorough check that NetEvWait is asynchronous.
|
||||
*
|
||||
* Revision 1.5 2003/09/04 20:28:05 steve
|
||||
* Support time0 resolution of combinational threads.
|
||||
*
|
||||
* Revision 1.4 2002/08/18 22:07:16 steve
|
||||
* Detect temporaries in sequential block synthesis.
|
||||
*
|
||||
* Revision 1.3 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2002/07/04 00:24:16 steve
|
||||
* initial statements are not asynchronous.
|
||||
*
|
||||
* Revision 1.1 2002/06/30 02:21:31 steve
|
||||
* Add structure for asynchronous logic synthesis.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
|
||||
ATTRIBUTE NAMING CONVENTIONS
|
||||
|
||||
Attributes that are specific to Icarus Verilog, and are intended to be
|
||||
of use to programmers, start with the prefix "ivl_".
|
||||
|
||||
Attributes with the "_ivl_" prefix are set aside for internal
|
||||
use. They may be generated internally by the compiler. They need not
|
||||
be documented here.
|
||||
|
||||
ATTRIBUTES TO CONTROL SYNTHESIS
|
||||
|
||||
The following is a summary of Verilog attributes that Icarus Verilog
|
||||
understands within Verilog source files to control synthesis
|
||||
behavior. This section documents generic synthesis attributes. For
|
||||
target specific attributes, see target specific documentation.
|
||||
|
||||
These attributes only effect the behavior of the synthesizer. For
|
||||
example, the ivl_combinational will not generate an error message
|
||||
if the Verilog is being compiled for simulation. (It may generate a
|
||||
warning.)
|
||||
|
||||
|
||||
* Attributes for "always" and "initial" statements
|
||||
|
||||
(* ivl_combinational *)
|
||||
|
||||
This attribute tells the compiler that the statement models
|
||||
combinational logic. If the compiler finds that it cannot make
|
||||
combinational logic out of a marked always statement, it will
|
||||
report an error.
|
||||
|
||||
This attribute can be used to prevent accidentally inferring
|
||||
latches or flip-flops where the user intended combinational
|
||||
logic.
|
||||
|
||||
(* ivl_synthesis_on *)
|
||||
|
||||
This attribute tells the compiler that the marked always statement
|
||||
is synthesizable. The compiler will attempt to synthesize the
|
||||
code in the marked "always" statement. If it cannot in any way
|
||||
synthesize it, then it will report an error.
|
||||
|
||||
(* ivl_synthesis_off *)
|
||||
|
||||
If this value is attached to an "always" statement, then the
|
||||
compiler will *not* synthesize the "always" statement. This can be
|
||||
used, for example, to mark embedded test bench code.
|
||||
|
||||
|
||||
* Attributes for modules
|
||||
|
||||
(* ivl_synthesis_cell *)
|
||||
|
||||
If this value is attached to a module during synthesis, that
|
||||
module will be considered a target architecture primitive, and
|
||||
its interior will not be synthesized further. The module can
|
||||
therefore hold a model for simulation purposes.
|
||||
|
||||
|
||||
* Attributes for signals (wire/reg/integer/tri/etc.)
|
||||
|
||||
(* PAD = "<pad assignment list>" *)
|
||||
|
||||
If this attribute is attached to a signal that happens to be a
|
||||
root module port, then targets that support it will use the string
|
||||
value as a list of pin assignments for the port/signal. The format
|
||||
is a comma separated list of location tokens, with the format of
|
||||
the token itself defined by the back-end tools in use.
|
||||
|
||||
* Other Attributes
|
||||
|
||||
[ none defined yet ]
|
||||
|
||||
|
||||
MISC
|
||||
|
||||
(* _ivl_schedule_push *)
|
||||
|
||||
If this attribute is attached to a thread object (always or
|
||||
initial statement) then the vvp code generator will generate code
|
||||
that causes the scheduler to push this thread at compile time. The
|
||||
compiler may internally add this attribute to always statements if
|
||||
it detects that it is combinational. This helps resolve time-0
|
||||
races.
|
||||
+5
-3
@@ -9,9 +9,11 @@
|
||||
echo "Autoconf in root..."
|
||||
autoconf
|
||||
|
||||
for dir
|
||||
in vpip vvp tgt-vvp
|
||||
for dir in vpip vpi vvp tgt-vvp tgt-fpga libveriuser cadpli
|
||||
do
|
||||
echo "Autoconf in $dir..."
|
||||
( cd $dir ; autoconf )
|
||||
( cd ./$dir ; autoconf --include=.. )
|
||||
done
|
||||
|
||||
echo "Precompiling lexor_keyword.gperf"
|
||||
gperf -o -i 7 -C -k 1-3,\$ -L ANSI-C -H keyword_hash -N check_identifier -t ./lexor_keyword.gperf > lexor_keyword.cc
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
Makefile
|
||||
cadpli.vpl
|
||||
dep
|
||||
configure
|
||||
config.log
|
||||
config.status
|
||||
autom4te.cache
|
||||
@@ -0,0 +1,105 @@
|
||||
#
|
||||
# This source code is free software; you can redistribute it
|
||||
# and/or modify it in source code form under the terms of the GNU
|
||||
# Library General Public License as published by the Free Software
|
||||
# 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 Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc.,
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.11 2004/10/04 01:09:07 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.0
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
srcdir = @srcdir@
|
||||
|
||||
VPATH = $(srcdir)
|
||||
|
||||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
includedir = $(prefix)/include
|
||||
|
||||
vpidir = @libdir@/ivl/@vpidir1@
|
||||
|
||||
strip_dynamic=@strip_dynamic@
|
||||
|
||||
CC = @CC@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @ident_support@ -I$(srcdir) -I$(srcdir)/.. -I.. @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CFLAGS = -Wall @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
STRIP = @STRIP@
|
||||
|
||||
SHARED = @shared@
|
||||
|
||||
all:
|
||||
|
||||
ifeq (@enable_vvp32@,yes)
|
||||
vpidir32 = $(libdir)/ivl/@vpidir2@
|
||||
ALL32 = all32
|
||||
INSTALL32 = install32
|
||||
UNINSTALL32 = uninistall32
|
||||
include $(srcdir)/enable_vvp32.mk
|
||||
endif
|
||||
|
||||
all: dep cadpli.vpl $(ALL32)
|
||||
|
||||
# No specific check operations.
|
||||
check: all
|
||||
|
||||
dep:
|
||||
mkdir dep
|
||||
|
||||
%.o: %.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -MD -c $<
|
||||
mv $*.d dep
|
||||
|
||||
O = cadpli.o
|
||||
|
||||
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
|
||||
ifeq (@WIN32@,yes)
|
||||
SYSTEM_VPI_LDFLAGS += @EXTRALIBS@
|
||||
endif
|
||||
|
||||
cadpli.vpl: $O ../vvp/libvpi.a ../libveriuser/libveriuser.o
|
||||
$(CC) @shared@ -o $@ $O ../libveriuser/libveriuser.o $(SYSTEM_VPI_LDFLAGS)
|
||||
|
||||
clean:
|
||||
rm -rf *.o dep cadpli.vpl bin32
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.status config.log config.cache
|
||||
|
||||
install: all installdirs $(vpidir)/cadpli.vpl $(INSTALL32)
|
||||
|
||||
$(vpidir)/cadpli.vpl: ./cadpli.vpl
|
||||
$(INSTALL_PROGRAM) ./cadpli.vpl $(vpidir)/cadpli.vpl
|
||||
|
||||
installdirs: ../mkinstalldirs
|
||||
$(srcdir)/../mkinstalldirs $(vpidir)
|
||||
|
||||
uninstall: $(UNINSTALL32)
|
||||
rm -f $(vpidir)/cadpli.vpl
|
||||
|
||||
ifeq (@enable_vvp32@,yes)
|
||||
include $(srcdir)/enable_vvp32.mk
|
||||
endif
|
||||
|
||||
-include $(patsubst %.o, dep/%.d, $O)
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cadpli.c,v 1.7 2004/09/10 00:15:45 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <vpi_user.h>
|
||||
# include <veriuser.h>
|
||||
# include <stdlib.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
# include "ivl_dlfcn.h"
|
||||
|
||||
typedef void* (*funcvp)(void);
|
||||
|
||||
static void thunker_register(void)
|
||||
{
|
||||
struct t_vpi_vlog_info vlog_info;
|
||||
void*mod;
|
||||
void*boot;
|
||||
struct t_tfcell*tf;
|
||||
int idx;
|
||||
|
||||
vpi_get_vlog_info(&vlog_info);
|
||||
|
||||
for (idx = 0 ; idx < vlog_info.argc ; idx += 1) {
|
||||
char*module, *cp, *bp;
|
||||
if (strncmp("-cadpli=", vlog_info.argv[idx], 8) != 0)
|
||||
continue;
|
||||
|
||||
cp = vlog_info.argv[idx] + 8;
|
||||
assert(cp);
|
||||
|
||||
bp = strchr(cp, ':');
|
||||
assert(bp);
|
||||
|
||||
module = malloc(bp-cp+1);
|
||||
strncpy(module, cp, bp-cp);
|
||||
module[bp-cp] = 0;
|
||||
|
||||
mod = ivl_dlopen(module);
|
||||
if (mod == 0) {
|
||||
vpi_printf("%s link: %s\n", vlog_info.argv[idx], dlerror());
|
||||
free(module);
|
||||
continue;
|
||||
}
|
||||
|
||||
bp += 1;
|
||||
boot = ivl_dlsym(mod, bp);
|
||||
if (boot == 0) {
|
||||
vpi_printf("%s: Symbol %s not found.\n",
|
||||
vlog_info.argv[idx], bp);
|
||||
free(module);
|
||||
continue;
|
||||
}
|
||||
|
||||
free(module);
|
||||
assert(boot);
|
||||
|
||||
tf = (*((funcvp)boot))();
|
||||
assert(tf);
|
||||
|
||||
veriusertfs_register_table(tf);
|
||||
}
|
||||
}
|
||||
|
||||
void (*vlog_startup_routines[])() = {
|
||||
thunker_register,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* $Log: cadpli.c,v $
|
||||
* Revision 1.7 2004/09/10 00:15:45 steve
|
||||
* Remove bad casts.
|
||||
*
|
||||
* Revision 1.6 2004/09/05 21:19:51 steve
|
||||
* Better type safety.
|
||||
*
|
||||
* Revision 1.5 2003/08/26 16:26:02 steve
|
||||
* ifdef idents correctly.
|
||||
*
|
||||
* Revision 1.4 2003/04/30 01:28:06 steve
|
||||
* Remove veriusertfs stuf.
|
||||
*
|
||||
* Revision 1.3 2003/02/22 04:04:38 steve
|
||||
* Only include malloc.h if it is present.
|
||||
*
|
||||
* Revision 1.2 2003/02/17 00:01:25 steve
|
||||
* Use a variant of ivl_dlfcn to do dynamic loading
|
||||
* from within the cadpli module.
|
||||
*
|
||||
* Change the +cadpli flag to -cadpli, to keep the
|
||||
* plusargs namespace clear.
|
||||
*
|
||||
* Revision 1.1 2003/02/16 02:23:54 steve
|
||||
* Add the cadpli interface module.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
|
||||
CADENCE PLI1 MODULES
|
||||
|
||||
Copyright 2003 Stephen Williams
|
||||
$Id: cadpli.txt,v 1.2 2003/02/17 00:01:25 steve Exp $
|
||||
|
||||
With the cadpli module, Icarus Verilog is able to load PLI1
|
||||
applications that were compiled and linked to be dynamic loaded by
|
||||
Verilog-XL or NC-Verilog. This allows Icarus Verilog users to run
|
||||
third-party modules that were compiled to interface with XL or
|
||||
NC. Obviously, this only works on the operating system that the PLI
|
||||
application was compiled to run on. For example, a Linux module can
|
||||
only be loaded and run under Linux.
|
||||
|
||||
Icarus Verilog uses an interface module, the "cadpli" module, to
|
||||
connect the worlds. This module is installed with Icarus Verilog, and
|
||||
is invoked by the usual -m flag to iverilog or vvp. This module in
|
||||
turn scans the extended arguments, looking for +cadpli= arguments. The
|
||||
latter specify the share object and bootstrap function for running the
|
||||
module. For example, to run the module product.so, that has the
|
||||
bootstrap function "my_boot":
|
||||
|
||||
vvp -mcadpli a.out -cadpli=./product.so:my_boot
|
||||
|
||||
The "-mcadpli" argument causes vvp to load the cadpli.vpl library
|
||||
module. This activates the -cadpli= argument interpreter. The
|
||||
-cadpli=<module>:<boot_func> argument, then, causes vvp, through the
|
||||
cadpli module, to load the loadable PLI application, invoke the
|
||||
my_boot function to get a veriusertfs table, and scan that table to
|
||||
register the system tasks and functions exported by that object. The
|
||||
format of the -cadpli= extended argument is essentially the same as
|
||||
the +loadpli1= argument to Verilog-XL.
|
||||
|
||||
The integration from this point is seamless. The PLI application
|
||||
hardly knows that it is being invoked by Icarus Verilog instead of
|
||||
Verilog-XL, so operates as it would otherwise.
|
||||
|
||||
$Log: cadpli.txt,v $
|
||||
Revision 1.2 2003/02/17 00:01:25 steve
|
||||
Use a variant of ivl_dlfcn to do dynamic loading
|
||||
from within the cadpli module.
|
||||
|
||||
Change the +cadpli flag to -cadpli, to keep the
|
||||
plusargs namespace clear.
|
||||
|
||||
Revision 1.1 2003/02/16 02:44:47 steve
|
||||
Add the cadpli HOWTO.
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
AC_INIT(Makefile.in)
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_CHECK_TOOL(STRIP, strip, true)
|
||||
|
||||
AC_EXEEXT
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
# Combined check for Microsoft-related bogosities; sets WIN32 if found
|
||||
AX_WIN32
|
||||
|
||||
AC_PROG_INSTALL
|
||||
|
||||
# vvp32 is by default disabled
|
||||
#enable_vvp32=no
|
||||
AC_SUBST(enable_vvp32)
|
||||
|
||||
AC_CHECK_HEADERS(malloc.h)
|
||||
|
||||
AC_CHECK_SIZEOF(unsigned long long)
|
||||
AC_CHECK_SIZEOF(unsigned long)
|
||||
AC_CHECK_SIZEOF(unsigned)
|
||||
|
||||
# --
|
||||
# Look for a dl library to use. First look for the standard dlopen
|
||||
# functions, and failing that look for the HP specific shl_load function.
|
||||
|
||||
AC_CHECK_HEADERS(dlfcn.h dl.h, break)
|
||||
|
||||
DLLIB=''
|
||||
AC_CHECK_LIB(dl,dlopen,[DLLIB=-ldl])
|
||||
if test -z "$DLLIB" ; then
|
||||
AC_CHECK_LIB(dld,shl_load,[DLLIB=-ldld])
|
||||
fi
|
||||
AC_SUBST(DLLIB)
|
||||
|
||||
AX_CPP_PRECOMP
|
||||
|
||||
# Compiler option for position independent code, needed whan making shared objects.
|
||||
AX_C_PICFLAG
|
||||
|
||||
# Linker option used when compiling the target
|
||||
AX_LD_RDYNAMIC
|
||||
|
||||
# linker options when building a shared library
|
||||
AX_LD_SHAREDLIB_OPTS
|
||||
|
||||
AX_LD_EXTRALIBS
|
||||
|
||||
#######################
|
||||
## test for underscores. The vpi module loader in vvm needs to know this
|
||||
## in order to know the name of the start symbol for the .vpi module.
|
||||
#######################
|
||||
|
||||
AX_C_UNDERSCORES_LEADING
|
||||
AX_C_UNDERSCORES_TRAILING
|
||||
|
||||
#######################
|
||||
## end of test for underscores
|
||||
#######################
|
||||
|
||||
AX_CPP_IDENT
|
||||
|
||||
# where to put vpi subdirectories
|
||||
AC_MSG_CHECKING(for VPI subdirectories)
|
||||
if test x${vpidir1} = x
|
||||
then
|
||||
vpidir1="."
|
||||
fi
|
||||
|
||||
AC_SUBST(vpidir1)
|
||||
AC_SUBST(vpidir2)
|
||||
AC_MSG_RESULT(${vpidir1} ${vpidir2})
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
@@ -0,0 +1,39 @@
|
||||
#
|
||||
# This source code is free software; you can redistribute it
|
||||
# and/or modify it in source code form under the terms of the GNU
|
||||
# Library General Public License as published by the Free Software
|
||||
# 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 Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc.,
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: enable_vvp32.mk,v 1.1 2003/10/09 01:07:20 steve Exp $"
|
||||
#
|
||||
|
||||
all32: bin32 bin32/cadpli.vpl
|
||||
|
||||
bin32:
|
||||
mkdir bin32
|
||||
|
||||
bin32/%.o: %.c
|
||||
$(CC) -m32 -Wall -I$(srcdir) -I$(srcdir)/.. $(CPPFLAGS) $(CFLAGS) -MD -c $< -o $@
|
||||
|
||||
bin32/cadpli.vpl: $(addprefix bin32/,$O) ../vvp/bin32/libvpi.a ../libveriuser/bin32/libveriuser.o
|
||||
$(CC) $(SHARED) -m32 -o $@ $(addprefix bin32/,$O) ../libveriuser/bin32/libveriuser.o ../vvp/bin32/libvpi.a
|
||||
|
||||
install32: all32 $(vpidir32)/cadpli.vpl
|
||||
|
||||
$(vpidir32)/cadpli.vpl: bin32/cadpli.vpl
|
||||
$(INSTALL_PROGRAM) bin32/cadpli.vpl $(vpidir32)/cadpli.vpl
|
||||
|
||||
uninstall32:
|
||||
rm -f $(vpidir32)/cadpli.vpl
|
||||
@@ -18,11 +18,15 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: ivl_dlfcn.h,v 1.1 2001/01/14 17:12:59 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: ivl_dlfcn.h,v 1.3 2004/10/04 01:10:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DLFCN_H)
|
||||
#if defined(__MINGW32__)
|
||||
# include <windows.h>
|
||||
# include <stdio.h>
|
||||
typedef void * ivl_dll_t;
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
# include <dlfcn.h>
|
||||
typedef void* ivl_dll_t;
|
||||
#elif defined(HAVE_DL_H)
|
||||
@@ -30,12 +34,44 @@ typedef void* ivl_dll_t;
|
||||
typedef shl_t ivl_dll_t;
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_DLFCN_H)
|
||||
#if defined(__MINGW32__)
|
||||
inline ivl_dll_t ivl_dlopen(const char *name)
|
||||
{ return (void *)LoadLibrary(name); }
|
||||
|
||||
inline void *ivl_dlsym(ivl_dll_t dll, const char *nm)
|
||||
{ return (void *)GetProcAddress((HINSTANCE)dll,nm);}
|
||||
|
||||
inline void ivl_dlclose(ivl_dll_t dll)
|
||||
{ (void)FreeLibrary((HINSTANCE)dll);}
|
||||
|
||||
inline const char *dlerror(void)
|
||||
{
|
||||
static char msg[256];
|
||||
unsigned long err = GetLastError();
|
||||
FormatMessage(
|
||||
FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,
|
||||
err,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
||||
(LPTSTR) &msg,
|
||||
sizeof(msg) - 1,
|
||||
NULL
|
||||
);
|
||||
return msg;
|
||||
}
|
||||
|
||||
#elif defined(HAVE_DLFCN_H)
|
||||
inline ivl_dll_t ivl_dlopen(const char*name)
|
||||
{ return dlopen(name,RTLD_NOW); }
|
||||
{ return dlopen(name,RTLD_LAZY); }
|
||||
|
||||
inline void* ivl_dlsym(ivl_dll_t dll, const char*nm)
|
||||
{ return dlsym(dll, nm); }
|
||||
{
|
||||
void*sym = dlsym(dll, nm);
|
||||
/* Not found? try without the leading _ */
|
||||
if (sym == 0 && nm[0] == '_')
|
||||
sym = dlsym(dll, nm+1);
|
||||
return sym;
|
||||
}
|
||||
|
||||
inline void ivl_dlclose(ivl_dll_t dll)
|
||||
{ dlclose(dll); }
|
||||
@@ -60,8 +96,18 @@ inline const char*dlerror(void)
|
||||
|
||||
/*
|
||||
* $Log: ivl_dlfcn.h,v $
|
||||
* Revision 1.1 2001/01/14 17:12:59 steve
|
||||
* possible HP/UX portability support.
|
||||
* Revision 1.3 2004/10/04 01:10:56 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.2 2003/12/12 05:43:08 steve
|
||||
* Some systems dlsym requires leading _ or not on whim.
|
||||
*
|
||||
* Revision 1.1 2003/02/17 00:01:25 steve
|
||||
* Use a variant of ivl_dlfcn to do dynamic loading
|
||||
* from within the cadpli module.
|
||||
*
|
||||
* Change the +cadpli flag to -cadpli, to keep the
|
||||
* plusargs namespace clear.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+4
-6
@@ -1,6 +1,4 @@
|
||||
|
||||
# The make check target uses this to check the compilation of the
|
||||
# compiler.
|
||||
|
||||
[-tvvm-check]
|
||||
<ivl>./ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tvvm -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -o%o.cc -- -
|
||||
functor:cprop
|
||||
functor:nodangle
|
||||
-t:dll
|
||||
flag:DLL=tgt-vvp/vvp.tgt
|
||||
|
||||
+106
-16
@@ -1,7 +1,7 @@
|
||||
#ifndef __compiler_H
|
||||
#define __compiler_H
|
||||
/*
|
||||
* Copyright (c) 1999-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-2004 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,10 +18,15 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: compiler.h,v 1.5 2000/10/31 17:49:02 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: compiler.h,v 1.26 2004/10/04 01:10:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include "netlist.h"
|
||||
# include "StringHeap.h"
|
||||
|
||||
/*
|
||||
* This defines constants and defaults for the compiler in general.
|
||||
*/
|
||||
@@ -59,30 +64,115 @@
|
||||
|
||||
/*
|
||||
* These are flags to enable various sorts of warnings. By default all
|
||||
* the warnings are of, the -W<list> parameter arranges for each to be
|
||||
* enabled.
|
||||
* the warnings are off, the -W<list> parameter arranges for each to be
|
||||
* enabled.
|
||||
*/
|
||||
|
||||
/* Implicit definitions of wires. */
|
||||
extern bool warn_implicit;
|
||||
extern bool error_implicit;
|
||||
|
||||
/* inherit timescales across files. */
|
||||
extern bool warn_timescale;
|
||||
|
||||
/* Warn about legal but questionable module port bindings. */
|
||||
extern bool warn_portbinding;
|
||||
|
||||
/* This is true if verbose output is requested. */
|
||||
extern bool verbose_flag;
|
||||
|
||||
extern bool debug_scopes;
|
||||
extern bool debug_eval_tree;
|
||||
extern bool debug_elaborate;
|
||||
|
||||
/* Path to a directory useful for finding subcomponents. */
|
||||
extern const char*basedir;
|
||||
|
||||
/* This is an ordered list of library suffixes to search. */
|
||||
extern list<const char*>library_suff;
|
||||
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. */
|
||||
enum generation_t {
|
||||
GN_VER1995 = 1,
|
||||
GN_VER2001 = 2,
|
||||
GN_SYSVER30 = 3,
|
||||
GN_DEFAULT = 3
|
||||
};
|
||||
|
||||
extern generation_t generation_flag;
|
||||
|
||||
/* This is the string to use to invoke the preprocessor. */
|
||||
extern char*ivlpp_string;
|
||||
|
||||
extern map<perm_string,unsigned> missing_modules;
|
||||
|
||||
/*
|
||||
* the lex_strings are perm_strings made up of tokens from the source
|
||||
* file. Identifiers are so likely to be used many times that it makes
|
||||
* much sense to use a StringHeapLex to hold them.
|
||||
*/
|
||||
extern StringHeapLex lex_strings;
|
||||
|
||||
|
||||
/*
|
||||
* system task/function listings.
|
||||
*/
|
||||
/*
|
||||
* This table describes all the return values of various system
|
||||
* functions. This table is used to elaborate expressions that are
|
||||
* system function calls.
|
||||
*/
|
||||
struct sfunc_return_type {
|
||||
const char* name;
|
||||
NetExpr::TYPE type;
|
||||
unsigned wid;
|
||||
int signed_flag;
|
||||
};
|
||||
|
||||
extern const struct sfunc_return_type* lookup_sys_func(const char*name);
|
||||
extern int load_sys_func_table(const char*path);
|
||||
|
||||
/*
|
||||
* $Log: compiler.h,v $
|
||||
* Revision 1.5 2000/10/31 17:49:02 steve
|
||||
* Support time variables.
|
||||
* Revision 1.26 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.4 2000/08/20 04:13:56 steve
|
||||
* Add ivl_target support for logic gates, and
|
||||
* make the interface more accessible.
|
||||
* Revision 1.25 2004/09/25 01:58:44 steve
|
||||
* Add a debug_elaborate flag
|
||||
*
|
||||
* Revision 1.3 2000/03/17 21:50:25 steve
|
||||
* Switch to control warnings.
|
||||
* Revision 1.24 2004/09/10 23:51:42 steve
|
||||
* Fix the evaluation of constant ternary expressions.
|
||||
*
|
||||
* Revision 1.2 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
* Revision 1.23 2004/09/05 17:44:41 steve
|
||||
* Add support for module instance arrays.
|
||||
*
|
||||
* Revision 1.1 1999/06/06 20:42:48 steve
|
||||
* Make compiler width a compile time constant.
|
||||
* Revision 1.22 2004/03/10 04:51:24 steve
|
||||
* Add support for system function table files.
|
||||
*
|
||||
* Revision 1.21 2004/03/09 04:29:42 steve
|
||||
* Separate out the lookup_sys_func table, for eventual
|
||||
* support for function type tables.
|
||||
*
|
||||
* Remove ipal compile flags.
|
||||
*
|
||||
* Revision 1.20 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.19 2003/11/13 05:55:33 steve
|
||||
* Move the DLL= flag to target config files.
|
||||
*
|
||||
* Revision 1.18 2003/11/08 20:06:21 steve
|
||||
* Spelling fixes in comments.
|
||||
*
|
||||
* Revision 1.17 2003/09/25 00:25:14 steve
|
||||
* Summary list of missing modules.
|
||||
*
|
||||
* Revision 1.16 2003/03/01 06:25:30 steve
|
||||
* Add the lex_strings string handler, and put
|
||||
* scope names and system task/function names
|
||||
* into this table. Also, permallocate event
|
||||
* names from the beginning.
|
||||
*/
|
||||
#endif
|
||||
|
||||
Vendored
+776
-324
File diff suppressed because it is too large
Load Diff
+88
@@ -0,0 +1,88 @@
|
||||
#ifndef __config_H /* -*- c++ -*- */
|
||||
#define __config_H
|
||||
/*
|
||||
* Copyright (c) 2001 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: config.h.in,v 1.11 2004/10/04 01:10:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
# if !defined(__GNUC__)
|
||||
using namespace std;
|
||||
# elif (__GNUC__ == 3)
|
||||
using namespace std;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
# undef NEED_LU
|
||||
# undef NEED_TU
|
||||
# undef WLU
|
||||
# undef WTU
|
||||
# undef HAVE_TIMES
|
||||
# undef HAVE_IOSFWD
|
||||
# undef HAVE_GETOPT_H
|
||||
# undef HAVE_LIBIBERTY_H
|
||||
# undef HAVE_MALLOC_H
|
||||
# undef HAVE_DLFCN_H
|
||||
# undef HAVE_DL_H
|
||||
# undef HAVE_FCHMOD
|
||||
# undef HAVE_LIBREADLINE
|
||||
# undef HAVE_LIBZ
|
||||
# undef HAVE_LIBBZ2
|
||||
# undef HAVE_SYS_WAIT_H
|
||||
# undef WORDS_BIGENDIAN
|
||||
|
||||
/*
|
||||
* $Log: config.h.in,v $
|
||||
* Revision 1.11 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.10 2003/08/26 16:26:01 steve
|
||||
* ifdef idents correctly.
|
||||
*
|
||||
* Revision 1.9 2003/07/03 16:29:55 steve
|
||||
* spemm WORDS_BIGENDIAN correctly.
|
||||
*
|
||||
* Revision 1.8 2003/03/07 02:44:33 steve
|
||||
* Implement $realtobits.
|
||||
*
|
||||
* Revision 1.7 2003/02/20 00:49:24 steve
|
||||
* detect -lz and -lbz2 libraries.
|
||||
*
|
||||
* Revision 1.6 2003/01/10 19:01:04 steve
|
||||
* Only use libiberty.h if available.
|
||||
*
|
||||
* Revision 1.5 2002/08/11 23:39:33 steve
|
||||
* Remove VVM option.
|
||||
*
|
||||
* Revision 1.4 2002/02/16 03:18:53 steve
|
||||
* Make vvm optional, normally off.
|
||||
*
|
||||
* Revision 1.3 2001/10/18 16:16:23 steve
|
||||
* Include HAVE_SYS_WAIT in config.h (PR#306)
|
||||
*
|
||||
* Revision 1.2 2001/09/15 18:27:04 steve
|
||||
* Make configure detect malloc.h
|
||||
*
|
||||
* Revision 1.1 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
*/
|
||||
#endif // __config_H
|
||||
Vendored
+484
-205
File diff suppressed because it is too large
Load Diff
+100
-107
@@ -1,17 +1,75 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(netlist.h)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_CONFIG_HEADER(_pli_types.h)
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_CHECK_TOOL(STRIP, strip, true)
|
||||
AC_CHECK_PROGS(XGPERF,gperf,none)
|
||||
if test "$XGPERF" = "none"
|
||||
then
|
||||
echo ""
|
||||
echo "*** Warning: No suitable gperf found. ***"
|
||||
echo " The gperf package is essential for building ivl from"
|
||||
echo " CVS sources, or modifying the parse engine of ivl itself."
|
||||
echo " You can get away without it when simply building from"
|
||||
echo " snapshots or major releases."
|
||||
echo ""
|
||||
fi
|
||||
|
||||
AC_CHECK_PROGS(LEX,flex,none)
|
||||
if test "$LEX" = "none"
|
||||
then
|
||||
echo "*** Error: No suitable flex found. ***"
|
||||
echo " Please install the 'flex' package."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_CHECK_PROGS(YACC,bison,none)
|
||||
if test "$YACC" = "none"
|
||||
then
|
||||
echo "*** Error: No suitable bison found. ***"
|
||||
echo " Please install the 'bison' package."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_EXEEXT
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
# Combined check for Microsoft-related bogosities; sets WIN32 if found
|
||||
AX_WIN32
|
||||
|
||||
# vvp32 is by default disabled
|
||||
#enable_vvp32=no
|
||||
AC_SUBST(enable_vvp32)
|
||||
|
||||
|
||||
AC_LANG_CPLUSPLUS
|
||||
|
||||
AC_CHECK_HEADERS(getopt.h iosfwd)
|
||||
AC_CHECK_HEADERS(getopt.h malloc.h inttypes.h libiberty.h iosfwd sys/wait.h)
|
||||
|
||||
AC_CHECK_HEADER(ipal.h, HAVE_IPAL=yes, HAVE_IPAL=)
|
||||
AC_SUBST(HAVE_IPAL)
|
||||
AC_CHECK_LIB(z, gzwrite)
|
||||
AC_CHECK_LIB(z, gzwrite, HAVE_LIBZ=yes, HAVE_LIBZ=no)
|
||||
AC_SUBST(HAVE_LIBZ)
|
||||
if test "$WIN32" = "yes"; then
|
||||
AC_CHECK_LIB(bz2, main)
|
||||
else
|
||||
AC_CHECK_LIB(bz2, BZ2_bzdopen)
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(for sys/times)
|
||||
AC_TRY_LINK(
|
||||
#include <unistd.h>
|
||||
#include <sys/times.h>
|
||||
,{clock_t a = times(0)/sysconf(_SC_CLK_TCK);},
|
||||
do_times=yes
|
||||
AC_DEFINE(HAVE_TIMES,1),
|
||||
do_times=no
|
||||
)
|
||||
AC_MSG_RESULT($do_times)
|
||||
|
||||
# --
|
||||
# Look for a dl library to use. First look for the standard dlopen
|
||||
@@ -29,125 +87,60 @@ AC_SUBST(DLLIB)
|
||||
AC_PROG_INSTALL
|
||||
|
||||
AC_LANG_C
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
# $host
|
||||
|
||||
AX_LD_EXTRALIBS
|
||||
|
||||
# Compiler option for position independent code, needed whan making shared objects.
|
||||
# CFLAGS inherited by cadpli/Makefile?
|
||||
AX_C_PICFLAG
|
||||
|
||||
# may modify CPPFLAGS and CFLAGS
|
||||
AX_CPP_PRECOMP
|
||||
|
||||
# Linker option used when compiling the target
|
||||
AX_LD_RDYNAMIC
|
||||
|
||||
# linker options when building a shared library
|
||||
AX_LD_SHAREDLIB_OPTS
|
||||
|
||||
#######################
|
||||
## test for underscores. The vpi module loader in vvm needs to know this
|
||||
## test for underscores. The vpi module loader needs to know this
|
||||
## in order to know the name of the start symbol for the .vpi module.
|
||||
#######################
|
||||
|
||||
AC_CYGWIN
|
||||
AC_EXEEXT
|
||||
AC_SUBST(CYGWIN)
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
AC_MSG_CHECKING("for leading and/or trailing underscores")
|
||||
cat << EOF > underscore.c
|
||||
void underscore(void){}
|
||||
EOF
|
||||
$CC -shared -c underscore.c > /dev/null 2>&1
|
||||
|
||||
CC_LEADING_UNDERSCORE=no
|
||||
CC_TRAILING_UNDERSCORE=no
|
||||
|
||||
output=`nm underscore.o|grep _underscore 2>&1`
|
||||
if test ! -z "$output" -a -z "$CYGWIN" ; then
|
||||
CC_LEADING_UNDERSCORE=yes
|
||||
AC_DEFINE(NEED_LU)
|
||||
fi
|
||||
|
||||
|
||||
|
||||
output=`nm underscore.o|grep underscore_ 2>&1`
|
||||
if test ! -z "$output"; then
|
||||
CC_TRAILING_UNDERSCORE=yes
|
||||
AC_DEFINE(NEED_TU)
|
||||
fi
|
||||
|
||||
if test "$CC_LEADING_UNDERSCORE" = yes; then
|
||||
AC_DEFINE(WLU)
|
||||
fi
|
||||
if test "$CC_TRAILING_UNDERSCORE" = yes; then
|
||||
AC_DEFINE(WTU)
|
||||
fi
|
||||
|
||||
rm underscore.c underscore.o
|
||||
|
||||
AC_MSG_RESULT("$CC_LEADING_UNDERSCORE $CC_TRAILING_UNDERSCORE")
|
||||
AX_C_UNDERSCORES_LEADING
|
||||
AX_C_UNDERSCORES_TRAILING
|
||||
|
||||
#######################
|
||||
## end of test for underscores
|
||||
#######################
|
||||
|
||||
# The -fPIC flag is used to tell the compiler to make position
|
||||
# independent code. It is needed when making shared objects.
|
||||
AX_CPP_IDENT
|
||||
|
||||
AC_MSG_CHECKING("for flag to make position independent code")
|
||||
PICFLAG=-fPIC
|
||||
case "${host}" in
|
||||
# If not otherwise specified, set the libdir64 variable
|
||||
# to the same as libdir.
|
||||
AC_MSG_CHECKING(for libdir64 path)
|
||||
if test x${libdir64} = x
|
||||
then
|
||||
libdir64="${libdir}"
|
||||
fi
|
||||
AC_SUBST(libdir64)
|
||||
AC_MSG_RESULT(${libdir64})
|
||||
|
||||
*-*-cygwin*)
|
||||
PICFLAG=
|
||||
;;
|
||||
# where to put vpi subdirectories
|
||||
AC_MSG_CHECKING(for VPI subdirectories)
|
||||
if test x${vpidir1} = x
|
||||
then
|
||||
vpidir1="."
|
||||
fi
|
||||
|
||||
*-*-hpux*)
|
||||
PICFLAG=+z
|
||||
;;
|
||||
AC_SUBST(vpidir1)
|
||||
AC_SUBST(vpidir2)
|
||||
AC_MSG_RESULT(${vpidir1} ${vpidir2})
|
||||
|
||||
esac
|
||||
AC_SUBST(PICFLAG)
|
||||
AC_MSG_RESULT($PICFLAG)
|
||||
AC_CONFIG_SUBDIRS(vvp vpi tgt-vvp tgt-fpga libveriuser cadpli)
|
||||
|
||||
|
||||
# The -rdynamic flag is used by iverilog when compiling the target,
|
||||
# to know how to export symbols of the main program to loadable modules
|
||||
# that are brought in by -ldl
|
||||
AC_MSG_CHECKING("for -rdynamic compiler flag")
|
||||
|
||||
rdynamic=-rdynamic
|
||||
case "${host}" in
|
||||
|
||||
*-*-netbsd*)
|
||||
rdynamic="-Wl,--export-dynamic"
|
||||
;;
|
||||
|
||||
*-*-solaris*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-cygwin*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
rdynamic="-E"
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(rdynamic)
|
||||
AC_MSG_RESULT($rdynamic)
|
||||
|
||||
AC_MSG_CHECKING("for shared library link flag")
|
||||
shared=-shared
|
||||
case "${host}" in
|
||||
|
||||
*-*-cygwin*)
|
||||
shared="-mdll -Wl,--enable-auto-image-base"
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
shared="-b"
|
||||
;;
|
||||
|
||||
esac
|
||||
|
||||
AC_SUBST(shared)
|
||||
|
||||
AC_MSG_RESULT($shared)
|
||||
|
||||
|
||||
AC_CONFIG_SUBDIRS(vpip vvp tgt-vvp)
|
||||
|
||||
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile vvm/Makefile driver/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
|
||||
AC_OUTPUT(Makefile ivlpp/Makefile driver/Makefile driver-vpi/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1998-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1998-2003 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
|
||||
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: cprop.cc,v 1.26 2001/02/18 01:07:32 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cprop.cc,v 1.47 2004/02/20 18:53:34 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "functor.h"
|
||||
@@ -28,7 +30,7 @@
|
||||
|
||||
|
||||
/*
|
||||
* The cprop function below invokes constant propogation where
|
||||
* The cprop function below invokes constant propagation where
|
||||
* possible. The elaboration generates NetConst objects. I can remove
|
||||
* these and replace the gates connected to it with simpler ones. I
|
||||
* may even be able to replace nets with a new constant.
|
||||
@@ -54,7 +56,7 @@ void cprop_functor::signal(Design*des, NetNet*obj)
|
||||
void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
|
||||
{
|
||||
// For now, only additions are handled.
|
||||
if (obj->attribute("LPM_Direction") != "ADD")
|
||||
if (obj->attribute(perm_string::literal("LPM_Direction")) != verinum("ADD"))
|
||||
return;
|
||||
|
||||
// If the low bit on the A side is 0, then eliminate it from
|
||||
@@ -62,11 +64,11 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
|
||||
// result. Don't reduce the adder smaller then a 1-bit
|
||||
// adder. These will be eliminated later.
|
||||
while ((obj->width() > 1)
|
||||
&& link_drivers_constant(obj->pin_DataA(0))
|
||||
&& (driven_value(obj->pin_DataA(0)) == verinum::V0)) {
|
||||
&& obj->pin_DataA(0).nexus()->drivers_constant()
|
||||
&& (obj->pin_DataA(0).nexus()->driven_value() == verinum::V0)) {
|
||||
|
||||
NetAddSub*tmp = 0;
|
||||
tmp = new NetAddSub(obj->name(), obj->width()-1);
|
||||
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
|
||||
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
|
||||
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
|
||||
//connect(tmp->pin_Clock(), obj->pin_Clock());
|
||||
@@ -87,11 +89,11 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
|
||||
|
||||
// Now do the same thing on the B side.
|
||||
while ((obj->width() > 1)
|
||||
&& link_drivers_constant(obj->pin_DataB(0))
|
||||
&& (driven_value(obj->pin_DataB(0)) == verinum::V0)) {
|
||||
&& obj->pin_DataB(0).nexus()->drivers_constant()
|
||||
&& (obj->pin_DataB(0).nexus()->driven_value() == verinum::V0)) {
|
||||
|
||||
NetAddSub*tmp = 0;
|
||||
tmp = new NetAddSub(obj->name(), obj->width()-1);
|
||||
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
|
||||
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
|
||||
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
|
||||
//connect(tmp->pin_Clock(), obj->pin_Clock());
|
||||
@@ -116,8 +118,8 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
|
||||
NetLogic*tmp;
|
||||
if (obj->pin_Cout().is_linked()) {
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
des->local_symbol(obj->name()), 3,
|
||||
NetLogic::AND);
|
||||
obj->scope()->local_symbol(),
|
||||
3, NetLogic::AND);
|
||||
connect(tmp->pin(0), obj->pin_Cout());
|
||||
connect(tmp->pin(1), obj->pin_DataA(0));
|
||||
connect(tmp->pin(2), obj->pin_DataB(0));
|
||||
@@ -151,21 +153,38 @@ void cprop_functor::lpm_compare(Design*des, NetCompare*obj)
|
||||
|
||||
void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
|
||||
{
|
||||
NetScope*scope = obj->scope();
|
||||
|
||||
unsigned const_count = 0;
|
||||
bool unknown_flag = false;
|
||||
|
||||
/* First, look for the case where constant bits on matching A
|
||||
and B inputs are different. This this is so, the device can
|
||||
be completely eliminated and replaced with a constant 0. */
|
||||
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
if (! link_drivers_constant(obj->pin_DataA(idx)))
|
||||
if (! obj->pin_DataA(idx).nexus()->drivers_constant())
|
||||
continue;
|
||||
if (! link_drivers_constant(obj->pin_DataB(idx)))
|
||||
continue;
|
||||
if (driven_value(obj->pin_DataA(idx)) ==
|
||||
driven_value(obj->pin_DataB(idx)))
|
||||
if (! obj->pin_DataB(idx).nexus()->drivers_constant())
|
||||
continue;
|
||||
|
||||
NetConst*zero = new NetConst(obj->name(), verinum::V0);
|
||||
const_count += 1;
|
||||
|
||||
verinum::V abit = obj->pin_DataA(idx).nexus()->driven_value();
|
||||
verinum::V bbit = obj->pin_DataB(idx).nexus()->driven_value();
|
||||
|
||||
if ((abit == verinum::V0) && (bbit == verinum::V0))
|
||||
continue;
|
||||
if ((abit == verinum::V1) && (bbit == verinum::V1))
|
||||
continue;
|
||||
|
||||
unknown_flag = true;
|
||||
if ((abit == verinum::Vz) || (abit == verinum::Vx))
|
||||
continue;
|
||||
if ((bbit == verinum::Vz) || (bbit == verinum::Vx))
|
||||
continue;
|
||||
|
||||
NetConst*zero = new NetConst(scope, obj->name(), verinum::V0);
|
||||
connect(zero->pin(0), obj->pin_AEB());
|
||||
delete obj;
|
||||
des->add_node(zero);
|
||||
@@ -173,16 +192,31 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
|
||||
return;
|
||||
}
|
||||
|
||||
/* If all the inputs are constant, then at this point the
|
||||
result is either V1 or Vx. */
|
||||
if (const_count == obj->width()) {
|
||||
|
||||
NetConst*val = new NetConst(scope, obj->name(),
|
||||
unknown_flag
|
||||
? verinum::Vx
|
||||
: verinum::V1);
|
||||
connect(val->pin(0), obj->pin_AEB());
|
||||
delete obj;
|
||||
des->add_node(val);
|
||||
count += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Still may need the gate. Run through the inputs again, and
|
||||
look for pairs of constants. Those inputs can be removed. */
|
||||
|
||||
unsigned top = obj->width();
|
||||
for (unsigned idx = 0 ; idx < top ; ) {
|
||||
if (! link_drivers_constant(obj->pin_DataA(idx))) {
|
||||
if (! obj->pin_DataA(idx).nexus()->drivers_constant()) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
if (! link_drivers_constant(obj->pin_DataB(idx))) {
|
||||
if (! obj->pin_DataB(idx).nexus()->drivers_constant()) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
@@ -202,7 +236,7 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
|
||||
/* If we wound up disconnecting all the inputs, then remove
|
||||
the device and replace it with a constant. */
|
||||
if (top == 0) {
|
||||
NetConst*one = new NetConst(obj->name(), verinum::V1);
|
||||
NetConst*one = new NetConst(scope, obj->name(), verinum::V1);
|
||||
connect(one->pin(0), obj->pin_AEB());
|
||||
delete obj;
|
||||
des->add_node(one);
|
||||
@@ -213,8 +247,8 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
|
||||
/* If there is only one bit left, then replace the comparator
|
||||
with a simple XOR gate. */
|
||||
if (top == 1) {
|
||||
NetLogic*tmp = new NetLogic(obj->scope(), obj->name(), 3,
|
||||
NetLogic::XOR);
|
||||
NetLogic*tmp = new NetLogic(scope, obj->name(), 3,
|
||||
NetLogic::XNOR);
|
||||
connect(tmp->pin(0), obj->pin_AEB());
|
||||
connect(tmp->pin(1), obj->pin_DataA(0));
|
||||
connect(tmp->pin(2), obj->pin_DataB(0));
|
||||
@@ -228,7 +262,7 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
|
||||
if (top == obj->width())
|
||||
return;
|
||||
|
||||
NetCompare*tmp = new NetCompare(obj->name(), top);
|
||||
NetCompare*tmp = new NetCompare(scope, obj->name(), top);
|
||||
connect(tmp->pin_AEB(), obj->pin_AEB());
|
||||
for (unsigned idx = 0 ; idx < top ; idx += 1) {
|
||||
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx));
|
||||
@@ -243,10 +277,14 @@ void cprop_functor::lpm_ff(Design*des, NetFF*obj)
|
||||
{
|
||||
// Look for and count unlinked FF outputs. Note that if the
|
||||
// Data and Q pins are connected together, they can be removed
|
||||
// from the circuit.
|
||||
// from the circuit, since it doesn't do anything.
|
||||
unsigned unlinked_count = 0;
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
if (connected(obj->pin_Data(idx), obj->pin_Q(idx))) {
|
||||
if (connected(obj->pin_Data(idx), obj->pin_Q(idx))
|
||||
&& (! obj->pin_Sclr().is_linked())
|
||||
&& (! obj->pin_Sset().is_linked())
|
||||
&& (! obj->pin_Aclr().is_linked())
|
||||
&& (! obj->pin_Aset().is_linked())) {
|
||||
obj->pin_Data(idx).unlink();
|
||||
obj->pin_Q(idx).unlink();
|
||||
}
|
||||
@@ -293,6 +331,8 @@ void cprop_functor::lpm_ff(Design*des, NetFF*obj)
|
||||
|
||||
void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
{
|
||||
NetScope*scope = obj->scope();
|
||||
|
||||
switch (obj->type()) {
|
||||
|
||||
case NetLogic::NAND:
|
||||
@@ -305,12 +345,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
on the output of an AND gate. */
|
||||
|
||||
while (idx < top) {
|
||||
if (! link_drivers_constant(obj->pin(idx))) {
|
||||
if (! obj->pin(idx).nexus()->drivers_constant()) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin(idx)) == verinum::V1) {
|
||||
if (obj->pin(idx).nexus()->driven_value()==verinum::V1) {
|
||||
obj->pin(idx).unlink();
|
||||
top -= 1;
|
||||
if (idx < top) {
|
||||
@@ -321,7 +361,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin(idx)) != verinum::V0) {
|
||||
if (obj->pin(idx).nexus()->driven_value() != verinum::V0) {
|
||||
idx += 1;
|
||||
xs += 1;
|
||||
continue;
|
||||
@@ -334,15 +374,19 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetConst*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::AND:
|
||||
tmp = new NetConst(obj->name(), verinum::V0);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V0);
|
||||
break;
|
||||
case NetLogic::NAND:
|
||||
tmp = new NetConst(obj->name(), verinum::V1);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V1);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -359,15 +403,19 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetConst*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::AND:
|
||||
tmp = new NetConst(obj->name(), verinum::V1);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V1);
|
||||
break;
|
||||
case NetLogic::NAND:
|
||||
tmp = new NetConst(obj->name(), verinum::V0);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -382,7 +430,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
gate with a Vx. */
|
||||
if (xs == (top-1)) {
|
||||
NetConst*tmp;
|
||||
tmp = new NetConst(obj->name(), verinum::Vx);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::Vx);
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -399,18 +447,23 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetLogic*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::AND:
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
break;
|
||||
case NetLogic::NAND:
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -422,12 +475,16 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
}
|
||||
|
||||
/* Finally, this cleans up the gate by creating a
|
||||
new [N]OR gate that has the right number of
|
||||
new [N]AND gate that has the right number of
|
||||
inputs, connected in the right place. */
|
||||
if (top < obj->pin_count()) {
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
NetLogic*tmp = new NetLogic(scope,
|
||||
obj->name(), top,
|
||||
obj->type());
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -452,12 +509,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
on the output of an OR gate. */
|
||||
|
||||
while (idx < top) {
|
||||
if (! link_drivers_constant(obj->pin(idx))) {
|
||||
if (! obj->pin(idx).nexus()->drivers_constant()) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin(idx)) == verinum::V0) {
|
||||
if (obj->pin(idx).nexus()->driven_value() == verinum::V0) {
|
||||
obj->pin(idx).unlink();
|
||||
top -= 1;
|
||||
if (idx < top) {
|
||||
@@ -468,7 +525,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
continue;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin(idx)) != verinum::V1) {
|
||||
if (obj->pin(idx).nexus()->driven_value() != verinum::V1) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
@@ -480,15 +537,19 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetConst*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::OR:
|
||||
tmp = new NetConst(obj->name(), verinum::V1);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V1);
|
||||
break;
|
||||
case NetLogic::NOR:
|
||||
tmp = new NetConst(obj->name(), verinum::V0);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -505,15 +566,19 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetConst*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::OR:
|
||||
tmp = new NetConst(obj->name(), verinum::V0);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V0);
|
||||
break;
|
||||
case NetLogic::NOR:
|
||||
tmp = new NetConst(obj->name(), verinum::V1);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V1);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -530,18 +595,22 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetLogic*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::OR:
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
break;
|
||||
case NetLogic::NOR:
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -556,9 +625,13 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
new [N]OR gate that has the right number of
|
||||
inputs, connected in the right place. */
|
||||
if (top < obj->pin_count()) {
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
NetLogic*tmp = new NetLogic(scope,
|
||||
obj->name(), top,
|
||||
obj->type());
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -578,14 +651,17 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
unsigned idx = 1;
|
||||
|
||||
/* Eliminate all the 0 inputs. They have no effect
|
||||
on the output of an XOR gate. */
|
||||
on the output of an XOR gate. The eliminate works
|
||||
by unlinking the current input and relinking the
|
||||
last input to this position. It's like bubbling
|
||||
all the 0 inputs to the end. */
|
||||
while (idx < top) {
|
||||
if (! link_drivers_constant(obj->pin(idx))) {
|
||||
if (! obj->pin(idx).nexus()->drivers_constant()) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin(idx)) == verinum::V0) {
|
||||
if (obj->pin(idx).nexus()->driven_value() == verinum::V0) {
|
||||
obj->pin(idx).unlink();
|
||||
top -= 1;
|
||||
if (idx < top) {
|
||||
@@ -610,12 +686,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
unsigned one = 0, ones = 0;
|
||||
idx = 1;
|
||||
while (idx < top) {
|
||||
if (! link_drivers_constant(obj->pin(idx))) {
|
||||
if (! obj->pin(idx).nexus()->drivers_constant()) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin(idx)) == verinum::V1) {
|
||||
if (obj->pin(idx).nexus()->driven_value() == verinum::V1) {
|
||||
if (one == 0) {
|
||||
one = idx;
|
||||
ones += 1;
|
||||
@@ -623,6 +699,8 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Here we found two constant V1
|
||||
inputs. Unlink both. */
|
||||
obj->pin(idx).unlink();
|
||||
top -= 1;
|
||||
if (idx < top) {
|
||||
@@ -637,8 +715,11 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
obj->pin(top).unlink();
|
||||
}
|
||||
|
||||
/* Reset ones counter and one index,
|
||||
start looking for the next pair. */
|
||||
assert(ones == 1);
|
||||
ones = 0;
|
||||
one = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -646,12 +727,16 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
}
|
||||
|
||||
/* If all the inputs were eliminated, then replace
|
||||
the gate with a constant 0 and I am done. */
|
||||
the gate with a constant value and I am done. */
|
||||
if (top == 1) {
|
||||
verinum::V out = obj->type()==NetLogic::XNOR
|
||||
? verinum::V1
|
||||
: verinum::V0;
|
||||
NetConst*tmp = new NetConst(obj->name(), out);
|
||||
NetConst*tmp = new NetConst(scope, obj->name(), out);
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
@@ -669,9 +754,9 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
|
||||
if ((top == 3) && (ones == 1)) {
|
||||
unsigned save;
|
||||
if (! link_drivers_constant(obj->pin(1)))
|
||||
if (! obj->pin(1).nexus()->drivers_constant())
|
||||
save = 1;
|
||||
else if (driven_value(obj->pin(1)) != verinum::V1)
|
||||
else if (obj->pin(1).nexus()->driven_value() != verinum::V1)
|
||||
save = 1;
|
||||
else
|
||||
save = 2;
|
||||
@@ -679,14 +764,18 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetLogic*tmp;
|
||||
|
||||
if (obj->type() == NetLogic::XOR)
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
else
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -704,14 +793,18 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetLogic*tmp;
|
||||
|
||||
if (obj->type() == NetLogic::XOR)
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
else
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
|
||||
tmp->rise_time(obj->rise_time());
|
||||
tmp->fall_time(obj->fall_time());
|
||||
tmp->decay_time(obj->decay_time());
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -726,7 +819,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
new XOR gate that has the right number of
|
||||
inputs, connected in the right place. */
|
||||
if (top < obj->pin_count()) {
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
NetLogic*tmp = new NetLogic(scope,
|
||||
obj->name(), top,
|
||||
obj->type());
|
||||
des->add_node(tmp);
|
||||
@@ -748,7 +841,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
}
|
||||
|
||||
/*
|
||||
* This detects the case where the mux selects between a value an
|
||||
* This detects the case where the mux selects between a value and
|
||||
* Vz. In this case, replace the device with a bufif with the sel
|
||||
* input used to enable the output.
|
||||
*/
|
||||
@@ -764,21 +857,22 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
||||
connected to the select input. */
|
||||
bool flag = true;
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
if (! link_drivers_constant(obj->pin_Data(idx, 0))) {
|
||||
if (! obj->pin_Data(idx, 0).nexus()->drivers_constant()) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin_Data(idx, 0)) != verinum::Vz) {
|
||||
if (obj->pin_Data(idx, 0).nexus()->driven_value() != verinum::Vz) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
NetScope*scope = obj->scope();
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
des->local_symbol(obj->name()),
|
||||
scope->local_symbol(),
|
||||
3, NetLogic::BUFIF1);
|
||||
|
||||
connect(obj->pin_Result(idx), tmp->pin(0));
|
||||
@@ -796,21 +890,22 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
|
||||
NetMux with an array of BUFIF0 devices. */
|
||||
flag = true;
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
if (! link_drivers_constant(obj->pin_Data(idx, 1))) {
|
||||
if (! obj->pin_Data(idx, 1).nexus()->drivers_constant()) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if (driven_value(obj->pin_Data(idx, 1)) != verinum::Vz) {
|
||||
if (obj->pin_Data(idx, 1).nexus()->driven_value() != verinum::Vz) {
|
||||
flag = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
NetScope*scope = obj->scope();
|
||||
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
des->local_symbol(obj->name()),
|
||||
scope->local_symbol(),
|
||||
3, NetLogic::BUFIF0);
|
||||
|
||||
connect(obj->pin_Result(idx), tmp->pin(0));
|
||||
@@ -839,7 +934,7 @@ struct cprop_dc_functor : public functor_t {
|
||||
void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
|
||||
{
|
||||
// 'bz constant values drive high impedance to whatever is
|
||||
// connected to it. In otherwords, it is a noop.
|
||||
// connected to it. In other words, it is a noop.
|
||||
{ unsigned tmp = 0;
|
||||
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1)
|
||||
if (obj->value(idx) == verinum::Vz) {
|
||||
@@ -882,7 +977,7 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
|
||||
return;
|
||||
|
||||
// Look for signals that have NetESignal nodes attached to
|
||||
// them. If I find any, this this constant is used by a
|
||||
// them. If I find any, then this constant is used by a
|
||||
// behavioral expression somewhere.
|
||||
for (unsigned idx = 0 ; idx < obj->pin_count() ; idx += 1) {
|
||||
Nexus*nex = obj->pin(idx).nexus();
|
||||
@@ -899,10 +994,17 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
|
||||
|
||||
assert(tmp->scope());
|
||||
|
||||
// If the net is a signal name from the source,
|
||||
// then users will probably want to see it in the
|
||||
// waveform dump, so unhooking the constant will
|
||||
// make it look wrong.
|
||||
if (! tmp->local_flag())
|
||||
return;
|
||||
|
||||
// If the net has an eref, then there is an
|
||||
// expression somewhere that reads this signal. So
|
||||
// the constant does get read.
|
||||
if (tmp->get_eref() > 0)
|
||||
if (tmp->peek_eref() > 0)
|
||||
return;
|
||||
|
||||
// If the net is a port of the root module, then
|
||||
@@ -915,7 +1017,6 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Done. Delete me.
|
||||
delete obj;
|
||||
}
|
||||
@@ -923,7 +1024,7 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
|
||||
|
||||
void cprop(Design*des)
|
||||
{
|
||||
// Continually propogate constants until a scan finds nothing
|
||||
// Continually propagate constants until a scan finds nothing
|
||||
// to do.
|
||||
cprop_functor prop;
|
||||
do {
|
||||
@@ -937,97 +1038,48 @@ void cprop(Design*des)
|
||||
|
||||
/*
|
||||
* $Log: cprop.cc,v $
|
||||
* Revision 1.26 2001/02/18 01:07:32 steve
|
||||
* check signals in the cprop functor.
|
||||
* Revision 1.47 2004/02/20 18:53:34 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.25 2001/02/16 03:27:31 steve
|
||||
* Constant propagation for compare ==.
|
||||
* Revision 1.46 2003/11/08 17:53:34 steve
|
||||
* Do not remove constants accessible to VPI.
|
||||
*
|
||||
* Revision 1.24 2001/02/10 04:50:54 steve
|
||||
* Catch constants driving root module ports. (PR#130)
|
||||
* Revision 1.45 2003/10/31 02:40:06 steve
|
||||
* Donot elide FF that has set or clr connections.
|
||||
*
|
||||
* Revision 1.23 2000/12/30 03:11:15 steve
|
||||
* Propagate initial value of constants into wires.
|
||||
* Revision 1.44 2003/04/25 05:06:32 steve
|
||||
* Handle X values in constant == nets.
|
||||
*
|
||||
* Revision 1.22 2000/11/23 01:55:52 steve
|
||||
* Propagate constants through xnor gates. (PR#51)
|
||||
* Revision 1.43 2003/03/06 00:28:41 steve
|
||||
* All NetObj objects have lex_string base names.
|
||||
*
|
||||
* Revision 1.21 2000/11/19 05:26:58 steve
|
||||
* Replace AND constand propagation.
|
||||
* Revision 1.42 2003/02/26 01:29:24 steve
|
||||
* LPM objects store only their base names.
|
||||
*
|
||||
* Revision 1.20 2000/11/18 05:13:27 steve
|
||||
* Thorough constant propagation for or and nor gates.
|
||||
* Revision 1.41 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.19 2000/11/18 04:10:37 steve
|
||||
* Handle constant propagation through XOR gates,
|
||||
* including reducing the gate to a constant,
|
||||
* a buffer or an inverter if possible.
|
||||
* Revision 1.40 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.18 2000/11/11 00:03:36 steve
|
||||
* Add support for the t-dll backend grabing flip-flops.
|
||||
* Revision 1.39 2002/08/20 04:12:22 steve
|
||||
* Copy gate delays when doing gate delay substitutions.
|
||||
*
|
||||
* Revision 1.17 2000/10/07 19:45:42 steve
|
||||
* Put logic devices into scopes.
|
||||
* Revision 1.38 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.16 2000/10/06 21:26:34 steve
|
||||
* Eliminate zero inputs to xor.
|
||||
* Revision 1.37 2002/06/25 01:33:22 steve
|
||||
* Cache calculated driven value.
|
||||
*
|
||||
* Revision 1.15 2000/08/02 14:48:01 steve
|
||||
* use bufif0 if z is in true case of mux.
|
||||
* Revision 1.36 2002/06/24 01:49:38 steve
|
||||
* Make link_drive_constant cache its results in
|
||||
* the Nexus, to improve cprop performance.
|
||||
*
|
||||
* Revision 1.14 2000/07/25 02:55:13 steve
|
||||
* Unlink z constants from nets.
|
||||
*
|
||||
* Revision 1.13 2000/07/15 05:13:43 steve
|
||||
* Detect muxing Vz as a bufufN.
|
||||
*
|
||||
* Revision 1.12 2000/06/25 19:59:41 steve
|
||||
* Redesign Links to include the Nexus class that
|
||||
* carries properties of the connected set of links.
|
||||
*
|
||||
* Revision 1.11 2000/06/24 22:55:19 steve
|
||||
* Get rid of useless next_link method.
|
||||
*
|
||||
* Revision 1.10 2000/05/14 17:55:04 steve
|
||||
* Support initialization of FF Q value.
|
||||
*
|
||||
* Revision 1.9 2000/05/07 04:37:56 steve
|
||||
* Carry strength values from Verilog source to the
|
||||
* pform and netlist for gates.
|
||||
*
|
||||
* Change vvm constants to use the driver_t to drive
|
||||
* a constant value. This works better if there are
|
||||
* multiple drivers on a signal.
|
||||
*
|
||||
* Revision 1.8 2000/04/28 21:00:28 steve
|
||||
* Over agressive signal elimination in constant probadation.
|
||||
*
|
||||
* Revision 1.7 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.6 2000/01/02 17:56:42 steve
|
||||
* Do not delete constants that input to exressions.
|
||||
*
|
||||
* Revision 1.5 1999/12/30 04:19:12 steve
|
||||
* Propogate constant 0 in low bits of adders.
|
||||
*
|
||||
* Revision 1.4 1999/12/17 06:18:15 steve
|
||||
* Rewrite the cprop functor to use the functor_t interface.
|
||||
*
|
||||
* Revision 1.3 1999/12/17 03:38:46 steve
|
||||
* NetConst can now hold wide constants.
|
||||
*
|
||||
* Revision 1.2 1998/12/02 04:37:13 steve
|
||||
* Add the nobufz function to eliminate bufz objects,
|
||||
* Object links are marked with direction,
|
||||
* constant propagation is more careful will wide links,
|
||||
* Signal folding is aware of attributes, and
|
||||
* the XNF target can dump UDP objects based on LCA
|
||||
* attributes.
|
||||
*
|
||||
* Revision 1.1 1998/11/13 06:23:17 steve
|
||||
* Introduce netlist optimizations with the
|
||||
* cprop function to do constant propogation.
|
||||
* Revision 1.35 2002/05/26 01:39:02 steve
|
||||
* Carry Verilog 2001 attributes with processes,
|
||||
* all the way through to the ivl_target API.
|
||||
*
|
||||
* Divide signal reference counts between rval
|
||||
* and lval references.
|
||||
*/
|
||||
|
||||
|
||||
+35
-53
@@ -1,53 +1,35 @@
|
||||
|
||||
This file describes the build procedure under cygwin32 (Windows 95/98/NT/2K)
|
||||
----------------------------------------------------------------------------
|
||||
To build using cygwin:
|
||||
|
||||
Prerequisites:
|
||||
|
||||
o Latest net release (1.1.4) of cygwin (sources.redhat.com/cygwin)
|
||||
o autoconf version 2.13 (or later) from cygutils (cygutils.netpedia.net)
|
||||
o cvs (1.10.8 or later) also from cygutils
|
||||
|
||||
Procedure:
|
||||
o Get the source code - see the main icarus verilog page for how to
|
||||
do this
|
||||
o cd to the verilog directory
|
||||
o autoconf
|
||||
o ./configure
|
||||
o make
|
||||
o make install
|
||||
|
||||
That's all that's needed. But there're two common problems during
|
||||
the make phase. All steps are in the verilog directory.
|
||||
|
||||
1.
|
||||
|
||||
If gcc dies saying virtual memory exhausted while compiling parse.c
|
||||
then recompile with -O1 or without -O flag and do these steps to
|
||||
continue
|
||||
o make CXXFLAGS='' parse.o
|
||||
o make
|
||||
|
||||
2.
|
||||
|
||||
If gcc dies in the vpi directory while compiling vpi_systask.c with the
|
||||
error, conflicting types for `_cygwin_dll_entry', then fix the line in
|
||||
/usr/include/cygwin/cygwin_dll.h. Change the line:
|
||||
|
||||
int WINAPI _cygwin_dll_entry (HANDLE h, DWORD reason, void *ptr); \
|
||||
to
|
||||
int WINAPI _cygwin_dll_entry (HINSTANCE h, DWORD reason, void *ptr); \
|
||||
|
||||
Note the change from HANDLE to HINSTANCE. Then do
|
||||
o make
|
||||
|
||||
To build your own extensions - just include vpi_user.h and link with
|
||||
a command like this:
|
||||
|
||||
$(CC) -shared -o <dllname> <objects> -Wl,--enable-auto-image-base -L../vvm -lvvm -lvpip
|
||||
|
||||
- Venkat Iyer <[email protected]>
|
||||
|
||||
|
||||
|
||||
|
||||
This file describes the build procedure under cygwin32 (Windows 95/98/NT/2K)
|
||||
----------------------------------------------------------------------------
|
||||
|
||||
Note: Icarus Verilog also compiles to native Windows binaries if you
|
||||
use the instructions in the mingw.txt file. Some people prefer cygwin
|
||||
binaries, and these instructions apply.
|
||||
|
||||
|
||||
To build using cygwin:
|
||||
|
||||
Prerequisites:
|
||||
|
||||
o Latest net release (1.1.4) of cygwin (sources.redhat.com/cygwin)
|
||||
|
||||
Procedure:
|
||||
o Get the source code - see the main Icarus Verilog page for how to
|
||||
do this
|
||||
o cd to the verilog directory
|
||||
o autoconf.sh
|
||||
o ./configure
|
||||
o make
|
||||
o make install
|
||||
|
||||
That's all that's needed.
|
||||
|
||||
To build your own extensions - just include vpi_user.h and link with
|
||||
a command like this:
|
||||
|
||||
$(CC) -shared -o <dllname> <objects> -Wl,--enable-auto-image-base -L../vvm -lvvm -lvpip
|
||||
|
||||
- Venkat Iyer <[email protected]>
|
||||
|
||||
|
||||
|
||||
|
||||
+362
-127
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: design_dump.cc,v 1.111 2001/02/17 05:13:36 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: design_dump.cc,v 1.149 2004/10/04 01:10:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
/*
|
||||
* This file contains all the dump methods of the netlist classes.
|
||||
*/
|
||||
@@ -75,7 +77,23 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
||||
o << " (local)";
|
||||
if (signed_)
|
||||
o << " signed";
|
||||
o << " (eref=" << get_eref() << ")";
|
||||
switch (port_type_) {
|
||||
case NetNet::NOT_A_PORT:
|
||||
break;
|
||||
case NetNet::PIMPLICIT:
|
||||
o << " implicit-port?";
|
||||
break;
|
||||
case NetNet::PINPUT:
|
||||
o << " input";
|
||||
break;
|
||||
case NetNet::POUTPUT:
|
||||
o << " output";
|
||||
break;
|
||||
case NetNet::PINOUT:
|
||||
o << " inout";
|
||||
break;
|
||||
}
|
||||
o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
|
||||
if (scope())
|
||||
o << " scope=" << scope()->name();
|
||||
o << " #(" << rise_time() << "," << fall_time() << "," <<
|
||||
@@ -99,6 +117,13 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetSubnet::dump_net(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "** " << name() << " is a NetSubnet **"
|
||||
<< endl;
|
||||
NetNet::dump_net(o, ind);
|
||||
}
|
||||
|
||||
void NetMemory::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << name_ << "[" << width_ << "] " <<
|
||||
@@ -156,9 +181,9 @@ void NetObj::dump_node_pins(ostream&o, unsigned ind) const
|
||||
void NetObj::dump_obj_attr(ostream&o, unsigned ind) const
|
||||
{
|
||||
unsigned idx;
|
||||
for (idx = 0 ; idx < attributes_.size() ; idx += 1) {
|
||||
o << setw(ind) << "" << attributes_.key(idx) << " = \"" <<
|
||||
attributes_.value(idx) << "\"" << endl;
|
||||
for (idx = 0 ; idx < attr_cnt() ; idx += 1) {
|
||||
o << setw(ind) << "" << attr_key(idx) << " = \"" <<
|
||||
attr_value(idx) << "\"" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,15 +244,6 @@ void NetMux::dump_node(ostream&o, unsigned ind) const
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetAssign_::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "Procedural assign (NetAssign_): " << name();
|
||||
if (bmux())
|
||||
o << "[" << *bmux() << "]";
|
||||
o << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
}
|
||||
|
||||
void NetBUFZ::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "NetBUFZ: " << name()
|
||||
@@ -255,7 +271,8 @@ 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()? scope()->name() : "") << endl;
|
||||
<< " scope=" << (scope()? scope()->name() : "")
|
||||
<< " aset_value=" << aset_value_ << endl;
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
@@ -298,6 +315,12 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
|
||||
case OR:
|
||||
o << "or";
|
||||
break;
|
||||
case PULLDOWN:
|
||||
o << "pulldown";
|
||||
break;
|
||||
case PULLUP:
|
||||
o << "pullup";
|
||||
break;
|
||||
case RNMOS:
|
||||
o << "rnmos";
|
||||
break;
|
||||
@@ -338,6 +361,14 @@ void NetRamDq::dump_node(ostream&o, unsigned ind) const
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetUserFunc::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << def_->name() << "(";
|
||||
o << ")" << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetTaskDef::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "task " << name_ << ";" << endl;
|
||||
@@ -367,77 +398,12 @@ void NetTaskDef::dump(ostream&o, unsigned ind) const
|
||||
o << setw(ind) << "" << "endtask" << endl;
|
||||
}
|
||||
|
||||
void NetUDP::dump_sequ_(ostream&o, unsigned ind) const
|
||||
{
|
||||
string tmp = "";
|
||||
for (unsigned idx = 0 ; idx < ind ; idx += 1)
|
||||
tmp += " ";
|
||||
|
||||
o << tmp << "Sequential UDP" << " #(" << rise_time() <<
|
||||
"," << fall_time() << "," << decay_time() << ") " << name() <<
|
||||
endl;
|
||||
|
||||
for (FSM_::const_iterator ent = fsm_.begin()
|
||||
; ent != fsm_.end() ; ent++) {
|
||||
o << setw(ind+6) << "" << (*ent).first << " -->";
|
||||
|
||||
state_t_*st = (*ent).second;
|
||||
assert((*ent).first[0] == st->out);
|
||||
for (unsigned idx = 1 ; idx < pin_count() ; idx += 1) {
|
||||
string tmp = (*ent).first;
|
||||
if (st->pins[idx].zer) {
|
||||
tmp[0] = st->pins[idx].zer->out;
|
||||
tmp[idx] = '0';
|
||||
o << " " << tmp;
|
||||
}
|
||||
|
||||
if (st->pins[idx].one) {
|
||||
tmp[0] = st->pins[idx].one->out;
|
||||
tmp[idx] = '1';
|
||||
o << " " << tmp;
|
||||
}
|
||||
|
||||
if (st->pins[idx].xxx) {
|
||||
tmp[0] = st->pins[idx].xxx->out;
|
||||
tmp[idx] = 'x';
|
||||
o << " " << tmp;
|
||||
}
|
||||
}
|
||||
|
||||
o << endl;
|
||||
}
|
||||
|
||||
o << setw(ind+6) << "" << "initial value == " << init_ << endl;
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetUDP::dump_comb_(ostream&o, unsigned ind) const
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void NetUDP::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
if (is_sequential())
|
||||
dump_sequ_(o, ind);
|
||||
else
|
||||
dump_comb_(o, ind);
|
||||
}
|
||||
|
||||
void NetUDP_COMB::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "Combinational primitive: ";
|
||||
o << setw(ind) << "" << "UDP (" << udp_name() << "): ";
|
||||
o << " #(" << rise_time() << "," << fall_time() << "," << decay_time() <<
|
||||
") " << name() << endl;
|
||||
|
||||
for (map<string,char>::const_iterator ent = cm_.begin()
|
||||
; ent != cm_.end() ; ent++) {
|
||||
o << setw(ind+6) << "" << (*ent).first << " --> " <<
|
||||
(*ent).second << endl;
|
||||
}
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
@@ -455,19 +421,47 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
|
||||
break;
|
||||
}
|
||||
|
||||
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1) {
|
||||
o << setw(ind+2) << "" << "(* " << attr_key(idx) << " = "
|
||||
<< attr_value(idx) << " *)" << endl;
|
||||
}
|
||||
|
||||
statement_->dump(o, ind+2);
|
||||
}
|
||||
|
||||
void NetAssign_::dump_lval(ostream&o) const
|
||||
{
|
||||
if (sig_) {
|
||||
o << sig_->name();
|
||||
if (bmux_) {
|
||||
o << "[" << *bmux_ << "]";
|
||||
|
||||
} else {
|
||||
o << "[" << (loff_+lwid_-1) << ":" << loff_ << "]";
|
||||
}
|
||||
} else if (mem_) {
|
||||
// Is there an obvious way to flag memories in the dump
|
||||
// as different from the _real_ bit mux case?
|
||||
// o << "**memory**";
|
||||
o << mem_->name() << "[";
|
||||
if (bmux_) o << *bmux_;
|
||||
else o << "**oops**";
|
||||
o << "]";
|
||||
} else if (var_) {
|
||||
o << "<real " << var_->basename() << ">";
|
||||
} else {
|
||||
o << "";
|
||||
}
|
||||
}
|
||||
|
||||
void NetAssignBase::dump_lval(ostream&o) const
|
||||
{
|
||||
o << "" << "{" << lval_->name();
|
||||
if (lval_->bmux())
|
||||
o << "[" << *lval_->bmux() << "]";
|
||||
o << "{";
|
||||
lval_->dump_lval(o);
|
||||
|
||||
for (NetAssign_*cur = lval_->more ; cur ; cur = cur->more) {
|
||||
o << ", " << cur->name();
|
||||
if (cur->bmux())
|
||||
o << "[" << *cur->bmux() << "]";
|
||||
o << ", ";
|
||||
cur->dump_lval(o);
|
||||
}
|
||||
|
||||
o << "}";
|
||||
@@ -480,8 +474,10 @@ void NetAssign::dump(ostream&o, unsigned ind) const
|
||||
dump_lval(o);
|
||||
|
||||
o << " = ";
|
||||
#if 0
|
||||
if (l_val(0)->rise_time())
|
||||
o << "#" << l_val(0)->rise_time() << " ";
|
||||
#endif
|
||||
o << *rval() << ";" << endl;
|
||||
}
|
||||
|
||||
@@ -491,36 +487,30 @@ void NetAssignNB::dump(ostream&o, unsigned ind) const
|
||||
dump_lval(o);
|
||||
|
||||
o << " <= ";
|
||||
#if 0
|
||||
if (l_val(0)->rise_time())
|
||||
o << "#" << l_val(0)->rise_time() << " ";
|
||||
#endif
|
||||
o << *rval() << ";" << endl;
|
||||
|
||||
}
|
||||
|
||||
void NetAssignMem::dump(ostream&o, unsigned ind) const
|
||||
void NetAssignBase::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "";
|
||||
o << "/* " << get_line() << " */" << endl;
|
||||
o << setw(ind) << "";
|
||||
o << memory()->name() << "[" << *index() << "] = ";
|
||||
rval()->dump(o);
|
||||
o << ";" << endl;
|
||||
}
|
||||
|
||||
void NetAssignMemNB::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "";
|
||||
o << "/* " << get_line() << " */" << endl;
|
||||
o << setw(ind) << "";
|
||||
o << memory()->name() << "[" << *index() << "] <= ";
|
||||
rval()->dump(o);
|
||||
o << ";" << endl;
|
||||
if (const NetAssignNB *n1 = dynamic_cast<const NetAssignNB*>(this)) {
|
||||
n1->dump(o,ind);
|
||||
} else if (const NetAssign *n2 = dynamic_cast<const NetAssign*>(this)) {
|
||||
n2->dump(o,ind);
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump a block statement */
|
||||
void NetBlock::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << type_ << endl;
|
||||
o << setw(ind) << "" << type_;
|
||||
if (subscope_)
|
||||
o << " : " << subscope_->name();
|
||||
o << endl;
|
||||
|
||||
if (last_) {
|
||||
const NetProc*cur = last_;
|
||||
@@ -655,6 +645,13 @@ void NetForever::dump(ostream&o, unsigned ind) const
|
||||
void NetFuncDef::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "function " << scope_->name() << endl;
|
||||
if (result_sig_)
|
||||
o << setw(ind+2) << "" << "Return signal: "
|
||||
<< result_sig_->name() << endl;
|
||||
if (result_var_)
|
||||
o << setw(ind+2) << "" << "Return variable: "
|
||||
<< result_var_->basename() << endl;
|
||||
|
||||
if (statement_)
|
||||
statement_->dump(o, ind+2);
|
||||
else
|
||||
@@ -680,8 +677,12 @@ void NetPDelay::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetRelease::dump(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "release " << lval_->name() << "; "
|
||||
<< "/* " << get_line() << " */" << endl;
|
||||
if (lval_)
|
||||
o << setw(ind) << "" << "release " << lval_->name() << "; "
|
||||
<< "/* " << get_line() << " */" << endl;
|
||||
else
|
||||
o << setw(ind) << "" << "release (null); "
|
||||
<< "/* " << get_line() << " */" << endl;
|
||||
}
|
||||
|
||||
void NetRepeat::dump(ostream&o, unsigned ind) const
|
||||
@@ -692,7 +693,9 @@ void NetRepeat::dump(ostream&o, unsigned ind) const
|
||||
|
||||
void NetScope::dump(ostream&o) const
|
||||
{
|
||||
/* This is a constructed hierarchical name. */
|
||||
o << name();
|
||||
|
||||
switch (type_) {
|
||||
case BEGIN_END:
|
||||
o << " sequential block";
|
||||
@@ -704,7 +707,7 @@ void NetScope::dump(ostream&o) const
|
||||
o << " function";
|
||||
break;
|
||||
case MODULE:
|
||||
o << " module <" << (module_name_? module_name_ : "") << ">";
|
||||
o << " module <" << (module_name_? module_name_.str() : "") << ">";
|
||||
break;
|
||||
case TASK:
|
||||
o << " task";
|
||||
@@ -712,28 +715,41 @@ void NetScope::dump(ostream&o) const
|
||||
}
|
||||
o << endl;
|
||||
|
||||
for (unsigned idx = 0 ; idx < attr_cnt() ; idx += 1)
|
||||
o << " (* " << attr_key(idx) << " = "
|
||||
<< attr_value(idx) << " *)" << endl;
|
||||
|
||||
o << " timescale = 10e" << time_unit() << " / 10e"
|
||||
<< time_precision() << endl;
|
||||
|
||||
/* Dump the parameters for this scope. */
|
||||
{
|
||||
map<string,NetExpr*>::const_iterator pp;
|
||||
for (pp = parameters_.begin()
|
||||
; pp != parameters_.end() ; pp ++) {
|
||||
o << " parameter " << (*pp).first << " = " <<
|
||||
*(*pp).second << ";" << endl;
|
||||
map<perm_string,param_expr_t>::const_iterator pp;
|
||||
for (pp = parameters.begin()
|
||||
; pp != parameters.end() ; pp ++) {
|
||||
o << " parameter ";
|
||||
|
||||
if ((*pp).second.signed_flag)
|
||||
o << "signed ";
|
||||
|
||||
if ((*pp).second.msb)
|
||||
o << "[" << *(*pp).second.msb
|
||||
<< ":" << *(*pp).second.lsb << "] ";
|
||||
|
||||
o << (*pp).first << " = " <<
|
||||
*(*pp).second.expr << ";" << endl;
|
||||
}
|
||||
|
||||
for (pp = localparams_.begin()
|
||||
; pp != localparams_.end() ; pp ++) {
|
||||
for (pp = localparams.begin()
|
||||
; pp != localparams.end() ; pp ++) {
|
||||
o << " localparam " << (*pp).first << " = " <<
|
||||
*(*pp).second << ";" << endl;
|
||||
*(*pp).second.expr << ";" << endl;
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump the saved defparam assignments here. */
|
||||
{
|
||||
map<string,NetExpr*>::const_iterator pp;
|
||||
map<hname_t,NetExpr*>::const_iterator pp;
|
||||
for (pp = defparams.begin()
|
||||
; pp != defparams.end() ; pp ++ ) {
|
||||
o << " defparam " << (*pp).first << " = " <<
|
||||
@@ -741,6 +757,11 @@ void NetScope::dump(ostream&o) const
|
||||
}
|
||||
}
|
||||
|
||||
for (NetVariable*cur = vars_ ; cur ; cur = cur->snext_) {
|
||||
o << " real " << cur->basename() << " // "
|
||||
<< cur->get_line() << endl;
|
||||
}
|
||||
|
||||
/* Dump the events in this scope. */
|
||||
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_) {
|
||||
o << " event " << cur->name() << "; nprobe="
|
||||
@@ -767,11 +788,16 @@ void NetScope::dump(ostream&o) const
|
||||
|
||||
switch (type_) {
|
||||
case FUNC:
|
||||
func_def()->dump(o, 4);
|
||||
if (func_def())
|
||||
func_def()->dump(o, 4);
|
||||
else
|
||||
o << " MISSING FUNCTION DEFINITION" << endl;
|
||||
break;
|
||||
case TASK:
|
||||
task_def()->dump(o, 4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Dump any sub-scopes. */
|
||||
@@ -816,10 +842,10 @@ void NetProc::dump(ostream&o, unsigned ind) const
|
||||
o << setw(ind) << "" << "// " << typeid(*this).name() << endl;
|
||||
}
|
||||
|
||||
/* Dump an expression that noone wrote a dump method for. */
|
||||
/* Dump an expression that no one wrote a dump method for. */
|
||||
void NetExpr::dump(ostream&o) const
|
||||
{
|
||||
o << "(?)";
|
||||
o << "(?" << typeid(*this).name() << "?)";
|
||||
}
|
||||
|
||||
void NetEBinary::dump(ostream&o) const
|
||||
@@ -864,6 +890,9 @@ void NetEBinary::dump(ostream&o) const
|
||||
case 'r':
|
||||
o << ">>";
|
||||
break;
|
||||
case 'R':
|
||||
o << ">>>";
|
||||
break;
|
||||
case 'X':
|
||||
o << "~^";
|
||||
break;
|
||||
@@ -875,8 +904,12 @@ void NetEBinary::dump(ostream&o) const
|
||||
|
||||
void NetEConcat::dump(ostream&o) const
|
||||
{
|
||||
if (repeat_ != 1)
|
||||
o << repeat_;
|
||||
if (repeat_calculated_) {
|
||||
if (repeat_value_ != 1)
|
||||
o << repeat_value_;
|
||||
} else if (repeat_) {
|
||||
o << "<" << *repeat_ << ">";
|
||||
}
|
||||
|
||||
if (parms_[0])
|
||||
o << "{" << *parms_[0];
|
||||
@@ -900,11 +933,54 @@ void NetEConst::dump(ostream&o) const
|
||||
o << value_;
|
||||
}
|
||||
|
||||
void NetEConstParam::dump(ostream&o) const
|
||||
{
|
||||
o << "<" << name_ << "=";
|
||||
NetEConst::dump(o);
|
||||
o << ">";
|
||||
}
|
||||
|
||||
void NetECReal::dump(ostream&o) const
|
||||
{
|
||||
o << value_;
|
||||
}
|
||||
|
||||
void NetECRealParam::dump(ostream&o) const
|
||||
{
|
||||
o << "<" << name_ << "=";
|
||||
NetECReal::dump(o);
|
||||
o << ">";
|
||||
}
|
||||
|
||||
void NetEEvent::dump(ostream&o) const
|
||||
{
|
||||
o << "<event=" << event_->name() << ">";
|
||||
}
|
||||
|
||||
void NetEScope::dump(ostream&o) const
|
||||
{
|
||||
o << "<scope=" << scope_->name() << ">";
|
||||
}
|
||||
|
||||
void NetESelect::dump(ostream&o) const
|
||||
{
|
||||
o << "<select";
|
||||
if (has_sign())
|
||||
o << "+=";
|
||||
else
|
||||
o << "=";
|
||||
|
||||
expr_->dump(o);
|
||||
o << "[";
|
||||
|
||||
if (base_)
|
||||
base_->dump(o);
|
||||
else
|
||||
o << "(0)";
|
||||
|
||||
o << "+:" << expr_width() << "]>";
|
||||
}
|
||||
|
||||
void NetESFunc::dump(ostream&o) const
|
||||
{
|
||||
o << name_ << "(";
|
||||
@@ -917,10 +993,12 @@ void NetESFunc::dump(ostream&o) const
|
||||
|
||||
void NetESignal::dump(ostream&o) const
|
||||
{
|
||||
o << name();
|
||||
if (has_sign())
|
||||
o << "+";
|
||||
o << name() << "[" << msi_<<":"<<lsi_ << "]";
|
||||
}
|
||||
|
||||
void NetESubSignal::dump(ostream&o) const
|
||||
void NetEBitSel::dump(ostream&o) const
|
||||
{
|
||||
sig_->dump(o);
|
||||
o << "[";
|
||||
@@ -937,7 +1015,10 @@ void NetEMemory::dump(ostream&o) const
|
||||
|
||||
void NetEParam::dump(ostream&o) const
|
||||
{
|
||||
o << "<" << scope_->name() << "." << name_ << ">";
|
||||
if (scope_ != 0)
|
||||
o << "<" << scope_->name() << "." << name_ << ">";
|
||||
else
|
||||
o << "<" << name_ << ">";
|
||||
}
|
||||
|
||||
void NetETernary::dump(ostream&o) const
|
||||
@@ -974,11 +1055,18 @@ void NetEUnary::dump(ostream&o) const
|
||||
o << ")";
|
||||
}
|
||||
|
||||
void NetEVariable::dump(ostream&o) const
|
||||
{
|
||||
o << var_->basename();
|
||||
}
|
||||
|
||||
void Design::dump(ostream&o) const
|
||||
{
|
||||
o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
|
||||
o << "SCOPES:" << endl;
|
||||
root_scope_->dump(o);
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->dump(o);
|
||||
|
||||
o << "ELABORATED NODES:" << endl;
|
||||
|
||||
@@ -1001,6 +1089,153 @@ void Design::dump(ostream&o) const
|
||||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.149 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.148 2004/05/31 23:34:36 steve
|
||||
* Rewire/generalize parsing an elaboration of
|
||||
* function return values to allow for better
|
||||
* speed and more type support.
|
||||
*
|
||||
* Revision 1.147 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.146 2004/02/18 17:11:54 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.145 2003/12/17 16:52:39 steve
|
||||
* Debug dumps for synth2.
|
||||
*
|
||||
* Revision 1.144 2003/07/26 03:34:42 steve
|
||||
* Start handling pad of expressions in code generators.
|
||||
*
|
||||
* Revision 1.143 2003/07/05 20:42:08 steve
|
||||
* Fix some enumeration warnings.
|
||||
*
|
||||
* Revision 1.142 2003/06/20 00:53:19 steve
|
||||
* Module attributes from the parser
|
||||
* through to elaborated form.
|
||||
*
|
||||
* Revision 1.141 2003/06/18 03:55:18 steve
|
||||
* Add arithmetic shift operators.
|
||||
*
|
||||
* Revision 1.140 2003/05/30 02:55:32 steve
|
||||
* Support parameters in real expressions and
|
||||
* as real expressions, and fix multiply and
|
||||
* divide with real results.
|
||||
*
|
||||
* Revision 1.139 2003/04/22 04:48:29 steve
|
||||
* Support event names as expressions elements.
|
||||
*
|
||||
* Revision 1.138 2003/03/10 23:40:53 steve
|
||||
* Keep parameter constants for the ivl_target API.
|
||||
*
|
||||
* Revision 1.137 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.136 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
* Revision 1.135 2002/10/23 01:47:17 steve
|
||||
* Fix synth2 handling of aset/aclr signals where
|
||||
* flip-flops are split by begin-end blocks.
|
||||
*
|
||||
* Revision 1.134 2002/10/19 22:59:49 steve
|
||||
* Redo the parameter vector support to allow
|
||||
* parameter names in range expressions.
|
||||
*
|
||||
* Revision 1.133 2002/08/19 00:06:11 steve
|
||||
* Allow release to handle removal of target net.
|
||||
*
|
||||
* Revision 1.132 2002/08/13 05:35:00 steve
|
||||
* Do not elide named blocks.
|
||||
*
|
||||
* Revision 1.131 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.130 2002/08/04 18:28:14 steve
|
||||
* Do not use hierarchical names of memories to
|
||||
* generate vvp labels. -tdll target does not
|
||||
* used hierarchical name string to look up the
|
||||
* memory objects in the design.
|
||||
*
|
||||
* Revision 1.129 2002/06/19 04:20:03 steve
|
||||
* Remove NetTmp and add NetSubnet class.
|
||||
*
|
||||
* Revision 1.128 2002/06/14 21:38:41 steve
|
||||
* Fix expression width for repeat concatenations.
|
||||
*
|
||||
* Revision 1.127 2002/06/08 23:42:46 steve
|
||||
* Add NetRamDq synthsesis from memory l-values.
|
||||
*
|
||||
* Revision 1.126 2002/06/05 03:44:25 steve
|
||||
* Add support for memory words in l-value of
|
||||
* non-blocking assignments, and remove the special
|
||||
* NetAssignMem_ and NetAssignMemNB classes.
|
||||
*
|
||||
* Revision 1.125 2002/06/04 05:38:44 steve
|
||||
* Add support for memory words in l-value of
|
||||
* blocking assignments, and remove the special
|
||||
* NetAssignMem class.
|
||||
*
|
||||
* Revision 1.124 2002/05/26 01:39:02 steve
|
||||
* Carry Verilog 2001 attributes with processes,
|
||||
* all the way through to the ivl_target API.
|
||||
*
|
||||
* Divide signal reference counts between rval
|
||||
* and lval references.
|
||||
*
|
||||
* Revision 1.123 2002/05/05 21:11:49 steve
|
||||
* Put off evaluation of concatenation repeat expresions
|
||||
* until after parameters are defined. This allows parms
|
||||
* to be used in repeat expresions.
|
||||
*
|
||||
* Add the builtin $signed system function.
|
||||
*
|
||||
* Revision 1.122 2002/03/09 02:10:22 steve
|
||||
* Add the NetUserFunc netlist node.
|
||||
*
|
||||
* Revision 1.121 2001/12/31 00:03:05 steve
|
||||
* Include s indicator in dump of signed numbers.
|
||||
*
|
||||
* Revision 1.120 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.119 2001/11/19 01:46:38 steve
|
||||
* Print typename is fallback expression node dump.
|
||||
*
|
||||
* Revision 1.118 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
* Revision 1.117 2001/08/25 23:50:02 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.116 2001/07/27 04:51:44 steve
|
||||
* Handle part select expressions as variants of
|
||||
* NetESignal/IVL_EX_SIGNAL objects, instead of
|
||||
* creating new and useless temporary signals.
|
||||
*
|
||||
* Revision 1.115 2001/07/27 02:41:55 steve
|
||||
* Fix binding of dangling function ports. do not elide them.
|
||||
*
|
||||
* Revision 1.114 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.113 2001/04/29 20:19:10 steve
|
||||
* Add pullup and pulldown devices.
|
||||
*
|
||||
* Revision 1.112 2001/04/22 23:09:46 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.111 2001/02/17 05:13:36 steve
|
||||
* Check that the port really exists here.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: dosify.c,v 1.5 2003/07/15 16:17:47 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is a simple program to make a dosified copy of the
|
||||
* original. That is, it converts unix style line ends to DOS
|
||||
* style. This is useful for installing text files.
|
||||
*
|
||||
* The exact substitution is to replace \n with \r\n. If the line
|
||||
* already ends with \r\n then it is not changed to \r\r\n.
|
||||
*/
|
||||
|
||||
# include <stdio.h>
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
FILE*ifile;
|
||||
FILE*ofile;
|
||||
int ch, pr;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s <input> <output>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ifile = fopen(argv[1], "rb");
|
||||
if (ifile == 0) {
|
||||
fprintf(stderr, "Unable to open %s for input.\n", argv[1]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
ofile = fopen(argv[2], "wb");
|
||||
if (ofile == 0) {
|
||||
fprintf(stderr, "Unable to open %s for output.\n", argv[2]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
pr = 0;
|
||||
while ((ch = fgetc(ifile)) != EOF) {
|
||||
|
||||
if ((ch == '\n') && (pr != '\r'))
|
||||
fputc('\r', ofile);
|
||||
|
||||
fputc(ch, ofile);
|
||||
pr = ch;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: dosify.c,v $
|
||||
* Revision 1.5 2003/07/15 16:17:47 steve
|
||||
* Fix spelling of ifdef.
|
||||
*
|
||||
* Revision 1.4 2003/07/15 03:49:22 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.3 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2002/08/11 23:47:04 steve
|
||||
* Add missing Log and Ident strings.
|
||||
*
|
||||
* Revision 1.1 2001/08/03 17:06:47 steve
|
||||
* Add install of examples for Windows.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
Makefile
|
||||
iverilog-vpi.exe
|
||||
@@ -0,0 +1,80 @@
|
||||
#
|
||||
# This source code is free software; you can redistribute it
|
||||
# and/or modify it in source code form under the terms of the GNU
|
||||
# Library General Public License as published by the Free Software
|
||||
# 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 Library General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Library General Public
|
||||
# License along with this program; if not, write to the Free
|
||||
# Software Foundation, Inc.,
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.6 2004/02/10 19:25:00 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.7
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
srcdir = @srcdir@
|
||||
|
||||
VPATH = $(srcdir)
|
||||
|
||||
bindir = $(exec_prefix)/bin
|
||||
libdir = $(exec_prefix)/lib
|
||||
includedir = $(prefix)/include
|
||||
mandir = @mandir@
|
||||
|
||||
dllib=@DLLIB@
|
||||
|
||||
CC = @CC@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @ident_support@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = -Wall @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
all: iverilog-vpi@EXEEXT@
|
||||
|
||||
clean:
|
||||
rm -f *.o
|
||||
rm -f iverilog-vpi@EXEEXT@
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile
|
||||
|
||||
O = main.o res.o
|
||||
|
||||
iverilog-vpi@EXEEXT@: $O
|
||||
$(CC) $(LDFLAGS) $O -o iverilog-vpi@EXEEXT@ @EXTRALIBS@
|
||||
|
||||
|
||||
main.o: main.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(srcdir)/main.c
|
||||
|
||||
# Windows specific...
|
||||
res.o: res.rc
|
||||
windres -i res.rc -o res.o
|
||||
#
|
||||
|
||||
install: all installdirs $(bindir)/iverilog-vpi@EXEEXT@
|
||||
|
||||
$(bindir)/iverilog-vpi@EXEEXT@: ./iverilog-vpi@EXEEXT@
|
||||
$(INSTALL_PROGRAM) ./iverilog-vpi@EXEEXT@ $(bindir)/iverilog-vpi@EXEEXT@
|
||||
|
||||
installdirs: ../mkinstalldirs
|
||||
$(srcdir)/../mkinstalldirs $(bindir)
|
||||
|
||||
uninstall:
|
||||
rm -f $(bindir)/iverilog-vpi@EXEEXT@
|
||||
@@ -0,0 +1,565 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Gus Baldauf (gus@picturel.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* iverilog-vpi.c
|
||||
*
|
||||
* this program provides the functionality of iverilog-vpi.sh under Win32
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/* Macros used for compiling and linking */
|
||||
|
||||
#define IVERILOG_VPI_CC "gcc" /* no .exe extension */
|
||||
#define IVERILOG_VPI_CXX "gcc" /* no .exe extension */
|
||||
#define IVERILOG_VPI_CFLAGS "-O" /* -I appended later */
|
||||
#define IVERILOG_VPI_LD "gcc" /* no .exe extension */
|
||||
#define IVERILOG_VPI_LDFLAGS "-shared -Wl,--enable-auto-image-base"
|
||||
#define IVERILOG_VPI_LDLIBS "-lveriuser -lvpi" /* -L prepended later */
|
||||
|
||||
/* pointers to global strings */
|
||||
|
||||
static struct global_strings {
|
||||
char *pCCSRC; /* list of C source files */
|
||||
char *pCXSRC; /* list of C++ source files */
|
||||
char *pOBJ; /* list of object files */
|
||||
char *pLIB; /* list of library files */
|
||||
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 */
|
||||
} gstr;
|
||||
|
||||
|
||||
static void deInitDynString(char *str)
|
||||
{
|
||||
free(str);
|
||||
}
|
||||
|
||||
/* when finished, free allocated memory and return error code */
|
||||
|
||||
static void myExit(int exitVal)
|
||||
{
|
||||
deInitDynString(gstr.pCCSRC);
|
||||
deInitDynString(gstr.pCXSRC);
|
||||
deInitDynString(gstr.pOBJ);
|
||||
deInitDynString(gstr.pLIB);
|
||||
deInitDynString(gstr.pOUT);
|
||||
deInitDynString(gstr.pMINGW);
|
||||
deInitDynString(gstr.pIVL);
|
||||
deInitDynString(gstr.pCFLAGS);
|
||||
deInitDynString(gstr.pLDLIBS);
|
||||
deInitDynString(gstr.pNewPath);
|
||||
|
||||
exit(exitVal);
|
||||
}
|
||||
|
||||
/* display usage summary and exit */
|
||||
|
||||
static void usage()
|
||||
{
|
||||
fprintf(stderr,"usage: iverilog-vpi [--name=name] [-llibrary] [-mingw=dir] [-ivl=dir] sourcefile...\n");
|
||||
fprintf(stderr," or iverilog-vpi -mingw=dir\n");
|
||||
fprintf(stderr," or iverilog-vpi -ivl=dir\n");
|
||||
myExit(1);
|
||||
}
|
||||
|
||||
static void initDynString(char **str)
|
||||
{
|
||||
*str = (char *) malloc(1);
|
||||
|
||||
if (!*str) {
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
myExit(4);
|
||||
}
|
||||
|
||||
*str[0] = 0;
|
||||
}
|
||||
|
||||
/* initialize dynamic memory buffers */
|
||||
|
||||
static void init()
|
||||
{
|
||||
initDynString(&gstr.pCCSRC);
|
||||
initDynString(&gstr.pCXSRC);
|
||||
initDynString(&gstr.pOBJ);
|
||||
initDynString(&gstr.pLIB);
|
||||
initDynString(&gstr.pOUT);
|
||||
initDynString(&gstr.pMINGW);
|
||||
initDynString(&gstr.pIVL);
|
||||
initDynString(&gstr.pCFLAGS);
|
||||
initDynString(&gstr.pLDLIBS);
|
||||
initDynString(&gstr.pNewPath);
|
||||
}
|
||||
|
||||
/* return true if "str" is terminated with with "end", case insensitive */
|
||||
|
||||
static int endsIn (char *end, char *str)
|
||||
{
|
||||
char *ext;
|
||||
|
||||
if (strlen(end) >= strlen(str))
|
||||
return 0;
|
||||
|
||||
ext = str + (strlen(str) - strlen(end));
|
||||
|
||||
return stricmp(end,ext) ? 0 : 1;
|
||||
}
|
||||
|
||||
/* return true if "str" begins with "prefix", case insensitive */
|
||||
|
||||
static int startsWith (char *prefix, char *str)
|
||||
{
|
||||
if (strlen(prefix) >= strlen(str))
|
||||
return 0;
|
||||
|
||||
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)
|
||||
{
|
||||
*ptr = (char *) realloc(*ptr,strlen(*ptr)+(count?count:strlen(app))+1);
|
||||
|
||||
if (*ptr == NULL) {
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
myExit(4);
|
||||
}
|
||||
|
||||
if (count)
|
||||
strncat(*ptr,app,count);
|
||||
else
|
||||
strcat(*ptr,app);
|
||||
}
|
||||
|
||||
/* append "app" to "ptr", allocating memory as needed */
|
||||
|
||||
static void append (char **ptr, char *app)
|
||||
{
|
||||
appendn(ptr,app,0);
|
||||
}
|
||||
|
||||
/* if the string does not end with a backslash, add one */
|
||||
|
||||
static void appendBackSlash(char **str)
|
||||
{
|
||||
if ((*str)[strlen(*str)-1] != '\\')
|
||||
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)
|
||||
{
|
||||
*ptr = (char *) realloc(*ptr,(count?count:strlen(str))+1);
|
||||
|
||||
if (*ptr == NULL) {
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
myExit(4);
|
||||
}
|
||||
|
||||
if (count) {
|
||||
strncpy(*ptr,str,count);
|
||||
(*ptr)[count] = 0;
|
||||
}
|
||||
else
|
||||
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);
|
||||
}
|
||||
|
||||
/* get a copy of a Icarus Verilog registry string key */
|
||||
|
||||
static int GetRegistryKey(char *key, char **value)
|
||||
{
|
||||
long lrv;
|
||||
HKEY hkKey;
|
||||
char *regKeyBuffer;
|
||||
DWORD regKeyType, regKeySize;
|
||||
|
||||
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);
|
||||
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
|
||||
lrv = RegCloseKey(hkKey);
|
||||
return 0;
|
||||
}
|
||||
|
||||
regKeyBuffer = (char *) malloc(regKeySize+1);
|
||||
if (!regKeyBuffer) {
|
||||
lrv = RegCloseKey(hkKey);
|
||||
fprintf(stderr,"error: out of memory\n");
|
||||
myExit(4);
|
||||
}
|
||||
regKeyBuffer[regKeySize] = 0; /* makes sure there is a trailing NULL */
|
||||
|
||||
lrv = RegQueryValueEx(hkKey,key,NULL,®KeyType,regKeyBuffer,®KeySize);
|
||||
if ((lrv != ERROR_SUCCESS) || (regKeyType != REG_SZ) || (!regKeySize)) {
|
||||
lrv = RegCloseKey(hkKey);
|
||||
free(regKeyBuffer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
RegCloseKey(hkKey);
|
||||
|
||||
assign(value,regKeyBuffer);
|
||||
free(regKeyBuffer);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* store a copy of a Icarus Verilog registry string key */
|
||||
|
||||
static void SetRegistryKey(char *key, char *value)
|
||||
{
|
||||
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;
|
||||
|
||||
RegSetValueEx(hkKey,key,0,REG_SZ,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);
|
||||
}
|
||||
|
||||
/* parse the command line, assign results to global variable strings */
|
||||
|
||||
static int parse(int argc, char *argv[])
|
||||
{
|
||||
int idx, srcFileCnt=0;
|
||||
|
||||
char dot_c_ext[] = ".c";
|
||||
char dot_cc_ext[] = ".cc";
|
||||
char dot_o_ext[] = ".o";
|
||||
char name_option[] = "--name=";
|
||||
char lib_option[] = "-l";
|
||||
char mingw_option[] = "-mingw=";
|
||||
char ivl_option[] = "-ivl=";
|
||||
|
||||
if (argc == 1)
|
||||
return 0;
|
||||
|
||||
for (idx=1; idx<argc; ++idx) {
|
||||
if (endsIn(dot_c_ext,argv[idx])) { /* check for C source files */
|
||||
++srcFileCnt;
|
||||
append(&gstr.pCCSRC,argv[idx]);
|
||||
append(&gstr.pCCSRC," ");
|
||||
if (!*gstr.pOUT)
|
||||
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_c_ext));
|
||||
}
|
||||
else if (endsIn(dot_cc_ext,argv[idx])) { /* check for C++ source files */
|
||||
++srcFileCnt;
|
||||
append(&gstr.pCXSRC,argv[idx]);
|
||||
append(&gstr.pCXSRC," ");
|
||||
if (!*gstr.pOUT)
|
||||
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_cc_ext));
|
||||
}
|
||||
else if (endsIn(dot_o_ext,argv[idx])) { /* check for compiled object files */
|
||||
++srcFileCnt;
|
||||
append(&gstr.pOBJ,argv[idx]);
|
||||
append(&gstr.pOBJ," ");
|
||||
if (!*gstr.pOUT)
|
||||
assignn(&gstr.pOUT,argv[idx],strlen(argv[idx])-strlen(dot_o_ext));
|
||||
}
|
||||
else if (startsWith(name_option,argv[idx])) { /* check for --name option */
|
||||
assignn(&gstr.pOUT,argv[idx]+sizeof(name_option)-1,strlen(argv[idx])-(sizeof(name_option)-1));
|
||||
}
|
||||
else if (startsWith(lib_option,argv[idx])) { /* check for -l option */
|
||||
append(&gstr.pLIB,argv[idx]);
|
||||
append(&gstr.pLIB," ");
|
||||
}
|
||||
else if (startsWith(mingw_option,argv[idx])) /* check for -mingw option */
|
||||
assignn(&gstr.pMINGW,argv[idx]+sizeof(mingw_option)-1,strlen(argv[idx])-(sizeof(mingw_option)-1));
|
||||
else if (startsWith(ivl_option,argv[idx])) /* check for -ivl option */
|
||||
assignn(&gstr.pIVL,argv[idx]+sizeof(ivl_option)-1,strlen(argv[idx])-(sizeof(ivl_option)-1));
|
||||
else
|
||||
return 0; /* different from iverilog-vpi.sh, we don't ignore accept arguments */
|
||||
}
|
||||
|
||||
if (0 == srcFileCnt)
|
||||
assign(&gstr.pOUT,""); /* in case they used --name with no source files */
|
||||
|
||||
if (!*gstr.pOUT) { /* normally it's an error if there are no *.c,*.cc,*.o files */
|
||||
if (!*gstr.pMINGW && !*gstr.pIVL) /* unless they are just setting the IVL or MinGW registry entries */
|
||||
usage();
|
||||
}
|
||||
else {
|
||||
append(&gstr.pOUT,".vpi"); /* the result file should have a .vpi extension */
|
||||
append(&gstr.pOUT," ");
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* do minimal check that the MinGW root directory looks valid */
|
||||
|
||||
static void checkMingwDir(char *root)
|
||||
{
|
||||
int irv;
|
||||
struct _stat stat_buf;
|
||||
|
||||
char *path;
|
||||
initDynString(&path);
|
||||
assign(&path,gstr.pMINGW);
|
||||
appendBackSlash(&path);
|
||||
append(&path,"bin\\" IVERILOG_VPI_CC ".exe");
|
||||
|
||||
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);
|
||||
appendBackSlash(&path);
|
||||
append(&path,"bin\\vvp.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.exe 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);
|
||||
}
|
||||
}
|
||||
|
||||
/* see if we can find mingw root */
|
||||
|
||||
#define IVL_REGKEY_MINGW "MingwDir"
|
||||
|
||||
static void setup_mingw_environment()
|
||||
{
|
||||
char *pOldPATH = getenv("PATH"); /* get current 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);
|
||||
}
|
||||
|
||||
assign(&gstr.pNewPath,"PATH="); /* create new path */
|
||||
append(&gstr.pNewPath,gstr.pMINGW);
|
||||
appendBackSlash(&gstr.pNewPath);
|
||||
append(&gstr.pNewPath,"bin;");
|
||||
append(&gstr.pNewPath,pOldPATH);
|
||||
|
||||
_putenv(gstr.pNewPath); /* place new path in environment variable */
|
||||
}
|
||||
|
||||
/* see if we can find iverilog root */
|
||||
|
||||
#define IVL_REGKEY_IVL "InstallDir"
|
||||
|
||||
static void setup_ivl_environment()
|
||||
{
|
||||
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.exe 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);
|
||||
}
|
||||
|
||||
/* build up the CFLAGS option string */
|
||||
|
||||
assign(&gstr.pCFLAGS,IVERILOG_VPI_CFLAGS);
|
||||
append(&gstr.pCFLAGS," -I");
|
||||
append(&gstr.pCFLAGS,gstr.pIVL);
|
||||
appendBackSlash(&gstr.pCFLAGS);
|
||||
append(&gstr.pCFLAGS,"include");
|
||||
|
||||
/* build up the LDFLAGS option string */
|
||||
|
||||
assign(&gstr.pLDLIBS,"-L");
|
||||
append(&gstr.pLDLIBS,gstr.pIVL);
|
||||
appendBackSlash(&gstr.pLDLIBS);
|
||||
append(&gstr.pLDLIBS,"lib ");
|
||||
append(&gstr.pLDLIBS,IVERILOG_VPI_LDLIBS);
|
||||
}
|
||||
|
||||
/* compile source modules */
|
||||
|
||||
static void compile(char *pSource, char **pObject, char *ext, int *compile_errors, char *compiler)
|
||||
{
|
||||
char *ptr1 = pSource;
|
||||
char *ptr2 = strchr(pSource,' ');
|
||||
char *buf=0,*src=0,*obj=0;
|
||||
|
||||
while (ptr2) {
|
||||
int len = ptr2 - ptr1;
|
||||
assignn(&src,ptr1,len);
|
||||
|
||||
assignn(&obj,ptr1,len-strlen(ext)); /* strip off the extension */
|
||||
append (&obj,".o");
|
||||
|
||||
assign (&buf,compiler);
|
||||
append (&buf," -c -o ");
|
||||
append (&buf,obj);
|
||||
append (&buf," ");
|
||||
append (&buf,gstr.pCFLAGS);
|
||||
append (&buf," ");
|
||||
append (&buf,src);
|
||||
|
||||
append (pObject,obj);
|
||||
append (pObject," ");
|
||||
|
||||
printf("%s\n",buf);
|
||||
|
||||
if (system(buf))
|
||||
++*compile_errors;
|
||||
|
||||
ptr1 = ptr2 + 1; /* advance to next token */
|
||||
ptr2 = strchr(ptr1,' ');
|
||||
}
|
||||
|
||||
free(buf);
|
||||
free(src);
|
||||
free(obj);
|
||||
}
|
||||
|
||||
/* using the global strings, compile and link */
|
||||
|
||||
static void compile_and_link()
|
||||
{
|
||||
char *buf=0;
|
||||
int iRet, compile_errors = 0;
|
||||
|
||||
/* print out the mingw and ivl directories to help the user debug problems */
|
||||
|
||||
printf("info: %s will be used as the MinGW root directory.\n",gstr.pMINGW);
|
||||
checkMingwDir(gstr.pMINGW);
|
||||
|
||||
printf("info: %s will be used as the Icarus Verilog root directory.\n",gstr.pIVL);
|
||||
checkIvlDir(gstr.pIVL);
|
||||
|
||||
/* compile */
|
||||
|
||||
compile(gstr.pCCSRC,&gstr.pOBJ,".c" ,&compile_errors,IVERILOG_VPI_CC ); /* compile the C source files */
|
||||
compile(gstr.pCXSRC,&gstr.pOBJ,".cc",&compile_errors,IVERILOG_VPI_CXX); /* compile the C++ source files */
|
||||
|
||||
if (compile_errors) {
|
||||
fprintf(stderr,"iverilog-vpi: Some %d files failed to compile.\n",compile_errors);
|
||||
myExit(2);
|
||||
}
|
||||
|
||||
/* link */
|
||||
|
||||
assign(&buf,IVERILOG_VPI_LD);
|
||||
append(&buf," -o ");
|
||||
append(&buf,gstr.pOUT); /* has a trailing space */
|
||||
append(&buf,IVERILOG_VPI_LDFLAGS);
|
||||
append(&buf," ");
|
||||
append(&buf,gstr.pOBJ) /* has a trailing space */;
|
||||
append(&buf,gstr.pLIB); /* has a trailing space */
|
||||
append(&buf,gstr.pLDLIBS);
|
||||
|
||||
printf("%s\n",buf);
|
||||
|
||||
iRet = system(buf);
|
||||
|
||||
free(buf);
|
||||
|
||||
if (iRet)
|
||||
myExit(3);
|
||||
}
|
||||
|
||||
/* program execution starts here */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
init();
|
||||
|
||||
if (!parse(argc,argv))
|
||||
usage();
|
||||
|
||||
setup_mingw_environment();
|
||||
setup_ivl_environment();
|
||||
|
||||
if (*gstr.pOUT) /* are there any *.c,*.cc,*.o files specified */
|
||||
compile_and_link();
|
||||
|
||||
myExit(0);
|
||||
}
|
||||
Executable
+38
@@ -0,0 +1,38 @@
|
||||
|
||||
// LANGUAGE ENGLISH
|
||||
LANGUAGE 9, 4
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
1 VERSIONINFO
|
||||
FILEVERSION 2002,11,13,0
|
||||
PRODUCTVERSION 0,7,0,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGS 0x2L
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Icarus Verilog\0"
|
||||
VALUE "FileDescription", "Icarus Verilog VPI Tool\0"
|
||||
VALUE "FileVersion", "2002, 11, 13, 0\0"
|
||||
VALUE "InternalName", "iverilog-vpi\0"
|
||||
VALUE "LegalCopyright", "Copyright 2002 Gus Baldauf\0"
|
||||
VALUE "OriginalFilename", "iverilog-vpi.exe\0"
|
||||
VALUE "ProductName", "Icarus Verilog\0"
|
||||
VALUE "ProductVersion", "0, 7, 0, 0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
@@ -1,6 +1,15 @@
|
||||
a.out
|
||||
Makefile
|
||||
parse.c
|
||||
parse.h
|
||||
parse.output
|
||||
lexor.c
|
||||
cfparse.c
|
||||
cfparse.h
|
||||
cfparse.output
|
||||
cflexor.c
|
||||
foo.*
|
||||
iverilog
|
||||
iverilog.ps
|
||||
iverilog.pdf
|
||||
tmp.pdf
|
||||
|
||||
+38
-20
@@ -3,9 +3,7 @@
|
||||
# and/or modify it in source code form under the terms of the GNU
|
||||
# Library General Public License as published by the Free Software
|
||||
# Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version. In order to redistribute the software in
|
||||
# binary form, you will need a Picture Elements Binary Software
|
||||
# License.
|
||||
# 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
|
||||
@@ -18,12 +16,12 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.3 2001/01/09 03:11:27 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.23 2004/02/10 19:25:00 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.0
|
||||
VERSION = 0.7
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -37,44 +35,61 @@ includedir = $(prefix)/include
|
||||
mandir = @mandir@
|
||||
|
||||
dllib=@DLLIB@
|
||||
rdynamic=@rdynamic@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @CFLAGS@ -I.
|
||||
CPPFLAGS = @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"' @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = -Wall @CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
all: iverilog@EXEEXT@
|
||||
|
||||
clean:
|
||||
rm -f *.o lexor.c parse.c parse.h parse.output
|
||||
rm -f cflexor.c cfparse.c cfparse.h cfparse.output
|
||||
rm -f iverilog@EXEEXT@
|
||||
|
||||
O = main.o build_string.o lexor.o parse.o
|
||||
distclean: clean
|
||||
rm -f Makefile
|
||||
|
||||
O = main.o substit.o cflexor.o cfparse.o
|
||||
|
||||
iverilog@EXEEXT@: $O
|
||||
$(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@
|
||||
$(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@ @EXTRALIBS@
|
||||
|
||||
lexor.c: lexor.lex
|
||||
flex -s -olexor.c $(srcdir)/lexor.lex
|
||||
cflexor.c: cflexor.lex
|
||||
flex -s -Pcf -ocflexor.c $(srcdir)/cflexor.lex
|
||||
|
||||
parse.h parse.c: parse.y
|
||||
bison --verbose -t -d $(srcdir)/parse.y -o parse.c
|
||||
cfparse.h cfparse.c: cfparse.y
|
||||
bison --verbose -t -d -o cfparse.c --name-prefix=cf $(srcdir)/cfparse.y
|
||||
|
||||
|
||||
main.o: main.c globals.h
|
||||
$(CC) $(CPPFLAGS) -c -DCXX='"@CXX@"' -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DRDYNAMIC=\"$(rdynamic)\" -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
|
||||
|
||||
build_string.o: build_string.c globals.h
|
||||
lexor.o: lexor.c parse.h globals.h
|
||||
parse.o: parse.c globals.h
|
||||
cflexor.o: cflexor.c cfparse.h cfparse_misc.h globals.h
|
||||
cfparse.o: cfparse.c globals.h cfparse_misc.h
|
||||
|
||||
iverilog.ps: $(srcdir)/iverilog.man
|
||||
man -t $(srcdir)/iverilog.man > iverilog.ps
|
||||
|
||||
install: all installdirs $(bindir)/iverilog@EXEEXT@ $(mandir)/man1/iverilog.1
|
||||
iverilog.pdf: iverilog.ps
|
||||
ps2pdf iverilog.ps iverilog.pdf
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
INSTALL_DOC = $(prefix)/iverilog.pdf $(mandir)/man1/iverilog.1
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
all: iverilog.pdf
|
||||
else
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog.1
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
endif
|
||||
|
||||
install: all installdirs $(bindir)/iverilog@EXEEXT@ $(INSTALL_DOC)
|
||||
|
||||
$(bindir)/iverilog@EXEEXT@: ./iverilog@EXEEXT@
|
||||
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ $(bindir)/iverilog@EXEEXT@
|
||||
@@ -82,8 +97,11 @@ $(bindir)/iverilog@EXEEXT@: ./iverilog@EXEEXT@
|
||||
$(mandir)/man1/iverilog.1: $(srcdir)/iverilog.man
|
||||
$(INSTALL_DATA) $(srcdir)/iverilog.man $(mandir)/man1/iverilog.1
|
||||
|
||||
$(prefix)/iverilog.pdf: iverilog.pdf
|
||||
$(INSTALL_DATA) iverilog.pdf $(prefix)/iverilog.pdf
|
||||
|
||||
installdirs: ../mkinstalldirs
|
||||
$(srcdir)/../mkinstalldirs $(bindir) $(mandir)/man1
|
||||
$(srcdir)/../mkinstalldirs $(bindir) $(INSTALL_DOCDIR)
|
||||
|
||||
uninstall:
|
||||
rm -f $(bindir)/iverilog@EXEEXT@
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@picturel.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: build_string.c,v 1.2 2000/10/28 03:45:47 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "globals.h"
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
|
||||
int build_string(char*output, size_t olen, const char*pattern)
|
||||
{
|
||||
char tmp_buf[1024];
|
||||
|
||||
char*output_save = output;
|
||||
while (*pattern) {
|
||||
|
||||
if (*pattern == '%') {
|
||||
pattern += 1;
|
||||
switch (*pattern) {
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case '%':
|
||||
*output++ = '%';
|
||||
break;
|
||||
|
||||
case '[': {
|
||||
const char*tail;
|
||||
pattern += 1;
|
||||
assert(*pattern);
|
||||
tail = strchr(pattern+1, ']');
|
||||
assert(tail);
|
||||
strncpy(tmp_buf, pattern+1, tail-pattern-1);
|
||||
tmp_buf[tail-pattern-1] = 0;
|
||||
|
||||
if (((*pattern == 's') && start)
|
||||
|| ((*pattern == 'N') && npath)
|
||||
|| ((*pattern == 'T') && mtm)) {
|
||||
int rc = build_string(output, olen,
|
||||
tmp_buf);
|
||||
output += rc;
|
||||
olen -= rc;
|
||||
}
|
||||
pattern = tail;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'B':
|
||||
strcpy(output, base);
|
||||
output += strlen(base);
|
||||
olen -= strlen(base);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (f_list) {
|
||||
strcpy(output, f_list);
|
||||
output += strlen(f_list);
|
||||
olen -= strlen(f_list);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (mod_list) {
|
||||
strcpy(output, mod_list);
|
||||
output += strlen(mod_list);
|
||||
olen -= strlen(mod_list);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
if (npath) {
|
||||
strcpy(output, npath);
|
||||
output += strlen(npath);
|
||||
olen -= strlen(npath);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
strcpy(output, opath);
|
||||
output += strlen(opath);
|
||||
olen -= strlen(opath);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
if (start) {
|
||||
strcpy(output, start);
|
||||
output += strlen(start);
|
||||
olen -= strlen(start);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
if (mtm) {
|
||||
strcpy(output, mtm);
|
||||
output += strlen(mtm);
|
||||
olen -= strlen(mtm);
|
||||
}
|
||||
break;
|
||||
|
||||
case 't':
|
||||
strcpy(output, targ);
|
||||
output += strlen(targ);
|
||||
olen -= strlen(targ);
|
||||
break;
|
||||
|
||||
case 'W':
|
||||
strcpy(output, warning_flags);
|
||||
output += strlen(warning_flags);
|
||||
olen -= strlen(warning_flags);
|
||||
break;
|
||||
|
||||
}
|
||||
pattern += 1;
|
||||
|
||||
} else {
|
||||
*output++ = *pattern++;
|
||||
olen -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
*output = 0;
|
||||
return output-output_save;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: build_string.c,v $
|
||||
* Revision 1.2 2000/10/28 03:45:47 steve
|
||||
* Use the conf file to generate the vvm ivl string.
|
||||
*
|
||||
* Revision 1.1 2000/10/08 22:36:56 steve
|
||||
* iverilog with an iverilog.conf configuration file.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2001 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cflexor.lex,v 1.8 2004/10/04 01:10:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "cfparse.h"
|
||||
# include "cfparse_misc.h"
|
||||
# include "globals.h"
|
||||
# include <string.h>
|
||||
|
||||
/*
|
||||
* Lexical location information is passed in the yylloc variable to th
|
||||
* parser. The file names, strings, are kept in a list so that I can
|
||||
* re-use them. The set_file_name function will return a pointer to
|
||||
* the name as it exists in the list (and delete the passed string.)
|
||||
* If the name is new, it will be added to the list.
|
||||
*/
|
||||
YYLTYPE yylloc;
|
||||
|
||||
static int comment_enter;
|
||||
|
||||
%}
|
||||
|
||||
%x CCOMMENT
|
||||
%x LCOMMENT
|
||||
%x PLUS_ARGS
|
||||
|
||||
%%
|
||||
|
||||
/* Accept C++ style comments. */
|
||||
"//".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
|
||||
<LCOMMENT>. { yymore(); }
|
||||
<LCOMMENT>\n { yylloc.first_line += 1; BEGIN(comment_enter); }
|
||||
|
||||
/* Accept C style comments. */
|
||||
"/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
|
||||
<CCOMMENT>. { yymore(); }
|
||||
<CCOMMENT>\n { yylloc.first_line += 1; yymore(); }
|
||||
<CCOMMENT>"*/" { BEGIN(comment_enter); }
|
||||
|
||||
/* Accept shell type comments. */
|
||||
^"#".* { ; }
|
||||
|
||||
/* Skip white space. */
|
||||
[ \t\f\r] { ; }
|
||||
/* Skip line ends, but also count the line. */
|
||||
\n { yylloc.first_line += 1; }
|
||||
|
||||
|
||||
"+define+" { BEGIN(PLUS_ARGS); return TOK_DEFINE; }
|
||||
|
||||
"+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; }
|
||||
|
||||
"+libdir+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR; }
|
||||
|
||||
"+libdir-nocase+" { BEGIN(PLUS_ARGS); return TOK_LIBDIR_NOCASE; }
|
||||
|
||||
"+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; }
|
||||
|
||||
|
||||
/* If it is not any known plus-flag, return the generic form. */
|
||||
"+"[^\n \t\b\f\r+]* {
|
||||
cflval.text = strdup(yytext);
|
||||
BEGIN(PLUS_ARGS);
|
||||
return TOK_PLUSWORD; }
|
||||
|
||||
/* Once in PLUS_ARGS mode, words are delimited by +
|
||||
characters. White space and line end terminate PLUS_ARGS mode,
|
||||
but + terminates only the word. */
|
||||
<PLUS_ARGS>[^\n \t\b\f\r+]* {
|
||||
cflval.text = strdup(yytext);
|
||||
return TOK_PLUSARG; }
|
||||
|
||||
/* Within plusargs, this is a delimiter. */
|
||||
<PLUS_ARGS>"+" { }
|
||||
|
||||
/* White space end plus_args mode. */
|
||||
<PLUS_ARGS>[ \t\b\f\r] { BEGIN(0); }
|
||||
|
||||
<PLUS_ARGS>\n {
|
||||
yylloc.first_line += 1;
|
||||
BEGIN(0); }
|
||||
|
||||
/* Notice the -a flag. */
|
||||
"-a" { return TOK_Da; }
|
||||
|
||||
/* Notice the -v flag. */
|
||||
"-v" { return TOK_Dv; }
|
||||
|
||||
/* Notice the -y flag. */
|
||||
"-y" { return TOK_Dy; }
|
||||
|
||||
/* This rule matches paths and strings that may be file names. This
|
||||
is a little bit tricky, as we don't want to mistake a comment for
|
||||
a string word. */
|
||||
"/"[^\*\/].* { cflval.text = strdup(yytext);
|
||||
return TOK_STRING; }
|
||||
|
||||
[^/\n \t\b\r+-].* { cflval.text = strdup(yytext);
|
||||
return TOK_STRING; }
|
||||
|
||||
/* Fallback match. */
|
||||
. { return yytext[0]; }
|
||||
|
||||
%%
|
||||
|
||||
int yywrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cfreset(FILE*fd, const char*path)
|
||||
{
|
||||
yyin = fd;
|
||||
yyrestart(fd);
|
||||
yylloc.first_line = 1;
|
||||
yylloc.text = (char*)path;
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 20001 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cfparse.y,v 1.10 2003/09/26 21:25:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
# include "globals.h"
|
||||
# include "cfparse_misc.h"
|
||||
# include <ctype.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
|
||||
|
||||
/*
|
||||
* This flag is set to 0, 1 or 2 if file names are to be translated to
|
||||
* uppercase(1) or lowercase(2).
|
||||
*/
|
||||
static int setcase_filename_flag = 0;
|
||||
static void translate_file_name(char*text)
|
||||
{
|
||||
switch (setcase_filename_flag) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
while (*text) {
|
||||
*text = toupper(*text);
|
||||
text += 1;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
while (*text) {
|
||||
*text = tolower(*text);
|
||||
text += 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
char*text;
|
||||
};
|
||||
|
||||
%token TOK_Da TOK_Dv TOK_Dy
|
||||
%token TOK_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT
|
||||
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
|
||||
|
||||
%%
|
||||
|
||||
start
|
||||
:
|
||||
| item_list
|
||||
;
|
||||
|
||||
item_list
|
||||
: item_list item
|
||||
| item
|
||||
;
|
||||
|
||||
item
|
||||
/* Absent any other matching, a token string is taken to be the name
|
||||
of a source file. Add the file to the file list. */
|
||||
|
||||
: TOK_STRING
|
||||
{ char*tmp = substitutions($1);
|
||||
translate_file_name(tmp);
|
||||
process_file_name(tmp);
|
||||
free($1);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* The -a flag is completely ignored. */
|
||||
|
||||
| TOK_Da { }
|
||||
|
||||
/* The -v <libfile> flag is ignored, and the <libfile> is processed
|
||||
as an ordinary source file. */
|
||||
|
||||
| TOK_Dv TOK_STRING
|
||||
{ char*tmp = substitutions($2);
|
||||
translate_file_name(tmp);
|
||||
process_file_name(tmp);
|
||||
fprintf(stderr, "%s:%u: Ignoring -v in front of %s\n",
|
||||
@1.text, @1.first_line, $2);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* This rule matches "-y <path>" sequences. This does the same thing
|
||||
as -y on the command line, so add the path to the library
|
||||
directory list. */
|
||||
|
||||
| TOK_Dy TOK_STRING
|
||||
{ char*tmp = substitutions($2);
|
||||
process_library_switch(tmp);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
| TOK_LIBDIR TOK_PLUSARG
|
||||
{ char*tmp = substitutions($2);
|
||||
process_library_switch(tmp);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
| TOK_LIBDIR_NOCASE TOK_PLUSARG
|
||||
{ char*tmp = substitutions($2);
|
||||
process_library_nocase_switch(tmp);
|
||||
free($2);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
| TOK_DEFINE TOK_PLUSARG
|
||||
{ process_define($2);
|
||||
free($2);
|
||||
}
|
||||
|
||||
/* The +incdir token introduces a list of +<path> arguments that are
|
||||
the include directories to search. */
|
||||
|
||||
| TOK_INCDIR inc_args
|
||||
|
||||
/* The +libext token introduces a list of +<ext> arguments that
|
||||
become individual -Y flags to ivl. */
|
||||
|
||||
| TOK_LIBEXT libext_args
|
||||
|
||||
/* The +<word> tokens that are not otherwise matched, are
|
||||
ignored. The skip_args rule arranges for all the argument words
|
||||
to be consumed. */
|
||||
|
||||
| TOK_PLUSWORD skip_args
|
||||
{ fprintf(stderr, "%s:%u: Ignoring %s\n",
|
||||
@1.text, @1.first_line, $1);
|
||||
free($1);
|
||||
}
|
||||
| TOK_PLUSWORD
|
||||
{ if (strcmp($1, "+toupper-filenames") == 0) {
|
||||
setcase_filename_flag = 1;
|
||||
} else if (strcmp($1, "+tolower-filenames") == 0) {
|
||||
setcase_filename_flag = 2;
|
||||
} else {
|
||||
fprintf(stderr, "%s:%u: Ignoring %s\n",
|
||||
@1.text, @1.first_line, $1);
|
||||
}
|
||||
free($1);
|
||||
}
|
||||
;
|
||||
|
||||
/* inc_args are +incdir+ arguments in order. */
|
||||
inc_args
|
||||
: inc_args inc_arg
|
||||
| inc_arg
|
||||
;
|
||||
|
||||
inc_arg : TOK_PLUSARG
|
||||
{ char*tmp = substitutions($1);
|
||||
process_include_dir(tmp);
|
||||
free($1);
|
||||
free(tmp);
|
||||
}
|
||||
;
|
||||
|
||||
/* inc_args are +incdir+ arguments in order. */
|
||||
libext_args
|
||||
: libext_args libext_arg
|
||||
| libext_arg
|
||||
;
|
||||
|
||||
libext_arg : TOK_PLUSARG
|
||||
{ process_library2_switch($1);
|
||||
free($1);
|
||||
}
|
||||
;
|
||||
|
||||
/* skip_args are arguments to a +word flag that is not otherwise
|
||||
parsed. This rule matches them and releases the strings, so that
|
||||
they can be safely ignored. */
|
||||
skip_args
|
||||
: skip_args skip_arg
|
||||
| skip_arg
|
||||
;
|
||||
|
||||
skip_arg : TOK_PLUSARG
|
||||
{ free($1);
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
int yyerror(const char*msg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef __cfparse_misc_H
|
||||
#define __cfparse_misc_H
|
||||
/*
|
||||
* Copyright (c) 2001 Picture Elements, Inc.
|
||||
* Stephen Williams (steve@picturel.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cfparse_misc.h,v 1.6 2004/02/15 18:03:30 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The vlltype supports the passing of detailed source file location
|
||||
* information between the lexical analyzer and the parser. Defining
|
||||
* YYLTYPE compels the lexor to use this type and not something other.
|
||||
*/
|
||||
struct cfltype {
|
||||
unsigned first_line;
|
||||
unsigned first_column;
|
||||
unsigned last_line;
|
||||
unsigned last_column;
|
||||
const char*text;
|
||||
};
|
||||
# define YYLTYPE struct cfltype
|
||||
extern YYLTYPE yylloc;
|
||||
|
||||
int cflex(void);
|
||||
int cferror(const char *);
|
||||
int cfparse(void);
|
||||
|
||||
/*
|
||||
* $Log: cfparse_misc.h,v $
|
||||
* Revision 1.6 2004/02/15 18:03:30 steve
|
||||
* Cleanup of warnings.
|
||||
*
|
||||
* Revision 1.5 2003/09/26 21:25:58 steve
|
||||
* Warnings cleanup.
|
||||
*
|
||||
* Revision 1.4 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.3 2002/01/02 02:39:34 steve
|
||||
* Use my own cfltype to defend against bison 1.30.
|
||||
*
|
||||
* Revision 1.2 2001/11/12 18:47:32 steve
|
||||
* Support +incdir in command files, and ignore other
|
||||
* +args flags. Also ignore -a and -v flags.
|
||||
*
|
||||
* Revision 1.1 2001/11/12 01:26:36 steve
|
||||
* More sophisticated command file parser.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+52
-20
@@ -18,8 +18,8 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: globals.h,v 1.3 2000/11/09 21:58:00 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: globals.h,v 1.19 2003/11/18 06:31:46 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stddef.h>
|
||||
@@ -27,14 +27,12 @@
|
||||
/* This is the base (i.e. -B<value>) of the Icarus Verilog files. */
|
||||
extern const char*base;
|
||||
|
||||
/* This is a list of all the -f<key>=<value> options from the
|
||||
command line, concatenated together. */
|
||||
extern char*f_list;
|
||||
/* This is the path to the iconfig file sent to ivl. */
|
||||
extern char* iconfig_path;
|
||||
extern char* iconfig_common_path;
|
||||
|
||||
extern char*mod_list;
|
||||
|
||||
/* This is the optional -Tmin|typ|max setting. */
|
||||
extern const char*mtm;
|
||||
/* Ths is the optional -M<dependfile> value, if one was supplied. */
|
||||
extern const char*depfile;
|
||||
|
||||
/* Ths is the optional -N<path> value, if one was supplied. */
|
||||
extern const char*npath;
|
||||
@@ -42,8 +40,8 @@ extern const char*npath;
|
||||
/* This is the name of the output file that the user selected. */
|
||||
extern const char*opath;
|
||||
|
||||
/* This pointer is set if there was a -s<value> parameter. */
|
||||
extern const char*start;
|
||||
/* This pointer is set if there were -s<value> parameters. */
|
||||
extern char*start;
|
||||
|
||||
/* This flag is true if the -S flag was used on the command line. */
|
||||
extern int synth_flag;
|
||||
@@ -51,22 +49,56 @@ extern int synth_flag;
|
||||
/* This is the name of the selected target. */
|
||||
extern const char*targ;
|
||||
|
||||
/* Perform variable substitutions on the string. */
|
||||
extern char* substitutions(const char*str);
|
||||
|
||||
/* Add the name to the list of source files. */
|
||||
extern void process_file_name(const char*name);
|
||||
|
||||
/* Add the name to the list of library directories. */
|
||||
extern void process_library_switch(const char*name);
|
||||
extern void process_library_nocase_switch(const char*name);
|
||||
extern void process_library2_switch(const char*name);
|
||||
|
||||
/* Add a new include file search directory */
|
||||
extern void process_include_dir(const char*name);
|
||||
|
||||
/* Add a new -D define. */
|
||||
extern void process_define(const char*name);
|
||||
|
||||
/* -v */
|
||||
extern int verbose_flag;
|
||||
|
||||
extern char warning_flags[];
|
||||
|
||||
extern const char*lookup_pattern(const char*key);
|
||||
|
||||
extern int build_string(char*out, size_t olen, const char*pattern);
|
||||
/* -y and -Y flags from the command line. */
|
||||
extern char* library_flags;
|
||||
extern char* library_flags2;
|
||||
|
||||
/*
|
||||
* $Log: globals.h,v $
|
||||
* Revision 1.3 2000/11/09 21:58:00 steve
|
||||
* Remember to include the -S condition.
|
||||
* Revision 1.19 2003/11/18 06:31:46 steve
|
||||
* Remove the iverilog.conf file.
|
||||
*
|
||||
* Revision 1.2 2000/10/28 03:45:47 steve
|
||||
* Use the conf file to generate the vvm ivl string.
|
||||
* Revision 1.18 2003/11/13 04:09:49 steve
|
||||
* Pass flags through the temporary config file.
|
||||
*
|
||||
* Revision 1.1 2000/10/08 22:36:56 steve
|
||||
* iverilog with an iverilog.conf configuration file.
|
||||
* Revision 1.17 2003/11/01 04:21:57 steve
|
||||
* Add support for a target static config file.
|
||||
*
|
||||
* Revision 1.16 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.15 2002/06/23 20:10:51 steve
|
||||
* Variable substitution in command files.
|
||||
*
|
||||
* Revision 1.14 2002/05/28 20:40:37 steve
|
||||
* ivl indexes the search path for libraries, and
|
||||
* supports case insensitive module-to-file lookup.
|
||||
*
|
||||
* Revision 1.13 2002/05/28 00:50:40 steve
|
||||
* Add the ivl -C flag for bulk configuration
|
||||
* from the driver, and use that to run library
|
||||
* modules through the preprocessor.
|
||||
*/
|
||||
#endif
|
||||
|
||||
+212
-44
@@ -1,17 +1,19 @@
|
||||
.TH iverilog 1 "$Date: 2001/01/20 19:02:05 $" Version "$Date: 2001/01/20 19:02:05 $"
|
||||
.TH iverilog 1 "$Date: 2004/10/04 01:10:56 $" Version "$Date: 2004/10/04 01:10:56 $"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog
|
||||
[-ESv] [-Cpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value] [-Iincludepath] [-mmodule] [-Nfile] [-ooutputfilename] [-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] sourcefile
|
||||
[-ESVv] [-Bpath] [-ccmdfile] [-g1|-g2|-g3.0] [-Dmacro[=defn]] [-pflag=value]
|
||||
[-Iincludedir] [-mmodule] [-Mfile] [-Nfile] [-ooutputfilename]
|
||||
[-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
\fIiverilog\fP is a compiler that translates Verilog source code into
|
||||
executable programs for simulation, or other netlist formats for
|
||||
further processing. The currenty supported targets are \fIvvm\fP (for
|
||||
executable simulation) and \fIxnf\fP for synthesis. Other target
|
||||
further processing. The currently supported targets are \fIvvp\fP for
|
||||
simulation, and \fIxnf\fP and \fIfpga\fP for synthesis. Other target
|
||||
types are added as code generators are implemented.
|
||||
|
||||
.SH OPTIONS
|
||||
@@ -19,27 +21,18 @@ types are added as code generators are implemented.
|
||||
\fIiverilog\fP accepts the following options:
|
||||
.TP 8
|
||||
.B -B\fIbase\fP
|
||||
The \fIiverilog\fP program uses external programs to preprocess and
|
||||
compile the verilog source. Normally, the path used to locate these
|
||||
tools is built into the \fIiverilog\fP program. However, the \fB-B\fP
|
||||
switch allows the user to select a different set of programs. The path
|
||||
given is used to locate \fIivlpp\fP, \fIivl\fP and the VPI modules.
|
||||
The \fIiverilog\fP program uses external programs and configuration
|
||||
files to preprocess and compile the Verilog source. Normally, the path
|
||||
used to locate these tools is built into the \fIiverilog\fP
|
||||
program. However, the \fB-B\fP switch allows the user to select a
|
||||
different set of programs. The path given is used to locate
|
||||
\fIivlpp\fP, \fIivl\fP, code generators and the VPI modules.
|
||||
.TP 8
|
||||
.B -c\fIfile\fP
|
||||
This flag specifies 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. The command file may
|
||||
contain C-style comments (/*-*/) or shell-style comments (# to the end
|
||||
of the line.)
|
||||
.TP 8
|
||||
.B -C\fIpath\fP
|
||||
This flag selects the driver configuration file to use. Normally, the
|
||||
iverilog program will read its configuration file from
|
||||
/usr/lib/ivl/iverilog.conf (or the install path configured at compile
|
||||
time) but the user can specify the path to a different configuration
|
||||
file. This is useful when testing new configuration files. See the
|
||||
installed configuration file for a summary of the file format.
|
||||
instead of taking them on the command line. See \fBCommand Files\fP below.
|
||||
.TP 8
|
||||
.B -D\fImacro\fP
|
||||
Defines macro \fImacro\fP with the string `1' as its definition. This
|
||||
@@ -53,18 +46,34 @@ Defines macro \fImacro\fP as \fIdefn\fP.
|
||||
Preprocess the Verilog source, but do not compile it. The output file
|
||||
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.
|
||||
Verilog source for use by other compilers.
|
||||
.TP 8
|
||||
.B -I\fIincludedir\fP
|
||||
Append directory \fIincludepdir\fP to list of directoriess searched
|
||||
.B -g1\fI|\fP-g2\fI|\fP-g3.0
|
||||
Select the Verilog language \fIgeneration\fP to support in the
|
||||
compiler. This selects between \fIIEEE1364-1995\fP(1),
|
||||
\fIIEEE1364-2001\fP(2), or \fISystemVerilog 3.0\fP(3.0). Normally,
|
||||
Icarus Verilog defaults to the latest known generation of the
|
||||
language. This flag is most useful to restrict the language to a set
|
||||
supported by tools of specific generations, for compatibility with
|
||||
other tools.
|
||||
.TP 8
|
||||
.B -I\fIincludedir\fP
|
||||
Append directory \fIincludedir\fP to list of directories searched
|
||||
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 -M\fIpath\fP
|
||||
Write into the file specified by path a list of files that contribute
|
||||
to the compilation of the design. This includes files that are
|
||||
included by include directives and files that are automatically loaded
|
||||
by library support. The output is one file name per line, with no
|
||||
leading or trailing space.
|
||||
.TP 8
|
||||
.B -m\fImodule\fP
|
||||
Add this module to the list of VPI modules to be loaded by the
|
||||
simulation. Many modules can be specified, and all will be loaded, in
|
||||
the order specified.
|
||||
the order specified. The system module is implicit and always included.
|
||||
.TP 8
|
||||
.B -N\fIpath\fP
|
||||
This is used for debugging the compiler proper. Dump the final netlist
|
||||
@@ -91,9 +100,10 @@ netlist format, the \fB-S\fP switch is unnecessary and has no effect.
|
||||
.TP 8
|
||||
.B -s \fItopmodule\fP
|
||||
Specify the top level module to elaborate. Icarus Verilog will by default
|
||||
choose the only module that has no ports. However, this simplistic
|
||||
heuristic is often not sufficient, and sometimes not what is wanted
|
||||
anyhow.
|
||||
choose modules that are not instantiated in any other modules, but
|
||||
sometimes that is not sufficient, or instantiates too many modules. If
|
||||
the user specifies one or more root modules with \fB-s\fP flags, then
|
||||
they will be used as root modules instead.
|
||||
.TP 8
|
||||
.B -T\fImin|typ|max\fP
|
||||
Use this switch to select min, typ or max times from min:typ:max
|
||||
@@ -109,13 +119,40 @@ Use this switch to specify the target output format. See the
|
||||
.B -v
|
||||
Turn on verbose messages. This will print the command lines that are
|
||||
executed to perform the actual compilation, along with version
|
||||
information from the various components.
|
||||
information from the various components, as well as the version of the
|
||||
product as a whole. You will notice that the command lines include
|
||||
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.
|
||||
.TP 8
|
||||
.B -V
|
||||
Print the version of the compiler, and exit.
|
||||
.TP 8
|
||||
.B -W\fIclass\fP
|
||||
Turn on different classes of warnings. See the \fBWARNING TYPES\fP
|
||||
section below for desctriptions of the different warning groups. If
|
||||
section below for descriptions of the different warning groups. If
|
||||
multiple \fB-W\fP switches are used, the warning set is the union of
|
||||
all the requested classes.
|
||||
.TP 8
|
||||
.B -y\fIlibdir\fP
|
||||
Append the directory to the library module search path. When the
|
||||
compiler finds an undefined module, it looks in these directories for
|
||||
files with the right name.
|
||||
|
||||
.SH MODULE LIBRARIES
|
||||
|
||||
The Icarus Verilog compiler supports module libraries as directories
|
||||
that contain Verilog source files. During elaboration, the compiler
|
||||
notices the instantiation of undefined module types. If the user
|
||||
specifies library search directories, the compiler will search the
|
||||
directory for files with the name of the missing module type. If it
|
||||
finds such a file, it loads it as a Verilog source file, they tries
|
||||
again to elaborate the module.
|
||||
|
||||
Library module files should contain only a single module, but this is
|
||||
not a requirement. Library modules may reference other modules in the
|
||||
library or in the main design.
|
||||
|
||||
.SH TARGETS
|
||||
|
||||
@@ -128,20 +165,28 @@ desired target.
|
||||
The null target causes no code to be generated. It is useful for
|
||||
checking the syntax of the Verilog source.
|
||||
.TP 8
|
||||
.B vvm
|
||||
This is the default. The target is an executable program that uses the
|
||||
vvm simulation runtime. The compiler actually generates C++ code, then
|
||||
compiles and links that code to make the output executable.
|
||||
.B vvp
|
||||
This is the default. The vvp target generates code for the vvp
|
||||
runtime. The output is a complete program that simulates the design
|
||||
but must be run by the \fBvvp\fP command.
|
||||
.TP 8
|
||||
.B xnf
|
||||
This is the Xilinx Netlist Format used by many tools for placing
|
||||
devices in FPGAs or other programmable devices. The Icarus Verilog XNF
|
||||
code generator can generate complete designs or XNF macros that can be
|
||||
imported into larger designs by other tools.
|
||||
devices in FPGAs or other programmable devices. This target is
|
||||
obsolete, use the \fBfpga\fP target instead.
|
||||
.TP 8
|
||||
.B fpga
|
||||
This is a synthesis target that supports a variety of fpga devices,
|
||||
mostly by EDIF format output. The Icarus Verilog fpga code generator
|
||||
can generate complete designs or EDIF macros that can in turn be
|
||||
imported into larger designs by other tools. The \fBfpga\fP target
|
||||
implies the synthesis \fB-S\fP flag.
|
||||
|
||||
.SH "WARNING TYPES"
|
||||
These are the types of warnings that can be selected by the \fB-W\fP
|
||||
switch.
|
||||
switch. All the warning types (other then \fBall\fP) can also be
|
||||
prefixed with \fBno-\fP to turn off that warning. This is most useful
|
||||
after a \fB-Wall\fP argument to suppress isolated warning types.
|
||||
|
||||
.TP 8
|
||||
.B all
|
||||
@@ -150,24 +195,146 @@ This enables all supported warning categories.
|
||||
.TP 8
|
||||
.B implicit
|
||||
This enables warnings for creation of implicit declarations. For
|
||||
example, if a scaler wire X is used but not declared in the Verilog
|
||||
example, if a scalar wire X is used but not declared in the Verilog
|
||||
source, this will print a warning at its first use.
|
||||
|
||||
.SH EXAMPLES
|
||||
.TP 8
|
||||
.B portbind
|
||||
This enables warnings for ports of module instantiations that are not
|
||||
connected but probably should be. Dangling input ports, for example,
|
||||
will generate a warning.
|
||||
|
||||
.TP 8
|
||||
.B timescale
|
||||
This enables warnings for inconsistent use of the timescale
|
||||
directive. It detects if some modules have no timescale, or if modules
|
||||
inherit timescale from another file. Both probably mean that
|
||||
timescales are inconsistent, and simulation timing can be confusing
|
||||
and dependent on compilation order.
|
||||
|
||||
.SH "SYSTEM FUNCTION TABLE FILES"
|
||||
If the source file name as a \fB.sft\fP suffix, then it is taken to be
|
||||
a system function table file. A System function table file is used to
|
||||
describe to the compiler the return types for system functions. This
|
||||
is necessary because the compiler needs this information to elaborate
|
||||
expressions that contain these system functions, but cannot run the
|
||||
sizetf functions since it has no run-time.
|
||||
|
||||
The format of the table is ASCII, one function per line. Empty lines
|
||||
are ignored, and lines that start with the '\fI#\fP' character are
|
||||
comment lines. Each non-comment line starts with the function name,
|
||||
then the vpi type (i.e. vpiSysFuncReal). The following types are
|
||||
supported:
|
||||
|
||||
.TP 8
|
||||
.B vpiSysFuncReal
|
||||
The function returns a real/realtime value.
|
||||
|
||||
.TP 8
|
||||
.B vpiSysFuncInt
|
||||
The function returns an integer.
|
||||
|
||||
.TP 8
|
||||
.B vpiSysFuncSized <wid> <signed|unsigned>
|
||||
The function returns a vector with the given width, and is signed or
|
||||
unsigned according to the flag.
|
||||
|
||||
.SH "COMMAND FILES"
|
||||
The command file allows the user to place source file names and
|
||||
certain command line switches into a text file instead of on a long
|
||||
command line. Command files can include C or C++ style comments, as
|
||||
well as # comments, if the # starts the line.
|
||||
|
||||
.TP 8
|
||||
.I "file name"
|
||||
A simple file name or file path is taken to be the name of a Verilog
|
||||
source file. The path starts with the first non-white-space
|
||||
character. Variables are substitued in file names.
|
||||
|
||||
.TP 8
|
||||
.B -y\ \fIlibdir\fP
|
||||
A \fB-y\fP token prefixes a library directory in the command file,
|
||||
exactly like it does on the command line. The parameter to the \fB-y\fP
|
||||
flag may be on the same line or the next non-comment line.
|
||||
|
||||
Variables in the \fIlibdir\fP are substituted.
|
||||
|
||||
.TP 8
|
||||
.B +incdir+\fIincludedir\fP
|
||||
The \fB+incdir+\fP token in command files gives directories to search
|
||||
for include files in much the same way that \fB-I\fP flags work on the
|
||||
command line. The difference is that multiple \fI+includedir\fP
|
||||
directories are valid parameters to a single \fB+incdir+\fP token,
|
||||
although you may also have multiple \fB+incdir+\fP lines.
|
||||
|
||||
Variables in the \fIincludedir\fP are substituted.
|
||||
|
||||
.TP 8
|
||||
.B +libext+\fIext\fP
|
||||
The \fB+libext\fP token in command files fives file extensions to try
|
||||
when looking for a library file. This is useful in conjunction with
|
||||
\fB-y\fP flags to list suffixes to try in each directory before moving
|
||||
on to the next library directory.
|
||||
|
||||
.TP 8
|
||||
.B +libdir+\fIdir\fP
|
||||
This is another way to specify library directories. See the -y flag.
|
||||
|
||||
.TP 8
|
||||
.B +libdir-nocase+\fIdir\fP
|
||||
This is like the \fB+libdir\fP statement, but file names inside the
|
||||
directories declared here are case insensitive. The missing module
|
||||
name in a lookup need not match the file name case, as long as the
|
||||
letters are correct. For example, "foo" matches "Foo.v" but not
|
||||
"bar.v".
|
||||
|
||||
.TP 8
|
||||
.B +define+\fINAME\fP=\fIvalue\fP
|
||||
The \fB+define+\fP token is the same as the \fB-D\fP option on the
|
||||
command line. The value part of the token is optional.
|
||||
|
||||
.TP 8
|
||||
.B +toupper-filename\fP
|
||||
This token causes file names after this in the command file to be
|
||||
translated to uppercase. This helps with situations where a directory
|
||||
has passed through a DOS machine, and in the process the file names
|
||||
become munged.
|
||||
|
||||
.TP 8
|
||||
.B +tolower-filename\fP
|
||||
This is similar to the \fB+toupper-filename\fP hack described above.
|
||||
|
||||
.SH "VARIABLES IN COMMAND FILES"
|
||||
|
||||
In certain cases, iverilog supports variables in command files. These
|
||||
are strings of the form "$(\fIvarname\fP)", where \fIvarname\fP is the
|
||||
name of the environment variable to read. The entire string is
|
||||
replaced with the contents of that variable. Variables are only
|
||||
substitued in contexts that explicitly support them, including file
|
||||
and directory strings.
|
||||
|
||||
Variable values come from the operating system environment, and not
|
||||
from preprocessor defines elsewhere in the file or the command line.
|
||||
|
||||
.SH EXAMPLES
|
||||
These examples assume that you have a Verilog source file called hello.v in
|
||||
the current directory
|
||||
|
||||
To compile hello.v to an executable file called a.out:
|
||||
|
||||
verilog hello.v
|
||||
iverilog hello.v
|
||||
|
||||
To compile hello.v to an executable file called hello:
|
||||
|
||||
verilog -o hello hello.v
|
||||
iverilog -o hello hello.v
|
||||
|
||||
To compile and run explicitly using the vvp runtime:
|
||||
|
||||
iverilog -ohello.vvp -tvvp hello.v
|
||||
|
||||
To compile hello.v to a file in XNF-format called hello.xnf
|
||||
|
||||
verilog -txnf -ohello.xnf hello.v
|
||||
iverilog -txnf -ohello.xnf hello.v
|
||||
|
||||
|
||||
.SH "AUTHOR"
|
||||
@@ -175,11 +342,12 @@ To compile hello.v to a file in XNF-format called hello.xnf
|
||||
Steve Williams ([email protected])
|
||||
|
||||
.SH SEE ALSO
|
||||
vvp(1),
|
||||
.BR "<http://www.icarus.com/eda/verilog/>"
|
||||
|
||||
.SH COPYRIGHT
|
||||
.nf
|
||||
Copyright \(co 2000 Stephen Williams
|
||||
Copyright \(co 2002 Stephen Williams
|
||||
|
||||
This document can be freely redistributed according to the terms of the
|
||||
This document can be freely redistributed according to the terms of the
|
||||
GNU General Public License version 2.0
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2000 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: lexor.lex,v 1.4 2000/12/15 02:00:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string.h>
|
||||
# include "parse.h"
|
||||
|
||||
%}
|
||||
|
||||
%x CTOKENS
|
||||
%x PATTERN
|
||||
|
||||
%%
|
||||
|
||||
"#".* { /* eat comments */; }
|
||||
|
||||
"\n" { /* eat line-ends */; }
|
||||
"\r" { /* eat line-ends */; }
|
||||
|
||||
"[" { BEGIN(CTOKENS); return '['; }
|
||||
|
||||
<CTOKENS>"]" { BEGIN(0); return ']'; }
|
||||
|
||||
<CTOKENS>[ \t\b]+ { /* skip white space */; }
|
||||
|
||||
<CTOKENS>"-S" { return CT_S; }
|
||||
|
||||
<CTOKENS>"-t"[a-zA-Z0-9\-_]+ {
|
||||
yylval.text = strdup(yytext+2);
|
||||
return CT_t; }
|
||||
|
||||
"<"[^>]*">" {
|
||||
BEGIN(PATTERN);
|
||||
yylval.text = strdup(yytext);
|
||||
return PATTERN_NAME; }
|
||||
|
||||
<PATTERN>.* {
|
||||
BEGIN(0);
|
||||
/* Trim off a trailing \r. This is an issue in the DOS world. */
|
||||
if (yytext[strlen(yytext)-1] == '\r')
|
||||
yytext[strlen(yytext)-1] = 0;
|
||||
|
||||
yylval.text = strdup(yytext);
|
||||
return PATTERN_TEXT; }
|
||||
|
||||
. { fprintf(stderr, "driver lexor: Unmatched character: %c\n", yytext[0]); }
|
||||
|
||||
%%
|
||||
|
||||
void reset_lexor(FILE*fd)
|
||||
{
|
||||
yyrestart(fd);
|
||||
}
|
||||
|
||||
int yywrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
+533
-298
File diff suppressed because it is too large
Load Diff
-162
@@ -1,162 +0,0 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2000 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: parse.y,v 1.2 2000/11/09 21:58:00 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
# include <malloc.h>
|
||||
# include "globals.h"
|
||||
|
||||
|
||||
void yyerror(const char*);
|
||||
|
||||
enum drive_code_t {
|
||||
CODE_S,
|
||||
CODE_t,
|
||||
};
|
||||
|
||||
struct drive_cond {
|
||||
struct drive_cond*next;
|
||||
enum drive_code_t code;
|
||||
char* text;
|
||||
};
|
||||
|
||||
static struct drive_cond *cur_cond = 0;
|
||||
|
||||
static void add_cond(enum drive_code_t code, char*text)
|
||||
{
|
||||
struct drive_cond*tmp;
|
||||
tmp = calloc(1, sizeof(struct drive_cond));
|
||||
tmp->code = code;
|
||||
tmp->text = text;
|
||||
|
||||
tmp->next = cur_cond;
|
||||
cur_cond = tmp;
|
||||
}
|
||||
|
||||
struct drive_pattern {
|
||||
struct drive_pattern*next;
|
||||
char*name;
|
||||
char*text;
|
||||
struct drive_cond*cond;
|
||||
};
|
||||
|
||||
static struct drive_pattern *patterns = 0;
|
||||
static struct drive_pattern *plast = 0;
|
||||
|
||||
static void add_pattern(char*name, char*text)
|
||||
{
|
||||
struct drive_pattern*tmp;
|
||||
tmp = calloc(1, sizeof(struct drive_pattern));
|
||||
tmp->name = name;
|
||||
tmp->text = text;
|
||||
tmp->cond = cur_cond;
|
||||
tmp->next = 0;
|
||||
|
||||
|
||||
if (plast) {
|
||||
plast->next = tmp;
|
||||
plast = tmp;
|
||||
} else {
|
||||
patterns = tmp;
|
||||
plast = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
const char*lookup_pattern(const char*key)
|
||||
{
|
||||
struct drive_pattern*cur;
|
||||
struct drive_cond*cc;
|
||||
|
||||
for (cur = patterns ; cur ; cur = cur->next) {
|
||||
|
||||
if (strcmp(key, cur->name) != 0)
|
||||
continue;
|
||||
|
||||
for (cc = cur->cond ; cc ; cc = cc->next) {
|
||||
|
||||
switch (cc->code) {
|
||||
case CODE_S:
|
||||
if (synth_flag)
|
||||
continue;
|
||||
break;
|
||||
case CODE_t:
|
||||
if (strcmp(targ, cc->text) == 0)
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (cc) continue;
|
||||
|
||||
return cur->text;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
char*text;
|
||||
};
|
||||
|
||||
%token <text> PATTERN_NAME PATTERN_TEXT
|
||||
%token <text> CT_t
|
||||
%token CT_S
|
||||
|
||||
%%
|
||||
|
||||
start: section_list
|
||||
|
||||
section_list
|
||||
: section
|
||||
| section_list section
|
||||
;
|
||||
|
||||
section : '[' ctoken_list ']' pattern_list { cur_cond = 0; } ;
|
||||
|
||||
ctoken_list
|
||||
: ctoken
|
||||
| ctoken_list ctoken
|
||||
;
|
||||
|
||||
ctoken : CT_S { add_cond(CODE_S, 0); }
|
||||
| CT_t { add_cond(CODE_t, $1); }
|
||||
;
|
||||
|
||||
pattern_list
|
||||
: pattern
|
||||
| pattern_list pattern
|
||||
;
|
||||
|
||||
pattern : PATTERN_NAME PATTERN_TEXT
|
||||
{ add_pattern($1, $2); }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
void yyerror(const char*msg)
|
||||
{
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
}
|
||||
@@ -0,0 +1,115 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: substit.c,v 1.5 2003/12/19 01:27:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string.h>
|
||||
# include <stdlib.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
|
||||
|
||||
char* substitutions(const char*str)
|
||||
{
|
||||
size_t nbuf = strlen(str) + 1;
|
||||
char*buf = malloc(nbuf);
|
||||
char*cp = buf;
|
||||
|
||||
while (*str) {
|
||||
|
||||
if ((str[0] == '$') && (str[1] == '(')) {
|
||||
/* If I find a $(x) string in the source, replace
|
||||
it in the destination with the contents of the
|
||||
environment variable x. */
|
||||
char*name;
|
||||
char*value;
|
||||
const char*ep = strchr(str, ')');
|
||||
str += 2;
|
||||
|
||||
name = malloc(ep-str+1);
|
||||
strncpy(name, str, ep-str);
|
||||
name[ep-str] = 0;
|
||||
|
||||
str = ep + 1;
|
||||
|
||||
value = getenv(name);
|
||||
free(name);
|
||||
if (value == 0)
|
||||
continue;
|
||||
|
||||
if (strlen(value) >= (nbuf - (cp-buf))) {
|
||||
size_t old_size = cp - buf;
|
||||
nbuf = (cp - buf) + strlen(value) + 1;
|
||||
buf = realloc(buf, nbuf);
|
||||
cp = buf + old_size;
|
||||
}
|
||||
|
||||
strcpy(cp, value);
|
||||
cp += strlen(cp);
|
||||
|
||||
} else {
|
||||
if ( cp == (buf + nbuf) ) {
|
||||
size_t old_size = nbuf;
|
||||
nbuf = old_size + 32;
|
||||
buf = realloc(buf, nbuf);
|
||||
cp = buf + old_size;
|
||||
}
|
||||
|
||||
*cp++ = *str++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the trailing nul to the string, and reallocate the
|
||||
buffer to be a tight fit. */
|
||||
if ( cp == (buf + nbuf) ) {
|
||||
size_t old_size = nbuf;
|
||||
nbuf = old_size + 1;
|
||||
buf = realloc(buf, nbuf);
|
||||
buf[old_size] = 0;
|
||||
} else {
|
||||
*cp++ = 0;
|
||||
nbuf = cp - buf;
|
||||
buf = realloc(buf, nbuf);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: substit.c,v $
|
||||
* Revision 1.5 2003/12/19 01:27:10 steve
|
||||
* Fix various unsigned compare warnings.
|
||||
*
|
||||
* Revision 1.4 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.3 2002/08/11 23:47:04 steve
|
||||
* Add missing Log and Ident strings.
|
||||
*
|
||||
* Revision 1.2 2002/06/25 01:33:01 steve
|
||||
* include malloc.h only when available.
|
||||
*
|
||||
* Revision 1.1 2002/06/23 20:10:51 steve
|
||||
* Variable substitution in command files.
|
||||
*
|
||||
*/
|
||||
|
||||
+160
-13
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2002 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
|
||||
@@ -16,30 +16,184 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: dup_expr.cc,v 1.4 2000/05/07 18:20:07 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: dup_expr.cc,v 1.18 2004/06/17 16:06:18 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
# include <cassert>
|
||||
|
||||
NetEBComp* NetEBComp::dup_expr() const
|
||||
{
|
||||
NetEBComp*result = new NetEBComp(op_, left_->dup_expr(),
|
||||
right_->dup_expr());
|
||||
return result;
|
||||
}
|
||||
|
||||
NetEConst* NetEConst::dup_expr() const
|
||||
{
|
||||
NetEConst*tmp = new NetEConst(value_);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEConstParam* NetEConstParam::dup_expr() const
|
||||
{
|
||||
NetEConstParam*tmp = new NetEConstParam(scope_, name_, value());
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetECRealParam* NetECRealParam::dup_expr() const
|
||||
{
|
||||
NetECRealParam*tmp = new NetECRealParam(scope_, name_, value());
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEEvent* NetEEvent::dup_expr() const
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEScope* NetEScope::dup_expr() const
|
||||
{
|
||||
assert(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetESelect* NetESelect::dup_expr() const
|
||||
{
|
||||
return new NetESelect(expr_->dup_expr(), base_->dup_expr(),
|
||||
expr_width());
|
||||
}
|
||||
|
||||
NetESFunc* NetESFunc::dup_expr() const
|
||||
{
|
||||
NetESFunc*tmp = new NetESFunc(name_, expr_width(), nparms());
|
||||
for (unsigned idx = 0 ; idx < nparms() ; idx += 1)
|
||||
tmp->parm(idx, tmp->parm(idx)->dup_expr());
|
||||
NetESFunc*tmp = new NetESFunc(name_, type_, expr_width(), nparms());
|
||||
assert(tmp);
|
||||
|
||||
tmp->cast_signed(has_sign());
|
||||
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
|
||||
assert(tmp->parm(idx));
|
||||
tmp->parm(idx, tmp->parm(idx)->dup_expr());
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetESignal* NetESignal::dup_expr() const
|
||||
{
|
||||
NetESignal*tmp = new NetESignal(net_, msi_, lsi_);
|
||||
assert(tmp);
|
||||
tmp->expr_width(expr_width());
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetETernary* NetETernary::dup_expr() const
|
||||
{
|
||||
NetETernary*tmp = new NetETernary(cond_->dup_expr(),
|
||||
true_val_->dup_expr(),
|
||||
false_val_->dup_expr());
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEUFunc* NetEUFunc::dup_expr() const
|
||||
{
|
||||
NetEUFunc*tmp;
|
||||
svector<NetExpr*> tmp_parms (parms_.count());
|
||||
|
||||
for (unsigned idx = 0 ; idx < tmp_parms.count() ; idx += 1) {
|
||||
assert(parms_[idx]);
|
||||
tmp_parms[idx] = parms_[idx]->dup_expr();
|
||||
}
|
||||
|
||||
tmp = 0;
|
||||
if (result_sig_)
|
||||
tmp = new NetEUFunc(func_, result_sig_->dup_expr(), tmp_parms);
|
||||
if (result_var_)
|
||||
tmp = new NetEUFunc(func_, result_var_->dup_expr(), tmp_parms);
|
||||
|
||||
assert(tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEUnary* NetEUnary::dup_expr() const
|
||||
{
|
||||
NetEUnary*tmp = new NetEUnary(op_, expr_->dup_expr());
|
||||
assert(tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEUReduce* NetEUReduce::dup_expr() const
|
||||
{
|
||||
NetEUReduce*tmp = new NetEUReduce(op_, expr_->dup_expr());
|
||||
assert(tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEVariable* NetEVariable::dup_expr() const
|
||||
{
|
||||
NetEVariable*tmp = new NetEVariable(var_);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: dup_expr.cc,v $
|
||||
* Revision 1.18 2004/06/17 16:06:18 steve
|
||||
* Help system function signedness survive elaboration.
|
||||
*
|
||||
* Revision 1.17 2004/05/31 23:34:36 steve
|
||||
* Rewire/generalize parsing an elaboration of
|
||||
* function return values to allow for better
|
||||
* speed and more type support.
|
||||
*
|
||||
* Revision 1.16 2003/10/31 02:47:11 steve
|
||||
* NetEUReduce has its own dup_expr method.
|
||||
*
|
||||
* Revision 1.15 2003/05/30 02:55:32 steve
|
||||
* Support parameters in real expressions and
|
||||
* as real expressions, and fix multiply and
|
||||
* divide with real results.
|
||||
*
|
||||
* Revision 1.14 2003/04/22 04:48:29 steve
|
||||
* Support event names as expressions elements.
|
||||
*
|
||||
* Revision 1.13 2003/03/15 18:08:43 steve
|
||||
* Comparison operators do have defined width.
|
||||
*
|
||||
* Revision 1.12 2003/03/15 04:46:28 steve
|
||||
* Better organize the NetESFunc return type guesses.
|
||||
*
|
||||
* Revision 1.11 2003/03/10 23:40:53 steve
|
||||
* Keep parameter constants for the ivl_target API.
|
||||
*
|
||||
* Revision 1.10 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
* Revision 1.9 2002/11/09 00:25:27 steve
|
||||
* Add dup_expr for user defined function calls.
|
||||
*
|
||||
* Revision 1.8 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.7 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.6 2001/11/19 01:54:14 steve
|
||||
* Port close cropping behavior from mcrgb
|
||||
* Move window array reset to libmc.
|
||||
*
|
||||
* Revision 1.5 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.4 2000/05/07 18:20:07 steve
|
||||
* Import MCD support from Stephen Tell, and add
|
||||
* system function parameter support to the IVL core.
|
||||
@@ -47,12 +201,5 @@ NetESFunc* NetESFunc::dup_expr() const
|
||||
* Revision 1.3 2000/05/04 03:37:58 steve
|
||||
* Add infrastructure for system functions, move
|
||||
* $time to that structure and add $random.
|
||||
*
|
||||
* Revision 1.2 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.1 1999/11/27 19:07:57 steve
|
||||
* Support the creation of scopes.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+64
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com.com)
|
||||
* Copyright (c) 2000-2003 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
|
||||
@@ -16,10 +16,12 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_anet.cc,v 1.2 2001/01/06 02:29:36 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_anet.cc,v 1.10 2004/10/04 01:10:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
/*
|
||||
* The elaborate_anet methods elaborate expressions that are intended
|
||||
* to be the left side of procedural continuous assignments.
|
||||
@@ -27,12 +29,13 @@
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include <iostream>
|
||||
|
||||
NetNet* PExpr::elaborate_anet(Design*des, NetScope*scope) const
|
||||
{
|
||||
cerr << get_line() << ": error: Invalid expression on left side "
|
||||
<< "of precedural continuous asignment." << endl;
|
||||
<< "of procedural continuous assignment." << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -84,7 +87,7 @@ NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
|
||||
Allow for a repeat count other then 1 by repeating the
|
||||
connect loop as many times as necessary. */
|
||||
|
||||
NetNet*osig = new NetNet(scope, des->local_symbol(scope->name()),
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT_REG, pins);
|
||||
|
||||
pins = 0;
|
||||
@@ -102,18 +105,35 @@ NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
|
||||
|
||||
NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetNet*sig = des->find_signal(scope, text_);
|
||||
assert(scope);
|
||||
|
||||
NetNet* sig = 0;
|
||||
NetMemory* mem = 0;
|
||||
NetVariable* var = 0;
|
||||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
|
||||
symbol_search(des, scope, path_, sig, mem, var, par, eve);
|
||||
|
||||
|
||||
if (mem != 0) {
|
||||
cerr << get_line() << ": error: memories not allowed "
|
||||
<< "on left side of procedural continuous "
|
||||
<< "assignment." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (eve != 0) {
|
||||
cerr << get_line() << ": error: named events not allowed "
|
||||
<< "on left side of procedural continuous "
|
||||
<< "assignment." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (sig == 0) {
|
||||
if (NetMemory*mem = des->find_memory(scope, text_)) {
|
||||
cerr << get_line() << ": error: memories not allowed "
|
||||
<< "on left side of procedural continuous "
|
||||
<< "asignment." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
cerr << get_line() << ": error: reg ``" << text_ << "'' "
|
||||
cerr << get_line() << ": error: reg ``" << path_ << "'' "
|
||||
<< "is undefined in this scope." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
@@ -125,7 +145,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
break;
|
||||
|
||||
default:
|
||||
cerr << get_line() << ": error: " << text_ << " is not "
|
||||
cerr << get_line() << ": error: " << path_ << " is not "
|
||||
<< "a reg in this context." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
@@ -136,8 +156,8 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
if (msb_ || lsb_) {
|
||||
|
||||
cerr << get_line() << ": error: bit/part selects not allowed "
|
||||
<< "on left side of procedural continuous asignment."
|
||||
<< endl;
|
||||
<< "on left side of procedural continuous assignment."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -147,6 +167,32 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_anet.cc,v $
|
||||
* Revision 1.10 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.9 2003/09/19 03:50:12 steve
|
||||
* Remove find_memory method from Design class.
|
||||
*
|
||||
* Revision 1.8 2003/06/21 01:21:43 steve
|
||||
* Harmless fixup of warnings.
|
||||
*
|
||||
* Revision 1.7 2003/03/06 00:28:41 steve
|
||||
* All NetObj objects have lex_string base names.
|
||||
*
|
||||
* Revision 1.6 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.5 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.4 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.3 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.2 2001/01/06 02:29:36 steve
|
||||
* Support arrays of integers.
|
||||
*
|
||||
|
||||
+596
-175
File diff suppressed because it is too large
Load Diff
+184
-81
@@ -16,32 +16,37 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_lval.cc,v 1.12 2001/02/09 03:16:48 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_lval.cc,v 1.29 2004/10/04 01:10:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
/*
|
||||
* These methods generate a NetAssign_ object for the l-value of the
|
||||
* assignemnt. This is common code for the = and <= statements.
|
||||
* assignment. This is common code for the = and <= statements.
|
||||
*
|
||||
* What gets generated depends on the structure of the l-value. If the
|
||||
* l-value is a simple name (i.e. foo <= <value>) the the NetAssign_
|
||||
* l-value is a simple name (i.e., foo <= <value>) the the NetAssign_
|
||||
* is created the width of the foo reg and connected to all the
|
||||
* bits.
|
||||
*
|
||||
* If there is a part select (i.e. foo[3:1] <= <value>) the NetAssign_
|
||||
* If there is a part select (i.e., foo[3:1] <= <value>) the NetAssign_
|
||||
* is made only as wide as it needs to be (3 bits in this example) and
|
||||
* connected to the correct bits of foo. A constant bit select is a
|
||||
* special case of the part select.
|
||||
* special case of the part select.
|
||||
*
|
||||
* If the bit-select is non-constant (i.e. foo[<expr>] = <value>) the
|
||||
* If the bit-select is non-constant (i.e., foo[<expr>] = <value>) the
|
||||
* NetAssign_ is made wide enough to connect to all the bits of foo,
|
||||
* then the mux expression is elaborated and attached to the
|
||||
* NetAssign_ node as a b_mux value. The target must interpret the
|
||||
* presense of a bmux value as taking a single bit and assigning it to
|
||||
* presence of a bmux value as taking a single bit and assigning it to
|
||||
* the bit selected by the bmux expression.
|
||||
*
|
||||
* If the l-value expression is non-trivial, but can be fully
|
||||
@@ -51,7 +56,7 @@
|
||||
* l-value.
|
||||
*
|
||||
* This last case can turn up in statements like: {a, b[1]} = c;
|
||||
* rather then create a NetAssign_ for each item in the contatenation,
|
||||
* rather then create a NetAssign_ for each item in the concatenation,
|
||||
* elaboration makes a single NetAssign_ and connects it up properly.
|
||||
*/
|
||||
|
||||
@@ -63,17 +68,14 @@
|
||||
*/
|
||||
NetAssign_* PExpr::elaborate_lval(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetNet*ll = elaborate_net(des, scope->name(), 0, 0, 0, 0);
|
||||
NetNet*ll = 0;
|
||||
if (ll == 0) {
|
||||
cerr << get_line() << ": Assignment l-value too complex."
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetAssign_*lv = new NetAssign_(scope->local_symbol(), ll->pin_count());
|
||||
for (unsigned idx = 0 ; idx < ll->pin_count() ; idx += 1)
|
||||
connect(lv->pin(idx), ll->pin(idx));
|
||||
des->add_node(lv);
|
||||
NetAssign_*lv = new NetAssign_(ll);
|
||||
return lv;
|
||||
}
|
||||
|
||||
@@ -102,6 +104,14 @@ NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
|
||||
NetAssign_*res = 0;
|
||||
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
|
||||
if (parms_[idx] == 0) {
|
||||
cerr << get_line() << ": error: Empty expressions "
|
||||
<< "not allowed in concatenations." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
NetAssign_*tmp = parms_[idx]->elaborate_lval(des, scope);
|
||||
|
||||
/* If the l-value doesn't elaborate, the error was
|
||||
@@ -112,42 +122,15 @@ NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
|
||||
|
||||
assert(tmp);
|
||||
|
||||
/* If adjacent l-values in the concatenation are not bit
|
||||
selects, then merge them into a single NetAssign_
|
||||
object.
|
||||
|
||||
If we cannot merge, then just link the new one to the
|
||||
previous one. */
|
||||
/* Link the new l-value to the previous one. */
|
||||
|
||||
if (res && (res->bmux() == 0) && (tmp->bmux() == 0)) {
|
||||
unsigned wid1 = tmp->pin_count();
|
||||
unsigned wid2 = res->pin_count() + tmp->pin_count();
|
||||
NetAssign_*tmp2 = new NetAssign_(res->name(), wid2);
|
||||
NetAssign_*last = tmp;
|
||||
while (last->more)
|
||||
last = last->more;
|
||||
|
||||
assert(tmp->more == 0);
|
||||
|
||||
tmp2->more = res->more;
|
||||
res->more = 0;
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid1 ; idx += 1)
|
||||
connect(tmp2->pin(idx), tmp->pin(idx));
|
||||
|
||||
for (unsigned idx = 0 ; idx < res->pin_count() ; idx += 1)
|
||||
connect(tmp2->pin(idx+wid1), res->pin(idx));
|
||||
|
||||
delete res;
|
||||
delete tmp;
|
||||
res = tmp2;
|
||||
des->add_node(res);
|
||||
|
||||
} else {
|
||||
NetAssign_*last = tmp;
|
||||
while (last->more)
|
||||
last = last->more;
|
||||
|
||||
last->more = res;
|
||||
res = tmp;
|
||||
}
|
||||
last->more = res;
|
||||
res = tmp;
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -159,29 +142,42 @@ NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
|
||||
*/
|
||||
NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
{
|
||||
/* Get the signal referenced by the identifier, and make sure
|
||||
it is a register. (Wires are not allows in this context. */
|
||||
NetNet*reg = des->find_signal(scope, name());
|
||||
NetNet* reg = 0;
|
||||
NetMemory* mem = 0;
|
||||
NetVariable* var = 0;
|
||||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
|
||||
symbol_search(des, scope, path_, reg, mem, var, par, eve);
|
||||
|
||||
if (mem) {
|
||||
return elaborate_mem_lval_(des, scope, mem);
|
||||
}
|
||||
|
||||
if (var) {
|
||||
NetAssign_*cur = new NetAssign_(var);
|
||||
return cur;
|
||||
}
|
||||
|
||||
if (reg == 0) {
|
||||
NetMemory*mem = des->find_memory(scope, name());
|
||||
if (mem != 0) {
|
||||
cerr << get_line() << ": sorry: I cannot handle "
|
||||
<< "memories in this l-value context." << endl;
|
||||
} else {
|
||||
cerr << get_line() << ": error: Could not find variable ``"
|
||||
<< name() << "'' in ``" << scope->name() <<
|
||||
"''" << endl;
|
||||
}
|
||||
cerr << get_line() << ": error: Could not find variable ``"
|
||||
<< path_ << "'' in ``" << scope->name() <<
|
||||
"''" << endl;
|
||||
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(reg);
|
||||
|
||||
/* Get the signal referenced by the identifier, and make sure
|
||||
it is a register. (Wires are not allows in this context. */
|
||||
if (reg->type() != NetNet::REG) {
|
||||
cerr << get_line() << ": error: " << name() <<
|
||||
cerr << get_line() << ": error: " << path_ <<
|
||||
" is not a reg/integer/time in " << scope->name() <<
|
||||
"." << endl;
|
||||
cerr << reg->get_line() << ": : " << path_ <<
|
||||
" is declared here as " << reg->type() << "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -194,19 +190,23 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
two bit select expressions, and both must be
|
||||
constant. Evaluate them and pass the results back to
|
||||
the caller. */
|
||||
verinum*vl = lsb_->eval_const(des, scope->name());
|
||||
verinum*vl = lsb_->eval_const(des, scope);
|
||||
if (vl == 0) {
|
||||
cerr << lsb_->get_line() << ": error: "
|
||||
"Part select expressions must be constant: "
|
||||
<< *lsb_;
|
||||
"Part select expressions must be constant."
|
||||
<< endl;
|
||||
cerr << lsb_->get_line() << ": : This lsb expression "
|
||||
"violates the rule: " << *lsb_ << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
verinum*vm = msb_->eval_const(des, scope->name());
|
||||
if (vl == 0) {
|
||||
verinum*vm = msb_->eval_const(des, scope);
|
||||
if (vm == 0) {
|
||||
cerr << msb_->get_line() << ": error: "
|
||||
"Part select expressions must be constant: "
|
||||
<< *msb_;
|
||||
"Part select expressions must be constant."
|
||||
<< endl;
|
||||
cerr << msb_->get_line() << ": : This msb expression "
|
||||
"violates the rule: " << *msb_ << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -223,7 +223,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
expression it not constant, then return the
|
||||
expression as a mux. */
|
||||
assert(lsb_ == 0);
|
||||
verinum*v = msb_->eval_const(des, scope->name());
|
||||
verinum*v = msb_->eval_const(des, scope);
|
||||
if (v == 0) {
|
||||
NetExpr*m = msb_->elaborate_expr(des, scope);
|
||||
assert(m);
|
||||
@@ -255,13 +255,9 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
if (mux) {
|
||||
|
||||
/* If there is a non-constant bit select, make a
|
||||
NetAssign_ the width of the target reg and attach a
|
||||
NetAssign_ to the target reg and attach a
|
||||
bmux to select the target bit. */
|
||||
unsigned wid = reg->pin_count();
|
||||
lv = new NetAssign_(des->local_symbol(scope->name()), wid);
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
||||
connect(lv->pin(idx), reg->pin(idx));
|
||||
lv = new NetAssign_(reg);
|
||||
|
||||
lv->set_bmux(mux);
|
||||
|
||||
@@ -274,8 +270,6 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
unsigned moff = reg->sb_to_idx(msb);
|
||||
unsigned wid = moff - loff + 1;
|
||||
|
||||
lv = new NetAssign_(des->local_symbol(scope->name()), wid);
|
||||
|
||||
if (moff < loff) {
|
||||
cerr << get_line() << ": error: part select "
|
||||
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
|
||||
@@ -297,20 +291,129 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(moff < reg->pin_count());
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
||||
connect(lv->pin(idx), reg->pin(idx+loff));
|
||||
lv = new NetAssign_(reg);
|
||||
lv->set_part(loff, wid);
|
||||
|
||||
assert(moff < reg->pin_count());
|
||||
}
|
||||
|
||||
|
||||
des->add_node(lv);
|
||||
|
||||
return lv;
|
||||
}
|
||||
|
||||
NetAssign_* PEIdent::elaborate_mem_lval_(Design*des, NetScope*scope,
|
||||
NetMemory*mem) const
|
||||
{
|
||||
if (msb_ == 0) {
|
||||
cerr << get_line() << ": error: Assign to memory \""
|
||||
<< mem->name() << "\" requires a word select index."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (msb_ && lsb_) {
|
||||
cerr << get_line() << ": error: Cannot use part select on "
|
||||
<< "memory \"" << mem->name() << ".\"" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(msb_ && !lsb_);
|
||||
|
||||
NetExpr*ix = msb_->elaborate_expr(des, scope);
|
||||
if (ix == 0)
|
||||
return 0;
|
||||
|
||||
/* Evaluate the memory index expression down as must as
|
||||
possible. Ideally, we can get it down to a constant. */
|
||||
if (! dynamic_cast<NetEConst*>(ix)) {
|
||||
NetExpr*tmp = ix->eval_tree();
|
||||
if (tmp) {
|
||||
tmp->set_line(*ix);
|
||||
delete ix;
|
||||
ix = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
NetAssign_*lv = new NetAssign_(mem);
|
||||
lv->set_bmux(ix);
|
||||
lv->set_part(0, mem->width());
|
||||
return lv;
|
||||
}
|
||||
|
||||
NetAssign_* PENumber::elaborate_lval(Design*des, NetScope*) const
|
||||
{
|
||||
cerr << get_line() << ": error: Constant values not allowed "
|
||||
<< "in l-value expressions." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: elab_lval.cc,v $
|
||||
* Revision 1.29 2004/10/04 01:10:52 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.28 2004/08/28 14:59:44 steve
|
||||
* More detailed error message about bad variable.
|
||||
*
|
||||
* Revision 1.27 2003/09/19 03:30:05 steve
|
||||
* Fix name search in elab_lval.
|
||||
*
|
||||
* Revision 1.26 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.25 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
* Revision 1.24 2003/01/19 00:35:39 steve
|
||||
* Detect null arguments to concatenation operator.
|
||||
*
|
||||
* Revision 1.23 2002/11/21 23:27:51 steve
|
||||
* Precalculate indices to l-value arrays.
|
||||
*
|
||||
* Revision 1.22 2002/11/21 18:15:40 steve
|
||||
* Fix const test of msb in assignment l-values.
|
||||
*
|
||||
* Revision 1.21 2002/11/02 01:10:49 steve
|
||||
* Detect memories without work index in l-value.
|
||||
*
|
||||
* Revision 1.20 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.19 2002/06/04 05:38:44 steve
|
||||
* Add support for memory words in l-value of
|
||||
* blocking assignments, and remove the special
|
||||
* NetAssignMem class.
|
||||
*
|
||||
* Revision 1.18 2002/03/09 04:02:26 steve
|
||||
* Constant expressions are not l-values for task ports.
|
||||
*
|
||||
* Revision 1.17 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.16 2001/11/08 05:15:50 steve
|
||||
* Remove string paths from PExpr elaboration.
|
||||
*
|
||||
* Revision 1.15 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.14 2001/08/25 23:50:02 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.13 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.12 2001/02/09 03:16:48 steve
|
||||
* Report bit/part select out of range errors. (PR#133)
|
||||
*
|
||||
|
||||
+1238
-678
File diff suppressed because it is too large
Load Diff
+104
-23
@@ -16,13 +16,18 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_pexpr.cc,v 1.8 2001/01/14 23:04:56 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_pexpr.cc,v 1.21 2004/02/20 06:22:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "compiler.h"
|
||||
# include "util.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
NetExpr*PExpr::elaborate_pexpr(Design*des, NetScope*sc) const
|
||||
{
|
||||
cerr << get_line() << ": error: invalid parameter expression: "
|
||||
@@ -57,33 +62,26 @@ NetExpr*PEBinary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||
* expressions can include concatenation expressions. This requires
|
||||
* that the subexpressions all have well-defined size (in spite of
|
||||
* being in a parameter expression) in order to get a defined
|
||||
* value. The sub-expressions themsilves must also be value parameter
|
||||
* value. The sub-expressions themselves must also be value parameter
|
||||
* expressions.
|
||||
*/
|
||||
NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
unsigned repeat = 1;
|
||||
NetExpr* repeat = 0;
|
||||
|
||||
/* If there is a repeat expression, then evaluate the constant
|
||||
value and set the repeat count.
|
||||
|
||||
XXXX Potential bug XXX In principle, the repeat expression
|
||||
can have a parameter name in it. Since where are in the
|
||||
working of parameters now, we will not be able to
|
||||
accurately evaluate such expressions. So eventually, I will
|
||||
need to be able to defer the evaluation of the expression. */
|
||||
value and set the repeat count. */
|
||||
if (repeat_) {
|
||||
verinum*vrep = repeat_->eval_const(des, scope->name());
|
||||
if (vrep == 0) {
|
||||
repeat = repeat_->elaborate_pexpr(des, scope);
|
||||
if (repeat == 0) {
|
||||
cerr << get_line() << ": error: "
|
||||
"concatenation repeat expression cannot be evaluated."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
repeat = vrep->as_ulong();
|
||||
delete vrep;
|
||||
/* continue on even if the repeat expression doesn't
|
||||
work, as we can find more errors. */
|
||||
}
|
||||
|
||||
/* Make the empty concat expression. */
|
||||
@@ -97,7 +95,22 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
assert(parms_[idx]);
|
||||
NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope);
|
||||
if (ex == 0) continue;
|
||||
|
||||
ex->set_line(*parms_[idx]);
|
||||
|
||||
if (dynamic_cast<NetEParam*>(ex)) {
|
||||
|
||||
/* If this parameter is a NetEParam, then put off
|
||||
the width check for later. */
|
||||
|
||||
} else if (! ex->has_width()) {
|
||||
cerr << ex->get_line() << ": error: operand of "
|
||||
<< "concatenation has indefinite width: "
|
||||
<< *ex << endl;
|
||||
des->errors += 1;
|
||||
|
||||
}
|
||||
|
||||
tmp->set(idx, ex);
|
||||
}
|
||||
|
||||
@@ -117,25 +130,44 @@ NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
*/
|
||||
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
string path = text_;
|
||||
string name = parse_last_name(path);
|
||||
hname_t path = path_;
|
||||
char*name = path.remove_tail_name();
|
||||
|
||||
NetScope*pscope = scope;
|
||||
if (path != "")
|
||||
if (path.peek_name(0))
|
||||
pscope = des->find_scope(scope, path);
|
||||
|
||||
assert(pscope);
|
||||
perm_string perm_name = lex_strings.make(name);
|
||||
delete name;
|
||||
|
||||
const NetExpr*ex = pscope->get_parameter(name);
|
||||
const NetExpr*ex = pscope->get_parameter(perm_name);
|
||||
if (ex == 0) {
|
||||
cerr << get_line() << ": error: identifier ``" << text_ <<
|
||||
cerr << get_line() << ": error: identifier ``" << path_ <<
|
||||
"'' is not a parameter in " << scope->name() << "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetExpr*res = new NetEParam(des, pscope, name);
|
||||
NetExpr*res = new NetEParam(des, pscope, perm_name);
|
||||
res->set_line(*this);
|
||||
assert(res);
|
||||
|
||||
assert(idx_ == 0);
|
||||
if (msb_ && lsb_) {
|
||||
cerr << get_line() << ": sorry: Cannot part select "
|
||||
"bits of parameters." << endl;
|
||||
des->errors += 1;
|
||||
|
||||
} else if (msb_) {
|
||||
|
||||
/* We have here a bit select. Insert a NetESelect node
|
||||
to handle it. */
|
||||
NetExpr*tmp = msb_->elaborate_pexpr(des, scope);
|
||||
if (tmp != 0) {
|
||||
res = new NetESelect(res, tmp, 1);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -199,6 +231,55 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_pexpr.cc,v $
|
||||
* Revision 1.21 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.20 2003/05/30 02:55:32 steve
|
||||
* Support parameters in real expressions and
|
||||
* as real expressions, and fix multiply and
|
||||
* divide with real results.
|
||||
*
|
||||
* Revision 1.19 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.18 2002/12/05 02:14:33 steve
|
||||
* Support bit select in constant expressions.
|
||||
*
|
||||
* Revision 1.17 2002/11/09 01:40:19 steve
|
||||
* Postpone parameter width check to evaluation.
|
||||
*
|
||||
* Revision 1.16 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.15 2002/05/06 02:30:27 steve
|
||||
* Allow parameters in concatenation of widths are defined.
|
||||
*
|
||||
* Revision 1.14 2002/05/05 21:11:50 steve
|
||||
* Put off evaluation of concatenation repeat expresions
|
||||
* until after parameters are defined. This allows parms
|
||||
* to be used in repeat expresions.
|
||||
*
|
||||
* Add the builtin $signed system function.
|
||||
*
|
||||
* Revision 1.13 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.12 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.11 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.10 2001/10/07 03:38:08 steve
|
||||
* parameter names do not have defined size.
|
||||
*
|
||||
* Revision 1.9 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.8 2001/01/14 23:04:56 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
|
||||
+333
-94
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2003 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
|
||||
@@ -16,10 +16,15 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_scope.cc,v 1.7 2000/12/16 01:45:48 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_scope.cc,v 1.35 2004/09/10 00:15:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "compiler.h"
|
||||
# include <iostream>
|
||||
# include <stdio.h>
|
||||
|
||||
/*
|
||||
* Elaboration happens in two passes, generally. The first scans the
|
||||
* pform to generate the NetScope tree and attach it to the Design
|
||||
@@ -28,6 +33,7 @@
|
||||
*/
|
||||
|
||||
# include "Module.h"
|
||||
# include "PData.h"
|
||||
# include "PEvent.h"
|
||||
# include "PExpr.h"
|
||||
# include "PGate.h"
|
||||
@@ -35,10 +41,17 @@
|
||||
# include "PWire.h"
|
||||
# include "Statement.h"
|
||||
# include "netlist.h"
|
||||
# include "util.h"
|
||||
# include <typeinfo>
|
||||
# include <assert.h>
|
||||
|
||||
bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
if (debug_scopes) {
|
||||
cerr << get_line() << ": debug: Elaborate scope "
|
||||
<< scope->name() << "." << endl;
|
||||
}
|
||||
|
||||
// Generate all the parameters that this instance of this
|
||||
// module introduces to the design. This loop elaborates the
|
||||
// parameters, but doesn't evaluate references to
|
||||
@@ -50,7 +63,8 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// the pform and just place a NetEParam placeholder in the
|
||||
// place of the elaborated expression.
|
||||
|
||||
typedef map<string,PExpr*>::const_iterator mparm_it_t;
|
||||
typedef map<perm_string,param_expr_t>::const_iterator mparm_it_t;
|
||||
typedef map<hname_t,PExpr*>::const_iterator hparm_it_t;
|
||||
|
||||
|
||||
// This loop scans the parameters in the module, and creates
|
||||
@@ -59,13 +73,23 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
for (mparm_it_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; cur ++) {
|
||||
|
||||
scope->set_parameter((*cur).first, new NetEParam);
|
||||
NetEParam*tmp = new NetEParam;
|
||||
tmp->set_line(*((*cur).second.expr));
|
||||
if ((*cur).second.msb)
|
||||
tmp->cast_signed( (*cur).second.signed_flag );
|
||||
|
||||
scope->set_parameter((*cur).first, tmp, 0, 0, false);
|
||||
}
|
||||
|
||||
for (mparm_it_t cur = localparams.begin()
|
||||
; cur != localparams.end() ; cur ++) {
|
||||
|
||||
scope->set_parameter((*cur).first, new NetEParam);
|
||||
NetEParam*tmp = new NetEParam;
|
||||
tmp->set_line(*((*cur).second.expr));
|
||||
if ((*cur).second.msb)
|
||||
tmp->cast_signed( (*cur).second.signed_flag );
|
||||
|
||||
scope->set_parameter((*cur).first, tmp, 0, 0, false);
|
||||
}
|
||||
|
||||
|
||||
@@ -77,11 +101,29 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
for (mparm_it_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; cur ++) {
|
||||
|
||||
PExpr*ex = (*cur).second;
|
||||
PExpr*ex = (*cur).second.expr;
|
||||
assert(ex);
|
||||
|
||||
NetExpr*val = ex->elaborate_pexpr(des, scope);
|
||||
val = scope->set_parameter((*cur).first, val);
|
||||
NetExpr*msb = 0;
|
||||
NetExpr*lsb = 0;
|
||||
bool signed_flag = false;
|
||||
|
||||
/* If the parameter declaration includes msb and lsb,
|
||||
then use them to calculate a width for the
|
||||
result. Then make sure the constant expression of the
|
||||
parameter value is coerced to have the correct
|
||||
and defined width. */
|
||||
if ((*cur).second.msb) {
|
||||
msb = (*cur).second.msb ->elaborate_pexpr(des, scope);
|
||||
assert(msb);
|
||||
lsb = (*cur).second.lsb ->elaborate_pexpr(des, scope);
|
||||
signed_flag = (*cur).second.signed_flag;
|
||||
}
|
||||
|
||||
val->cast_signed(signed_flag);
|
||||
val = scope->set_parameter((*cur).first, val,
|
||||
msb, lsb, signed_flag);
|
||||
assert(val);
|
||||
delete val;
|
||||
}
|
||||
@@ -89,11 +131,29 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
for (mparm_it_t cur = localparams.begin()
|
||||
; cur != localparams.end() ; cur ++) {
|
||||
|
||||
PExpr*ex = (*cur).second;
|
||||
PExpr*ex = (*cur).second.expr;
|
||||
assert(ex);
|
||||
|
||||
NetExpr*val = ex->elaborate_pexpr(des, scope);
|
||||
val = scope->set_parameter((*cur).first, val);
|
||||
NetExpr*msb = 0;
|
||||
NetExpr*lsb = 0;
|
||||
bool signed_flag = false;
|
||||
|
||||
/* If the parameter declaration includes msb and lsb,
|
||||
then use them to calculate a width for the
|
||||
result. Then make sure the constant expression of the
|
||||
parameter value is coerced to have the correct
|
||||
and defined width. */
|
||||
if ((*cur).second.msb) {
|
||||
msb = (*cur).second.msb ->elaborate_pexpr(des, scope);
|
||||
assert(msb);
|
||||
lsb = (*cur).second.lsb ->elaborate_pexpr(des, scope);
|
||||
signed_flag = (*cur).second.signed_flag;
|
||||
}
|
||||
|
||||
val->cast_signed(signed_flag);
|
||||
val = scope->set_parameter((*cur).first, val,
|
||||
msb, lsb, signed_flag);
|
||||
assert(val);
|
||||
delete val;
|
||||
}
|
||||
@@ -105,10 +165,10 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// It is OK to elaborate the expressions of the defparam here
|
||||
// because Verilog requires that the expressions only use
|
||||
// local parameter names. It is *not* OK to do the override
|
||||
// here becuase the parameter receiving the assignment may be
|
||||
// here because the parameter receiving the assignment may be
|
||||
// in a scope not discovered by this pass.
|
||||
|
||||
for (mparm_it_t cur = defparms.begin()
|
||||
for (hparm_it_t cur = defparms.begin()
|
||||
; cur != defparms.end() ; cur ++ ) {
|
||||
|
||||
PExpr*ex = (*cur).second;
|
||||
@@ -119,13 +179,23 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
scope->defparams[(*cur).first] = val;
|
||||
}
|
||||
|
||||
// Evaluate the attributes. Evaluate them in the scope of the
|
||||
// module that the attribute is attached to. Is this correct?
|
||||
unsigned nattr;
|
||||
attrib_list_t*attr = evaluate_attributes(attributes, nattr, des, scope);
|
||||
|
||||
for (unsigned idx = 0 ; idx < nattr ; idx += 1)
|
||||
scope->attribute(attr[idx].key, attr[idx].val);
|
||||
|
||||
delete[]attr;
|
||||
|
||||
|
||||
// Tasks introduce new scopes, so scan the tasks in this
|
||||
// module. Create a scope for the task and pass that to the
|
||||
// elaborate_scope method of the PTask for detailed
|
||||
// processing.
|
||||
|
||||
typedef map<string,PTask*>::const_iterator tasks_it_t;
|
||||
typedef map<perm_string,PTask*>::const_iterator tasks_it_t;
|
||||
|
||||
for (tasks_it_t cur = tasks_.begin()
|
||||
; cur != tasks_.end() ; cur ++ ) {
|
||||
@@ -140,7 +210,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// perspective of scopes. So handle them exactly the same
|
||||
// way.
|
||||
|
||||
typedef map<string,PFunction*>::const_iterator funcs_it_t;
|
||||
typedef map<perm_string,PFunction*>::const_iterator funcs_it_t;
|
||||
|
||||
for (funcs_it_t cur = funcs_.begin()
|
||||
; cur != funcs_.end() ; cur ++ ) {
|
||||
@@ -155,7 +225,6 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// scan all of them to create those scopes.
|
||||
|
||||
typedef list<PGate*>::const_iterator gates_it_t;
|
||||
|
||||
for (gates_it_t cur = gates_.begin()
|
||||
; cur != gates_.end() ; cur ++ ) {
|
||||
|
||||
@@ -180,27 +249,38 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// elaboration, so do it now. This allows for normal
|
||||
// elaboration to reference these events.
|
||||
|
||||
for (map<string,PEvent*>::const_iterator et = events.begin()
|
||||
for (map<perm_string,PEvent*>::const_iterator et = events.begin()
|
||||
; et != events.end() ; et ++ ) {
|
||||
|
||||
(*et).second->elaborate_scope(des, scope);
|
||||
}
|
||||
|
||||
for (map<hname_t,PData*>::const_iterator cur = datum.begin()
|
||||
; cur != datum.end() ; cur ++ ) {
|
||||
|
||||
(*cur).second->elaborate_scope(des, scope);
|
||||
}
|
||||
|
||||
return des->errors == 0;
|
||||
}
|
||||
|
||||
void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
{
|
||||
if (get_name() == "") {
|
||||
cerr << get_line() << ": error: Instantiation of module "
|
||||
<< mod->mod_name() << " requires an instance name." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Missing module instance names have already been rejected.
|
||||
assert(get_name() != "");
|
||||
|
||||
string path = sc->name();
|
||||
|
||||
// Check for duplicate scopes. Simply look up the scope I'm
|
||||
// about to create, and if I find it then somebody beat me to
|
||||
// it.
|
||||
|
||||
if (NetScope*tmp = des->find_scope(path + "." + get_name())) {
|
||||
if (sc->child(get_name())) {
|
||||
cerr << get_line() << ": error: Instance/Scope name " <<
|
||||
get_name() << " already used in this context." <<
|
||||
endl;
|
||||
@@ -216,11 +296,11 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
if (scn->type() != NetScope::MODULE)
|
||||
continue;
|
||||
|
||||
if (mod->get_name() != scn->module_name())
|
||||
if (strcmp(mod->mod_name(), scn->module_name()) != 0)
|
||||
continue;
|
||||
|
||||
cerr << get_line() << ": error: You cannot instantiate "
|
||||
<< "module " << mod->get_name() << " within itself." << endl;
|
||||
<< "module " << mod->mod_name() << " within itself." << endl;
|
||||
|
||||
cerr << get_line() << ": : The offending instance is "
|
||||
<< sc->name() << "." << get_name() << " within "
|
||||
@@ -230,74 +310,178 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
return;
|
||||
}
|
||||
|
||||
// Create the new scope as a MODULE with my name.
|
||||
NetScope*my_scope = new NetScope(sc, get_name(), NetScope::MODULE);
|
||||
my_scope->set_module_name(mod->get_name().c_str());
|
||||
verinum*msb = msb_ ? msb_->eval_const(des, sc) : 0;
|
||||
verinum*lsb = lsb_ ? lsb_->eval_const(des, sc) : 0;
|
||||
|
||||
// Set time units and precision.
|
||||
my_scope->time_unit(mod->time_unit);
|
||||
my_scope->time_precision(mod->time_precision);
|
||||
des->set_precision(mod->time_precision);
|
||||
assert( (msb == 0) || (lsb != 0) );
|
||||
|
||||
// This call actually arranges for the description of the
|
||||
// module type to process this instance and handle parameters
|
||||
// and sub-scopes that might occur. Parameters are also
|
||||
// created in that scope, as they exist. (I'll override them
|
||||
// later.)
|
||||
mod->elaborate_scope(des, my_scope);
|
||||
long instance_low = 0;
|
||||
long instance_high = 0;
|
||||
long instance_count = 1;
|
||||
bool instance_array = false;
|
||||
|
||||
// Look for module parameter replacements. This map receives
|
||||
// those replacements.
|
||||
if (msb) {
|
||||
instance_array = true;
|
||||
instance_high = msb->as_long();
|
||||
instance_low = lsb->as_long();
|
||||
if (instance_high > instance_low)
|
||||
instance_count = instance_high - instance_low + 1;
|
||||
else
|
||||
instance_count = instance_low - instance_high + 1;
|
||||
}
|
||||
|
||||
typedef map<string,PExpr*>::const_iterator mparm_it_t;
|
||||
map<string,PExpr*> replace;
|
||||
NetScope::scope_vec_t instances (instance_count);
|
||||
if (debug_scopes) {
|
||||
cerr << get_line() << ": debug: Create " << instance_count
|
||||
<< " instances of " << get_name()
|
||||
<< "." << endl;
|
||||
}
|
||||
|
||||
// Run through the module instances, and make scopes out of
|
||||
// them. Also do parameter overrides that are done on the
|
||||
// instantiation line.
|
||||
for (int idx = 0 ; idx < instance_count ; idx += 1) {
|
||||
|
||||
// Positional parameter overrides are matched to parameter
|
||||
// names by using the param_names list of parameter
|
||||
// names. This is an ordered list of names so the first name
|
||||
// is parameter 0, the second parameter 1, and so on.
|
||||
perm_string use_name = get_name();
|
||||
|
||||
if (overrides_) {
|
||||
assert(parms_ == 0);
|
||||
list<string>::const_iterator cur = mod->param_names.begin();
|
||||
for (unsigned idx = 0
|
||||
; idx < overrides_->count()
|
||||
; idx += 1, cur++) {
|
||||
replace[*cur] = (*overrides_)[idx];
|
||||
if (instance_array) {
|
||||
char name_buf[128];
|
||||
int instance_idx = idx;
|
||||
if (instance_low < instance_high)
|
||||
instance_idx = instance_low + idx;
|
||||
else
|
||||
instance_idx = instance_low - idx;
|
||||
|
||||
snprintf(name_buf, sizeof name_buf,
|
||||
"%s[%d]", get_name().str(), instance_idx);
|
||||
use_name = lex_strings.make(name_buf);
|
||||
}
|
||||
|
||||
if (debug_scopes) {
|
||||
cerr << get_line() << ": debug: Module instance " << use_name
|
||||
<< " becomes child of " << sc->name()
|
||||
<< "." << endl;
|
||||
}
|
||||
|
||||
// Create the new scope as a MODULE with my name.
|
||||
NetScope*my_scope = new NetScope(sc, use_name, NetScope::MODULE);
|
||||
my_scope->set_module_name(mod->mod_name());
|
||||
my_scope->default_nettype(mod->default_nettype);
|
||||
|
||||
instances[idx] = my_scope;
|
||||
|
||||
// Set time units and precision.
|
||||
my_scope->time_unit(mod->time_unit);
|
||||
my_scope->time_precision(mod->time_precision);
|
||||
des->set_precision(mod->time_precision);
|
||||
|
||||
// This call actually arranges for the description of the
|
||||
// module type to process this instance and handle parameters
|
||||
// and sub-scopes that might occur. Parameters are also
|
||||
// created in that scope, as they exist. (I'll override them
|
||||
// later.)
|
||||
mod->elaborate_scope(des, my_scope);
|
||||
|
||||
// Look for module parameter replacements. The "replace" map
|
||||
// maps parameter name to replacement expression that is
|
||||
// passed. It is built up by the ordered overrides or named
|
||||
// overrides.
|
||||
|
||||
typedef map<perm_string,PExpr*>::const_iterator mparm_it_t;
|
||||
map<perm_string,PExpr*> replace;
|
||||
|
||||
|
||||
// Positional parameter overrides are matched to parameter
|
||||
// names by using the param_names list of parameter
|
||||
// names. This is an ordered list of names so the first name
|
||||
// is parameter 0, the second parameter 1, and so on.
|
||||
|
||||
if (overrides_) {
|
||||
assert(parms_ == 0);
|
||||
list<perm_string>::const_iterator cur
|
||||
= mod->param_names.begin();
|
||||
unsigned idx = 0;
|
||||
for (;;) {
|
||||
if (idx >= overrides_->count())
|
||||
break;
|
||||
if (cur == mod->param_names.end())
|
||||
break;
|
||||
|
||||
replace[*cur] = (*overrides_)[idx];
|
||||
|
||||
idx += 1;
|
||||
cur ++;
|
||||
}
|
||||
}
|
||||
|
||||
// Named parameter overrides carry a name with each override
|
||||
// so the mapping into the replace list is much easier.
|
||||
if (parms_) {
|
||||
assert(overrides_ == 0);
|
||||
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
|
||||
replace[parms_[idx].name] = parms_[idx].parm;
|
||||
|
||||
}
|
||||
|
||||
|
||||
// And here we scan the replacements we collected. Elaborate
|
||||
// the expression in my context, then replace the sub-scope
|
||||
// parameter value with the new expression.
|
||||
|
||||
for (mparm_it_t cur = replace.begin()
|
||||
; cur != replace.end() ; cur ++ ) {
|
||||
|
||||
PExpr*tmp = (*cur).second;
|
||||
NetExpr*val = tmp->elaborate_pexpr(des, sc);
|
||||
bool flag = my_scope->replace_parameter((*cur).first, val);
|
||||
if (! flag) {
|
||||
cerr << val->get_line() << ": warning: parameter "
|
||||
<< (*cur).first << " not found in "
|
||||
<< sc->name() << "." << endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Named parameter overrides carry a name with each override
|
||||
// so the mapping into the replace list is much easier.
|
||||
if (parms_) {
|
||||
assert(overrides_ == 0);
|
||||
for (unsigned idx = 0 ; idx < nparms_ ; idx += 1)
|
||||
replace[parms_[idx].name] = parms_[idx].parm;
|
||||
/* Stash the instance array of scopes into the parent
|
||||
scope. Later elaboration passes will use this vector to
|
||||
further elaborate the array. */
|
||||
sc->instance_arrays[get_name()] = instances;
|
||||
}
|
||||
|
||||
/*
|
||||
* Elaborate the datum within the module. This variable may be
|
||||
* within a subscope (i.e., a function or task) so use the components
|
||||
* of the name to find the precise scope where this item goes.
|
||||
*/
|
||||
void PData::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetScope*sub_scope = scope;
|
||||
for (unsigned idx = 0 ; idx < (hname_.component_count()-1); idx += 1) {
|
||||
sub_scope = sub_scope->child(hname_.peek_name(idx));
|
||||
|
||||
if (sub_scope == 0) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Could not find sub-scope "
|
||||
<< hname_.peek_name(idx) << " of "
|
||||
<< hname_ << " in module " << scope->name()
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// And here we scan the replacements we collected. Elaborate
|
||||
// the expression in my context, then replace the sub-scope
|
||||
// parameter value with the new expression.
|
||||
|
||||
for (mparm_it_t cur = replace.begin()
|
||||
; cur != replace.end() ; cur ++ ) {
|
||||
|
||||
PExpr*tmp = (*cur).second;
|
||||
NetExpr*val = tmp->elaborate_pexpr(des, sc);
|
||||
val = my_scope->set_parameter((*cur).first, val);
|
||||
assert(val);
|
||||
delete val;
|
||||
}
|
||||
const char*basename = hname_.peek_tail_name();
|
||||
NetVariable*tmp = new NetVariable(lex_strings.make(basename));
|
||||
tmp->set_line(*this);
|
||||
sub_scope->add_variable(tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* The isn't really able to create new scopes, but it does create the
|
||||
* event name in the current scope, so can be done during the
|
||||
* elaborate_scope scan.
|
||||
* elaborate_scope scan. Note that the name_ of the PEvent object has
|
||||
* no hierarchy, but neither does the NetEvent, until it is stored in
|
||||
* the NetScope object.
|
||||
*/
|
||||
void PEvent::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
@@ -308,11 +492,18 @@ void PEvent::elaborate_scope(Design*des, NetScope*scope) const
|
||||
|
||||
void PFunction::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(scope->type() == NetScope::FUNC);
|
||||
|
||||
if (statement_)
|
||||
statement_->elaborate_scope(des, scope);
|
||||
}
|
||||
|
||||
void PTask::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(scope->type() == NetScope::TASK);
|
||||
|
||||
if (statement_)
|
||||
statement_->elaborate_scope(des, scope);
|
||||
}
|
||||
|
||||
|
||||
@@ -334,7 +525,7 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetScope*my_scope = scope;
|
||||
|
||||
if (name_ != "") {
|
||||
if (name_ != 0) {
|
||||
my_scope = new NetScope(scope, name_, bl_type_==BL_PAR
|
||||
? NetScope::FORK_JOIN
|
||||
: NetScope::BEGIN_END);
|
||||
@@ -346,7 +537,7 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
||||
}
|
||||
|
||||
/*
|
||||
* The case statement itseof does not introduce scope, but contains
|
||||
* The case statement itself does not introduce scope, but contains
|
||||
* other statements that may be named blocks. So scan the case items
|
||||
* with the elaborate_scope method.
|
||||
*/
|
||||
@@ -444,34 +635,82 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_scope.cc,v $
|
||||
* Revision 1.7 2000/12/16 01:45:48 steve
|
||||
* Detect recursive instantiations (PR#2)
|
||||
* Revision 1.35 2004/09/10 00:15:17 steve
|
||||
* Missing stdio.h header for warnings.
|
||||
*
|
||||
* Revision 1.6 2000/07/30 18:25:43 steve
|
||||
* Rearrange task and function elaboration so that the
|
||||
* NetTaskDef and NetFuncDef functions are created during
|
||||
* signal enaboration, and carry these objects in the
|
||||
* NetScope class instead of the extra, useless map in
|
||||
* the Design class.
|
||||
* Revision 1.34 2004/09/05 17:44:41 steve
|
||||
* Add support for module instance arrays.
|
||||
*
|
||||
* Revision 1.5 2000/07/22 22:09:03 steve
|
||||
* Parse and elaborate timescale to scopes.
|
||||
* Revision 1.33 2004/08/26 04:02:03 steve
|
||||
* Add support for localparam ranges.
|
||||
*
|
||||
* Revision 1.4 2000/04/09 17:44:30 steve
|
||||
* Catch event declarations during scope elaborate.
|
||||
* Revision 1.32 2004/06/13 04:56:54 steve
|
||||
* Add support for the default_nettype directive.
|
||||
*
|
||||
* Revision 1.3 2000/03/12 17:09:41 steve
|
||||
* Support localparam.
|
||||
* Revision 1.31 2004/05/25 19:21:06 steve
|
||||
* More identifier lists use perm_strings.
|
||||
*
|
||||
* Revision 1.2 2000/03/11 03:25:52 steve
|
||||
* Locate scopes in statements.
|
||||
* Revision 1.30 2004/02/20 06:22:56 steve
|
||||
* parameter keys are per_strings.
|
||||
*
|
||||
* Revision 1.1 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
* Revision 1.29 2004/02/19 07:06:57 steve
|
||||
* LPM, logic and Variables have perm_string names.
|
||||
*
|
||||
* Revision 1.28 2004/02/18 17:11:55 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.27 2003/09/13 01:01:51 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.26 2003/08/28 04:11:17 steve
|
||||
* Spelling patch.
|
||||
*
|
||||
* Revision 1.25 2003/06/24 01:38:02 steve
|
||||
* Various warnings fixed.
|
||||
*
|
||||
* Revision 1.24 2003/06/20 00:53:19 steve
|
||||
* Module attributes from the parser
|
||||
* through to elaborated form.
|
||||
*
|
||||
* Revision 1.23 2003/06/16 00:34:08 steve
|
||||
* Functions can have sub-scope.
|
||||
*
|
||||
* Revision 1.22 2003/06/13 19:10:46 steve
|
||||
* Properly manage real variables in subscopes.
|
||||
*
|
||||
* Revision 1.21 2003/05/30 02:55:32 steve
|
||||
* Support parameters in real expressions and
|
||||
* as real expressions, and fix multiply and
|
||||
* divide with real results.
|
||||
*
|
||||
* Revision 1.20 2003/03/06 00:28:41 steve
|
||||
* All NetObj objects have lex_string base names.
|
||||
*
|
||||
* Revision 1.19 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.18 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
* Revision 1.17 2002/10/19 22:59:49 steve
|
||||
* Redo the parameter vector support to allow
|
||||
* parameter names in range expressions.
|
||||
*
|
||||
* Revision 1.16 2002/09/01 03:01:48 steve
|
||||
* Properly cast signedness of parameters with ranges.
|
||||
*
|
||||
* Revision 1.15 2002/08/19 02:39:16 steve
|
||||
* Support parameters with defined ranges.
|
||||
*
|
||||
* Revision 1.14 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.13 2001/12/30 04:47:57 steve
|
||||
* Properly handle empty target in positionla parameter override.
|
||||
*
|
||||
* Revision 1.12 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*/
|
||||
|
||||
|
||||
+372
-123
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2000-2004 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
|
||||
@@ -16,15 +16,20 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_sig.cc,v 1.12 2001/02/17 05:15:33 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_sig.cc,v 1.36 2004/09/27 22:34:10 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "Module.h"
|
||||
# include "PExpr.h"
|
||||
# include "PGate.h"
|
||||
# include "PTask.h"
|
||||
# include "PWire.h"
|
||||
# include "compiler.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "util.h"
|
||||
@@ -35,7 +40,7 @@
|
||||
* within the port_t that have a matching name.
|
||||
*/
|
||||
static bool signal_is_in_port(const svector<Module::port_t*>&ports,
|
||||
const string&name)
|
||||
const hname_t&name)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
|
||||
@@ -49,7 +54,7 @@ static bool signal_is_in_port(const svector<Module::port_t*>&ports,
|
||||
// together that form the port.
|
||||
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
|
||||
assert(pp->expr[cc]);
|
||||
if (pp->expr[cc]->name() == name)
|
||||
if (pp->expr[cc]->path() == name)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -63,24 +68,62 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
// Get all the explicitly declared wires of the module and
|
||||
// start the signals list with them.
|
||||
const map<string,PWire*>&wl = get_wires();
|
||||
const map<hname_t,PWire*>&wl = get_wires();
|
||||
|
||||
for (map<string,PWire*>::const_iterator wt = wl.begin()
|
||||
// Scan all the ports of the module, and make sure that each
|
||||
// is connected to wires that have port declarations.
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
Module::port_t*pp = ports[idx];
|
||||
if (pp == 0)
|
||||
continue;
|
||||
|
||||
map<hname_t,PWire*>::const_iterator wt;
|
||||
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
|
||||
hname_t port_path (pp->expr[cc]->path());
|
||||
wt = wl.find(port_path);
|
||||
|
||||
if (wt == wl.end()) {
|
||||
cerr << get_line() << ": error: "
|
||||
<< "Port " << pp->expr[cc]->path() << " ("
|
||||
<< (idx+1) << ") of module " << name_
|
||||
<< " is not declared within module." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*wt).second->get_port_type() == NetNet::NOT_A_PORT) {
|
||||
cerr << get_line() << ": error: "
|
||||
<< "Port " << pp->expr[cc]->path() << " ("
|
||||
<< (idx+1) << ") of module " << name_
|
||||
<< " has no direction declaration."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (map<hname_t,PWire*>::const_iterator wt = wl.begin()
|
||||
; wt != wl.end()
|
||||
; wt ++ ) {
|
||||
|
||||
PWire*cur = (*wt).second;
|
||||
cur->elaborate_sig(des, scope);
|
||||
|
||||
NetNet*sig = scope->find_signal_in_child(cur->path());
|
||||
|
||||
// If this wire is a signal of the module (as opposed to
|
||||
// a port of a function) and is a port, then check that
|
||||
// the module knows about it.
|
||||
NetNet*sig = scope->find_signal(cur->name());
|
||||
// the module knows about it. We know that the signal is
|
||||
// the name of a signal within a subscope of a module
|
||||
// (a task, a function, etc.) if the name for the PWire
|
||||
// has hierarchy.
|
||||
|
||||
if (sig && (sig->scope() == scope)
|
||||
&& (cur->get_port_type() != NetNet::NOT_A_PORT)) {
|
||||
string name = (*wt).first;
|
||||
|
||||
if (! signal_is_in_port(ports_, name)) {
|
||||
hname_t name = (*wt).first;
|
||||
|
||||
if (! signal_is_in_port(ports, name)) {
|
||||
|
||||
cerr << cur->get_line() << ": error: Signal "
|
||||
<< name << " has a declared direction "
|
||||
@@ -88,6 +131,33 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If the signal is an input and is also declared as a
|
||||
reg, then report an error. */
|
||||
|
||||
if (sig && (sig->scope() == scope)
|
||||
&& (sig->port_type() == NetNet::PINPUT)
|
||||
&& (sig->type() == NetNet::REG)) {
|
||||
|
||||
cerr << cur->get_line() << ": error: "
|
||||
<< cur->path() << " in module "
|
||||
<< scope->module_name()
|
||||
<< " declared as input and as a reg type." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (sig && (sig->scope() == scope)
|
||||
&& (sig->port_type() == NetNet::PINOUT)
|
||||
&& (sig->type() == NetNet::REG)) {
|
||||
|
||||
cerr << cur->get_line() << ": error: "
|
||||
<< cur->path() << " in module "
|
||||
<< scope->module_name()
|
||||
<< " declared as inout and as a reg type." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Get all the gates of the module and elaborate them by
|
||||
@@ -105,7 +175,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
}
|
||||
|
||||
|
||||
typedef map<string,PFunction*>::const_iterator mfunc_it_t;
|
||||
typedef map<perm_string,PFunction*>::const_iterator mfunc_it_t;
|
||||
|
||||
for (mfunc_it_t cur = funcs_.begin()
|
||||
; cur != funcs_.end() ; cur ++) {
|
||||
@@ -126,7 +196,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
// elaborate the ports of the tasks defined within this
|
||||
// module. Run through them now.
|
||||
|
||||
typedef map<string,PTask*>::const_iterator mtask_it_t;
|
||||
typedef map<perm_string,PTask*>::const_iterator mtask_it_t;
|
||||
|
||||
for (mtask_it_t cur = tasks_.begin()
|
||||
; cur != tasks_.end() ; cur ++) {
|
||||
@@ -141,48 +211,130 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
bool PGModule::elaborate_sig_mod_(Design*des, NetScope*scope,
|
||||
Module*rmod) const
|
||||
{
|
||||
// Missing module instance names have already been rejected.
|
||||
assert(get_name() != "");
|
||||
bool flag = true;
|
||||
|
||||
NetScope::scope_vec_t instance = scope->instance_arrays[get_name()];
|
||||
|
||||
for (unsigned idx = 0 ; idx < instance.count() ; idx += 1) {
|
||||
// I know a priori that the elaborate_scope created the scope
|
||||
// already, so just look it up as a child of the current scope.
|
||||
NetScope*my_scope = instance[idx];
|
||||
assert(my_scope);
|
||||
|
||||
if (my_scope->parent() != scope) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Instance " << my_scope->name()
|
||||
<< " is in parent " << my_scope->parent()->name()
|
||||
<< " instead of " << scope->name()
|
||||
<< endl;
|
||||
}
|
||||
assert(my_scope->parent() == scope);
|
||||
|
||||
if (! rmod->elaborate_sig(des, my_scope))
|
||||
flag = false;
|
||||
|
||||
if (msb_) {
|
||||
cerr << get_line() << ": sorry: Module instantiation arrays "
|
||||
"are not yet supported." << endl;
|
||||
des->errors += 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// I know a priori that the elaborate_scope created the scope
|
||||
// already, so just look it up as a child of the current scope.
|
||||
NetScope*my_scope = scope->child(get_name());
|
||||
assert(my_scope);
|
||||
|
||||
return rmod->elaborate_sig(des, my_scope);
|
||||
return flag;
|
||||
}
|
||||
|
||||
/*
|
||||
* A function definition exists within an elaborated module.
|
||||
* A function definition exists within an elaborated module. This
|
||||
* matters when elaborating signals, as the ports of the function are
|
||||
* created as signals/variables for each instance of the
|
||||
* function. That is why PFunction has an elaborate_sig method.
|
||||
*/
|
||||
void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
string fname = scope->basename();
|
||||
perm_string fname = scope->basename();
|
||||
assert(scope->type() == NetScope::FUNC);
|
||||
|
||||
svector<NetNet*>ports (ports_? ports_->count()+1 : 1);
|
||||
|
||||
/* Get the reg for the return value. I know the name of the
|
||||
reg variable, and I know that it is in this scope, so look
|
||||
it up directly. */
|
||||
ports[0] = scope->find_signal(scope->basename());
|
||||
if (ports[0] == 0) {
|
||||
cerr << get_line() << ": internal error: function scope "
|
||||
<< scope->name() << " is missing return reg "
|
||||
<< fname << "." << endl;
|
||||
scope->dump(cerr);
|
||||
/* 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) {
|
||||
cerr << get_line() << ": error: Function " << fname
|
||||
<< " has no ports." << endl;
|
||||
cerr << get_line() << ": : Functions must have"
|
||||
<< " at least one input port." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
NetNet*ret_sig = 0;
|
||||
NetVariable*ret_real = 0;
|
||||
|
||||
/* Create the signals/variables of the return value and write
|
||||
them into the function scope. */
|
||||
switch (return_type_.type) {
|
||||
|
||||
case PTF_REG:
|
||||
if (return_type_.range) {
|
||||
NetExpr*me = elab_and_eval(des, scope,
|
||||
(*return_type_.range)[0]);
|
||||
assert(me);
|
||||
NetExpr*le = elab_and_eval(des, scope,
|
||||
(*return_type_.range)[1]);
|
||||
assert(le);
|
||||
|
||||
long mnum = 0, lnum = 0;
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(me)) {
|
||||
mnum = tmp->value().as_long();
|
||||
} else {
|
||||
cerr << me->get_line() << ": error: "
|
||||
"Unable to evaluate constant expression "
|
||||
<< *me << "." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(le)) {
|
||||
lnum = tmp->value().as_long();
|
||||
} else {
|
||||
cerr << le->get_line() << ": error: "
|
||||
"Unable to evaluate constant expression "
|
||||
<< *le << "." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, mnum, lnum);
|
||||
|
||||
} else {
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG);
|
||||
}
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
break;
|
||||
|
||||
case PTF_INTEGER:
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, INTEGER_WIDTH);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(true);
|
||||
ret_sig->set_isint(true);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
break;
|
||||
|
||||
case PTF_TIME:
|
||||
ret_sig = new NetNet(scope, fname, NetNet::REG, 64);
|
||||
ret_sig->set_line(*this);
|
||||
ret_sig->set_signed(false);
|
||||
ret_sig->set_isint(false);
|
||||
ret_sig->port_type(NetNet::POUTPUT);
|
||||
break;
|
||||
|
||||
case PTF_REAL:
|
||||
case PTF_REALTIME:
|
||||
ret_real = new NetVariable(fname);
|
||||
ret_real->set_line(*this);
|
||||
scope->add_variable(ret_real);
|
||||
break;
|
||||
|
||||
default:
|
||||
cerr << get_line() << ": internal error: I don't know how "
|
||||
<< "to deal with return type of function "
|
||||
<< scope->basename() << "." << endl;
|
||||
}
|
||||
|
||||
svector<NetNet*>ports (ports_? ports_->count() : 0);
|
||||
|
||||
if (ports_)
|
||||
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
|
||||
|
||||
@@ -190,12 +342,13 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
name. We know by design that the port name is given
|
||||
as two components: <func>.<port>. */
|
||||
|
||||
string pname = (*ports_)[idx]->name();
|
||||
string ppath = parse_first_name(pname);
|
||||
hname_t path = (*ports_)[idx]->path();
|
||||
perm_string pname = lex_strings.make(path.peek_name(1));
|
||||
perm_string ppath = lex_strings.make(path.peek_name(0));
|
||||
|
||||
if (ppath != scope->basename()) {
|
||||
cerr << get_line() << ": internal error: function "
|
||||
<< "port " << (*ports_)[idx]->name()
|
||||
<< "port " << (*ports_)[idx]->path()
|
||||
<< " has wrong name for function "
|
||||
<< scope->name() << "." << endl;
|
||||
des->errors += 1;
|
||||
@@ -207,14 +360,19 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
<< scope->name() << " is missing port "
|
||||
<< pname << "." << endl;
|
||||
scope->dump(cerr);
|
||||
cerr << get_line() << ": Continuing..." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
ports[idx+1] = tmp;
|
||||
ports[idx] = tmp;
|
||||
}
|
||||
|
||||
|
||||
NetFuncDef*def = new NetFuncDef(scope, ports);
|
||||
NetFuncDef*def = 0;
|
||||
if (ret_sig) def = new NetFuncDef(scope, ret_sig, ports);
|
||||
if (ret_real) def = new NetFuncDef(scope, ret_real, ports);
|
||||
|
||||
assert(def);
|
||||
scope->set_func_def(def);
|
||||
}
|
||||
|
||||
@@ -238,16 +396,15 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
|
||||
name. We know by design that the port name is given
|
||||
as two components: <task>.<port>. */
|
||||
|
||||
string pname = (*ports_)[idx]->name();
|
||||
string ppath = parse_first_name(pname);
|
||||
assert(pname != "");
|
||||
hname_t path = (*ports_)[idx]->path();
|
||||
assert(path.peek_name(0) && path.peek_name(1));
|
||||
|
||||
/* check that the current scope really does have the
|
||||
name of the first component of the task port name. Do
|
||||
this by looking up the task scope in the parent of
|
||||
the current scope. */
|
||||
if (scope->parent()->child(ppath) != scope) {
|
||||
cerr << "internal error: task scope " << ppath
|
||||
if (scope->parent()->child(path.peek_name(0)) != scope) {
|
||||
cerr << "internal error: task scope " << path
|
||||
<< " not the same as scope " << scope->name()
|
||||
<< "?!" << endl;
|
||||
return;
|
||||
@@ -256,11 +413,11 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
|
||||
/* 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(pname);
|
||||
NetNet*tmp = scope->find_signal(path.peek_name(1));
|
||||
|
||||
if (tmp == 0) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Could not find port " << pname
|
||||
<< "Could not find port " << path.peek_name(1)
|
||||
<< " in scope " << scope->name() << endl;
|
||||
scope->dump(cerr);
|
||||
}
|
||||
@@ -280,28 +437,30 @@ bool PGate::elaborate_sig(Design*des, NetScope*scope) const
|
||||
/*
|
||||
* Elaborate a source wire. The "wire" is the declaration of wires,
|
||||
* registers, ports and memories. The parser has already merged the
|
||||
* multiple properties of a wire (i.e. "input wire") so come the
|
||||
* multiple properties of a wire (i.e., "input wire") so come the
|
||||
* elaboration this creates an object in the design that represent the
|
||||
* defined item.
|
||||
*/
|
||||
void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
{
|
||||
|
||||
/* The parser may produce hierarchical names for wires. I here
|
||||
follow the scopes down to the base where I actually want to
|
||||
elaborate the NetNet object. */
|
||||
string basename = name_;
|
||||
for (;;) {
|
||||
string p = parse_first_name(basename);
|
||||
if (basename == "") {
|
||||
basename = p;
|
||||
break;
|
||||
}
|
||||
{ hname_t tmp_path = hname_;
|
||||
free(tmp_path.remove_tail_name());
|
||||
for (unsigned idx = 0 ; tmp_path.peek_name(idx) ; idx += 1) {
|
||||
scope = scope->child(tmp_path.peek_name(idx));
|
||||
|
||||
scope = scope->child(p);
|
||||
assert(scope);
|
||||
if (scope == 0) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Bad scope component for name "
|
||||
<< hname_ << endl;
|
||||
assert(scope);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const string path = scope->name();
|
||||
NetNet::Type wtype = type_;
|
||||
if (wtype == NetNet::IMPLICIT)
|
||||
wtype = NetNet::WIRE;
|
||||
@@ -315,14 +474,26 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
if (msb_.count()) {
|
||||
svector<long>mnum (msb_.count());
|
||||
svector<long>lnum (msb_.count());
|
||||
/* There may be places where the signal is declared as a
|
||||
scalar. Count those here, for consistency check
|
||||
later. */
|
||||
unsigned count_scalars = 0;
|
||||
|
||||
/* There may be multiple declarations of ranges, because
|
||||
the symbol may have its range declared in i.e. input
|
||||
the symbol may have its range declared in e.g., input
|
||||
and reg declarations. Calculate *all* the numbers
|
||||
here. I will resolve the values later. */
|
||||
|
||||
for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
|
||||
|
||||
if (msb_[idx] == 0) {
|
||||
count_scalars += 1;
|
||||
assert(lsb_[idx] == 0);
|
||||
mnum[idx] = 0;
|
||||
lnum[idx] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
NetEConst*tmp;
|
||||
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx]);
|
||||
|
||||
@@ -353,6 +524,18 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
}
|
||||
|
||||
/* Check that the declarations were all scalar or all
|
||||
vector. It is an error to mix them. Use the
|
||||
count_scalars to know. */
|
||||
if ((count_scalars > 0) && (count_scalars != msb_.count())) {
|
||||
cerr << get_line() << ": error: Signal ``" << hname_
|
||||
<< "'' declared both as a vector and a scalar."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Make sure all the values for msb and lsb match by
|
||||
value. If not, report an error. */
|
||||
for (unsigned idx = 1 ; idx < msb_.count() ; idx += 1) {
|
||||
@@ -360,7 +543,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
cerr << get_line() << ": error: Inconsistent width, "
|
||||
"[" << mnum[idx] << ":" << lnum[idx] << "]"
|
||||
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
|
||||
" for signal ``" << basename << "''" << endl;
|
||||
" for signal ``" << hname_ << "''" << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
@@ -376,90 +559,156 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
}
|
||||
|
||||
unsigned nattrib = 0;
|
||||
attrib_list_t*attrib_list = evaluate_attributes(attributes, nattrib,
|
||||
des, scope);
|
||||
|
||||
/* If the ident has idx expressions, then this is a
|
||||
memory. It can only have the idx registers after the msb
|
||||
and lsb expressions are filled. And, if it has one index,
|
||||
it has both. */
|
||||
if (lidx_ || ridx_) {
|
||||
assert(lidx_ && ridx_);
|
||||
|
||||
// If the register has indices, then this is a
|
||||
// memory. Create the memory object.
|
||||
verinum*lval = lidx_->eval_const(des, path);
|
||||
verinum*rval = ridx_->eval_const(des, path);
|
||||
NetExpr*lexp = elab_and_eval(des, scope, lidx_);
|
||||
NetExpr*rexp = elab_and_eval(des, scope, ridx_);
|
||||
|
||||
if ((lval == 0) || (rval == 0)) {
|
||||
if ((lexp == 0) || (rexp == 0)) {
|
||||
cerr << get_line() << ": internal error: There is "
|
||||
<< "a problem evaluating indices for ``"
|
||||
<< basename << "''." << endl;
|
||||
<< hname_.peek_tail_name() << "''." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
assert(lval);
|
||||
assert(rval);
|
||||
NetEConst*lcon = dynamic_cast<NetEConst*> (lexp);
|
||||
NetEConst*rcon = dynamic_cast<NetEConst*> (rexp);
|
||||
|
||||
long lnum = lval->as_long();
|
||||
long rnum = rval->as_long();
|
||||
delete lval;
|
||||
delete rval;
|
||||
NetMemory*sig = new NetMemory(scope, path+"."+basename,
|
||||
wid, lnum, rnum);
|
||||
if ((lcon == 0) || (rcon == 0)) {
|
||||
cerr << get_line() << ": internal error: The indices "
|
||||
<< "are not constant for memory ``"
|
||||
<< hname_.peek_tail_name() << "''." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
verinum lval = lcon->value();
|
||||
verinum rval = rcon->value();
|
||||
|
||||
delete lexp;
|
||||
delete rexp;
|
||||
|
||||
perm_string name = lex_strings.make(hname_.peek_tail_name());
|
||||
|
||||
long lnum = lval.as_long();
|
||||
long rnum = rval.as_long();
|
||||
|
||||
new NetMemory(scope, name, wid, lnum, rnum);
|
||||
// The constructor automatically adds the memory object
|
||||
// to the scope. Do I need to set line number information?
|
||||
|
||||
} else {
|
||||
|
||||
NetNet*sig = new NetNet(scope, path + "." +basename, wtype, msb, lsb);
|
||||
perm_string name = lex_strings.make(hname_.peek_tail_name());
|
||||
NetNet*sig = new NetNet(scope, name, wtype, msb, lsb);
|
||||
sig->set_line(*this);
|
||||
sig->port_type(port_type_);
|
||||
sig->set_signed(get_signed());
|
||||
sig->set_attributes(attributes);
|
||||
sig->set_isint(get_isint());
|
||||
|
||||
for (unsigned idx = 0 ; idx < nattrib ; idx += 1)
|
||||
sig->attribute(attrib_list[idx].key, attrib_list[idx].val);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: elab_sig.cc,v $
|
||||
* Revision 1.36 2004/09/27 22:34:10 steve
|
||||
* Cleanup and factoring of autoconf.
|
||||
*
|
||||
* Revision 1.35 2004/09/05 17:44:41 steve
|
||||
* Add support for module instance arrays.
|
||||
*
|
||||
* Revision 1.34 2004/05/31 23:34:37 steve
|
||||
* Rewire/generalize parsing an elaboration of
|
||||
* function return values to allow for better
|
||||
* speed and more type support.
|
||||
*
|
||||
* Revision 1.33 2004/02/18 17:11:55 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.32 2003/09/20 05:24:00 steve
|
||||
* Evaluate memory index constants using elab_and_eval.
|
||||
*
|
||||
* Revision 1.31 2003/07/15 03:49:22 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.30 2003/06/24 01:38:02 steve
|
||||
* Various warnings fixed.
|
||||
*
|
||||
* Revision 1.29 2003/06/21 01:21:43 steve
|
||||
* Harmless fixup of warnings.
|
||||
*
|
||||
* Revision 1.28 2003/03/06 00:28:41 steve
|
||||
* All NetObj objects have lex_string base names.
|
||||
*
|
||||
* Revision 1.27 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.26 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.25 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.24 2002/08/05 04:18:45 steve
|
||||
* Store only the base name of memories.
|
||||
*
|
||||
* Revision 1.23 2002/06/21 04:59:35 steve
|
||||
* Carry integerness throughout the compilation.
|
||||
*
|
||||
* Revision 1.22 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.21 2002/05/19 23:37:28 steve
|
||||
* Parse port_declaration_lists from the 2001 Standard.
|
||||
*
|
||||
* Revision 1.20 2002/01/26 05:28:28 steve
|
||||
* Detect scalar/vector declarion mismatch.
|
||||
*
|
||||
* Revision 1.19 2002/01/23 03:35:17 steve
|
||||
* Detect incorrect function ports.
|
||||
*
|
||||
* Revision 1.18 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.17 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.16 2001/11/01 05:21:26 steve
|
||||
* Catch ports that have no direction.
|
||||
*
|
||||
* Revision 1.15 2001/10/31 03:11:15 steve
|
||||
* detect module ports not declared within the module.
|
||||
*
|
||||
* Revision 1.14 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.13 2001/05/25 02:21:34 steve
|
||||
* Detect input and input ports declared as reg.
|
||||
*
|
||||
* Revision 1.12 2001/02/17 05:15:33 steve
|
||||
* Allow task ports to be given real types.
|
||||
*
|
||||
* Revision 1.11 2001/02/10 20:29:39 steve
|
||||
* In the context of range declarations, use elab_and_eval instead
|
||||
* of the less robust eval_const methods.
|
||||
*
|
||||
* Revision 1.10 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
* Revision 1.9 2001/01/07 07:00:31 steve
|
||||
* Detect port direction attached to non-ports.
|
||||
*
|
||||
* Revision 1.8 2001/01/04 04:47:51 steve
|
||||
* Add support for << is signal indices.
|
||||
*
|
||||
* Revision 1.7 2000/12/11 00:31:43 steve
|
||||
* Add support for signed reg variables,
|
||||
* simulate in t-vvm signed comparisons.
|
||||
*
|
||||
* Revision 1.6 2000/12/04 17:37:04 steve
|
||||
* Add Attrib class for holding NetObj attributes.
|
||||
*
|
||||
* Revision 1.5 2000/11/20 00:58:40 steve
|
||||
* Add support for supply nets (PR#17)
|
||||
*
|
||||
* Revision 1.4 2000/09/07 22:37:48 steve
|
||||
* ack, detect when lval fails.
|
||||
*
|
||||
* Revision 1.3 2000/07/30 18:25:43 steve
|
||||
* Rearrange task and function elaboration so that the
|
||||
* NetTaskDef and NetFuncDef functions are created during
|
||||
* signal enaboration, and carry these objects in the
|
||||
* NetScope class instead of the extra, useless map in
|
||||
* the Design class.
|
||||
*
|
||||
* Revision 1.2 2000/07/14 06:12:57 steve
|
||||
* Move inital value handling from NetNet to Nexus
|
||||
* objects. This allows better propogation of inital
|
||||
* values.
|
||||
*
|
||||
* Clean up constant propagation a bit to account
|
||||
* for regs that are not really values.
|
||||
*
|
||||
* Revision 1.1 2000/05/02 16:27:38 steve
|
||||
* Move signal elaboration to a seperate pass.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+1245
-946
File diff suppressed because it is too large
Load Diff
@@ -16,10 +16,14 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: emit.cc,v 1.56 2001/03/27 03:31:06 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: emit.cc,v 1.77 2004/10/04 01:10:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
/*
|
||||
* The emit function is called to generate the output required of the
|
||||
* target.
|
||||
@@ -41,12 +45,6 @@ bool NetLogic::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetUDP_COMB::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->udp_comb(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetUDP::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->udp(this);
|
||||
@@ -59,12 +57,6 @@ bool NetAddSub::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetAssign_::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->net_assign(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetCaseCmp::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->net_case_cmp(this);
|
||||
@@ -136,6 +128,11 @@ bool NetRamDq::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetUserFunc::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->net_function(this);
|
||||
}
|
||||
|
||||
bool NetBUFZ::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->bufz(this);
|
||||
@@ -164,18 +161,6 @@ bool NetAssignNB::emit_proc(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetAssignMem::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
tgt->proc_assign_mem(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetAssignMemNB::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
tgt->proc_assign_mem_nb(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetBlock::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
return tgt->proc_block(this);
|
||||
@@ -194,8 +179,7 @@ bool NetCAssign::emit_proc(struct target_t*tgt) const
|
||||
|
||||
bool NetCondit::emit_proc(struct target_t*tgt) const
|
||||
{
|
||||
tgt->proc_condit(this);
|
||||
return true;
|
||||
return tgt->proc_condit(this);
|
||||
}
|
||||
|
||||
bool NetDeassign::emit_proc(struct target_t*tgt) const
|
||||
@@ -271,16 +255,20 @@ void NetBlock::emit_recurse(struct target_t*tgt) const
|
||||
} while (cur != last_);
|
||||
}
|
||||
|
||||
void NetCondit::emit_recurse_if(struct target_t*tgt) const
|
||||
bool NetCondit::emit_recurse_if(struct target_t*tgt) const
|
||||
{
|
||||
if (if_)
|
||||
if_->emit_proc(tgt);
|
||||
return if_->emit_proc(tgt);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetCondit::emit_recurse_else(struct target_t*tgt) const
|
||||
bool NetCondit::emit_recurse_else(struct target_t*tgt) const
|
||||
{
|
||||
if (else_)
|
||||
else_->emit_proc(tgt);
|
||||
return else_->emit_proc(tgt);
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetEvProbe::emit_node(struct target_t*tgt) const
|
||||
@@ -324,6 +312,9 @@ void NetScope::emit_scope(struct target_t*tgt) const
|
||||
for (NetEvent*cur = events_ ; cur ; cur = cur->snext_)
|
||||
tgt->event(cur);
|
||||
|
||||
for (NetVariable*cur = vars_ ; cur ; cur = cur->snext_)
|
||||
tgt->variable(cur);
|
||||
|
||||
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
|
||||
cur->emit_scope(tgt);
|
||||
|
||||
@@ -344,23 +335,27 @@ void NetScope::emit_scope(struct target_t*tgt) const
|
||||
}
|
||||
}
|
||||
|
||||
void NetScope::emit_defs(struct target_t*tgt) const
|
||||
bool NetScope::emit_defs(struct target_t*tgt) const
|
||||
{
|
||||
bool flag = true;
|
||||
|
||||
switch (type_) {
|
||||
case MODULE:
|
||||
for (NetScope*cur = sub_ ; cur ; cur = cur->sib_)
|
||||
cur->emit_defs(tgt);
|
||||
flag &= cur->emit_defs(tgt);
|
||||
break;
|
||||
|
||||
case FUNC:
|
||||
tgt->func_def(this->func_def());
|
||||
flag &= tgt->func_def(this);
|
||||
break;
|
||||
case TASK:
|
||||
tgt->task_def(this->task_def());
|
||||
tgt->task_def(this);
|
||||
break;
|
||||
default: /* BEGIN_END and FORK_JOIN, do nothing */
|
||||
break;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
void NetWhile::emit_proc_recurse(struct target_t*tgt) const
|
||||
@@ -377,7 +372,9 @@ bool Design::emit(struct target_t*tgt) const
|
||||
return false;
|
||||
|
||||
// enumerate the scopes
|
||||
root_scope_->emit_scope(tgt);
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->emit_scope(tgt);
|
||||
|
||||
|
||||
// emit nodes
|
||||
@@ -391,7 +388,9 @@ bool Design::emit(struct target_t*tgt) const
|
||||
|
||||
|
||||
// emit task and function definitions
|
||||
root_scope_->emit_defs(tgt);
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
rc &= (*scope)->emit_defs(tgt);
|
||||
|
||||
|
||||
// emit the processes
|
||||
@@ -419,6 +418,21 @@ void NetEConst::expr_scan(struct expr_scan_t*tgt) const
|
||||
tgt->expr_const(this);
|
||||
}
|
||||
|
||||
void NetEConstParam::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_param(this);
|
||||
}
|
||||
|
||||
void NetECReal::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_creal(this);
|
||||
}
|
||||
|
||||
void NetECRealParam::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_rparam(this);
|
||||
}
|
||||
|
||||
void NetEMemory::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_memory(this);
|
||||
@@ -430,11 +444,21 @@ void NetEParam::expr_scan(struct expr_scan_t*tgt) const
|
||||
<< endl;
|
||||
}
|
||||
|
||||
void NetEEvent::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_event(this);
|
||||
}
|
||||
|
||||
void NetEScope::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_scope(this);
|
||||
}
|
||||
|
||||
void NetESelect::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_select(this);
|
||||
}
|
||||
|
||||
void NetESFunc::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_sfunc(this);
|
||||
@@ -450,7 +474,7 @@ void NetESignal::expr_scan(struct expr_scan_t*tgt) const
|
||||
tgt->expr_signal(this);
|
||||
}
|
||||
|
||||
void NetESubSignal::expr_scan(struct expr_scan_t*tgt) const
|
||||
void NetEBitSel::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_subsignal(this);
|
||||
}
|
||||
@@ -465,6 +489,11 @@ void NetEUnary::expr_scan(struct expr_scan_t*tgt) const
|
||||
tgt->expr_unary(this);
|
||||
}
|
||||
|
||||
void NetEVariable::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_variable(this);
|
||||
}
|
||||
|
||||
bool emit(const Design*des, const char*type)
|
||||
{
|
||||
for (unsigned idx = 0 ; target_table[idx] ; idx += 1) {
|
||||
@@ -473,11 +502,98 @@ bool emit(const Design*des, const char*type)
|
||||
return des->emit(tgt->meth);
|
||||
|
||||
}
|
||||
|
||||
cerr << "error: Code generator type " << type
|
||||
<< " not found." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: emit.cc,v $
|
||||
* Revision 1.77 2004/10/04 01:10:53 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.76 2004/05/31 23:34:37 steve
|
||||
* Rewire/generalize parsing an elaboration of
|
||||
* function return values to allow for better
|
||||
* speed and more type support.
|
||||
*
|
||||
* Revision 1.75 2003/09/13 01:30:07 steve
|
||||
* Missing case warnings.
|
||||
*
|
||||
* Revision 1.74 2003/05/30 02:55:32 steve
|
||||
* Support parameters in real expressions and
|
||||
* as real expressions, and fix multiply and
|
||||
* divide with real results.
|
||||
*
|
||||
* Revision 1.73 2003/04/22 04:48:29 steve
|
||||
* Support event names as expressions elements.
|
||||
*
|
||||
* Revision 1.72 2003/03/10 23:40:53 steve
|
||||
* Keep parameter constants for the ivl_target API.
|
||||
*
|
||||
* Revision 1.71 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
* Revision 1.70 2002/11/03 20:36:10 steve
|
||||
* Error message for mising code generator type.
|
||||
*
|
||||
* Revision 1.69 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.68 2002/06/05 03:44:25 steve
|
||||
* Add support for memory words in l-value of
|
||||
* non-blocking assignments, and remove the special
|
||||
* NetAssignMem_ and NetAssignMemNB classes.
|
||||
*
|
||||
* Revision 1.67 2002/06/04 05:38:44 steve
|
||||
* Add support for memory words in l-value of
|
||||
* blocking assignments, and remove the special
|
||||
* NetAssignMem class.
|
||||
*
|
||||
* Revision 1.66 2002/03/09 02:10:22 steve
|
||||
* Add the NetUserFunc netlist node.
|
||||
*
|
||||
* Revision 1.65 2002/01/28 00:52:41 steve
|
||||
* Add support for bit select of parameters.
|
||||
* This leads to a NetESelect node and the
|
||||
* vvp code generator to support that.
|
||||
*
|
||||
* Revision 1.64 2002/01/19 19:02:08 steve
|
||||
* Pass back target errors processing conditionals.
|
||||
*
|
||||
* Revision 1.63 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
* Revision 1.62 2001/08/25 23:50:02 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.61 2001/07/27 04:51:44 steve
|
||||
* Handle part select expressions as variants of
|
||||
* NetESignal/IVL_EX_SIGNAL objects, instead of
|
||||
* creating new and useless temporary signals.
|
||||
*
|
||||
* Revision 1.60 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.59 2001/04/22 23:09:46 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.58 2001/04/06 02:28:02 steve
|
||||
* Generate vvp code for functions with ports.
|
||||
*
|
||||
* Revision 1.57 2001/04/02 02:28:12 steve
|
||||
* Generate code for task calls.
|
||||
*
|
||||
* Revision 1.56 2001/03/27 03:31:06 steve
|
||||
* Support error code from target_t::end_design method.
|
||||
*
|
||||
|
||||
@@ -16,73 +16,100 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: eval.cc,v 1.20 2001/02/09 02:49:59 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: eval.cc,v 1.36 2003/06/21 01:21:43 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "netlist.h"
|
||||
# include "compiler.h"
|
||||
|
||||
verinum* PExpr::eval_const(const Design*, const string&) const
|
||||
verinum* PExpr::eval_const(const Design*, const NetScope*) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum* PEBinary::eval_const(const Design*des, const string&path) const
|
||||
verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verinum*l = left_->eval_const(des, path);
|
||||
verinum*l = left_->eval_const(des, scope);
|
||||
if (l == 0) return 0;
|
||||
verinum*r = right_->eval_const(des, path);
|
||||
verinum*r = right_->eval_const(des, scope);
|
||||
if (r == 0) {
|
||||
delete l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum*res;
|
||||
|
||||
switch (op_) {
|
||||
case '+': {
|
||||
assert(l->is_defined());
|
||||
assert(r->is_defined());
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv+rv, l->len());
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
res = new verinum(*l + *r);
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '-': {
|
||||
assert(l->is_defined());
|
||||
assert(r->is_defined());
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv-rv, l->len());
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
res = new verinum(*l - *r);
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '*': {
|
||||
assert(l->is_defined());
|
||||
assert(r->is_defined());
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv * rv, l->len());
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
res = new verinum(*l * *r);
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '/': {
|
||||
assert(l->is_defined());
|
||||
assert(r->is_defined());
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv / rv, l->len());
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv / rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '%': {
|
||||
assert(l->is_defined());
|
||||
assert(r->is_defined());
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv % rv, l->len());
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv % rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'l': {
|
||||
case '>': {
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv > rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '<': {
|
||||
if (l->is_defined() && r->is_defined()) {
|
||||
long lv = l->as_long();
|
||||
long rv = r->as_long();
|
||||
res = new verinum(lv < rv, l->len());
|
||||
} else {
|
||||
res = new verinum(verinum::Vx, l->len());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'l': { // left shift (<<)
|
||||
assert(r->is_defined());
|
||||
unsigned long rv = r->as_ulong();
|
||||
res = new verinum(verinum::V0, l->len());
|
||||
@@ -93,6 +120,17 @@ verinum* PEBinary::eval_const(const Design*des, const string&path) const
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'r': { // right shift (>>)
|
||||
assert(r->is_defined());
|
||||
unsigned long rv = r->as_ulong();
|
||||
res = new verinum(verinum::V0, l->len());
|
||||
if (rv < res->len()) {
|
||||
unsigned cnt = res->len() - rv;
|
||||
for (unsigned idx = 0 ; idx < cnt ; idx += 1)
|
||||
res->set(idx, l->get(idx+rv));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
delete l;
|
||||
@@ -110,42 +148,50 @@ verinum* PEBinary::eval_const(const Design*des, const string&path) const
|
||||
* Evaluate an identifier as a constant expression. This is only
|
||||
* possible if the identifier is that of a parameter.
|
||||
*/
|
||||
verinum* PEIdent::eval_const(const Design*des, const string&path) const
|
||||
verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
const NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
const NetExpr*expr = des->find_parameter(scope, text_);
|
||||
const NetExpr*expr = des->find_parameter(scope, path_);
|
||||
|
||||
if (expr == 0)
|
||||
return 0;
|
||||
|
||||
assert(msb_ == 0);
|
||||
|
||||
if (dynamic_cast<const NetEParam*>(expr)) {
|
||||
cerr << get_line() << ": sorry: I cannot evaluate ``" <<
|
||||
text_ << "'' in this scope: " << scope->name() << endl;
|
||||
const NetEConst*eval = dynamic_cast<const NetEConst*>(expr);
|
||||
if (eval == 0) {
|
||||
cerr << get_line() << ": internal error: Unable to evaluate "
|
||||
<< "constant expression (parameter=" << path_
|
||||
<< "): " << *expr << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const NetEConst*eval = dynamic_cast<const NetEConst*>(expr);
|
||||
assert(eval);
|
||||
|
||||
if (msb_ || lsb_)
|
||||
return 0;
|
||||
|
||||
|
||||
return new verinum(eval->value());
|
||||
}
|
||||
|
||||
verinum* PEFNumber::eval_const(const Design*, const string&) const
|
||||
verinum* PEFNumber::eval_const(const Design*, const NetScope*) const
|
||||
{
|
||||
long val = value_->as_long();
|
||||
return new verinum(val);
|
||||
}
|
||||
|
||||
verinum* PENumber::eval_const(const Design*, const string&) const
|
||||
verinum* PENumber::eval_const(const Design*, const NetScope*) const
|
||||
{
|
||||
return new verinum(value());
|
||||
}
|
||||
|
||||
verinum* PETernary::eval_const(const Design*des, const string&path) const
|
||||
verinum* PEString::eval_const(const Design*, const NetScope*) const
|
||||
{
|
||||
verinum*test = expr_->eval_const(des, path);
|
||||
return new verinum(string(text_));
|
||||
}
|
||||
|
||||
verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verinum*test = expr_->eval_const(des, scope);
|
||||
if (test == 0)
|
||||
return 0;
|
||||
|
||||
@@ -153,9 +199,9 @@ verinum* PETernary::eval_const(const Design*des, const string&path) const
|
||||
delete test;
|
||||
switch (bit) {
|
||||
case verinum::V0:
|
||||
return fal_->eval_const(des, path);
|
||||
return fal_->eval_const(des, scope);
|
||||
case verinum::V1:
|
||||
return tru_->eval_const(des, path);
|
||||
return tru_->eval_const(des, scope);
|
||||
default:
|
||||
return 0;
|
||||
// XXXX It is possible to handle this case if both fal_
|
||||
@@ -163,9 +209,9 @@ verinum* PETernary::eval_const(const Design*des, const string&path) const
|
||||
}
|
||||
}
|
||||
|
||||
verinum* PEUnary::eval_const(const Design*des, const string&path) const
|
||||
verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verinum*val = expr_->eval_const(des, path);
|
||||
verinum*val = expr_->eval_const(des, scope);
|
||||
if (val == 0)
|
||||
return 0;
|
||||
|
||||
@@ -194,6 +240,63 @@ verinum* PEUnary::eval_const(const Design*des, const string&path) const
|
||||
|
||||
/*
|
||||
* $Log: eval.cc,v $
|
||||
* Revision 1.36 2003/06/21 01:21:43 steve
|
||||
* Harmless fixup of warnings.
|
||||
*
|
||||
* Revision 1.35 2003/04/14 03:40:21 steve
|
||||
* Make some effort to preserve bits while
|
||||
* operating on constant values.
|
||||
*
|
||||
* Revision 1.34 2003/03/26 06:16:18 steve
|
||||
* Evaluate > and < in constant expressions.
|
||||
*
|
||||
* Revision 1.33 2003/03/10 23:40:53 steve
|
||||
* Keep parameter constants for the ivl_target API.
|
||||
*
|
||||
* Revision 1.32 2002/10/19 22:59:49 steve
|
||||
* Redo the parameter vector support to allow
|
||||
* parameter names in range expressions.
|
||||
*
|
||||
* Revision 1.31 2002/10/13 05:01:07 steve
|
||||
* More verbose eval_const assert message.
|
||||
*
|
||||
* Revision 1.30 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.29 2002/06/07 02:57:54 steve
|
||||
* Simply give up on constants with indices.
|
||||
*
|
||||
* Revision 1.28 2002/06/06 18:57:04 steve
|
||||
* Better error for identifier index eval.
|
||||
*
|
||||
* Revision 1.27 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.26 2001/12/29 22:10:10 steve
|
||||
* constant eval of arithmetic with x and z.
|
||||
*
|
||||
* Revision 1.25 2001/12/29 00:43:55 steve
|
||||
* Evaluate constant right shifts.
|
||||
*
|
||||
* Revision 1.24 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.23 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.22 2001/11/06 06:11:55 steve
|
||||
* Support more real arithmetic in delay constants.
|
||||
*
|
||||
* Revision 1.21 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.20 2001/02/09 02:49:59 steve
|
||||
* Be more clear about scope of failure.
|
||||
*
|
||||
@@ -214,59 +317,5 @@ verinum* PEUnary::eval_const(const Design*des, const string&path) const
|
||||
*
|
||||
* Revision 1.15 2000/09/07 22:38:13 steve
|
||||
* Support unary + and - in constants.
|
||||
*
|
||||
* Revision 1.14 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.13 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.12 1999/11/30 04:48:17 steve
|
||||
* Handle evaluation of ternary during elaboration.
|
||||
*
|
||||
* Revision 1.11 1999/11/28 23:42:02 steve
|
||||
* NetESignal object no longer need to be NetNode
|
||||
* objects. Let them keep a pointer to NetNet objects.
|
||||
*
|
||||
* Revision 1.10 1999/11/21 20:03:24 steve
|
||||
* Handle multiply in constant expressions.
|
||||
*
|
||||
* Revision 1.9 1999/10/08 17:48:09 steve
|
||||
* Support + in constant expressions.
|
||||
*
|
||||
* Revision 1.8 1999/09/20 02:21:10 steve
|
||||
* Elaborate parameters in phases.
|
||||
*
|
||||
* Revision 1.7 1999/09/18 01:52:48 steve
|
||||
* Remove spurious message.
|
||||
*
|
||||
* Revision 1.6 1999/09/16 04:18:15 steve
|
||||
* elaborate concatenation repeats.
|
||||
*
|
||||
* Revision 1.5 1999/08/06 04:05:28 steve
|
||||
* Handle scope of parameters.
|
||||
*
|
||||
* Revision 1.4 1999/07/17 19:51:00 steve
|
||||
* netlist support for ternary operator.
|
||||
*
|
||||
* Revision 1.3 1999/05/30 01:11:46 steve
|
||||
* Exressions are trees that can duplicate, and not DAGS.
|
||||
*
|
||||
* Revision 1.2 1999/05/10 00:16:58 steve
|
||||
* Parse and elaborate the concatenate operator
|
||||
* in structural contexts, Replace vector<PExpr*>
|
||||
* and list<PExpr*> with svector<PExpr*>, evaluate
|
||||
* constant expressions with parameters, handle
|
||||
* memories as lvalues.
|
||||
*
|
||||
* Parse task declarations, integer types.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:28:58 steve
|
||||
* Introduce verilog to CVS.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2002-2004 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: eval_attrib.cc,v 1.7 2004/02/20 18:53:35 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "util.h"
|
||||
# include "PExpr.h"
|
||||
# include "netlist.h"
|
||||
# include <iostream>
|
||||
# include <assert.h>
|
||||
|
||||
/*
|
||||
* The evaluate_attributes function evaluates the attribute
|
||||
* expressions from the map, and returns a table in a form suitable
|
||||
* for passing to netlist devices.
|
||||
*/
|
||||
|
||||
attrib_list_t* evaluate_attributes(const map<perm_string,PExpr*>&att,
|
||||
unsigned&natt,
|
||||
const Design*des,
|
||||
const NetScope*scope)
|
||||
{
|
||||
natt = att.size();
|
||||
if (natt == 0)
|
||||
return 0;
|
||||
|
||||
attrib_list_t*table = new attrib_list_t [natt];
|
||||
|
||||
unsigned idx = 0;
|
||||
|
||||
typedef map<perm_string,PExpr*>::const_iterator iter_t;
|
||||
for (iter_t cur = att.begin() ; cur != att.end() ; cur ++, idx++) {
|
||||
table[idx].key = (*cur).first;
|
||||
PExpr*exp = (*cur).second;
|
||||
|
||||
/* If the attribute value is given in the source, then
|
||||
evaluate it as a constant. If the value is not
|
||||
given, then assume the value is 1. */
|
||||
verinum*tmp;
|
||||
if (exp)
|
||||
tmp = exp->eval_const(des, scope);
|
||||
else
|
||||
tmp = new verinum(1);
|
||||
|
||||
if (tmp == 0)
|
||||
cerr << "internal error: no result for " << *exp << endl;
|
||||
assert(tmp);
|
||||
|
||||
table[idx].val = *tmp;
|
||||
delete tmp;
|
||||
}
|
||||
|
||||
assert(idx == natt);
|
||||
return table;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: eval_attrib.cc,v $
|
||||
* Revision 1.7 2004/02/20 18:53:35 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.6 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.5 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.4 2002/08/10 21:59:39 steve
|
||||
* The default attribute value is 1.
|
||||
*
|
||||
* Revision 1.3 2002/06/06 18:57:18 steve
|
||||
* Use standard name for iostream.
|
||||
*
|
||||
* Revision 1.2 2002/06/03 03:55:14 steve
|
||||
* compile warnings.
|
||||
*
|
||||
* Revision 1.1 2002/05/23 03:08:51 steve
|
||||
* Add language support for Verilog-2001 attribute
|
||||
* syntax. Hook this support into existing $attribute
|
||||
* handling, and add number and void value types.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
*/
|
||||
|
||||
+719
-193
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
,*
|
||||
hello_vpi.vpi
|
||||
show_vcd.vcd
|
||||
+1035
File diff suppressed because it is too large
Load Diff
+6
-6
@@ -26,21 +26,21 @@
|
||||
* Compile this program with the command:
|
||||
*
|
||||
* iverilog -ohello hello.vl
|
||||
*
|
||||
*
|
||||
* After churning for a little while, the program will create the output
|
||||
* file "hello" which is compiled, linked and ready to run. Run this
|
||||
* program like so:
|
||||
*
|
||||
* ./hello
|
||||
*
|
||||
*
|
||||
* vvp hello
|
||||
*
|
||||
* and the program will print the message to its output. Easy! For
|
||||
* more on how to make the iverilog command work, see the iverilog
|
||||
* manual page.
|
||||
*/
|
||||
|
||||
module main();
|
||||
|
||||
initial
|
||||
|
||||
initial
|
||||
begin
|
||||
$display("Hello, World");
|
||||
$finish ;
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: hello_vpi.c,v 1.3 2002/08/12 01:35:01 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This file contains an example VPI module to demonstrate the tools
|
||||
* to create vpi modules. To compile this module, use the iverilog-vpi
|
||||
* command like so:
|
||||
*
|
||||
* iverilog-vpi hello_vpi.c
|
||||
*
|
||||
* The result is the hello_vpi.vpi module. See the hello_vpi.vl
|
||||
* program for example Verilog code to call this module.
|
||||
*/
|
||||
|
||||
# include <vpi_user.h>
|
||||
|
||||
static int my_hello_calltf(char *xx)
|
||||
{
|
||||
vpi_printf("Hello World, from VPI.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void my_hello_register()
|
||||
{
|
||||
s_vpi_systf_data tf_data;
|
||||
|
||||
tf_data.type = vpiSysTask;
|
||||
tf_data.tfname = "$my_hello";
|
||||
tf_data.calltf = my_hello_calltf;
|
||||
tf_data.compiletf = 0;
|
||||
tf_data.sizetf = 0;
|
||||
vpi_register_systf(&tf_data);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a table of register functions. This table is the external
|
||||
* symbol that the simulator looks for when loading this .vpi module.
|
||||
*/
|
||||
void (*vlog_startup_routines[])() = {
|
||||
my_hello_register,
|
||||
0
|
||||
};
|
||||
/*
|
||||
* $Log: hello_vpi.c,v $
|
||||
* Revision 1.3 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.2 2002/08/11 23:47:04 steve
|
||||
* Add missing Log and Ident strings.
|
||||
*
|
||||
* Revision 1.1 2002/04/18 03:25:16 steve
|
||||
* More examples.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2002 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Here we have the canonical "Hello, World" program written in Verilog,
|
||||
* with VPI. It uses the hello_vpi.vpi module that is compiled from
|
||||
* the hello_vpi.c program also in this directory. See the
|
||||
* hello_vpi.c for instructions on how to compile it.
|
||||
*
|
||||
* Compile this program with the command:
|
||||
*
|
||||
* iverilog -ohello_vpi hello_vpi.vl
|
||||
*
|
||||
* After churning for a little while, the program will create the output
|
||||
* file "hello" which is compiled, linked and ready to run. Run this
|
||||
* program like so:
|
||||
*
|
||||
* vvp -M. -mhello_vpi hello_vpi
|
||||
*
|
||||
* and the program will print the message to its output. Easy! For
|
||||
* more on how to make the iverilog command work, see the iverilog
|
||||
* manual page.
|
||||
*/
|
||||
|
||||
module main();
|
||||
|
||||
initial
|
||||
begin
|
||||
$my_hello;
|
||||
$finish ;
|
||||
end
|
||||
|
||||
endmodule
|
||||
+12
-12
@@ -20,36 +20,36 @@
|
||||
/*
|
||||
* This example program simulates a 16x1 ram, and is used as an
|
||||
* example for using VCD output and waveform viewers.
|
||||
*
|
||||
*
|
||||
* Like any other Verilog simulation, compile this program with the
|
||||
* command:
|
||||
*
|
||||
*
|
||||
* iverilog show_vcd.vl
|
||||
*
|
||||
*
|
||||
* This will generate the show_vcd command in the current directory.
|
||||
* When you run the command, you will see the output from all the
|
||||
* calls to $display, but also there will be a dump file ``show_vcd.vcd''.
|
||||
* The name of this file is set by the statement:
|
||||
*
|
||||
* $dumpfile("show_vcd.vcd");
|
||||
*
|
||||
*
|
||||
* in the main module. The output file uses the standard VCD file format
|
||||
* so can be viewed using off-the-shelf waveform viewers. The remaining
|
||||
* steps describe how to use GTKWave to view the file. If you are using
|
||||
* a different viewer, see the documentation for that tool.
|
||||
*
|
||||
*
|
||||
* To view the output generated by running show_vcd, start the GTKWave
|
||||
* viewer with the command:
|
||||
*
|
||||
* wave show_vcd.vcd
|
||||
*
|
||||
*
|
||||
* gtkwave show_vcd.vcd
|
||||
*
|
||||
* The GTKWave program will display its main window, and show in a small
|
||||
* status box (upper left corner) that it succeeded in loading the dump
|
||||
* file. However, there are no waveforms displayed yet. Select signals to
|
||||
* add to the waveform display using the menu selection:
|
||||
*
|
||||
* "Search --> Signal Search Tree"
|
||||
*
|
||||
*
|
||||
* This will bring up a dialog box that shows in directory tree format
|
||||
* the signals of the program. Select the signals you wish to view, and
|
||||
* click one of the buttons on the bottom of the dialog box to display
|
||||
@@ -60,7 +60,7 @@
|
||||
* $dumpvars system tasks. The $dumpfile task tells the simulation where
|
||||
* to write the VCD output. This task must be called once before the
|
||||
* $dumpvars task is called.
|
||||
*
|
||||
*
|
||||
* The $dumpvars task tells the simulation what variables to write to
|
||||
* the VCD output. The first parameter is how far to descend while
|
||||
* scanning a scope, and the remaining paramters are signals or scope
|
||||
@@ -77,7 +77,7 @@ module ram16x1 (q, d, a, we, wclk);
|
||||
input wclk;
|
||||
|
||||
reg mem[15:0];
|
||||
|
||||
|
||||
assign q = mem[a];
|
||||
always @(posedge wclk) if (we) mem[a] = d;
|
||||
|
||||
@@ -88,7 +88,7 @@ module main;
|
||||
reg d;
|
||||
reg [3:0] a;
|
||||
reg we, wclk;
|
||||
|
||||
|
||||
ram16x1 r1 (q, d, a, we, wclk);
|
||||
|
||||
initial begin
|
||||
|
||||
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* $Id: sqrt-virtex.v,v 1.4 2003/11/25 18:35:31 steve Exp $"
|
||||
*/
|
||||
|
||||
/*
|
||||
* This module is a synthesizeable square-root function. It is also a
|
||||
* detailed example of how to target Xilinx Virtex parts using
|
||||
* Icarus Verilog. In fact, for no particular reason other then to
|
||||
* be excessively specific, I will step through the process of
|
||||
* generating a design for a Spartan-II XC2S15-VQ100, and also how to
|
||||
* generate a generic library part for larger Virtex designs.
|
||||
*
|
||||
* In addition to Icarus Verilog, you will need implementation
|
||||
* software from Xilinx. As of this writing, this example was tested
|
||||
* with Foundation 4.2i, but it should work the same with ISE and
|
||||
* Webpack software.
|
||||
*
|
||||
* This example source contains all the Verilog needed to do
|
||||
* everything described below. We use conditional compilation to
|
||||
* select the bits of Verilog that are needed to perform each specific
|
||||
* task.
|
||||
*
|
||||
* SIMULATE THE DESIGN
|
||||
*
|
||||
* This source file includes a simulation test bench. To compile the
|
||||
* program to include this test bench, use the command line:
|
||||
*
|
||||
* iverilog -DSIMULATE=1 -oa.out sqrt-virtex.v
|
||||
*
|
||||
* This generates the file "a.out" that can then be executed with the
|
||||
* command:
|
||||
*
|
||||
* vvp a.out
|
||||
*
|
||||
* This causes the simulation to run a long set of example sqrt
|
||||
* calculations. Each result is checked by the test bench to assure
|
||||
* that the result is valid. When it is done, the program prints
|
||||
* "PASSED" and finishes the simulation.
|
||||
*
|
||||
* When you take a close look at the "main" module below, you will see
|
||||
* that it uses Verilog constructs that are not synthesizeable. This
|
||||
* is fine, as we will never try to synthesize it.
|
||||
*
|
||||
* LIBRARY PARTS
|
||||
*
|
||||
* One can use the sqrt32 module to generate an EDIF file suitable for
|
||||
* use as a library part. This part can be imported to the Xilinx
|
||||
* schematic editor, then placed like any other pre-existing
|
||||
* macro. One can also pass the generated EDIF as a precompiled macro
|
||||
* that other designers may use as they see fit.
|
||||
*
|
||||
* To make an EDIF file from the sqrt32 module, execute the command:
|
||||
*
|
||||
* iverilog -osqrt32.edf -tfpga -parch=virtex sqrt-virtex.v
|
||||
*
|
||||
* The -parch=virtex tells the code generator to generate code for the
|
||||
* virtex architecture family (we don't yet care what specific part)
|
||||
* and the -osqrt32.edf places the output into the file
|
||||
* sqrt32.edf.
|
||||
*
|
||||
* Without any preprocessor directives, the only module is the sqrt32
|
||||
* module, so sqrt32 is compiled as the root. The ports of the module
|
||||
* are automatically made into ports of the sqrt32.edf netlist, and
|
||||
* the contents of the sqrt32 module are connected approprately.
|
||||
*
|
||||
* COMPLETE CHIP DESIGNS
|
||||
*
|
||||
* To make a complete chip design, there are other bits that need to
|
||||
* be accounted for. Signals must be assigned to pins, and some
|
||||
* special devices may need to be created. We also want to write into
|
||||
* the EDIF file complete part information so that the implementation
|
||||
* tools know how to route the complete design. The command to compile
|
||||
* for our target part is:
|
||||
*
|
||||
* iverilog -ochip.edf -tfpga \
|
||||
* -parch=virtex -ppart=XC2S15-VQ100 \
|
||||
* -DMAKE_CHIP=1 sqrt-virtex.v
|
||||
*
|
||||
* This command uses the "chip" module as the root. This module in
|
||||
* turn has ports that are destined to be the pins of the completed
|
||||
* part. The -ppart= option gives complete part information, that is
|
||||
* in turn written into the EDIF file. This saves us the drudgery of
|
||||
* repeating that part number for later commands.
|
||||
*
|
||||
* The next steps involve Xilinx software, and to talk to Xilinx
|
||||
* software, the netlist must be in the form of an "ngd" file, a
|
||||
* binary netlist format. The command:
|
||||
*
|
||||
* ngdbuild chip.edf chip.ngd
|
||||
*
|
||||
* does the trick. The input to ngdbuild is the chip.edf file created
|
||||
* by Icarus Verilog, and the output is the chip.ngd file that the
|
||||
* implementation tools may read. From this point, it is best to refer
|
||||
* to Xilinx documentation for the software you are using, but the
|
||||
* quick summary is:
|
||||
*
|
||||
* map -o map.ncd chip.ngd
|
||||
* par -w map.ncd chip.ncd
|
||||
*
|
||||
* The result of this sequence of commands is the chip.ncd file that
|
||||
* is ready to be viewed by FPGA Edit, or converted to a bit stream,
|
||||
* or whatever.
|
||||
*
|
||||
* POST MAP SIMULATION
|
||||
*
|
||||
* Warm fuzzies are good, and retesting your design after the part
|
||||
* is mapped by the Xilinx backend tools is a cheap source of fuzzies.
|
||||
* The command to make a Verilog file out of the mapped design is:
|
||||
*
|
||||
* ngd2ver chip.ngd chip_root.v
|
||||
*
|
||||
* This command creates from the chip.ngd the file "chip_root.v" that
|
||||
* contains Verilog code that simulates the mapped design. This output
|
||||
* Verilog has the single root module "chip_root", which came from the
|
||||
* name of the root module when we were making hte EDIF file in the
|
||||
* first place. The module has ports named just line the ports of the
|
||||
* chip_root module below.
|
||||
*
|
||||
* The generated Verilog uses the library in the directory
|
||||
* $(XILINX)/verilog/src/simprims. This directory comes with the ISE
|
||||
* WebPACK installation that you are using. Icarus Verilog is able to
|
||||
* simulate using that library.
|
||||
*
|
||||
* To compile a post-map simulation of the chip_root.v, use the
|
||||
* command:
|
||||
*
|
||||
* iverilog -DSIMULATE -DPOST_MAP -ob.out \
|
||||
* -y $(XILINX)/verilog/src/simprims \
|
||||
* sqrt-virtex.v chip_root.v \
|
||||
* $(XILINX)/verilog/src/glbl.v
|
||||
*
|
||||
* This command line generates b.out from the source files
|
||||
* sqrt-virtex.v and chip_root.v (the latter from ngd2ver)
|
||||
* and the "-y <path>" flag specifies the library directory that will
|
||||
* be needed. The glbl.v source file is also included to provide the
|
||||
* GSR and related signals.
|
||||
*
|
||||
* The POST_MAP compiler directive causes the GSR manipulations
|
||||
* included in the test bench to be compiled in, to simulate the chip
|
||||
* startup. Other then that, the test bench runs the post-map design
|
||||
* the same way the pre-synthesis design works.
|
||||
*
|
||||
* Run this design with the command:
|
||||
*
|
||||
* vvp b.out
|
||||
*
|
||||
* And there you go.
|
||||
*/
|
||||
|
||||
`ifndef POST_MAP
|
||||
/*
|
||||
* This module approximates the square root of an unsigned 32bit
|
||||
* number. The algorithm works by doing a bit-wise binary search.
|
||||
* Starting from the most significant bit, the accumulated value
|
||||
* tries to put a 1 in the bit position. If that makes the square
|
||||
* too big for the input, the bit is left zero, otherwise it is set
|
||||
* in the result. This continues for each bit, decreasing in
|
||||
* significance, until all the bits are calculated or all the
|
||||
* remaining bits are zero.
|
||||
*
|
||||
* Since the result is an integer, this function really calculates
|
||||
* value of the expression:
|
||||
*
|
||||
* x = floor(sqrt(y))
|
||||
*
|
||||
* where sqrt(y) is the exact square root of y and floor(N) is the
|
||||
* largest integer <= N.
|
||||
*
|
||||
* For 32bit numbers, this will never run more then 16 iterations,
|
||||
* which amounts to 16 clocks.
|
||||
*/
|
||||
|
||||
module sqrt32(clk, rdy, reset, x, .y(acc));
|
||||
input clk;
|
||||
output rdy;
|
||||
input reset;
|
||||
|
||||
input [31:0] x;
|
||||
output [15:0] acc;
|
||||
|
||||
|
||||
// acc holds the accumulated result, and acc2 is the accumulated
|
||||
// square of the accumulated result.
|
||||
reg [15:0] acc;
|
||||
reg [31:0] acc2;
|
||||
|
||||
// Keep track of which bit I'm working on.
|
||||
reg [4:0] bitl;
|
||||
wire [15:0] bit = 1 << bitl;
|
||||
wire [31:0] bit2 = 1 << (bitl << 1);
|
||||
|
||||
// The output is ready when the bitl counter underflows.
|
||||
wire rdy = bitl[4];
|
||||
|
||||
// guess holds the potential next values for acc, and guess2 holds
|
||||
// the square of that guess. The guess2 calculation is a little bit
|
||||
// subtle. The idea is that:
|
||||
//
|
||||
// guess2 = (acc + bit) * (acc + bit)
|
||||
// = (acc * acc) + 2*acc*bit + bit*bit
|
||||
// = acc2 + 2*acc*bit + bit2
|
||||
// = acc2 + 2 * (acc<<bitl) + bit
|
||||
//
|
||||
// This works out using shifts because bit and bit2 are known to
|
||||
// have only a single bit in them.
|
||||
wire [15:0] guess = acc | bit;
|
||||
wire [31:0] guess2 = acc2 + bit2 + ((acc << bitl) << 1);
|
||||
|
||||
(* ivl_synthesis_on *)
|
||||
always @(posedge clk or posedge reset)
|
||||
if (reset) begin
|
||||
acc = 0;
|
||||
acc2 = 0;
|
||||
bitl = 15;
|
||||
end else begin
|
||||
if (guess2 <= x) begin
|
||||
acc <= guess;
|
||||
acc2 <= guess2;
|
||||
end
|
||||
bitl <= bitl - 5'd1;
|
||||
end
|
||||
|
||||
endmodule // sqrt32
|
||||
|
||||
`endif // `ifndef POST_MAP
|
||||
|
||||
`ifdef SIMULATE
|
||||
/*
|
||||
* This module is a test bench for the sqrt32 module. It runs some
|
||||
* test input values through the sqrt32 module, and checks that the
|
||||
* output is valid. If an invalid output is generated, print and
|
||||
* error message and stop immediately. If all the tested values pass,
|
||||
* then print PASSED after the test is complete.
|
||||
*/
|
||||
module main;
|
||||
|
||||
reg [31:0] x;
|
||||
reg clk, reset;
|
||||
|
||||
wire [15:0] y;
|
||||
wire rdy;
|
||||
|
||||
`ifdef POST_MAP
|
||||
chip_root dut(.clk(clk), .reset(reset), .rdy(rdy), .x(x), .y(y));
|
||||
`else
|
||||
sqrt32 dut(.clk(clk), .reset(reset), .rdy(rdy), .x(x), .y(y));
|
||||
`endif
|
||||
|
||||
(* ivl_synthesis_off *)
|
||||
always #5 clk = !clk;
|
||||
|
||||
task reset_dut;
|
||||
begin
|
||||
reset = 1;
|
||||
@(posedge clk) ;
|
||||
#1 reset = 0;
|
||||
@(negedge clk) ;
|
||||
end
|
||||
endtask // reset_dut
|
||||
|
||||
task crank_dut;
|
||||
begin
|
||||
while (rdy == 0) begin
|
||||
@(posedge clk) /* wait */;
|
||||
end
|
||||
end
|
||||
endtask // crank_dut
|
||||
|
||||
`ifdef POST_MAP
|
||||
reg GSR;
|
||||
assign glbl.GSR = GSR;
|
||||
`endif
|
||||
|
||||
integer idx;
|
||||
|
||||
(* ivl_synthesis_off *)
|
||||
initial begin
|
||||
reset = 0;
|
||||
clk = 0;
|
||||
|
||||
/* If doing a post-map simulation, when we need to wiggle
|
||||
The GSR bit to simulate chip power-up. */
|
||||
`ifdef POST_MAP
|
||||
GSR = 1;
|
||||
#100 GSR = 0;
|
||||
`endif
|
||||
#100 x = 1;
|
||||
reset_dut;
|
||||
crank_dut;
|
||||
$display("x=%d, y=%d", x, y);
|
||||
|
||||
x = 3;
|
||||
reset_dut;
|
||||
crank_dut;
|
||||
$display("x=%d, y=%d", x, y);
|
||||
|
||||
x = 4;
|
||||
reset_dut;
|
||||
crank_dut;
|
||||
$display("x=%d, y=%d", x, y);
|
||||
|
||||
for (idx = 0 ; idx < 200 ; idx = idx + 1) begin
|
||||
x = $random;
|
||||
reset_dut;
|
||||
crank_dut;
|
||||
$display("x=%d, y=%d", x, y);
|
||||
|
||||
if (x < (y * y)) begin
|
||||
$display("ERROR: y is too big");
|
||||
$finish;
|
||||
end
|
||||
|
||||
if (x > ((y + 1)*(y + 1))) begin
|
||||
$display("ERROR: y is too small");
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
$display("PASSED");
|
||||
$finish;
|
||||
end
|
||||
|
||||
endmodule // main
|
||||
`endif
|
||||
|
||||
`ifdef MAKE_CHIP
|
||||
/*
|
||||
* This module represents the chip packaging that we intend to
|
||||
* generate. We bind pins here, and route the clock to the global
|
||||
* clock buffer.
|
||||
*/
|
||||
module chip_root(clk, rdy, reset, x, y);
|
||||
input clk;
|
||||
output rdy;
|
||||
input reset;
|
||||
|
||||
input [31:0] x;
|
||||
output [15:0] y;
|
||||
|
||||
wire clk_int;
|
||||
|
||||
(* cellref="BUFG:O,I" *)
|
||||
buf gbuf (clk_int, clk);
|
||||
|
||||
sqrt32 dut(.clk(clk_int), .reset(reset), .rdy(rdy), .x(x), .y(y));
|
||||
|
||||
/* Assign the clk to GCLK0, which is on pin P39. */
|
||||
$attribute(clk, "PAD", "P39");
|
||||
|
||||
// We don't care where the remaining pins go, so set the pin number
|
||||
// to 0. This tells the implementation tools that we want a PAD,
|
||||
// but we don't care which. Also note the use of a comma (,)
|
||||
// separated list to assign pins to the bits of a vector.
|
||||
$attribute(rdy, "PAD", "0");
|
||||
$attribute(reset, "PAD", "0");
|
||||
$attribute(x, "PAD", "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0");
|
||||
$attribute(y, "PAD", "0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0");
|
||||
|
||||
endmodule // chip_root
|
||||
|
||||
`endif
|
||||
+5
-5
@@ -16,7 +16,7 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* $Id: sqrt.vl,v 1.3 2000/11/04 01:53:24 steve Exp $"
|
||||
* $Id: sqrt.vl,v 1.4 2004/10/04 01:10:56 steve Exp $"
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -97,8 +97,8 @@ module sqrt32(clk, rdy, reset, x, .y(acc));
|
||||
bitl = 15;
|
||||
end
|
||||
endtask
|
||||
|
||||
initial clear;
|
||||
|
||||
initial clear;
|
||||
|
||||
always @(reset or posedge clk)
|
||||
if (reset)
|
||||
@@ -121,14 +121,14 @@ module main;
|
||||
wire rdy;
|
||||
|
||||
sqrt32 root(.clk(clk), .rdy(rdy), .reset(reset), .x(value), .y(result));
|
||||
|
||||
|
||||
always #5 clk = ~clk;
|
||||
|
||||
always @(posedge rdy) begin
|
||||
$display("sqrt(%d) --> %d", value, result);
|
||||
$finish;
|
||||
end
|
||||
|
||||
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
|
||||
+2
-2
@@ -72,8 +72,8 @@ module main;
|
||||
// These attribute commands assign pins to the listed wires.
|
||||
// This can be done to wires and registers, as internally both
|
||||
// are treated as named signals. It doesn't work (yet) on vectors,
|
||||
// though, so break out the vectors with scaler assignments.
|
||||
|
||||
// though, so break out the vectors with scalar assignments.
|
||||
|
||||
assign a[0] = a0;
|
||||
assign a[1] = a1;
|
||||
assign a[2] = a2;
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
|
||||
// This example describes a 16x1 RAM that can be synthesized into
|
||||
// a CLB ram in a Xilinx FPGA.
|
||||
|
||||
module ram16x1 (q, d, a, we, wclk);
|
||||
output q;
|
||||
input d;
|
||||
input [3:0] a;
|
||||
input we;
|
||||
input wclk;
|
||||
|
||||
reg mem[15:0];
|
||||
|
||||
assign q = mem[a];
|
||||
always @(posedge wclk) if (we) mem[a] = d;
|
||||
|
||||
endmodule /* ram16x1 */
|
||||
|
||||
module main;
|
||||
wire q;
|
||||
reg d;
|
||||
reg [3:0] a;
|
||||
reg we, wclk;
|
||||
|
||||
ram16x1 r1 (q, d, a, we, wclk);
|
||||
|
||||
initial begin
|
||||
$monitor("q = %b", q);
|
||||
d = 0;
|
||||
wclk = 0;
|
||||
a = 5;
|
||||
we = 1;
|
||||
#1 wclk = 1;
|
||||
#1 wclk = 0;
|
||||
end
|
||||
endmodule /* main */
|
||||
+541
-111
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2004 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
|
||||
@@ -16,10 +16,14 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: expr_synth.cc,v 1.20 2001/02/15 06:59:36 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: expr_synth.cc,v 1.59 2004/06/30 02:16:26 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
@@ -38,17 +42,24 @@ NetNet* NetEBAdd::synthesize(Design*des)
|
||||
{
|
||||
assert((op()=='+') || (op()=='-'));
|
||||
|
||||
string path = des->local_symbol("SYNTH");
|
||||
NetNet*lsig = left_->synthesize(des);
|
||||
NetNet*rsig = right_->synthesize(des);
|
||||
|
||||
|
||||
assert(expr_width() >= lsig->pin_count());
|
||||
assert(expr_width() >= rsig->pin_count());
|
||||
|
||||
lsig = pad_to_width(des, lsig, expr_width());
|
||||
rsig = pad_to_width(des, rsig, expr_width());
|
||||
|
||||
assert(lsig->pin_count() == rsig->pin_count());
|
||||
unsigned width=lsig->pin_count();
|
||||
|
||||
perm_string path = lsig->scope()->local_symbol();
|
||||
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width);
|
||||
osig->local_flag(true);
|
||||
|
||||
string oname = des->local_symbol(path);
|
||||
NetAddSub *adder = new NetAddSub(oname, width);
|
||||
perm_string oname = osig->scope()->local_symbol();
|
||||
NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width);
|
||||
for (unsigned idx = 0 ; idx < width; idx += 1) {
|
||||
connect(lsig->pin(idx), adder->pin_DataA(idx));
|
||||
connect(rsig->pin(idx), adder->pin_DataB(idx));
|
||||
@@ -58,10 +69,10 @@ NetNet* NetEBAdd::synthesize(Design*des)
|
||||
|
||||
switch (op()) {
|
||||
case '+':
|
||||
adder->attribute("LPM_Direction", "ADD");
|
||||
adder->attribute(perm_string::literal("LPM_Direction"), verinum("ADD"));
|
||||
break;
|
||||
case '-':
|
||||
adder->attribute("LPM_Direction", "SUB");
|
||||
adder->attribute(perm_string::literal("LPM_Direction"), verinum("SUB"));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -83,15 +94,46 @@ NetNet* NetEBBits::synthesize(Design*des)
|
||||
assert(scope);
|
||||
string path = des->local_symbol(scope->name());
|
||||
|
||||
if (lsig->pin_count() != rsig->pin_count()) {
|
||||
cerr << get_line() << ": internal error: bitwise (" << op_
|
||||
<< ") widths do not match: " << lsig->pin_count()
|
||||
<< " != " << rsig->pin_count() << endl;
|
||||
cerr << get_line() << ": : width="
|
||||
<< lsig->pin_count() << ": " << *left_ << endl;
|
||||
cerr << get_line() << ": : width="
|
||||
<< rsig->pin_count() << ": " << *right_ << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(lsig->pin_count() == rsig->pin_count());
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT,
|
||||
lsig->pin_count());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, lsig->pin_count());
|
||||
osig->local_flag(true);
|
||||
|
||||
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) {
|
||||
string oname = des->local_symbol(path);
|
||||
perm_string oname = scope->local_symbol();
|
||||
NetLogic*gate;
|
||||
|
||||
/* If the rsig bit is constant, then look for special
|
||||
cases that I can use to reduce the generated
|
||||
logic. If I find one, then handle it immediately and
|
||||
skip the rest of the processing of this bit. */
|
||||
if (rsig->pin(idx).nexus()->drivers_constant()) {
|
||||
verinum::V bval = rsig->pin(idx).nexus()->driven_value();
|
||||
|
||||
/* (A & 0) is (0) */
|
||||
if ((op() == '&') && bval == verinum::V0) {
|
||||
connect(osig->pin(idx), rsig->pin(idx));
|
||||
continue;
|
||||
}
|
||||
|
||||
/* (A & 1) is A */
|
||||
if ((op() == '&') && bval == verinum::V1) {
|
||||
connect(osig->pin(idx), lsig->pin(idx));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
switch (op()) {
|
||||
case '&':
|
||||
gate = new NetLogic(scope, oname, 3, NetLogic::AND);
|
||||
@@ -124,12 +166,82 @@ NetNet* NetEBBits::synthesize(Design*des)
|
||||
|
||||
NetNet* NetEBComp::synthesize(Design*des)
|
||||
{
|
||||
NetEConst*lcon = reinterpret_cast<NetEConst*>(left_);
|
||||
NetEConst*rcon = reinterpret_cast<NetEConst*>(right_);
|
||||
|
||||
/* Handle the special case where one of the inputs is constant
|
||||
0. We can use an OR gate to do the comparison. Synthesize
|
||||
the non-const side as normal, then or(nor) the signals
|
||||
together to get result. */
|
||||
if ((rcon && (rcon->value() == verinum(0UL,rcon->expr_width())))
|
||||
|| (lcon && (lcon->value() == verinum(0UL,lcon->expr_width())))) {
|
||||
|
||||
NetNet*lsig = rcon
|
||||
? left_->synthesize(des)
|
||||
: right_->synthesize(des);
|
||||
NetScope*scope = lsig->scope();
|
||||
assert(scope);
|
||||
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, 1);
|
||||
osig->local_flag(true);
|
||||
|
||||
NetLogic*gate;
|
||||
switch (op_) {
|
||||
case 'e':
|
||||
case 'E':
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
lsig->pin_count()+1, NetLogic::NOR);
|
||||
break;
|
||||
case 'n':
|
||||
case 'N':
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
lsig->pin_count()+1, NetLogic::OR);
|
||||
break;
|
||||
|
||||
case '>':
|
||||
/* sig > 0 is true if any bit in sig is set. This
|
||||
is very much like sig != 0. (0 > sig) shouldn't
|
||||
happen. */
|
||||
if (rcon) {
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
lsig->pin_count()+1, NetLogic::OR);
|
||||
} else {
|
||||
assert(0);
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
lsig->pin_count()+1, NetLogic::NOR);
|
||||
}
|
||||
break;
|
||||
|
||||
case '<':
|
||||
/* 0 < sig is handled like sig > 0. */
|
||||
if (! rcon) {
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
lsig->pin_count()+1, NetLogic::OR);
|
||||
} else {
|
||||
assert(0);
|
||||
gate = new NetLogic(scope, scope->local_symbol(),
|
||||
lsig->pin_count()+1, NetLogic::NOR);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
|
||||
connect(gate->pin(idx+1), lsig->pin(idx));
|
||||
|
||||
des->add_node(gate);
|
||||
return osig;
|
||||
}
|
||||
|
||||
NetNet*lsig = left_->synthesize(des);
|
||||
NetNet*rsig = right_->synthesize(des);
|
||||
|
||||
NetScope*scope = lsig->scope();
|
||||
assert(scope);
|
||||
string path = des->local_symbol(scope->name());
|
||||
|
||||
unsigned width = lsig->pin_count();
|
||||
if (rsig->pin_count() > lsig->pin_count())
|
||||
@@ -138,13 +250,14 @@ NetNet* NetEBComp::synthesize(Design*des)
|
||||
lsig = pad_to_width(des, lsig, width);
|
||||
rsig = pad_to_width(des, rsig, width);
|
||||
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, 1);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, 1);
|
||||
osig->local_flag(true);
|
||||
|
||||
/* Handle the special case of a single bit equality
|
||||
operation. Make an XNOR gate instead of a comparator. */
|
||||
if ((width == 1) && ((op_ == 'e') || (op_ == 'E'))) {
|
||||
NetLogic*gate = new NetLogic(scope, des->local_symbol(path),
|
||||
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
|
||||
3, NetLogic::XNOR);
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
connect(gate->pin(1), lsig->pin(0));
|
||||
@@ -157,7 +270,7 @@ NetNet* NetEBComp::synthesize(Design*des)
|
||||
operation. This is similar to single bit equality, but uses
|
||||
an XOR instead of an XNOR gate. */
|
||||
if ((width == 1) && ((op_ == 'n') || (op_ == 'N'))) {
|
||||
NetLogic*gate = new NetLogic(scope, des->local_symbol(path),
|
||||
NetLogic*gate = new NetLogic(scope, scope->local_symbol(),
|
||||
3, NetLogic::XOR);
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
connect(gate->pin(1), lsig->pin(0));
|
||||
@@ -167,7 +280,7 @@ NetNet* NetEBComp::synthesize(Design*des)
|
||||
}
|
||||
|
||||
|
||||
NetCompare*dev = new NetCompare(des->local_symbol(path), width);
|
||||
NetCompare*dev = new NetCompare(scope, scope->local_symbol(), width);
|
||||
des->add_node(dev);
|
||||
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
|
||||
@@ -209,12 +322,102 @@ NetNet* NetEBComp::synthesize(Design*des)
|
||||
return osig;
|
||||
}
|
||||
|
||||
NetNet* NetEBMult::synthesize(Design*des)
|
||||
{
|
||||
NetNet*lsig = left_->synthesize(des);
|
||||
NetNet*rsig = right_->synthesize(des);
|
||||
|
||||
if (lsig == 0)
|
||||
return 0;
|
||||
|
||||
if (rsig == 0)
|
||||
return 0;
|
||||
|
||||
NetScope*scope = lsig->scope();
|
||||
assert(scope);
|
||||
|
||||
NetMult*mult = new NetMult(scope, scope->local_symbol(),
|
||||
expr_width(),
|
||||
lsig->pin_count(),
|
||||
rsig->pin_count());
|
||||
des->add_node(mult);
|
||||
|
||||
mult->set_signed( has_sign() );
|
||||
mult->set_line(*this);
|
||||
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
|
||||
connect(mult->pin_DataA(idx), lsig->pin(idx));
|
||||
|
||||
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
|
||||
connect(mult->pin_DataB(idx), rsig->pin(idx));
|
||||
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, expr_width());
|
||||
osig->local_flag(true);
|
||||
|
||||
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
|
||||
connect(mult->pin_Result(idx), osig->pin(idx));
|
||||
|
||||
return osig;
|
||||
}
|
||||
|
||||
NetNet* NetEBDiv::synthesize(Design*des)
|
||||
{
|
||||
cerr << get_line() << ": internal error: cannot synthesize division: "
|
||||
<< *this << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
NetNet*lsig = left_->synthesize(des);
|
||||
NetNet*rsig = right_->synthesize(des);
|
||||
|
||||
NetScope*scope = lsig->scope();
|
||||
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, expr_width());
|
||||
osig->local_flag(true);
|
||||
|
||||
switch (op()) {
|
||||
|
||||
case '/': {
|
||||
NetDivide*div = new NetDivide(scope, scope->local_symbol(),
|
||||
expr_width(),
|
||||
lsig->pin_count(),
|
||||
rsig->pin_count());
|
||||
des->add_node(div);
|
||||
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
|
||||
connect(div->pin_DataA(idx), lsig->pin(idx));
|
||||
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
|
||||
connect(div->pin_DataB(idx), rsig->pin(idx));
|
||||
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
|
||||
connect(div->pin_Result(idx), osig->pin(idx));
|
||||
break;
|
||||
}
|
||||
|
||||
case '%': {
|
||||
NetModulo*div = new NetModulo(scope, scope->local_symbol(),
|
||||
expr_width(),
|
||||
lsig->pin_count(),
|
||||
rsig->pin_count());
|
||||
des->add_node(div);
|
||||
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
|
||||
connect(div->pin_DataA(idx), lsig->pin(idx));
|
||||
for (unsigned idx = 0 ; idx < rsig->pin_count() ; idx += 1)
|
||||
connect(div->pin_DataB(idx), rsig->pin(idx));
|
||||
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1)
|
||||
connect(div->pin_Result(idx), osig->pin(idx));
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "NetEBDiv has unexpeced op() code: "
|
||||
<< op() << endl;
|
||||
des->errors += 1;
|
||||
|
||||
delete osig;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return osig;
|
||||
}
|
||||
|
||||
NetNet* NetEBLogic::synthesize(Design*des)
|
||||
@@ -230,9 +433,9 @@ NetNet* NetEBLogic::synthesize(Design*des)
|
||||
|
||||
NetScope*scope = lsig->scope();
|
||||
assert(scope);
|
||||
string path = des->local_symbol(scope->name());
|
||||
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, 1);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, 1);
|
||||
osig->local_flag(true);
|
||||
|
||||
|
||||
@@ -242,12 +445,11 @@ NetNet* NetEBLogic::synthesize(Design*des)
|
||||
comparison with a single wide OR gate. So handle this
|
||||
magically. */
|
||||
|
||||
string oname = des->local_symbol(path);
|
||||
NetLogic*olog;
|
||||
perm_string oname = scope->local_symbol();
|
||||
|
||||
olog = new NetLogic(scope, oname,
|
||||
lsig->pin_count()+rsig->pin_count()+1,
|
||||
NetLogic::OR);
|
||||
NetLogic*olog = new NetLogic(scope, oname,
|
||||
lsig->pin_count()+rsig->pin_count()+1,
|
||||
NetLogic::OR);
|
||||
|
||||
connect(osig->pin(0), olog->pin(0));
|
||||
|
||||
@@ -267,7 +469,7 @@ NetNet* NetEBLogic::synthesize(Design*des)
|
||||
/* Create the logic AND gate. This is a single bit
|
||||
output, with inputs for each of the operands. */
|
||||
NetLogic*olog;
|
||||
string oname = des->local_symbol(path);
|
||||
perm_string oname = scope->local_symbol();
|
||||
|
||||
olog = new NetLogic(scope, oname, 3, NetLogic::AND);
|
||||
|
||||
@@ -285,36 +487,137 @@ NetNet* NetEBLogic::synthesize(Design*des)
|
||||
connect(lsig->pin(0), olog->pin(1));
|
||||
|
||||
assert(rsig->pin_count() == 1);
|
||||
connect(lsig->pin(0), olog->pin(2));
|
||||
connect(rsig->pin(0), olog->pin(2));
|
||||
}
|
||||
|
||||
|
||||
return osig;
|
||||
}
|
||||
|
||||
NetNet* NetEBShift::synthesize(Design*des)
|
||||
{
|
||||
if (! dynamic_cast<NetEConst*>(right_)) {
|
||||
NetExpr*tmp = right_->eval_tree();
|
||||
if (tmp) {
|
||||
delete right_;
|
||||
right_ = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
NetNet*lsig = left_->synthesize(des);
|
||||
if (lsig == 0)
|
||||
return 0;
|
||||
|
||||
bool right_flag = op_ == 'r' || op_ == 'R';
|
||||
bool signed_flag = op_ == 'R';
|
||||
|
||||
NetScope*scope = lsig->scope();
|
||||
|
||||
/* Detect the special case where the shift amount is
|
||||
constant. Evaluate the shift amount, and simply reconnect
|
||||
the left operand to the output, but shifted. */
|
||||
if (NetEConst*rcon = dynamic_cast<NetEConst*>(right_)) {
|
||||
verinum shift_v = rcon->value();
|
||||
long shift = shift_v.as_long();
|
||||
|
||||
if (op() == 'r')
|
||||
shift = 0-shift;
|
||||
|
||||
if (shift == 0)
|
||||
return lsig;
|
||||
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, expr_width());
|
||||
osig->local_flag(true);
|
||||
|
||||
NetConst*zcon = new NetConst(scope, scope->local_symbol(),
|
||||
verinum::V0);
|
||||
des->add_node(zcon);
|
||||
NetNet*zsig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, 1);
|
||||
connect(zcon->pin(0), zsig->pin(0));
|
||||
|
||||
if (shift > 0) {
|
||||
unsigned long ushift = shift;
|
||||
for (unsigned idx = 0; idx < osig->pin_count(); idx += 1)
|
||||
if (idx < ushift) {
|
||||
connect(osig->pin(idx), zsig->pin(0));
|
||||
} else {
|
||||
connect(osig->pin(idx), lsig->pin(idx-ushift));
|
||||
}
|
||||
} else {
|
||||
unsigned long dshift = 0-shift;
|
||||
for (unsigned idx = 0; idx < osig->pin_count() ; idx += 1)
|
||||
if (idx+dshift < lsig->pin_count())
|
||||
connect(osig->pin(idx), lsig->pin(idx+dshift));
|
||||
else
|
||||
connect(osig->pin(idx), zsig->pin(0));
|
||||
}
|
||||
|
||||
|
||||
return osig;
|
||||
}
|
||||
|
||||
NetNet*rsig = right_->synthesize(des);
|
||||
if (rsig == 0)
|
||||
return 0;
|
||||
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, expr_width());
|
||||
osig->local_flag(true);
|
||||
|
||||
assert(op() == 'l');
|
||||
NetCLShift*dev = new NetCLShift(scope, scope->local_symbol(),
|
||||
osig->pin_count(),
|
||||
rsig->pin_count(),
|
||||
right_flag, signed_flag);
|
||||
des->add_node(dev);
|
||||
|
||||
for (unsigned idx = 0 ; idx < dev->width() ; idx += 1)
|
||||
connect(dev->pin_Result(idx), osig->pin(idx));
|
||||
|
||||
assert(lsig->pin_count() >= dev->width());
|
||||
for (unsigned idx = 0 ; idx < dev->width() ; idx += 1)
|
||||
connect(dev->pin_Data(idx), lsig->pin(idx));
|
||||
|
||||
for (unsigned idx = 0 ; idx < dev->width_dist() ; idx += 1)
|
||||
connect(dev->pin_Distance(idx), rsig->pin(idx));
|
||||
|
||||
return osig;
|
||||
}
|
||||
|
||||
NetNet* NetEConcat::synthesize(Design*des)
|
||||
{
|
||||
NetScope*scope = des->find_root_scope();
|
||||
assert(scope);
|
||||
assert(repeat_ == 1);
|
||||
/* First, synthesize the operands. */
|
||||
NetNet**tmp = new NetNet*[parms_.count()];
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
|
||||
tmp[idx] = parms_[idx]->synthesize(des);
|
||||
|
||||
string path = des->local_symbol("SYNTH");
|
||||
assert(tmp[0]);
|
||||
NetScope*scope = tmp[0]->scope();
|
||||
assert(scope);
|
||||
|
||||
/* Make a NetNet object to carry the output vector. */
|
||||
perm_string path = scope->local_symbol();
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width());
|
||||
osig->local_flag(true);
|
||||
|
||||
/* Connect the output vector to the operands. */
|
||||
unsigned obit = 0;
|
||||
for (unsigned idx = parms_.count() ; idx > 0 ; idx -= 1) {
|
||||
NetNet*tmp = parms_[idx-1]->synthesize(des);
|
||||
|
||||
for (unsigned bit = 0 ; bit < tmp->pin_count() ; bit += 1) {
|
||||
connect(osig->pin(obit), tmp->pin(bit));
|
||||
assert(tmp[idx-1]);
|
||||
|
||||
for (unsigned bit = 0; bit < tmp[idx-1]->pin_count(); bit += 1) {
|
||||
connect(osig->pin(obit), tmp[idx-1]->pin(bit));
|
||||
obit += 1;
|
||||
}
|
||||
|
||||
if (tmp->local_flag() && tmp->get_eref() == 0)
|
||||
delete tmp;
|
||||
if (tmp[idx-1]->local_flag() && tmp[idx-1]->get_refs() == 0)
|
||||
delete tmp[idx-1];
|
||||
}
|
||||
|
||||
delete[]tmp;
|
||||
return osig;
|
||||
}
|
||||
|
||||
@@ -323,12 +626,13 @@ NetNet* NetEConst::synthesize(Design*des)
|
||||
NetScope*scope = des->find_root_scope();
|
||||
assert(scope);
|
||||
|
||||
string path = des->local_symbol("SYNTH");
|
||||
perm_string path = scope->local_symbol();
|
||||
unsigned width=expr_width();
|
||||
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
|
||||
osig->local_flag(true);
|
||||
NetConst*con = new NetConst(des->local_symbol(path), value());
|
||||
osig->set_signed(has_sign());
|
||||
NetConst*con = new NetConst(scope, scope->local_symbol(), value());
|
||||
for (unsigned idx = 0 ; idx < width; idx += 1)
|
||||
connect(osig->pin(idx), con->pin(idx));
|
||||
|
||||
@@ -336,6 +640,14 @@ NetNet* NetEConst::synthesize(Design*des)
|
||||
return osig;
|
||||
}
|
||||
|
||||
NetNet* NetECReal::synthesize(Design*des)
|
||||
{
|
||||
cerr << get_line() << ": error: Real constants are "
|
||||
<< "not synthesizable." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* The bitwise unary logic operator (there is only one) is turned
|
||||
* into discrete gates just as easily as the binary ones above.
|
||||
@@ -346,14 +658,13 @@ NetNet* NetEUBits::synthesize(Design*des)
|
||||
|
||||
NetScope*scope = isig->scope();
|
||||
assert(scope);
|
||||
string path = des->local_symbol(scope->name());
|
||||
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT,
|
||||
isig->pin_count());
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, isig->pin_count());
|
||||
osig->local_flag(true);
|
||||
|
||||
for (unsigned idx = 0 ; idx < osig->pin_count() ; idx += 1) {
|
||||
string oname = des->local_symbol(path);
|
||||
perm_string oname = scope->local_symbol();
|
||||
NetLogic*gate;
|
||||
|
||||
switch (op()) {
|
||||
@@ -379,12 +690,12 @@ NetNet* NetEUReduce::synthesize(Design*des)
|
||||
|
||||
NetScope*scope = isig->scope();
|
||||
assert(scope);
|
||||
string path = des->local_symbol(scope->name());
|
||||
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, 1);
|
||||
NetNet*osig = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, 1);
|
||||
osig->local_flag(true);
|
||||
|
||||
string oname = des->local_symbol(path);
|
||||
perm_string oname = scope->local_symbol();
|
||||
NetLogic*gate;
|
||||
|
||||
switch (op()) {
|
||||
@@ -399,6 +710,26 @@ NetNet* NetEUReduce::synthesize(Design*des)
|
||||
NetLogic::AND);
|
||||
break;
|
||||
|
||||
case '|':
|
||||
gate = new NetLogic(scope, oname, isig->pin_count()+1,
|
||||
NetLogic::OR);
|
||||
break;
|
||||
|
||||
case '^':
|
||||
gate = new NetLogic(scope, oname, isig->pin_count()+1,
|
||||
NetLogic::XOR);
|
||||
break;
|
||||
|
||||
case 'A':
|
||||
gate = new NetLogic(scope, oname, isig->pin_count()+1,
|
||||
NetLogic::NAND);
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
gate = new NetLogic(scope, oname, isig->pin_count()+1,
|
||||
NetLogic::XNOR);
|
||||
break;
|
||||
|
||||
default:
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Unable to synthesize " << *this << "." << endl;
|
||||
@@ -413,21 +744,72 @@ NetNet* NetEUReduce::synthesize(Design*des)
|
||||
return osig;
|
||||
}
|
||||
|
||||
NetNet* NetESelect::synthesize(Design *des)
|
||||
{
|
||||
// XXXX For now, only support pad form
|
||||
assert(base_ == 0);
|
||||
|
||||
NetNet*sub = expr_->synthesize(des);
|
||||
if (sub == 0)
|
||||
return 0;
|
||||
|
||||
NetScope*scope = sub->scope();
|
||||
NetNet*net = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::IMPLICIT, expr_width());
|
||||
if (has_sign()) {
|
||||
unsigned idx;
|
||||
|
||||
for (idx = 0 ; idx < sub->pin_count() ; idx += 1)
|
||||
connect(sub->pin(idx), net->pin(idx));
|
||||
|
||||
for ( ; idx < net->pin_count(); idx += 1)
|
||||
connect(sub->pin(sub->pin_count()-1), net->pin(idx));
|
||||
|
||||
} else {
|
||||
unsigned idx;
|
||||
for (idx = 0 ; idx < sub->pin_count() ; idx += 1)
|
||||
connect(sub->pin(idx), net->pin(idx));
|
||||
|
||||
NetConst*tmp = new NetConst(scope, scope->local_symbol(),
|
||||
verinum::V0);
|
||||
|
||||
for ( ; idx < net->pin_count() ; idx += 1)
|
||||
connect(net->pin(idx), tmp->pin(0));
|
||||
|
||||
des->add_node(tmp);
|
||||
}
|
||||
|
||||
return net;
|
||||
}
|
||||
|
||||
/*
|
||||
* Synthesize a ?: operator as a NetMux device. Connect the condition
|
||||
* expression to the select input, then connect the true and false
|
||||
* expressions to the B and A inputs. This way, when the select input
|
||||
* is one, the B input, which is the true expression, is selected.
|
||||
*/
|
||||
NetNet* NetETernary::synthesize(Design *des)
|
||||
{
|
||||
string path = des->local_symbol("SYNTH");
|
||||
NetNet*csig = cond_->synthesize(des);
|
||||
NetNet*tsig = true_val_->synthesize(des);
|
||||
NetNet*fsig = false_val_->synthesize(des);
|
||||
|
||||
perm_string path = csig->scope()->local_symbol();
|
||||
|
||||
assert(csig->pin_count() == 1);
|
||||
assert(tsig->pin_count() == fsig->pin_count());
|
||||
unsigned width=tsig->pin_count();
|
||||
|
||||
unsigned width=expr_width();
|
||||
NetNet*osig = new NetNet(csig->scope(), path, NetNet::IMPLICIT, width);
|
||||
osig->local_flag(true);
|
||||
|
||||
string oname = des->local_symbol(path);
|
||||
/* Make sure both value operands are the right width. */
|
||||
tsig = pad_to_width(des, tsig, width);
|
||||
fsig = pad_to_width(des, fsig, width);
|
||||
|
||||
assert(width <= tsig->pin_count());
|
||||
assert(width <= fsig->pin_count());
|
||||
|
||||
perm_string oname = csig->scope()->local_symbol();
|
||||
NetMux *mux = new NetMux(csig->scope(), oname, width, 2, 1);
|
||||
for (unsigned idx = 0 ; idx < width; idx += 1) {
|
||||
connect(tsig->pin(idx), mux->pin_Data(idx, 1));
|
||||
@@ -440,95 +822,143 @@ NetNet* NetETernary::synthesize(Design *des)
|
||||
return osig;
|
||||
}
|
||||
|
||||
/*
|
||||
* When synthesizing a signal expression, it is usually fine to simply
|
||||
* return the NetNet that it refers to. If this is a part select,
|
||||
* though, a bit more work needs to be done. Return a temporary that
|
||||
* represents the connections to the selected bits.
|
||||
*
|
||||
* For example, if there is a reg foo, like so:
|
||||
* reg [5:0] foo;
|
||||
* and this expression node represents a part select foo[3:2], then
|
||||
* create a temporary like so:
|
||||
*
|
||||
* foo
|
||||
* +---+
|
||||
* | 5 |
|
||||
* +---+
|
||||
* tmp | 4 |
|
||||
* +---+ +---+
|
||||
* | 1 | <---> | 3 |
|
||||
* +---+ +---+
|
||||
* | 0 | <---> | 2 |
|
||||
* +---+ +---+
|
||||
* | 1 |
|
||||
* +---+
|
||||
* | 0 |
|
||||
* +---+
|
||||
* The temporary is marked as a temporary and returned to the
|
||||
* caller. This causes the caller to get only the selected part of the
|
||||
* signal, and when it hooks up to tmp, it hooks up to the right parts
|
||||
* of foo.
|
||||
*/
|
||||
NetNet* NetESignal::synthesize(Design*des)
|
||||
{
|
||||
return net_;
|
||||
if ((lsi_ == 0) && (msi_ == (net_->pin_count() - 1)))
|
||||
return net_;
|
||||
|
||||
assert(msi_ >= lsi_);
|
||||
unsigned wid = msi_ - lsi_ + 1;
|
||||
|
||||
NetScope*scope = net_->scope();
|
||||
assert(scope);
|
||||
|
||||
perm_string name = scope->local_symbol();
|
||||
NetNet*tmp = new NetNet(scope, name, NetNet::WIRE, wid);
|
||||
tmp->local_flag(true);
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
||||
connect(tmp->pin(idx), net_->pin(idx+lsi_));
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: expr_synth.cc,v $
|
||||
* Revision 1.20 2001/02/15 06:59:36 steve
|
||||
* FreeBSD port has a maintainer now.
|
||||
* Revision 1.59 2004/06/30 02:16:26 steve
|
||||
* Implement signed divide and signed right shift in nets.
|
||||
*
|
||||
* Revision 1.19 2001/01/18 03:16:35 steve
|
||||
* NetMux needs a scope. (PR#115)
|
||||
* Revision 1.58 2004/06/16 16:21:34 steve
|
||||
* Connect rsif of multiply to DataB.
|
||||
*
|
||||
* Revision 1.18 2000/11/29 23:16:18 steve
|
||||
* Do not delete synthesized signals used in expressions.
|
||||
* Revision 1.57 2004/06/12 15:00:02 steve
|
||||
* Support / and % in synthesized contexts.
|
||||
*
|
||||
* Revision 1.17 2000/11/29 05:24:00 steve
|
||||
* synthesis for unary reduction ! and N operators.
|
||||
* Revision 1.56 2004/06/01 01:04:57 steve
|
||||
* Fix synthesis method for logical and/or
|
||||
*
|
||||
* Revision 1.16 2000/11/29 02:09:52 steve
|
||||
* Add support for || synthesis (PR#53)
|
||||
* Revision 1.55 2004/02/20 18:53:35 steve
|
||||
* Addtrbute keys are perm_strings.
|
||||
*
|
||||
* Revision 1.15 2000/10/07 19:45:43 steve
|
||||
* Put logic devices into scopes.
|
||||
* Revision 1.54 2004/02/18 17:11:56 steve
|
||||
* Use perm_strings for named langiage items.
|
||||
*
|
||||
* Revision 1.14 2000/05/02 00:58:12 steve
|
||||
* Move signal tables to the NetScope class.
|
||||
* Revision 1.53 2004/02/15 04:23:48 steve
|
||||
* Fix evaluation of compare to constant expression.
|
||||
*
|
||||
* Revision 1.13 2000/04/28 18:43:23 steve
|
||||
* integer division in expressions properly get width.
|
||||
* Revision 1.52 2003/11/10 19:39:20 steve
|
||||
* Remove redundant scope tokens.
|
||||
*
|
||||
* Revision 1.12 2000/04/20 00:28:03 steve
|
||||
* Catch some simple identity compareoptimizations.
|
||||
* Revision 1.51 2003/10/27 06:04:21 steve
|
||||
* More flexible width handling for synthesized add.
|
||||
*
|
||||
* Revision 1.11 2000/04/16 23:32:18 steve
|
||||
* Synthesis of comparator in expressions.
|
||||
* Revision 1.50 2003/09/26 02:44:27 steve
|
||||
* Assure ternary arguments are wide enough.
|
||||
*
|
||||
* Connect the NetEvent and related classes
|
||||
* together better.
|
||||
* Revision 1.49 2003/09/03 23:31:36 steve
|
||||
* Support synthesis of constant downshifts.
|
||||
*
|
||||
* Revision 1.10 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
* Revision 1.48 2003/08/28 04:11:18 steve
|
||||
* Spelling patch.
|
||||
*
|
||||
* Revision 1.9 2000/01/01 06:18:00 steve
|
||||
* Handle synthesis of concatenation.
|
||||
* Revision 1.47 2003/08/09 03:23:40 steve
|
||||
* Add support for IVL_LPM_MULT device.
|
||||
*
|
||||
* Revision 1.8 1999/12/17 06:18:15 steve
|
||||
* Rewrite the cprop functor to use the functor_t interface.
|
||||
* Revision 1.46 2003/07/26 03:34:42 steve
|
||||
* Start handling pad of expressions in code generators.
|
||||
*
|
||||
* Revision 1.7 1999/12/17 03:38:46 steve
|
||||
* NetConst can now hold wide constants.
|
||||
* Revision 1.45 2003/06/24 01:38:02 steve
|
||||
* Various warnings fixed.
|
||||
*
|
||||
* Revision 1.6 1999/11/28 23:42:02 steve
|
||||
* NetESignal object no longer need to be NetNode
|
||||
* objects. Let them keep a pointer to NetNet objects.
|
||||
* Revision 1.44 2003/04/19 04:52:56 steve
|
||||
* Less picky about expression widths while synthesizing ternary.
|
||||
*
|
||||
* Revision 1.5 1999/11/27 19:07:57 steve
|
||||
* Support the creation of scopes.
|
||||
* Revision 1.43 2003/04/08 05:07:15 steve
|
||||
* Detect constant shift distances in synthesis.
|
||||
*
|
||||
* Revision 1.4 1999/11/19 03:00:59 steve
|
||||
* Whoops, created a signal with a duplicate name.
|
||||
* Revision 1.42 2003/04/08 04:33:55 steve
|
||||
* Synthesize shift expressions.
|
||||
*
|
||||
* Revision 1.3 1999/11/05 04:40:40 steve
|
||||
* Patch to synthesize LPM_ADD_SUB from expressions,
|
||||
* Thanks to Larry Doolittle. Also handle constants
|
||||
* in expressions.
|
||||
* Revision 1.41 2003/03/06 00:28:41 steve
|
||||
* All NetObj objects have lex_string base names.
|
||||
*
|
||||
* Synthesize adders in XNF, based on a patch from
|
||||
* Larry. Accept synthesis of constants from Larry
|
||||
* as is.
|
||||
* Revision 1.40 2003/02/26 01:29:24 steve
|
||||
* LPM objects store only their base names.
|
||||
*
|
||||
* Revision 1.2 1999/11/04 03:53:26 steve
|
||||
* Patch to synthesize unary ~ and the ternary operator.
|
||||
* Thanks to Larry Doolittle <LRDoolittle@lbl.gov>.
|
||||
* Revision 1.39 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Add the LPM_MUX device, and integrate it with the
|
||||
* ternary synthesis from Larry. Replace the lpm_mux
|
||||
* generator in t-xnf.cc to use XNF EQU devices to
|
||||
* put muxs into function units.
|
||||
* Revision 1.38 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
* Rewrite elaborate_net for the PETernary class to
|
||||
* also use the LPM_MUX device.
|
||||
* Revision 1.37 2002/11/17 23:37:55 steve
|
||||
* Magnitude compare to 0.
|
||||
*
|
||||
* Revision 1.1 1999/11/02 04:55:34 steve
|
||||
* Add the synthesize method to NetExpr to handle
|
||||
* synthesis of expressions, and use that method
|
||||
* to improve r-value handling of LPM_FF synthesis.
|
||||
* Revision 1.36 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Modify the XNF target to handle LPM_FF objects.
|
||||
* Revision 1.35 2002/07/07 22:31:39 steve
|
||||
* Smart synthesis of binary AND expressions.
|
||||
*
|
||||
* Revision 1.34 2002/07/05 21:26:17 steve
|
||||
* Avoid emitting to vvp local net symbols.
|
||||
*
|
||||
* Revision 1.33 2002/05/26 01:39:02 steve
|
||||
* Carry Verilog 2001 attributes with processes,
|
||||
* all the way through to the ivl_target API.
|
||||
*
|
||||
* Divide signal reference counts between rval
|
||||
* and lval references.
|
||||
*/
|
||||
|
||||
|
||||
+60
-118
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 1999-2002 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
|
||||
@@ -16,10 +16,14 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: functor.cc,v 1.24 2000/11/19 20:48:30 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: functor.cc,v 1.32 2004/10/04 01:10:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "functor.h"
|
||||
# include "netlist.h"
|
||||
|
||||
@@ -110,7 +114,9 @@ void NetScope::run_functor(Design*des, functor_t*fun)
|
||||
void Design::functor(functor_t*fun)
|
||||
{
|
||||
// Scan the scopes
|
||||
root_scope_->run_functor(this, fun);
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->run_functor(this, fun);
|
||||
|
||||
// apply to processes
|
||||
procs_idx_ = procs_;
|
||||
@@ -122,30 +128,31 @@ void Design::functor(functor_t*fun)
|
||||
|
||||
// apply to nodes
|
||||
if (nodes_) {
|
||||
assert(nodes_functor_cur_ == 0);
|
||||
assert(nodes_functor_nxt_ == 0);
|
||||
|
||||
/* Scan the circular list of nodes, starting with the
|
||||
front of the list. (nodes_ points to the *end* of the
|
||||
list.) The bar is the end point. At the end of the
|
||||
do-while loop, I know that the bar has been
|
||||
processed or (if bar == 0) no undeleted node has been
|
||||
processed. */
|
||||
NetNode*cur = nodes_->node_next_;
|
||||
NetNode*bar = 0;
|
||||
front of the list.
|
||||
|
||||
This loop interacts with the Design::del_node method
|
||||
so that the functor is free to delete any nodes it
|
||||
choose. The destructors of the NetNode objects call
|
||||
the del_node method, which checks with the
|
||||
nodes_functor_* members, to keep the iterator
|
||||
operating safely. */
|
||||
nodes_functor_cur_ = nodes_;
|
||||
do {
|
||||
NetNode*tmp = cur->node_next_;
|
||||
cur->functor_node(this, fun);
|
||||
nodes_functor_nxt_ = nodes_functor_cur_->node_next_;
|
||||
nodes_functor_cur_->functor_node(this, fun);
|
||||
|
||||
/* Detect the case that cur has been deleted by
|
||||
noticing if tmp->node_prev_ no longer points to
|
||||
cur. If that's the case, clear the bar. */
|
||||
if (tmp->node_prev_ != cur) {
|
||||
if (cur == bar)
|
||||
bar = 0;
|
||||
} else if (bar == 0) {
|
||||
bar = cur;
|
||||
}
|
||||
cur = tmp;
|
||||
if (nodes_functor_nxt_ == 0)
|
||||
break;
|
||||
|
||||
nodes_functor_cur_ = nodes_functor_nxt_;
|
||||
} while (nodes_ && (nodes_functor_cur_ != nodes_));
|
||||
nodes_functor_cur_ = 0;
|
||||
nodes_functor_nxt_ = 0;
|
||||
|
||||
} while (nodes_ && (cur != bar));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,35 +235,13 @@ int NetAssignNB::match_proc(proc_match_t*that)
|
||||
return that->assign_nb(this);
|
||||
}
|
||||
|
||||
int proc_match_t::assign_mem(NetAssignMem*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NetAssignMem::match_proc(proc_match_t*that)
|
||||
{
|
||||
return that->assign_mem(this);
|
||||
}
|
||||
|
||||
int proc_match_t::assign_mem_nb(NetAssignMemNB*)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NetAssignMemNB::match_proc(proc_match_t*that)
|
||||
{
|
||||
return that->assign_mem_nb(this);
|
||||
}
|
||||
|
||||
int proc_match_t::block(NetBlock*)
|
||||
{
|
||||
cerr << "default (failing) match for block" << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int NetBlock::match_proc(proc_match_t*that)
|
||||
{
|
||||
cerr << "NetBlock::match_proc" << endl;
|
||||
return that->block(this);
|
||||
}
|
||||
|
||||
@@ -282,6 +267,35 @@ int proc_match_t::event_wait(NetEvWait*)
|
||||
|
||||
/*
|
||||
* $Log: functor.cc,v $
|
||||
* Revision 1.32 2004/10/04 01:10:53 steve
|
||||
* Clean up spurious trailing white space.
|
||||
*
|
||||
* Revision 1.31 2002/08/16 05:18:27 steve
|
||||
* Fix intermix of node functors and node delete.
|
||||
*
|
||||
* Revision 1.30 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.29 2002/08/10 22:07:38 steve
|
||||
* Remove useless error messages.
|
||||
*
|
||||
* Revision 1.28 2002/06/05 03:44:25 steve
|
||||
* Add support for memory words in l-value of
|
||||
* non-blocking assignments, and remove the special
|
||||
* NetAssignMem_ and NetAssignMemNB classes.
|
||||
*
|
||||
* Revision 1.27 2002/06/04 05:38:44 steve
|
||||
* Add support for memory words in l-value of
|
||||
* blocking assignments, and remove the special
|
||||
* NetAssignMem class.
|
||||
*
|
||||
* Revision 1.26 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
* Revision 1.25 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.24 2000/11/19 20:48:30 steve
|
||||
* Fix cases where signal iteration might die early.
|
||||
*
|
||||
@@ -293,77 +307,5 @@ int proc_match_t::event_wait(NetEvWait*)
|
||||
*
|
||||
* Revision 1.21 2000/08/01 02:48:41 steve
|
||||
* Support <= in synthesis of DFF and ram devices.
|
||||
*
|
||||
* Revision 1.20 2000/07/16 04:56:07 steve
|
||||
* Handle some edge cases during node scans.
|
||||
*
|
||||
* Revision 1.19 2000/07/15 05:13:43 steve
|
||||
* Detect muxing Vz as a bufufN.
|
||||
*
|
||||
* Revision 1.18 2000/05/02 00:58:12 steve
|
||||
* Move signal tables to the NetScope class.
|
||||
*
|
||||
* Revision 1.17 2000/04/20 00:28:03 steve
|
||||
* Catch some simple identity compareoptimizations.
|
||||
*
|
||||
* Revision 1.16 2000/04/18 04:50:19 steve
|
||||
* Clean up unneeded NetEvent objects.
|
||||
*
|
||||
* Revision 1.15 2000/04/16 23:32:18 steve
|
||||
* Synthesis of comparator in expressions.
|
||||
*
|
||||
* Connect the NetEvent and related classes
|
||||
* together better.
|
||||
*
|
||||
* Revision 1.14 2000/04/12 20:02:53 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
* and get started supporting multiple events in a
|
||||
* wait in vvm.
|
||||
*
|
||||
* Revision 1.13 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.12 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.11 2000/02/13 04:35:43 steve
|
||||
* Include some block matching from Larry.
|
||||
*
|
||||
* Revision 1.10 2000/01/13 03:35:35 steve
|
||||
* Multiplication all the way to simulation.
|
||||
*
|
||||
* Revision 1.9 2000/01/02 17:57:20 steve
|
||||
* Handle nodes running out during node scan.
|
||||
*
|
||||
* Revision 1.8 1999/12/30 04:19:12 steve
|
||||
* Propogate constant 0 in low bits of adders.
|
||||
*
|
||||
* Revision 1.7 1999/12/17 06:18:16 steve
|
||||
* Rewrite the cprop functor to use the functor_t interface.
|
||||
*
|
||||
* Revision 1.6 1999/12/05 02:24:08 steve
|
||||
* Synthesize LPM_RAM_DQ for writes into memories.
|
||||
*
|
||||
* Revision 1.5 1999/12/01 06:06:16 steve
|
||||
* Redo synth to use match_proc_t scanner.
|
||||
*
|
||||
* Revision 1.4 1999/11/18 03:52:19 steve
|
||||
* Turn NetTmp objects into normal local NetNet objects,
|
||||
* and add the nodangle functor to clean up the local
|
||||
* symbols generated by elaboration and other steps.
|
||||
*
|
||||
* Revision 1.3 1999/11/01 02:07:40 steve
|
||||
* Add the synth functor to do generic synthesis
|
||||
* and add the LPM_FF device to handle rows of
|
||||
* flip-flops.
|
||||
*
|
||||
* Revision 1.2 1999/07/18 05:52:46 steve
|
||||
* xnfsyn generates DFF objects for XNF output, and
|
||||
* properly rewrites the Design netlist in the process.
|
||||
*
|
||||
* Revision 1.1 1999/07/17 22:01:13 steve
|
||||
* Add the functor interface for functor transforms.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: functor.h,v 1.17 2000/09/17 21:26:15 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: functor.h,v 1.20 2002/08/12 01:34:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -83,9 +83,7 @@ struct proc_match_t {
|
||||
virtual ~proc_match_t();
|
||||
|
||||
virtual int assign(class NetAssign*);
|
||||
virtual int assign_mem(class NetAssignMem*);
|
||||
virtual int assign_nb(class NetAssignNB*);
|
||||
virtual int assign_mem_nb(class NetAssignMemNB*);
|
||||
virtual int condit(class NetCondit*);
|
||||
virtual int event_wait(class NetEvWait*);
|
||||
virtual int block(class NetBlock*);
|
||||
@@ -94,6 +92,19 @@ struct proc_match_t {
|
||||
|
||||
/*
|
||||
* $Log: functor.h,v $
|
||||
* Revision 1.20 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.19 2002/06/05 03:44:25 steve
|
||||
* Add support for memory words in l-value of
|
||||
* non-blocking assignments, and remove the special
|
||||
* NetAssignMem_ and NetAssignMemNB classes.
|
||||
*
|
||||
* Revision 1.18 2002/06/04 05:38:44 steve
|
||||
* Add support for memory words in l-value of
|
||||
* blocking assignments, and remove the special
|
||||
* NetAssignMem class.
|
||||
*
|
||||
* Revision 1.17 2000/09/17 21:26:15 steve
|
||||
* Add support for modulus (Eric Aardoom)
|
||||
*
|
||||
@@ -108,32 +119,5 @@ struct proc_match_t {
|
||||
*
|
||||
* Revision 1.13 2000/04/20 00:28:03 steve
|
||||
* Catch some simple identity compareoptimizations.
|
||||
*
|
||||
* Revision 1.12 2000/04/18 04:50:19 steve
|
||||
* Clean up unneeded NetEvent objects.
|
||||
*
|
||||
* Revision 1.11 2000/04/12 20:02:53 steve
|
||||
* Finally remove the NetNEvent and NetPEvent classes,
|
||||
* Get synthesis working with the NetEvWait class,
|
||||
* and get started supporting multiple events in a
|
||||
* wait in vvm.
|
||||
*
|
||||
* Revision 1.10 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.9 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.8 2000/02/13 04:35:43 steve
|
||||
* Include some block matching from Larry.
|
||||
*
|
||||
* Revision 1.7 2000/01/13 03:35:35 steve
|
||||
* Multiplication all the way to simulation.
|
||||
*
|
||||
* Revision 1.6 1999/12/30 04:19:12 steve
|
||||
* Propogate constant 0 in low bits of adders.
|
||||
*
|
||||
* Revision 1.5 1999/12/17 06:18:16 steve
|
||||
* Rewrite the cprop functor to use the functor_t interface.
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
Throughout Icarus Verilog descriptions and source code, I use a
|
||||
variety of terms and acronyms that might be specific to Icarus
|
||||
Verilog, have an Icarus Verilog specific meaning, or just aren't
|
||||
widely known. So here I define these terms.
|
||||
|
||||
|
||||
LRM - Language Reference Manual
|
||||
This is a generic acronym, but in the Verilog world we sometimes
|
||||
mean *the* language reference manual, the IEEE1364 standard.
|
||||
|
||||
|
||||
PLI - Programming Language Interface
|
||||
This is a C API into Verilog simulators that is defined by the
|
||||
IEEE1364. There are two major interfaces, sometimes called PLI 1
|
||||
and PLI 2. PLI 2 is also often called VPI.
|
||||
|
||||
|
||||
UDP - User Defined Primitive
|
||||
These are objects that Verilog programmers define with the
|
||||
"primitive" keyword. They are truth-table based devices. The
|
||||
syntax for defining them is described in the LRM.
|
||||
|
||||
|
||||
VPI -
|
||||
This is the C API that is defined by the Verilog standard, and
|
||||
that Icarus Verilog partially implements. See also PLI.
|
||||
|
||||
|
||||
VVM - Verilog Virtual Machine
|
||||
This is the Icarus Verilog runtime that works with the code
|
||||
generator that generates C++.
|
||||
|
||||
|
||||
VVP - Verilog Virtual Processor
|
||||
This is the Icarus Verilog runtime that reads in custom code in a
|
||||
form that I call "VVP Assembly". See the vvp/ directory for
|
||||
documentation on that.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user