mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-23 22:36:54 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
@@ -2,9 +2,14 @@ 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
|
||||
@@ -15,5 +20,7 @@ check.cc
|
||||
config.status
|
||||
config.log
|
||||
config.cache
|
||||
autom4te.cache
|
||||
config.h
|
||||
_pli_types.h
|
||||
dosify
|
||||
|
||||
@@ -16,8 +16,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)
|
||||
#ident "$Id: Attrib.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Attrib.cc,v 1.5 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -36,14 +36,15 @@ Attrib::~Attrib()
|
||||
delete[] list_;
|
||||
}
|
||||
|
||||
void Attrib::set_attributes(const map<string,string>&attr)
|
||||
#if 0
|
||||
void Attrib::copy_attributes(const map<string,verinum>&attr)
|
||||
{
|
||||
assert(list_ == 0);
|
||||
|
||||
nlist_ = attr.size();
|
||||
list_ = new cell_[nlist_];
|
||||
|
||||
map<string,string>::const_iterator idx;
|
||||
map<string,verinum>::const_iterator idx;
|
||||
unsigned jdx;
|
||||
for (idx = attr.begin(), jdx = 0 ; idx != attr.end() ; idx ++, jdx++) {
|
||||
struct cell_*tmp = list_ + jdx;
|
||||
@@ -51,8 +52,9 @@ void Attrib::set_attributes(const map<string,string>&attr)
|
||||
tmp->val = (*idx).second;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
string Attrib::attribute(const string&key) const
|
||||
const verinum& Attrib::attribute(const string&key) const
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < nlist_ ; idx += 1) {
|
||||
|
||||
@@ -60,10 +62,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(const string&key, const verinum&value)
|
||||
{
|
||||
unsigned idx;
|
||||
|
||||
@@ -92,7 +95,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;
|
||||
}
|
||||
@@ -100,18 +103,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
|
||||
const char* Attrib::attr_key(unsigned idx) const
|
||||
{
|
||||
assert(idx < nlist_);
|
||||
return list_[idx].key;
|
||||
return list_[idx].key.c_str();
|
||||
}
|
||||
|
||||
string Attrib::value(unsigned idx) const
|
||||
const verinum& Attrib::attr_value(unsigned idx) const
|
||||
{
|
||||
assert(idx < nlist_);
|
||||
return list_[idx].val;
|
||||
@@ -120,6 +123,24 @@ string Attrib::value(unsigned idx) const
|
||||
|
||||
/*
|
||||
* $Log: Attrib.cc,v $
|
||||
* 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)
|
||||
|
||||
@@ -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.4 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
# include <map>
|
||||
# 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(const string&key) const;
|
||||
void attribute(const 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;
|
||||
const char* attr_key(unsigned idx) const;
|
||||
const verinum& attr_value(unsigned idx) const;
|
||||
|
||||
|
||||
private:
|
||||
struct cell_ {
|
||||
string key;
|
||||
string val;
|
||||
string key;
|
||||
verinum val;
|
||||
};
|
||||
|
||||
unsigned nlist_;
|
||||
@@ -62,6 +62,24 @@ class Attrib {
|
||||
|
||||
/*
|
||||
* $Log: Attrib.h,v $
|
||||
* 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.
|
||||
|
||||
|
||||
@@ -16,14 +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)
|
||||
#ident "$Id: HName.cc,v 1.1 2001/12/03 04:47:14 steve Exp $"
|
||||
#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()
|
||||
{
|
||||
@@ -71,6 +75,11 @@ hname_t::~hname_t()
|
||||
}
|
||||
}
|
||||
|
||||
unsigned hname_t::component_count() const
|
||||
{
|
||||
return count_;
|
||||
}
|
||||
|
||||
void hname_t::append(const char*text)
|
||||
{
|
||||
char**tmp;
|
||||
@@ -249,6 +258,19 @@ ostream& operator<< (ostream&out, const hname_t&that)
|
||||
|
||||
/*
|
||||
* $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.
|
||||
|
||||
@@ -18,14 +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)
|
||||
#ident "$Id: HName.h,v 1.1 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: HName.h,v 1.4 2002/11/02 03:27:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IOSFWD
|
||||
# include <iosfwd>
|
||||
#else
|
||||
class ostream;
|
||||
# include <iostream>
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ > 2
|
||||
using namespace std;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -60,6 +61,10 @@ class hname_t {
|
||||
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:
|
||||
@@ -78,6 +83,16 @@ 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.
|
||||
|
||||
+29
-6
@@ -16,14 +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.2 2001/07/25 03:10:48 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()
|
||||
{
|
||||
@@ -31,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)
|
||||
@@ -42,8 +49,24 @@ 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)
|
||||
|
||||
+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.
|
||||
*
|
||||
|
||||
+140
-90
@@ -16,12 +16,16 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.109 2001/12/06 02:55:24 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.160 2003/11/26 01:36:55 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.5
|
||||
# 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,7 +37,10 @@ VPATH = $(srcdir)
|
||||
|
||||
bindir = @bindir@
|
||||
libdir = @libdir@
|
||||
includedir = $(prefix)/include
|
||||
includedir = @includedir@
|
||||
mandir = @mandir@
|
||||
|
||||
libdir64 = @libdir64@
|
||||
|
||||
dllib=@DLLIB@
|
||||
rdynamic=@rdynamic@
|
||||
@@ -46,6 +53,8 @@ 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)
|
||||
@@ -60,89 +69,74 @@ ifeq ('@HAVE_IPAL@','yes')
|
||||
TARGETS += tgt-pal
|
||||
endif
|
||||
|
||||
|
||||
all: ivl@EXEEXT@ libvpi.a
|
||||
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
|
||||
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 vpi 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: dosify.exe
|
||||
all: dep dosify.exe
|
||||
dosify.exe: dosify.c
|
||||
$(CC) -o dosify.exe dosify.c
|
||||
|
||||
ifeq (@MINGW32@,yes)
|
||||
SUBDIRS += driver-vpi
|
||||
endif
|
||||
|
||||
else
|
||||
all: dep iverilog-vpi
|
||||
endif
|
||||
|
||||
# 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'
|
||||
driver/iverilog -Ccheck.conf -ocheck.vvp -tvvp-check -B./ivlpp $(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 libvpi.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 \
|
||||
load_module.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 \
|
||||
set_width.o symbol_search.o sync.o \
|
||||
verinum.o verireal.o target.o targets.o \
|
||||
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.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.h.in config.status
|
||||
./config.status
|
||||
|
||||
|
||||
libvpi.a: vpithunk.o
|
||||
rm -f $@
|
||||
ar cvq $@ vpithunk.o
|
||||
ranlib $@
|
||||
|
||||
# The vpithunk.c file (that makes up the libvpi.a library) needs to
|
||||
# be make with PIC flags, because shared objects load it.
|
||||
vpithunk.o: vpithunk.c
|
||||
@[ -d dep ] || mkdir dep
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(PICFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep/$*.d
|
||||
|
||||
|
||||
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
|
||||
@@ -159,9 +153,23 @@ ivl@EXEEXT@: $O
|
||||
endif
|
||||
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
|
||||
else
|
||||
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
|
||||
$(CXX) -Wall @ident_support@ $(CPPFLAGS) $(CXXFLAGS) -MD -c $< -o $*.o
|
||||
mv $*.d dep/$*.d
|
||||
|
||||
|
||||
@@ -169,49 +177,86 @@ lexor.o: lexor.cc parse.h
|
||||
|
||||
parse.o: parse.cc
|
||||
|
||||
parse.h parse.cc: $(srcdir)/parse.y
|
||||
bison --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
|
||||
mv parse.cc.h parse.h || mv parse.hh 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
|
||||
|
||||
iverilog-vpi.pdf: iverilog-vpi.ps
|
||||
ps2pdf iverilog-vpi.ps iverilog-vpi.pdf
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/QUICK_START.txt
|
||||
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
|
||||
|
||||
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/iverilog.conf $(includedir)/ivl_target.h $(includedir)/vpi_user.h $(libdir)/libvpi.a $(WIN32_INSTALL)
|
||||
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
|
||||
ifeq (@WIN32@,yes)
|
||||
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/sqrt-virtex.v $(prefix)/QUICK_START.txt
|
||||
else
|
||||
WIN32_INSTALL = $(bindir)/iverilog-vpi
|
||||
endif
|
||||
|
||||
$(libdir)/libvpi.a : ./libvpi.a
|
||||
$(INSTALL_DATA) libvpi.a $(libdir)/libvpi.a
|
||||
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) $(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 (@WIN32@,yes)
|
||||
@@ -223,27 +268,32 @@ $(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)
|
||||
|
||||
@@ -16,8 +16,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: Module.cc,v 1.17 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Module.cc,v 1.21 2003/04/02 03:00:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -27,17 +27,14 @@
|
||||
# include "PWire.h"
|
||||
# include <assert.h>
|
||||
|
||||
Module::Module(const char*name, const svector<Module::port_t*>*pp)
|
||||
: name_(strdup(name))
|
||||
/* n is a permallocated string. */
|
||||
Module::Module(const char*n)
|
||||
: name_(n)
|
||||
{
|
||||
if (pp)
|
||||
ports_ = *pp;
|
||||
|
||||
}
|
||||
|
||||
Module::~Module()
|
||||
{
|
||||
free(name_);
|
||||
}
|
||||
|
||||
void Module::add_gate(PGate*gate)
|
||||
@@ -72,7 +69,7 @@ void Module::add_behavior(PProcess*b)
|
||||
|
||||
unsigned Module::port_count() const
|
||||
{
|
||||
return ports_.count();
|
||||
return ports.count();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -82,11 +79,11 @@ unsigned Module::port_count() const
|
||||
*/
|
||||
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;
|
||||
}
|
||||
@@ -94,11 +91,21 @@ const svector<PEIdent*>& Module::get_port(unsigned idx) const
|
||||
unsigned Module::find_port(const string&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();
|
||||
}
|
||||
|
||||
|
||||
@@ -142,6 +149,18 @@ const list<PProcess*>& Module::get_behaviors() const
|
||||
|
||||
/*
|
||||
* $Log: Module.cc,v $
|
||||
* 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.
|
||||
|
||||
@@ -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: Module.h,v 1.24 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Module.h,v 1.32 2003/06/20 00:53:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
@@ -29,6 +29,7 @@
|
||||
# include "named.h"
|
||||
# include "LineInfo.h"
|
||||
# include <string>
|
||||
class PData;
|
||||
class PEvent;
|
||||
class PExpr;
|
||||
class PEIdent;
|
||||
@@ -60,15 +61,29 @@ class Module : public LineInfo {
|
||||
};
|
||||
|
||||
public:
|
||||
explicit Module(const char*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(const char*name);
|
||||
~Module();
|
||||
|
||||
|
||||
/* 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<string,param_expr_t>parameters;
|
||||
map<string,param_expr_t>localparams;
|
||||
|
||||
|
||||
/* specparams are simpler then other params, in that they have
|
||||
no type information. They are merely constant
|
||||
expressions. */
|
||||
map<string,PExpr*>specparams;
|
||||
|
||||
/* The module also has defparam assignments which don't create
|
||||
new parameters within the module, but may be used to set
|
||||
@@ -84,9 +99,18 @@ class Module : public LineInfo {
|
||||
a parameter-index to its name. */
|
||||
list<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;
|
||||
|
||||
/* Keep a table of datum variables declared in the module. */
|
||||
map<hname_t,PData*>datum;
|
||||
|
||||
map<string,PExpr*> attributes;
|
||||
|
||||
/* These are the timescale for this module. The default is
|
||||
set by the `timescale directive. */
|
||||
int time_unit, time_precision;
|
||||
@@ -125,11 +149,7 @@ class Module : public LineInfo {
|
||||
bool elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
char* name_;
|
||||
|
||||
/* This is an array of port descriptors, which is in turn a
|
||||
named array of PEident pointers. */
|
||||
svector<port_t*> ports_;
|
||||
const char* name_;
|
||||
|
||||
map<hname_t,PWire*> wires_;
|
||||
list<PGate*> gates_;
|
||||
@@ -145,96 +165,30 @@ class Module : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: Module.h,v $
|
||||
* Revision 1.24 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
* Revision 1.32 2003/06/20 00:53:19 steve
|
||||
* Module attributes from the parser
|
||||
* through to elaborated form.
|
||||
*
|
||||
* Revision 1.23 2001/10/31 03:11:15 steve
|
||||
* detect module ports not declared within the module.
|
||||
* Revision 1.31 2003/06/13 19:10:45 steve
|
||||
* Properly manage real variables in subscopes.
|
||||
*
|
||||
* Revision 1.22 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
* Revision 1.30 2003/03/06 04:37:12 steve
|
||||
* lex_strings.add module names earlier.
|
||||
*
|
||||
* Revision 1.21 2000/11/05 06:05:59 steve
|
||||
* Handle connectsion to internally unconnected modules (PR#38)
|
||||
* Revision 1.29 2003/02/27 06:45:11 steve
|
||||
* specparams as far as pform.
|
||||
*
|
||||
* Revision 1.20 2000/07/22 22:09:03 steve
|
||||
* Parse and elaborate timescale to scopes.
|
||||
* Revision 1.28 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
* 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.27 2002/08/19 02:39:16 steve
|
||||
* Support parameters with defined ranges.
|
||||
*
|
||||
* Revision 1.18 2000/05/02 16:27:38 steve
|
||||
* Move signal elaboration to a seperate pass.
|
||||
*
|
||||
* Revision 1.17 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
* Revision 1.16 2000/03/12 17:09:40 steve
|
||||
* Support localparam.
|
||||
*
|
||||
* 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.14 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.13 2000/01/09 20:37:57 steve
|
||||
* Careful with wires connected to multiple ports.
|
||||
*
|
||||
* Revision 1.12 2000/01/09 05:50:48 steve
|
||||
* Support named parameter override lists.
|
||||
*
|
||||
* Revision 1.11 1999/12/11 05:45:41 steve
|
||||
* Fix support for attaching attributes to primitive gates.
|
||||
*
|
||||
* 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
|
||||
+67
-30
@@ -16,8 +16,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: PDelays.cc,v 1.7 2001/11/22 06:20:59 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"
|
||||
@@ -30,14 +30,17 @@
|
||||
|
||||
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)
|
||||
@@ -45,45 +48,65 @@ 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);
|
||||
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, NetScope*scope,
|
||||
@@ -93,8 +116,6 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||
{
|
||||
assert(scope);
|
||||
|
||||
int shift = scope->time_unit() - des->get_precision();
|
||||
|
||||
|
||||
if (delay_[0]) {
|
||||
rise_time = calculate_val(des, scope, delay_[0]);
|
||||
@@ -125,6 +146,22 @@ void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||
|
||||
/*
|
||||
* $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.
|
||||
*
|
||||
|
||||
@@ -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,17 +18,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: PDelays.h,v 1.4 2001/11/22 06:20:59 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;
|
||||
@@ -45,8 +46,11 @@ 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, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
@@ -57,6 +61,7 @@ class PDelays {
|
||||
|
||||
private:
|
||||
PExpr* delay_[3];
|
||||
bool delete_flag_;
|
||||
|
||||
private: // not implemented
|
||||
PDelays(const PDelays&);
|
||||
@@ -67,6 +72,15 @@ 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.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 200Stephen Williams ([email protected])
|
||||
* 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
|
||||
@@ -16,15 +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.2 2001/07/25 03:10:48 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PEvent.cc,v 1.4 2003/03/01 06:25:30 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PEvent.h"
|
||||
|
||||
PEvent::PEvent(const string&n)
|
||||
PEvent::PEvent(const char*n)
|
||||
: name_(n)
|
||||
{
|
||||
}
|
||||
@@ -33,13 +33,22 @@ PEvent::~PEvent()
|
||||
{
|
||||
}
|
||||
|
||||
string PEvent::name() const
|
||||
const char* PEvent::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PEvent.cc,v $
|
||||
* 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)
|
||||
|
||||
@@ -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: PEvent.h,v 1.5 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PEvent.h,v 1.8 2003/03/01 06:25:30 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
@@ -31,20 +31,21 @@ class NetScope;
|
||||
/*
|
||||
* The PEvent class represents event objects. These are things that
|
||||
* are declared in Verilog as ``event foo;'' The name passed to the
|
||||
* constructure is the "foo" part of the declaration.
|
||||
* 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.
|
||||
explicit PEvent(const char*name);
|
||||
~PEvent();
|
||||
|
||||
string name() const;
|
||||
const char* name() const;
|
||||
|
||||
void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
const char* name_;
|
||||
|
||||
private: // not implemented
|
||||
PEvent(const PEvent&);
|
||||
@@ -53,6 +54,18 @@ class PEvent : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: PEvent.h,v $
|
||||
* 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.
|
||||
|
||||
@@ -16,8 +16,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: PExpr.cc,v 1.28 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PExpr.cc,v 1.33 2003/01/27 05:09:17 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -46,19 +46,7 @@ bool PExpr::is_constant(Module*) const
|
||||
return false;
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_net(Design*des, NetScope*scope, 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, NetScope*) const
|
||||
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*, bool) const
|
||||
{
|
||||
cerr << get_line() << ": error: expression not valid in assign l-value: "
|
||||
<< *this << endl;
|
||||
@@ -166,19 +154,19 @@ const hname_t& PEIdent::path() const
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
{
|
||||
if (mod == 0) return false;
|
||||
|
||||
{ map<string,PExpr*>::const_iterator cur;
|
||||
{ map<string,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->parameters.find(path_.peek_name(0));
|
||||
if (cur != mod->parameters.end()) return true;
|
||||
}
|
||||
|
||||
{ map<string,PExpr*>::const_iterator cur;
|
||||
{ map<string,Module::param_expr_t>::const_iterator cur;
|
||||
cur = mod->localparams.find(path_.peek_name(0));
|
||||
if (cur != mod->localparams.end()) return true;
|
||||
}
|
||||
@@ -216,13 +204,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
|
||||
@@ -267,6 +256,21 @@ bool PEUnary::is_constant(Module*m) const
|
||||
|
||||
/*
|
||||
* $Log: PExpr.cc,v $
|
||||
* 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.
|
||||
|
||||
@@ -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.53 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PExpr.h,v 1.65 2003/02/08 19:49:21 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
|
||||
@@ -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, NetScope*scope) 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.
|
||||
@@ -88,11 +91,6 @@ class PExpr : public LineInfo {
|
||||
// evaluated, return 0.
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) 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;
|
||||
|
||||
// This method returns true if that expression is the same as
|
||||
// this expression. This method is used for comparing
|
||||
// expressions that must be structurally "identical".
|
||||
@@ -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,7 +121,8 @@ class PEConcat : public PExpr {
|
||||
// continuous assignments.
|
||||
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
|
||||
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
|
||||
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,
|
||||
@@ -131,7 +130,8 @@ class PEConcat : public PExpr {
|
||||
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;
|
||||
@@ -184,13 +184,11 @@ class PEFNumber : public PExpr {
|
||||
any rounding that is needed to get the value. */
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
|
||||
/* This method returns the full floating point value. */
|
||||
virtual verireal* eval_rconst(const Design*, const NetScope*) 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;
|
||||
@@ -211,7 +209,8 @@ 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, NetScope*scope) 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;
|
||||
@@ -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
|
||||
@@ -234,7 +234,6 @@ class PEIdent : public PExpr {
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
verireal*eval_rconst(const Design*des, const NetScope*sc) const;
|
||||
|
||||
const hname_t& path() const;
|
||||
|
||||
@@ -255,6 +254,19 @@ class PEIdent : public PExpr {
|
||||
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 {
|
||||
@@ -273,10 +285,12 @@ class PENumber : public PExpr {
|
||||
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 NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
|
||||
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
virtual verireal*eval_rconst(const Design*, const NetScope*) const;
|
||||
|
||||
virtual bool is_the_same(const PExpr*that) const;
|
||||
virtual bool is_constant(Module*) const;
|
||||
@@ -285,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 {
|
||||
@@ -316,7 +346,8 @@ class PEUnary : public PExpr {
|
||||
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 NetScope*sc) const;
|
||||
|
||||
@@ -343,10 +374,10 @@ class PEBinary : public PExpr {
|
||||
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 NetScope*sc) const;
|
||||
virtual verireal*eval_rconst(const Design*des, const NetScope*sc) const;
|
||||
|
||||
private:
|
||||
char op_;
|
||||
@@ -417,7 +448,8 @@ class PETernary : public PExpr {
|
||||
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 NetScope*sc) const;
|
||||
|
||||
@@ -429,7 +461,8 @@ 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:
|
||||
@@ -438,17 +471,74 @@ class PECallFunction : public PExpr {
|
||||
~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:
|
||||
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.65 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.64 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.63 2002/11/09 19:20:48 steve
|
||||
* Port expressions for output ports are lnets, not nets.
|
||||
*
|
||||
* Revision 1.62 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* 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.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.
|
||||
*
|
||||
* Add to the ivl_target API new functions for access
|
||||
* of complex attributes attached to gates.
|
||||
*
|
||||
* Revision 1.59 2002/04/23 03:53:59 steve
|
||||
* Add support for non-constant bit select.
|
||||
*
|
||||
* Revision 1.58 2002/04/14 03:55:25 steve
|
||||
* Precalculate unary - if possible.
|
||||
*
|
||||
* Revision 1.57 2002/04/13 02:33:17 steve
|
||||
* Detect missing indices to memories (PR#421)
|
||||
*
|
||||
* Revision 1.56 2002/03/09 04:02:26 steve
|
||||
* Constant expressions are not l-values for task ports.
|
||||
*
|
||||
* Revision 1.55 2002/03/09 02:10:22 steve
|
||||
* Add the NetUserFunc netlist node.
|
||||
*
|
||||
* Revision 1.54 2001/12/30 21:32:03 steve
|
||||
* Support elaborate_net for PEString objects.
|
||||
*
|
||||
* Revision 1.53 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
@@ -461,26 +551,5 @@ class PECallFunction : public PExpr {
|
||||
*
|
||||
* Revision 1.50 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.49 2001/11/06 06:11:55 steve
|
||||
* Support more real arithmetic in delay constants.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Allow parameters to be referenced by hierarchical name.
|
||||
*
|
||||
* Revision 1.47 2000/12/16 19:03:30 steve
|
||||
* Evaluate <= and ?: in parameter expressions (PR#81)
|
||||
*
|
||||
* Revision 1.46 2000/12/10 22:01:35 steve
|
||||
* Support decimal constants in behavioral delays.
|
||||
*
|
||||
* Revision 1.45 2000/12/06 06:31:09 steve
|
||||
* Check lvalue of procedural continuous assign (PR#29)
|
||||
*
|
||||
* Revision 1.44 2000/09/17 21:26:15 steve
|
||||
* Add support for modulus (Eric Aardoom)
|
||||
*/
|
||||
#endif
|
||||
|
||||
+5
-2
@@ -16,8 +16,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: PFunction.cc,v 1.5 2001/07/25 03:10:48 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PFunction.cc,v 1.6 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -54,6 +54,9 @@ void PFunction::set_output(PWire*o)
|
||||
|
||||
/*
|
||||
* $Log: PFunction.cc,v $
|
||||
* 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)
|
||||
|
||||
@@ -16,8 +16,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: PGate.cc,v 1.13 2001/11/22 06:20:59 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PGate.cc,v 1.15 2003/03/06 04:37:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -146,7 +146,7 @@ PGModule::PGModule(const char*type, const string&name, svector<PExpr*>*pins)
|
||||
: PGate(name, pins), overrides_(0), pins_(0),
|
||||
npins_(0), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
type_ = strdup(type);
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
PGModule::PGModule(const char*type, const string&name,
|
||||
@@ -154,12 +154,11 @@ PGModule::PGModule(const char*type, const string&name,
|
||||
: PGate(name, 0), overrides_(0), pins_(pins),
|
||||
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
type_ = strdup(type);
|
||||
type_ = type;
|
||||
}
|
||||
|
||||
PGModule::~PGModule()
|
||||
{
|
||||
free(type_);
|
||||
}
|
||||
|
||||
void PGModule::set_parameters(svector<PExpr*>*o)
|
||||
@@ -192,6 +191,12 @@ const char* PGModule::get_type()
|
||||
|
||||
/*
|
||||
* $Log: PGate.cc,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
@@ -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: PGate.h,v 1.22 2001/11/22 06:20:59 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PGate.h,v 1.25 2003/03/06 04:37:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
@@ -79,7 +79,7 @@ class PGate : public LineInfo {
|
||||
void strength0(strength_t);
|
||||
void strength1(strength_t);
|
||||
|
||||
map<string,string> attributes;
|
||||
map<string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const;
|
||||
@@ -171,6 +171,9 @@ class PGBuiltin : public PGate {
|
||||
class PGModule : public PGate {
|
||||
|
||||
public:
|
||||
// NOTE: The type parameter to all the constructors is assumed
|
||||
// to have been permallocated.
|
||||
|
||||
// If the binding of ports is by position, this constructor
|
||||
// builds everything all at once.
|
||||
explicit PGModule(const char*type, const string&name,
|
||||
@@ -198,10 +201,12 @@ class PGModule : public PGate {
|
||||
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.
|
||||
const char* get_type();
|
||||
|
||||
private:
|
||||
char* type_;
|
||||
const char* type_;
|
||||
svector<PExpr*>*overrides_;
|
||||
named<PExpr*>*pins_;
|
||||
unsigned npins_;
|
||||
@@ -222,6 +227,20 @@ class PGModule : public PGate {
|
||||
|
||||
/*
|
||||
* $Log: PGate.h,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
@@ -16,8 +16,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: PTask.cc,v 1.6 2001/07/25 03:10:48 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"
|
||||
@@ -48,6 +48,9 @@ void PTask::set_statement(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)
|
||||
|
||||
@@ -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: PTask.h,v 1.11 2001/11/22 06:20:59 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PTask.h,v 1.12 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
@@ -98,6 +98,9 @@ class PFunction : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: PTask.h,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
+13
-10
@@ -1,7 +1,5 @@
|
||||
#ifndef __debug_H
|
||||
#define __debug_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 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
|
||||
@@ -18,16 +16,21 @@
|
||||
* 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: debug.h,v 1.1 2001/05/05 23:55:46 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PUdp.cc,v 1.1 2003/07/15 05:07:13 steve Exp $"
|
||||
#endif
|
||||
|
||||
extern void breakpoint(void);
|
||||
# include "PUdp.h"
|
||||
|
||||
PUdp::PUdp(const string&n, unsigned nports)
|
||||
: ports(nports), sequential(false), initial(verinum::Vx), name_(n)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: debug.h,v $
|
||||
* Revision 1.1 2001/05/05 23:55:46 steve
|
||||
* Add the beginnings of an interactive debugger.
|
||||
* $Log: PUdp.cc,v $
|
||||
* Revision 1.1 2003/07/15 05:07:13 steve
|
||||
* Move PUdp constructor into compiled file.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
@@ -18,25 +18,21 @@
|
||||
* 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.5 2001/04/22 23:09:45 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PUdp.h,v 1.10 2003/07/15 05:07:13 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <map>
|
||||
# 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,13 +47,12 @@ 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(const string&n, unsigned nports);
|
||||
|
||||
svector<string>ports;
|
||||
bool sequential;
|
||||
@@ -68,7 +63,7 @@ class PUdp {
|
||||
|
||||
verinum::V initial;
|
||||
|
||||
map<string,string> attributes;
|
||||
map<string,PExpr*> attributes;
|
||||
|
||||
void dump(ostream&out) const;
|
||||
|
||||
@@ -82,6 +77,26 @@ class PUdp {
|
||||
|
||||
/*
|
||||
* $Log: PUdp.h,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
@@ -16,37 +16,41 @@
|
||||
* 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.7 2001/12/03 04:47:14 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 hname_t&n, NetNet::Type t, NetNet::PortType pt)
|
||||
: hname_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0)
|
||||
: 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), lidx_(0), ridx_(0)
|
||||
: 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
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
#if 0
|
||||
string PWire::name() const
|
||||
{
|
||||
string name = hname_[0];
|
||||
for (unsigned idx = 1 ; hname_[idx] ; idx += 1)
|
||||
name = name + "." + hname_[idx];
|
||||
}
|
||||
#endif
|
||||
|
||||
const hname_t& PWire::path() const
|
||||
{
|
||||
return hname_;
|
||||
@@ -64,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:
|
||||
@@ -110,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);
|
||||
@@ -127,6 +140,15 @@ 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.
|
||||
|
||||
@@ -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.11 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: PWire.h,v 1.16 2003/01/30 16:23:07 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
@@ -38,7 +38,7 @@ 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
|
||||
@@ -53,7 +53,6 @@ class PWire : public LineInfo {
|
||||
PWire(char*name, NetNet::Type t, NetNet::PortType pt);
|
||||
|
||||
// Return a hierarchical name.
|
||||
//const string name() const;
|
||||
const hname_t&path() const;
|
||||
|
||||
NetNet::Type get_wire_type() const;
|
||||
@@ -64,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<string,PExpr*> attributes;
|
||||
|
||||
// Write myself to the specified stream.
|
||||
void dump(ostream&out) const;
|
||||
@@ -81,6 +81,7 @@ class PWire : public LineInfo {
|
||||
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.
|
||||
@@ -99,6 +100,27 @@ class PWire : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: PWire.h,v $
|
||||
* 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.
|
||||
|
||||
+1
-1
@@ -79,5 +79,5 @@ Verilog packages from the main Debian software site.
|
||||
|
||||
* Install From Source
|
||||
|
||||
In this case, see the readme and other documentation that comes with
|
||||
In this case, see README.txt and other documentation that comes with
|
||||
the source.
|
||||
|
||||
+206
-172
@@ -1,5 +1,5 @@
|
||||
THE ICARUS VERILOG COMPILATION SYSTEM
|
||||
September 17, 2000
|
||||
Copyright 2000-2003 Stephen Williams
|
||||
|
||||
|
||||
1.0 What is ICARUS Verilog?
|
||||
@@ -12,14 +12,13 @@ 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, another faster simulator called VVP 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, structural Verilog, VHDL, etc.
|
||||
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.
|
||||
For instructions on how to run Icarus Verilog,
|
||||
see the ``iverilog'' man page.
|
||||
|
||||
|
||||
2.0 Building/Installing Icarus Verilog From Source
|
||||
@@ -30,6 +29,8 @@ 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
|
||||
@@ -38,7 +39,7 @@ on a UNIX-like system:
|
||||
- GNU Make
|
||||
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
|
||||
@@ -58,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
|
||||
@@ -67,13 +84,13 @@ with the commands:
|
||||
./configure
|
||||
make
|
||||
|
||||
Normally, this command automatically figures out every thing it needs
|
||||
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
|
||||
libaries are installed or not.
|
||||
libraries are installed or not.
|
||||
|
||||
--prefix=<root>
|
||||
The default is /usr/local, which causes the tool suite to
|
||||
@@ -81,8 +98,31 @@ configure script that modify its behavior:
|
||||
/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.
|
||||
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
|
||||
|
||||
@@ -91,7 +131,7 @@ 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
|
||||
Verilog on your own Verilog sources before the package is installed
|
||||
by root.
|
||||
|
||||
2.4 Installation
|
||||
@@ -127,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
|
||||
|
||||
@@ -150,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
|
||||
@@ -182,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
|
||||
@@ -206,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>);
|
||||
@@ -234,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)
|
||||
@@ -241,102 +289,8 @@ 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)
|
||||
|
||||
NOTE: The preferred method of running Icarus Verilog is the
|
||||
iverilog command described above. The instructions below may
|
||||
change at any time without notice.
|
||||
|
||||
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
|
||||
ivl -V
|
||||
|
||||
-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.
|
||||
|
||||
-h
|
||||
Print usage information, and exit.
|
||||
|
||||
-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 locate all the modules that are defined but
|
||||
never instantiated, and use these as the design roots for
|
||||
elaboration. This flag allows the choice of root module(s) to
|
||||
be manually overridden. It can be used more than once on the
|
||||
command line if multiple root modules are needed.
|
||||
|
||||
-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 progress indications, and (if supported by the system)
|
||||
executions times in ivl precessing steps.
|
||||
|
||||
-V
|
||||
Print version and copyright information for ivl, and exit.
|
||||
|
||||
-y <dir>
|
||||
Add the specified directory to the library search path. If
|
||||
missing modules are discovered during elaboration, ivl will
|
||||
attempt to locate an implementation by searching the library
|
||||
directories for a Verilog source file with the same name as
|
||||
the module.
|
||||
|
||||
4.2 EXAMPLES
|
||||
4.1 EXAMPLES
|
||||
|
||||
Example: Compiling "hello.vl"
|
||||
|
||||
@@ -353,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:
|
||||
@@ -374,29 +328,12 @@ 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.
|
||||
|
||||
@@ -404,36 +341,133 @@ constructs.
|
||||
|
||||
- trireg is not supported. tri0 and tri1 are supported.
|
||||
|
||||
- tran primitives, i.e. tran, tranif1, tranif0, rtran, rtranif1
|
||||
and rtranif0 are not supported.
|
||||
|
||||
- Module instance arrays are not supported, although gate instance
|
||||
arrays do work.
|
||||
|
||||
- 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.
|
||||
|
||||
$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.
|
||||
|
||||
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]>
|
||||
Venkat Iyer <[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
|
||||
@@ -447,14 +481,14 @@ 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]>
|
||||
@@ -477,10 +511,10 @@ 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.
|
||||
|
||||
|
||||
+24
-3
@@ -16,8 +16,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: Statement.cc,v 1.25 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Statement.cc,v 1.28 2002/08/12 01:34:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -32,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_()
|
||||
@@ -188,6 +190,7 @@ PDisable::~PDisable()
|
||||
PEventStatement::PEventStatement(const svector<PEEvent*>&ee)
|
||||
: expr_(ee), statement_(0)
|
||||
{
|
||||
assert(expr_.count() > 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -197,6 +200,11 @@ PEventStatement::PEventStatement(PEEvent*ee)
|
||||
expr_[0] = ee;
|
||||
}
|
||||
|
||||
PEventStatement::PEventStatement(void)
|
||||
: statement_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PEventStatement::~PEventStatement()
|
||||
{
|
||||
// delete the events and the statement?
|
||||
@@ -287,6 +295,19 @@ PWhile::~PWhile()
|
||||
|
||||
/*
|
||||
* $Log: Statement.cc,v $
|
||||
* Revision 1.28 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* 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.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.
|
||||
*
|
||||
* Revision 1.25 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
|
||||
+42
-6
@@ -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: Statement.h,v 1.31 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: Statement.h,v 1.38 2003/05/19 02:50:58 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
@@ -56,6 +56,8 @@ class PProcess : public LineInfo {
|
||||
Type type() const { return type_; }
|
||||
Statement*statement() { return statement_; }
|
||||
|
||||
map<string,PExpr*> attributes;
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -97,7 +99,7 @@ class PAssign_ : public Statement {
|
||||
protected:
|
||||
NetAssign_* elaborate_lval(Design*, NetScope*scope) const;
|
||||
|
||||
PDelays delay_;
|
||||
PExpr* delay_;
|
||||
PEventStatement*event_;
|
||||
|
||||
private:
|
||||
@@ -117,8 +119,6 @@ class PAssign : public PAssign_ {
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
NetProc*assign_to_memory_(class NetMemory*, PExpr*,
|
||||
Design*des, NetScope*scope) const;
|
||||
};
|
||||
|
||||
class PAssignNB : public PAssign_ {
|
||||
@@ -287,7 +287,7 @@ 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 {
|
||||
|
||||
@@ -308,6 +308,7 @@ class PDisable : public Statement {
|
||||
*
|
||||
* @name <statement>;
|
||||
* @(expr) <statement>;
|
||||
* @* <statement>;
|
||||
*/
|
||||
class PEventStatement : public Statement {
|
||||
|
||||
@@ -315,6 +316,8 @@ class PEventStatement : public Statement {
|
||||
|
||||
explicit PEventStatement(const svector<PEEvent*>&ee);
|
||||
explicit PEventStatement(PEEvent*ee);
|
||||
// Make an @* statement.
|
||||
explicit PEventStatement(void);
|
||||
|
||||
~PEventStatement();
|
||||
|
||||
@@ -328,6 +331,8 @@ class PEventStatement : public Statement {
|
||||
// elaborated statement to the event.
|
||||
NetProc* elaborate_st(Design*des, NetScope*scope, NetProc*st) const;
|
||||
|
||||
NetProc* elaborate_wait(Design*des, NetScope*scope, NetProc*st) const;
|
||||
|
||||
private:
|
||||
svector<PEEvent*>expr_;
|
||||
Statement*statement_;
|
||||
@@ -450,6 +455,37 @@ class PWhile : public Statement {
|
||||
|
||||
/*
|
||||
* $Log: Statement.h,v $
|
||||
* 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.
|
||||
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2002-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: StringHeap.cc,v 1.5 2003/03/01 06:25:30 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;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: StringHeap.cc,v $
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
#ifndef __StringHeap_H
|
||||
#define __StringHeap_H
|
||||
/*
|
||||
* Copyright (c) 2002-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: StringHeap.h,v 1.4 2003/03/01 06:25:30 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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*);
|
||||
|
||||
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*);
|
||||
|
||||
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.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
|
||||
+348
@@ -0,0 +1,348 @@
|
||||
#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.19 2003/10/10 02:57:45 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 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 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.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
+69
@@ -0,0 +1,69 @@
|
||||
# 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.1 2003/11/08 19:27:50 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; 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
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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.5 2003/09/04 20:28:05 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;
|
||||
}
|
||||
|
||||
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;
|
||||
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.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
-2
@@ -9,8 +9,11 @@
|
||||
echo "Autoconf in root..."
|
||||
autoconf
|
||||
|
||||
for dir in vpip vvp tgt-vvp tgt-fpga
|
||||
for dir in vpip vvp tgt-vvp tgt-fpga libveriuser cadpli
|
||||
do
|
||||
echo "Autoconf in $dir..."
|
||||
( cd $dir ; autoconf )
|
||||
( cd ./$dir ; autoconf )
|
||||
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,106 @@
|
||||
#
|
||||
# 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.8 2003/11/08 19:30:15 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@
|
||||
CXX = @CXX@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||
CFLAGS = @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) -Wall -I$(srcdir) -I$(srcdir)/.. -I.. $(CPPFLAGS) $(CFLAGS) -MD -c $<
|
||||
mv $*.d dep
|
||||
|
||||
O = cadpli.o
|
||||
|
||||
SYSTEM_VPI_LDFLAGS = -L../vvp -lvpi
|
||||
ifeq (@WIN32@,yes)
|
||||
SYSTEM_VPI_LDFLAGS += -liberty
|
||||
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
|
||||
|
||||
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)
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* 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.5 2003/08/26 16:26:02 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;
|
||||
void*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.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,223 @@
|
||||
AC_INIT(Makefile.in)
|
||||
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_CHECK_TOOL(STRIP, strip, true)
|
||||
|
||||
AC_CYGWIN
|
||||
AC_EXEEXT
|
||||
AC_MINGW32
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
# Darwin requires -no-cpp-precomp
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
CPPFLAGS="-no-cpp-precomp $CPPFLAGS"
|
||||
CFLAGS="-no-cpp-precomp $CFLAGS"
|
||||
;;
|
||||
esac
|
||||
|
||||
# The -fPIC flag is used to tell the compiler to make position
|
||||
# independent code. It is needed when making shared objects.
|
||||
|
||||
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)
|
||||
|
||||
# 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. VPI support requires this.
|
||||
AC_MSG_CHECKING("for -rdynamic compiler flag")
|
||||
|
||||
rdynamic=-rdynamic
|
||||
case "${host}" in
|
||||
|
||||
*-*-netbsd*)
|
||||
rdynamic="-Wl,--export-dynamic"
|
||||
;;
|
||||
|
||||
*-*-solaris*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-cygwin*)
|
||||
rdynamic=""
|
||||
;;
|
||||
|
||||
*-*-hpux*)
|
||||
rdynamic="-E"
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
rdynamic="-Wl,-all_load"
|
||||
;;
|
||||
|
||||
esac
|
||||
AC_SUBST(rdynamic)
|
||||
AC_MSG_RESULT($rdynamic)
|
||||
|
||||
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)
|
||||
|
||||
AC_MSG_CHECKING("for extra libs needed")
|
||||
EXTRALIBS=
|
||||
case "${host}" in
|
||||
*-*-cygwin*)
|
||||
EXTRALIBS="-liberty"
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(EXTRALIBS)
|
||||
AC_MSG_RESULT($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.
|
||||
#######################
|
||||
|
||||
AC_CYGWIN
|
||||
AC_EXEEXT
|
||||
AC_MINGW32
|
||||
|
||||
|
||||
WIN32=no
|
||||
AC_MSG_CHECKING("Checking for windows")
|
||||
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
|
||||
then
|
||||
WIN32=yes
|
||||
fi
|
||||
AC_SUBST(WIN32)
|
||||
AC_MSG_RESULT($WIN32)
|
||||
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 "$CYGWIN" != "yes" -a "$MINGW32" != "yes"; 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")
|
||||
|
||||
#######################
|
||||
## end of test for underscores
|
||||
#######################
|
||||
|
||||
|
||||
|
||||
AC_MSG_CHECKING("for ident support in C compiler")
|
||||
ident_support='-DHAVE_CVS_IDENT=1'
|
||||
case "${host}" in
|
||||
|
||||
*-*-cygwin*)
|
||||
ident_support=
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
ident_support=
|
||||
;;
|
||||
|
||||
*-*-machten*)
|
||||
ident_support=
|
||||
;;
|
||||
esac
|
||||
|
||||
AC_SUBST(ident_support)
|
||||
AC_MSG_RESULT($ident_support)
|
||||
|
||||
# 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,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: ivl_dlfcn.h,v 1.3 2001/05/22 02:14:47 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: ivl_dlfcn.h,v 1.1 2003/02/17 00:01:25 steve Exp $"
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
@@ -45,11 +45,24 @@ inline void ivl_dlclose(ivl_dll_t dll)
|
||||
{ (void)FreeLibrary((HINSTANCE)dll);}
|
||||
|
||||
inline const char *dlerror(void)
|
||||
{ static char s[30]; sprintf(s,"DLError:%ld", GetLastError()); return s;}
|
||||
{
|
||||
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); }
|
||||
@@ -77,18 +90,12 @@ inline const char*dlerror(void)
|
||||
|
||||
/*
|
||||
* $Log: ivl_dlfcn.h,v $
|
||||
* Revision 1.3 2001/05/22 02:14:47 steve
|
||||
* Update the mingw build to not require cygwin files.
|
||||
* 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.
|
||||
*
|
||||
* Revision 1.2 2001/05/20 15:09:40 steve
|
||||
* Mingw32 support (Venkat Iyer)
|
||||
*
|
||||
* Revision 1.1 2001/03/16 01:44:34 steve
|
||||
* Add structures for VPI support, and all the %vpi_call
|
||||
* instruction. Get linking of VPI modules to work.
|
||||
*
|
||||
* Revision 1.1 2001/01/14 17:12:59 steve
|
||||
* possible HP/UX portability support.
|
||||
* Change the +cadpli flag to -cadpli, to keep the
|
||||
* plusargs namespace clear.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+2
-2
@@ -2,5 +2,5 @@
|
||||
# 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 -- -
|
||||
[-tvvp-check]
|
||||
<ivl>./ivl %[N-N%N] -C%C -tdll -fDLL=./tgt-vvp/vvp.tgt -Fcprop -Fnodangle -fVPI_MODULE_PATH=vpi %f %m -- -
|
||||
|
||||
+78
-25
@@ -18,11 +18,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: compiler.h,v 1.7 2001/11/16 05:07:19 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: compiler.h,v 1.19 2003/11/13 05:55:33 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include <string>
|
||||
# include "StringHeap.h"
|
||||
|
||||
/*
|
||||
* This defines constants and defaults for the compiler in general.
|
||||
@@ -61,43 +64,93 @@
|
||||
|
||||
/*
|
||||
* 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
|
||||
* 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;
|
||||
|
||||
/* This is an ordered list of libraries to search. */
|
||||
extern list<const char*>library_dirs;
|
||||
/* 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<string,unsigned> missing_modules;
|
||||
|
||||
extern StringHeapLex lex_strings;
|
||||
|
||||
/*
|
||||
* $Log: compiler.h,v $
|
||||
* 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.
|
||||
*
|
||||
* Revision 1.15 2003/02/22 04:12:49 steve
|
||||
* Add the portbind warning.
|
||||
*
|
||||
* Revision 1.14 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.13 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.12 2002/05/28 20:40:37 steve
|
||||
* ivl indexes the search path for libraries, and
|
||||
* supports case insensitive module-to-file lookup.
|
||||
*
|
||||
* Revision 1.11 2002/05/28 00:50:39 steve
|
||||
* Add the ivl -C flag for bulk configuration
|
||||
* from the driver, and use that to run library
|
||||
* modules through the preprocessor.
|
||||
*
|
||||
* Revision 1.10 2002/05/24 01:13:00 steve
|
||||
* Support language generation flag -g.
|
||||
*
|
||||
* Revision 1.9 2002/04/22 00:53:39 steve
|
||||
* Do not allow implicit wires in sensitivity lists.
|
||||
*
|
||||
* Revision 1.8 2002/04/15 00:04:22 steve
|
||||
* Timescale warnings.
|
||||
*
|
||||
* Revision 1.7 2001/11/16 05:07:19 steve
|
||||
* Add support for +libext+ in command files.
|
||||
*
|
||||
* Revision 1.6 2001/10/20 23:02:40 steve
|
||||
* Add automatic module libraries.
|
||||
*
|
||||
* Revision 1.5 2000/10/31 17:49:02 steve
|
||||
* Support time variables.
|
||||
*
|
||||
* 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.3 2000/03/17 21:50:25 steve
|
||||
* Switch to control warnings.
|
||||
*
|
||||
* Revision 1.2 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.1 1999/06/06 20:42:48 steve
|
||||
* Make compiler width a compile time constant.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
Vendored
+547
-366
File diff suppressed because it is too large
Load Diff
+27
-2
@@ -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)
|
||||
#ident "$Id: config.h.in,v 1.3 2001/10/18 16:16:23 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: config.h.in,v 1.10 2003/08/26 16:26:01 steve Exp $"
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
@@ -37,15 +37,40 @@
|
||||
# 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.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)
|
||||
*
|
||||
|
||||
Vendored
+319
-130
@@ -1,8 +1,10 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script, version 1.1.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# Configuration validation subroutine script.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
|
||||
# 2000, 2001, 2002 Free Software Foundation, Inc.
|
||||
|
||||
timestamp='2002-07-03'
|
||||
|
||||
# This file is (in principle) common to ALL GNU software.
|
||||
# The presence of a machine in this file suggests that SOME GNU software
|
||||
# can handle that machine. It does not imply ALL GNU software can.
|
||||
@@ -27,8 +29,8 @@
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Written by Per Bothner <[email protected]>.
|
||||
# Please send patches to <[email protected]>.
|
||||
# Please send patches to <[email protected]>. Submit a context
|
||||
# diff and a properly formatted ChangeLog entry.
|
||||
#
|
||||
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||
# Supply the specified configuration type as an argument.
|
||||
@@ -50,30 +52,73 @@
|
||||
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
|
||||
# It is wrong to echo any other type of specification.
|
||||
|
||||
if [ x$1 = x ]
|
||||
then
|
||||
echo Configuration name missing. 1>&2
|
||||
echo "Usage: $0 CPU-MFR-OPSYS" 1>&2
|
||||
echo "or $0 ALIAS" 1>&2
|
||||
echo where ALIAS is a recognized configuration type. 1>&2
|
||||
exit 1
|
||||
fi
|
||||
me=`echo "$0" | sed -e 's,.*/,,'`
|
||||
|
||||
# First pass through any local machine types.
|
||||
case $1 in
|
||||
*local*)
|
||||
echo $1
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
usage="\
|
||||
Usage: $0 [OPTION] CPU-MFR-OPSYS
|
||||
$0 [OPTION] ALIAS
|
||||
|
||||
Canonicalize a configuration name.
|
||||
|
||||
Operation modes:
|
||||
-h, --help print this help, then exit
|
||||
-t, --time-stamp print date of last modification, then exit
|
||||
-v, --version print version number, then exit
|
||||
|
||||
Report bugs and patches to <[email protected]>."
|
||||
|
||||
version="\
|
||||
GNU config.sub ($timestamp)
|
||||
|
||||
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
This is free software; see the source for copying conditions. There is NO
|
||||
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
|
||||
|
||||
help="
|
||||
Try \`$me --help' for more information."
|
||||
|
||||
# Parse command line
|
||||
while test $# -gt 0 ; do
|
||||
case $1 in
|
||||
--time-stamp | --time* | -t )
|
||||
echo "$timestamp" ; exit 0 ;;
|
||||
--version | -v )
|
||||
echo "$version" ; exit 0 ;;
|
||||
--help | --h* | -h )
|
||||
echo "$usage"; exit 0 ;;
|
||||
-- ) # Stop option processing
|
||||
shift; break ;;
|
||||
- ) # Use stdin as input.
|
||||
break ;;
|
||||
-* )
|
||||
echo "$me: invalid option $1$help"
|
||||
exit 1 ;;
|
||||
|
||||
*local*)
|
||||
# First pass through any local machine types.
|
||||
echo $1
|
||||
exit 0;;
|
||||
|
||||
* )
|
||||
break ;;
|
||||
esac
|
||||
done
|
||||
|
||||
case $# in
|
||||
0) echo "$me: missing argument$help" >&2
|
||||
exit 1;;
|
||||
1) ;;
|
||||
*) echo "$me: too many arguments$help" >&2
|
||||
exit 1;;
|
||||
esac
|
||||
|
||||
# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
|
||||
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
nto-qnx* | linux-gnu*)
|
||||
nto-qnx* | linux-gnu* | freebsd*-gnu* | storm-chaos* | os2-emx* | windows32-* | rtmk-nova*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
;;
|
||||
@@ -99,7 +144,7 @@ case $os in
|
||||
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
|
||||
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
|
||||
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
|
||||
-apple)
|
||||
-apple | -axis)
|
||||
os=
|
||||
basic_machine=$1
|
||||
;;
|
||||
@@ -113,6 +158,14 @@ case $os in
|
||||
os=-vxworks
|
||||
basic_machine=$1
|
||||
;;
|
||||
-chorusos*)
|
||||
os=-chorusos
|
||||
basic_machine=$1
|
||||
;;
|
||||
-chorusrdb)
|
||||
os=-chorusrdb
|
||||
basic_machine=$1
|
||||
;;
|
||||
-hiux*)
|
||||
os=-hiuxwe2
|
||||
;;
|
||||
@@ -171,30 +224,58 @@ esac
|
||||
case $basic_machine in
|
||||
# Recognize the basic CPU types without company name.
|
||||
# Some are omitted here because they have special meanings below.
|
||||
tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
|
||||
| arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
|
||||
| 580 | i960 | h8300 \
|
||||
| x86 | ppcbe | mipsbe | mipsle | shbe | shle | armbe | armle \
|
||||
| hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \
|
||||
| hppa64 \
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \
|
||||
| alphaev6[78] \
|
||||
| we32k | ns16k | clipper | i370 | sh | powerpc | powerpcle \
|
||||
| 1750a | dsp16xx | pdp11 | mips16 | mips64 | mipsel | mips64el \
|
||||
| mips64orion | mips64orionel | mipstx39 | mipstx39el \
|
||||
| mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \
|
||||
| mips64vr5000 | miprs64vr5000el | mcore \
|
||||
| sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \
|
||||
| thumb | d10v | fr30 | avr)
|
||||
1750a | 580 \
|
||||
| a29k \
|
||||
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
|
||||
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
|
||||
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
|
||||
| c4x | clipper \
|
||||
| d10v | d30v | dlx | dsp16xx \
|
||||
| fr30 | frv \
|
||||
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
|
||||
| i370 | i860 | i960 | ia64 \
|
||||
| ip2k \
|
||||
| m32r | m68000 | m68k | m88k | mcore \
|
||||
| mips | mipsbe | mipseb | mipsel | mipsle \
|
||||
| mips16 \
|
||||
| mips64 | mips64el \
|
||||
| mips64orion | mips64orionel \
|
||||
| mips64vr4100 | mips64vr4100el \
|
||||
| mips64vr4300 | mips64vr4300el \
|
||||
| mips64vr5000 | mips64vr5000el \
|
||||
| mipsisa32 | mipsisa32el \
|
||||
| mipsisa64 | mipsisa64el \
|
||||
| mipsisa64sb1 | mipsisa64sb1el \
|
||||
| mipstx39 | mipstx39el \
|
||||
| mn10200 | mn10300 \
|
||||
| ns16k | ns32k \
|
||||
| openrisc | or32 \
|
||||
| pdp10 | pdp11 | pj | pjl \
|
||||
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
|
||||
| pyramid \
|
||||
| sh | sh[1234] | sh3e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
|
||||
| sh64 | sh64le \
|
||||
| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv9 | sparcv9b \
|
||||
| strongarm \
|
||||
| tahoe | thumb | tic80 | tron \
|
||||
| v850 | v850e \
|
||||
| we32k \
|
||||
| x86 | xscale | xstormy16 | xtensa \
|
||||
| z8k)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl)
|
||||
m6811 | m68hc11 | m6812 | m68hc12)
|
||||
# Motorola 68HC11/12.
|
||||
basic_machine=$basic_machine-unknown
|
||||
os=-none
|
||||
;;
|
||||
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
|
||||
;;
|
||||
|
||||
# We use `pc' rather than `unknown'
|
||||
# because (1) that's what they normally are, and
|
||||
# (2) the word "unknown" tends to confuse beginning users.
|
||||
i[34567]86)
|
||||
i*86 | x86_64)
|
||||
basic_machine=$basic_machine-pc
|
||||
;;
|
||||
# Object if more than one company name word.
|
||||
@@ -203,28 +284,54 @@ case $basic_machine in
|
||||
exit 1
|
||||
;;
|
||||
# Recognize the basic CPU types with company name.
|
||||
# FIXME: clean up the formatting here.
|
||||
vax-* | tahoe-* | i[34567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \
|
||||
| m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
|
||||
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
|
||||
| power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \
|
||||
| xmp-* | ymp-* \
|
||||
| x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* | armbe-* | armle-* \
|
||||
| hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
|
||||
| hppa2.0n-* | hppa64-* \
|
||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \
|
||||
| alphaev6[78]-* \
|
||||
| we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \
|
||||
| clipper-* | orion-* \
|
||||
| sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
|
||||
| sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
|
||||
| mips64el-* | mips64orion-* | mips64orionel-* \
|
||||
| mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \
|
||||
| mipstx39-* | mipstx39el-* | mcore-* \
|
||||
| f301-* | armv*-* | s390-* | sv1-* | t3e-* \
|
||||
| m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \
|
||||
| thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \
|
||||
| bs2000-*)
|
||||
580-* \
|
||||
| a29k-* \
|
||||
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
|
||||
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
|
||||
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
|
||||
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
|
||||
| avr-* \
|
||||
| bs2000-* \
|
||||
| c[123]* | c30-* | [cjt]90-* | c54x-* \
|
||||
| clipper-* | cydra-* \
|
||||
| d10v-* | d30v-* | dlx-* \
|
||||
| elxsi-* \
|
||||
| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
|
||||
| h8300-* | h8500-* \
|
||||
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
|
||||
| i*86-* | i860-* | i960-* | ia64-* \
|
||||
| ip2k-* \
|
||||
| m32r-* \
|
||||
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
|
||||
| m88110-* | m88k-* | mcore-* \
|
||||
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
|
||||
| mips16-* \
|
||||
| mips64-* | mips64el-* \
|
||||
| mips64orion-* | mips64orionel-* \
|
||||
| mips64vr4100-* | mips64vr4100el-* \
|
||||
| mips64vr4300-* | mips64vr4300el-* \
|
||||
| mips64vr5000-* | mips64vr5000el-* \
|
||||
| mipsisa32-* | mipsisa32el-* \
|
||||
| mipsisa64-* | mipsisa64el-* \
|
||||
| mipsisa64sb1-* | mipsisa64sb1el-* \
|
||||
| mipstx39 | mipstx39el \
|
||||
| none-* | np1-* | ns16k-* | ns32k-* \
|
||||
| orion-* \
|
||||
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
|
||||
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
|
||||
| pyramid-* \
|
||||
| romp-* | rs6000-* \
|
||||
| sh-* | sh[1234]-* | sh3e-* | sh[34]eb-* | shbe-* \
|
||||
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
|
||||
| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
|
||||
| sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
|
||||
| tahoe-* | thumb-* | tic30-* | tic54x-* | tic80-* | tron-* \
|
||||
| v850-* | v850e-* | vax-* \
|
||||
| we32k-* \
|
||||
| x86-* | x86_64-* | xps100-* | xscale-* | xstormy16-* \
|
||||
| xtensa-* \
|
||||
| ymp-* \
|
||||
| z8k-*)
|
||||
;;
|
||||
# Recognize the various machine names and aliases which stand
|
||||
# for a CPU type and a company and sometimes even an OS.
|
||||
@@ -261,14 +368,14 @@ case $basic_machine in
|
||||
os=-sysv
|
||||
;;
|
||||
amiga | amiga-*)
|
||||
basic_machine=m68k-cbm
|
||||
basic_machine=m68k-unknown
|
||||
;;
|
||||
amigaos | amigados)
|
||||
basic_machine=m68k-cbm
|
||||
basic_machine=m68k-unknown
|
||||
os=-amigaos
|
||||
;;
|
||||
amigaunix | amix)
|
||||
basic_machine=m68k-cbm
|
||||
basic_machine=m68k-unknown
|
||||
os=-sysv4
|
||||
;;
|
||||
apollo68)
|
||||
@@ -287,6 +394,10 @@ case $basic_machine in
|
||||
basic_machine=ns32k-sequent
|
||||
os=-dynix
|
||||
;;
|
||||
c90)
|
||||
basic_machine=c90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
convex-c1)
|
||||
basic_machine=c1-convex
|
||||
os=-bsd
|
||||
@@ -307,27 +418,30 @@ case $basic_machine in
|
||||
basic_machine=c38-convex
|
||||
os=-bsd
|
||||
;;
|
||||
cray | ymp)
|
||||
basic_machine=ymp-cray
|
||||
os=-unicos
|
||||
;;
|
||||
cray2)
|
||||
basic_machine=cray2-cray
|
||||
os=-unicos
|
||||
;;
|
||||
[ctj]90-cray)
|
||||
basic_machine=c90-cray
|
||||
cray | j90)
|
||||
basic_machine=j90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
crds | unos)
|
||||
basic_machine=m68k-crds
|
||||
;;
|
||||
cris | cris-* | etrax*)
|
||||
basic_machine=cris-axis
|
||||
;;
|
||||
da30 | da30-*)
|
||||
basic_machine=m68k-da30
|
||||
;;
|
||||
decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
|
||||
basic_machine=mips-dec
|
||||
;;
|
||||
decsystem10* | dec10*)
|
||||
basic_machine=pdp10-dec
|
||||
os=-tops10
|
||||
;;
|
||||
decsystem20* | dec20*)
|
||||
basic_machine=pdp10-dec
|
||||
os=-tops20
|
||||
;;
|
||||
delta | 3300 | motorola-3300 | motorola-delta \
|
||||
| 3300-motorola | delta-motorola)
|
||||
basic_machine=m68k-motorola
|
||||
@@ -369,6 +483,10 @@ case $basic_machine in
|
||||
basic_machine=tron-gmicro
|
||||
os=-sysv
|
||||
;;
|
||||
go32)
|
||||
basic_machine=i386-pc
|
||||
os=-go32
|
||||
;;
|
||||
h3050r* | hiux*)
|
||||
basic_machine=hppa1.1-hitachi
|
||||
os=-hiuxwe2
|
||||
@@ -444,19 +562,19 @@ case $basic_machine in
|
||||
basic_machine=i370-ibm
|
||||
;;
|
||||
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
|
||||
i[34567]86v32)
|
||||
i*86v32)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-sysv32
|
||||
;;
|
||||
i[34567]86v4*)
|
||||
i*86v4*)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-sysv4
|
||||
;;
|
||||
i[34567]86v)
|
||||
i*86v)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-sysv
|
||||
;;
|
||||
i[34567]86sol2)
|
||||
i*86sol2)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-solaris2
|
||||
;;
|
||||
@@ -468,14 +586,6 @@ case $basic_machine in
|
||||
basic_machine=i386-unknown
|
||||
os=-vsta
|
||||
;;
|
||||
i386-go32 | go32)
|
||||
basic_machine=i386-unknown
|
||||
os=-go32
|
||||
;;
|
||||
i386-mingw32 | mingw32)
|
||||
basic_machine=i386-unknown
|
||||
os=-mingw32
|
||||
;;
|
||||
iris | iris4d)
|
||||
basic_machine=mips-sgi
|
||||
case $os in
|
||||
@@ -501,6 +611,10 @@ case $basic_machine in
|
||||
basic_machine=ns32k-utek
|
||||
os=-sysv
|
||||
;;
|
||||
mingw32)
|
||||
basic_machine=i386-pc
|
||||
os=-mingw32
|
||||
;;
|
||||
miniframe)
|
||||
basic_machine=m68000-convergent
|
||||
;;
|
||||
@@ -508,14 +622,6 @@ case $basic_machine in
|
||||
basic_machine=m68k-atari
|
||||
os=-mint
|
||||
;;
|
||||
mipsel*-linux*)
|
||||
basic_machine=mipsel-unknown
|
||||
os=-linux-gnu
|
||||
;;
|
||||
mips*-linux*)
|
||||
basic_machine=mips-unknown
|
||||
os=-linux-gnu
|
||||
;;
|
||||
mips3*-*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
|
||||
;;
|
||||
@@ -530,8 +636,12 @@ case $basic_machine in
|
||||
basic_machine=m68k-rom68k
|
||||
os=-coff
|
||||
;;
|
||||
morphos)
|
||||
basic_machine=powerpc-unknown
|
||||
os=-morphos
|
||||
;;
|
||||
msdos)
|
||||
basic_machine=i386-unknown
|
||||
basic_machine=i386-pc
|
||||
os=-msdos
|
||||
;;
|
||||
mvs)
|
||||
@@ -595,6 +705,10 @@ case $basic_machine in
|
||||
basic_machine=i960-intel
|
||||
os=-mon960
|
||||
;;
|
||||
nonstopux)
|
||||
basic_machine=mips-compaq
|
||||
os=-nonstopux
|
||||
;;
|
||||
np1)
|
||||
basic_machine=np1-gould
|
||||
;;
|
||||
@@ -605,6 +719,10 @@ case $basic_machine in
|
||||
basic_machine=hppa1.1-oki
|
||||
os=-proelf
|
||||
;;
|
||||
or32 | or32-*)
|
||||
basic_machine=or32-unknown
|
||||
os=-coff
|
||||
;;
|
||||
OSE68000 | ose68000)
|
||||
basic_machine=m68000-ericsson
|
||||
os=-ose
|
||||
@@ -630,28 +748,28 @@ case $basic_machine in
|
||||
pc532 | pc532-*)
|
||||
basic_machine=ns32k-pc532
|
||||
;;
|
||||
pentium | p5 | k5 | k6 | nexen)
|
||||
pentium | p5 | k5 | k6 | nexgen | viac3)
|
||||
basic_machine=i586-pc
|
||||
;;
|
||||
pentiumpro | p6 | 6x86)
|
||||
pentiumpro | p6 | 6x86 | athlon)
|
||||
basic_machine=i686-pc
|
||||
;;
|
||||
pentiumii | pentium2)
|
||||
basic_machine=i786-pc
|
||||
basic_machine=i686-pc
|
||||
;;
|
||||
pentium-* | p5-* | k5-* | k6-* | nexen-*)
|
||||
pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
|
||||
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pentiumpro-* | p6-* | 6x86-*)
|
||||
pentiumpro-* | p6-* | 6x86-* | athlon-*)
|
||||
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pentiumii-* | pentium2-*)
|
||||
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pn)
|
||||
basic_machine=pn-gould
|
||||
;;
|
||||
power) basic_machine=rs6000-ibm
|
||||
power) basic_machine=power-ibm
|
||||
;;
|
||||
ppc) basic_machine=powerpc-unknown
|
||||
;;
|
||||
@@ -663,9 +781,23 @@ case $basic_machine in
|
||||
ppcle-* | powerpclittle-*)
|
||||
basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppc64) basic_machine=powerpc64-unknown
|
||||
;;
|
||||
ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ppc64le | powerpc64little | ppc64-le | powerpc64-little)
|
||||
basic_machine=powerpc64le-unknown
|
||||
;;
|
||||
ppc64le-* | powerpc64little-*)
|
||||
basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
ps2)
|
||||
basic_machine=i386-ibm
|
||||
;;
|
||||
pw32)
|
||||
basic_machine=i586-unknown
|
||||
os=-pw32
|
||||
;;
|
||||
rom68k)
|
||||
basic_machine=m68k-rom68k
|
||||
os=-coff
|
||||
@@ -676,6 +808,12 @@ case $basic_machine in
|
||||
rtpc | rtpc-*)
|
||||
basic_machine=romp-ibm
|
||||
;;
|
||||
s390 | s390-*)
|
||||
basic_machine=s390-ibm
|
||||
;;
|
||||
s390x | s390x-*)
|
||||
basic_machine=s390x-ibm
|
||||
;;
|
||||
sa29200)
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
@@ -687,7 +825,7 @@ case $basic_machine in
|
||||
basic_machine=sh-hitachi
|
||||
os=-hms
|
||||
;;
|
||||
sparclite-wrs)
|
||||
sparclite-wrs | simso-wrs)
|
||||
basic_machine=sparclite-wrs
|
||||
os=-vxworks
|
||||
;;
|
||||
@@ -745,7 +883,7 @@ case $basic_machine in
|
||||
sun386 | sun386i | roadrunner)
|
||||
basic_machine=i386-sun
|
||||
;;
|
||||
sv1)
|
||||
sv1)
|
||||
basic_machine=sv1-cray
|
||||
os=-unicos
|
||||
;;
|
||||
@@ -753,16 +891,32 @@ case $basic_machine in
|
||||
basic_machine=i386-sequent
|
||||
os=-dynix
|
||||
;;
|
||||
t3e)
|
||||
basic_machine=t3e-cray
|
||||
t3d)
|
||||
basic_machine=alpha-cray
|
||||
os=-unicos
|
||||
;;
|
||||
t3e)
|
||||
basic_machine=alphaev5-cray
|
||||
os=-unicos
|
||||
;;
|
||||
t90)
|
||||
basic_machine=t90-cray
|
||||
os=-unicos
|
||||
;;
|
||||
tic54x | c54x*)
|
||||
basic_machine=tic54x-unknown
|
||||
os=-coff
|
||||
;;
|
||||
tx39)
|
||||
basic_machine=mipstx39-unknown
|
||||
;;
|
||||
tx39el)
|
||||
basic_machine=mipstx39el-unknown
|
||||
;;
|
||||
toad1)
|
||||
basic_machine=pdp10-xkl
|
||||
os=-tops20
|
||||
;;
|
||||
tower | tower-32)
|
||||
basic_machine=m68k-ncr
|
||||
;;
|
||||
@@ -809,13 +963,17 @@ case $basic_machine in
|
||||
basic_machine=hppa1.1-winbond
|
||||
os=-proelf
|
||||
;;
|
||||
xmp)
|
||||
basic_machine=xmp-cray
|
||||
os=-unicos
|
||||
windows32)
|
||||
basic_machine=i386-pc
|
||||
os=-windows32-msvcrt
|
||||
;;
|
||||
xps | xps100)
|
||||
basic_machine=xps100-honeywell
|
||||
;;
|
||||
ymp)
|
||||
basic_machine=ymp-cray
|
||||
os=-unicos
|
||||
;;
|
||||
z8k-*-coff)
|
||||
basic_machine=z8k-unknown
|
||||
os=-sim
|
||||
@@ -836,13 +994,6 @@ case $basic_machine in
|
||||
op60c)
|
||||
basic_machine=hppa1.1-oki
|
||||
;;
|
||||
mips)
|
||||
if [ x$os = x-linux-gnu ]; then
|
||||
basic_machine=mips-unknown
|
||||
else
|
||||
basic_machine=mips-mips
|
||||
fi
|
||||
;;
|
||||
romp)
|
||||
basic_machine=romp-ibm
|
||||
;;
|
||||
@@ -852,13 +1003,23 @@ case $basic_machine in
|
||||
vax)
|
||||
basic_machine=vax-dec
|
||||
;;
|
||||
pdp10)
|
||||
# there are many clones, so DEC is not a safe bet
|
||||
basic_machine=pdp10-unknown
|
||||
;;
|
||||
pdp11)
|
||||
basic_machine=pdp11-dec
|
||||
;;
|
||||
we32k)
|
||||
basic_machine=we32k-att
|
||||
;;
|
||||
sparc | sparcv9)
|
||||
sh3 | sh4 | sh3eb | sh4eb | sh[1234]le | sh3ele)
|
||||
basic_machine=sh-unknown
|
||||
;;
|
||||
sh64)
|
||||
basic_machine=sh64-unknown
|
||||
;;
|
||||
sparc | sparcv9 | sparcv9b)
|
||||
basic_machine=sparc-sun
|
||||
;;
|
||||
cydra)
|
||||
@@ -880,6 +1041,9 @@ case $basic_machine in
|
||||
basic_machine=c4x-none
|
||||
os=-coff
|
||||
;;
|
||||
*-unknown)
|
||||
# Make sure to match an already-canonicalized machine name.
|
||||
;;
|
||||
*)
|
||||
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
|
||||
exit 1
|
||||
@@ -936,15 +1100,19 @@ case $os in
|
||||
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -chorusos* | -chorusrdb* \
|
||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -mingw32* | -linux* | -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
|
||||
| -openstep* | -oskit*)
|
||||
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
|
||||
| -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
|
||||
| -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
|
||||
| -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* | -powermax*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
-qnx*)
|
||||
case $basic_machine in
|
||||
x86-* | i[34567]86-*)
|
||||
x86-* | i*86-*)
|
||||
;;
|
||||
*)
|
||||
os=-nto$os
|
||||
@@ -961,9 +1129,6 @@ case $os in
|
||||
-mac*)
|
||||
os=`echo $os | sed -e 's|mac|macos|'`
|
||||
;;
|
||||
-linux*)
|
||||
os=`echo $os | sed -e 's|linux|linux-gnu|'`
|
||||
;;
|
||||
-sunos5*)
|
||||
os=`echo $os | sed -e 's|sunos5|solaris2|'`
|
||||
;;
|
||||
@@ -991,16 +1156,22 @@ case $os in
|
||||
-acis*)
|
||||
os=-aos
|
||||
;;
|
||||
-atheos*)
|
||||
os=-atheos
|
||||
;;
|
||||
-386bsd)
|
||||
os=-bsd
|
||||
;;
|
||||
-ctix* | -uts*)
|
||||
os=-sysv
|
||||
;;
|
||||
-nova*)
|
||||
os=-rtmk-nova
|
||||
;;
|
||||
-ns2 )
|
||||
os=-nextstep2
|
||||
;;
|
||||
-nsk)
|
||||
-nsk*)
|
||||
os=-nsk
|
||||
;;
|
||||
# Preserve the version number of sinix5.
|
||||
@@ -1037,7 +1208,7 @@ case $os in
|
||||
-xenix)
|
||||
os=-xenix
|
||||
;;
|
||||
-*mint | -*MiNT)
|
||||
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
||||
os=-mint
|
||||
;;
|
||||
-none)
|
||||
@@ -1071,6 +1242,10 @@ case $basic_machine in
|
||||
arm*-semi)
|
||||
os=-aout
|
||||
;;
|
||||
# This must come before the *-dec entry.
|
||||
pdp10-*)
|
||||
os=-tops20
|
||||
;;
|
||||
pdp11-*)
|
||||
os=-none
|
||||
;;
|
||||
@@ -1098,6 +1273,9 @@ case $basic_machine in
|
||||
mips*-*)
|
||||
os=-elf
|
||||
;;
|
||||
or32-*)
|
||||
os=-coff
|
||||
;;
|
||||
*-tti) # must be before sparc entry or we get the wrong os.
|
||||
os=-sysv3
|
||||
;;
|
||||
@@ -1179,7 +1357,7 @@ case $basic_machine in
|
||||
*-masscomp)
|
||||
os=-rtu
|
||||
;;
|
||||
f301-fujitsu)
|
||||
f30[01]-fujitsu | f700-fujitsu)
|
||||
os=-uxpv
|
||||
;;
|
||||
*-rom68k)
|
||||
@@ -1245,7 +1423,7 @@ case $basic_machine in
|
||||
-ptx*)
|
||||
vendor=sequent
|
||||
;;
|
||||
-vxsim* | -vxworks*)
|
||||
-vxsim* | -vxworks* | -windiss*)
|
||||
vendor=wrs
|
||||
;;
|
||||
-aux*)
|
||||
@@ -1257,12 +1435,23 @@ case $basic_machine in
|
||||
-mpw* | -macos*)
|
||||
vendor=apple
|
||||
;;
|
||||
-*mint | -*MiNT)
|
||||
-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
|
||||
vendor=atari
|
||||
;;
|
||||
-vos*)
|
||||
vendor=stratus
|
||||
;;
|
||||
esac
|
||||
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
|
||||
;;
|
||||
esac
|
||||
|
||||
echo $basic_machine$os
|
||||
exit 0
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "timestamp='"
|
||||
# time-stamp-format: "%:y-%02m-%02d"
|
||||
# time-stamp-end: "'"
|
||||
# End:
|
||||
|
||||
+89
-67
@@ -1,6 +1,7 @@
|
||||
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)
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
@@ -14,9 +15,55 @@ then
|
||||
exit 1
|
||||
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_CYGWIN
|
||||
AC_EXEEXT
|
||||
AC_MINGW32
|
||||
|
||||
WIN32=no
|
||||
AC_MSG_CHECKING("Checking for windows")
|
||||
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
|
||||
then
|
||||
WIN32=yes
|
||||
fi
|
||||
|
||||
AC_SUBST(MINGW32)
|
||||
AC_SUBST(WIN32)
|
||||
AC_MSG_RESULT($WIN32)
|
||||
AC_SUBST(EXEEXT)
|
||||
|
||||
# vvp32 is by default disabled
|
||||
#enable_vvp32=no
|
||||
AC_SUBST(enable_vvp32)
|
||||
|
||||
|
||||
AC_LANG_CPLUSPLUS
|
||||
|
||||
AC_CHECK_HEADERS(getopt.h malloc.h iosfwd sys/wait.h)
|
||||
AC_CHECK_HEADERS(getopt.h malloc.h inttypes.h libiberty.h iosfwd sys/wait.h)
|
||||
|
||||
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(
|
||||
@@ -30,7 +77,8 @@ do_times=no
|
||||
AC_MSG_RESULT($do_times)
|
||||
|
||||
AC_CHECK_HEADER(ipal.h, HAVE_IPAL=yes, HAVE_IPAL=)
|
||||
AC_ARG_WITH(ipal,enable PAL target,
|
||||
AC_ARG_WITH(ipal,
|
||||
[ --with-ipal enable PAL target],
|
||||
if test "$with_ipal" = no; then
|
||||
echo Disabling ipal support
|
||||
HAVE_IPAL=
|
||||
@@ -54,70 +102,11 @@ AC_SUBST(DLLIB)
|
||||
AC_PROG_INSTALL
|
||||
|
||||
AC_LANG_C
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
AC_CANONICAL_HOST
|
||||
# $host
|
||||
|
||||
|
||||
#######################
|
||||
## 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.
|
||||
#######################
|
||||
|
||||
AC_CYGWIN
|
||||
AC_EXEEXT
|
||||
AC_MINGW32
|
||||
|
||||
|
||||
WIN32=no
|
||||
AC_MSG_CHECKING("Checking for windows")
|
||||
if test "$CYGWIN" = "yes" -o "$MINGW32" = "yes"
|
||||
then
|
||||
WIN32=yes
|
||||
fi
|
||||
AC_SUBST(WIN32)
|
||||
AC_MSG_RESULT($WIN32)
|
||||
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" -a -z "$MINGW32"; 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")
|
||||
|
||||
#######################
|
||||
## 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.
|
||||
|
||||
@@ -153,8 +142,8 @@ AC_MSG_RESULT($EXTRALIBS)
|
||||
# Darwin requires -no-cpp-precomp
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
CPPFLAGS="-no-cpp-precomp"
|
||||
CFLAGS="-no-cpp-precomp"
|
||||
CPPFLAGS="-no-cpp-precomp $CPPFLAGS"
|
||||
CFLAGS="-no-cpp-precomp $CFLAGS"
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -215,10 +204,43 @@ case "${host}" in
|
||||
esac
|
||||
|
||||
AC_SUBST(shared)
|
||||
|
||||
AC_MSG_RESULT($shared)
|
||||
|
||||
#######################
|
||||
## 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_CONFIG_SUBDIRS(vpip vvp tgt-vvp tgt-fpga)
|
||||
AX_C_UNDERSCORES_LEADING
|
||||
AX_C_UNDERSCORES_TRAILING
|
||||
|
||||
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile vvm/Makefile driver/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
|
||||
#######################
|
||||
## end of test for underscores
|
||||
#######################
|
||||
|
||||
AX_CPP_IDENT
|
||||
|
||||
# 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})
|
||||
|
||||
# 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_CONFIG_SUBDIRS(vvp tgt-vvp tgt-fpga libveriuser cadpli)
|
||||
|
||||
AC_OUTPUT(Makefile vpi/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,8 +16,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: cprop.cc,v 1.30 2001/10/28 01:14:53 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cprop.cc,v 1.46 2003/11/08 17:53:34 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -30,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.
|
||||
@@ -56,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("LPM_Direction") != verinum("ADD"))
|
||||
return;
|
||||
|
||||
// If the low bit on the A side is 0, then eliminate it from
|
||||
@@ -64,8 +64,8 @@ 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->scope(), obj->name(), obj->width()-1);
|
||||
@@ -89,8 +89,8 @@ 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->scope(), obj->name(), obj->width()-1);
|
||||
@@ -118,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));
|
||||
@@ -155,17 +155,33 @@ 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)))
|
||||
if (! obj->pin_DataB(idx).nexus()->drivers_constant())
|
||||
continue;
|
||||
if (driven_value(obj->pin_DataA(idx)) ==
|
||||
driven_value(obj->pin_DataB(idx)))
|
||||
|
||||
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);
|
||||
@@ -176,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;
|
||||
}
|
||||
@@ -217,7 +248,7 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
|
||||
with a simple XOR gate. */
|
||||
if (top == 1) {
|
||||
NetLogic*tmp = new NetLogic(scope, obj->name(), 3,
|
||||
NetLogic::XOR);
|
||||
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));
|
||||
@@ -246,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();
|
||||
}
|
||||
@@ -310,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) {
|
||||
@@ -326,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;
|
||||
@@ -348,6 +383,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
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());
|
||||
@@ -373,6 +412,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
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());
|
||||
@@ -416,6 +459,11 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
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());
|
||||
@@ -427,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(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());
|
||||
@@ -457,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) {
|
||||
@@ -473,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;
|
||||
}
|
||||
@@ -494,6 +546,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
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());
|
||||
@@ -519,6 +575,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
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());
|
||||
@@ -547,6 +607,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
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());
|
||||
@@ -564,6 +628,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
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());
|
||||
@@ -583,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) {
|
||||
@@ -615,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;
|
||||
@@ -628,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) {
|
||||
@@ -642,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;
|
||||
}
|
||||
|
||||
@@ -651,13 +727,17 @@ 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(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());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -674,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;
|
||||
@@ -692,6 +772,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
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());
|
||||
@@ -717,6 +801,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
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());
|
||||
@@ -753,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.
|
||||
*/
|
||||
@@ -769,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));
|
||||
@@ -801,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));
|
||||
@@ -844,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) {
|
||||
@@ -887,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();
|
||||
@@ -904,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
|
||||
@@ -920,7 +1017,6 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Done. Delete me.
|
||||
delete obj;
|
||||
}
|
||||
@@ -928,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 {
|
||||
@@ -942,110 +1038,45 @@ void cprop(Design*des)
|
||||
|
||||
/*
|
||||
* $Log: cprop.cc,v $
|
||||
* Revision 1.30 2001/10/28 01:14:53 steve
|
||||
* NetObj constructor finally requires a scope.
|
||||
* Revision 1.46 2003/11/08 17:53:34 steve
|
||||
* Do not remove constants accessible to VPI.
|
||||
*
|
||||
* Revision 1.29 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.45 2003/10/31 02:40:06 steve
|
||||
* Donot elide FF that has set or clr connections.
|
||||
*
|
||||
* Revision 1.28 2001/06/15 04:14:18 steve
|
||||
* Generate vvp code for GT and GE comparisons.
|
||||
* Revision 1.44 2003/04/25 05:06:32 steve
|
||||
* Handle X values in constant == nets.
|
||||
*
|
||||
* Revision 1.27 2001/06/07 02:12:43 steve
|
||||
* Support structural addition.
|
||||
* Revision 1.43 2003/03/06 00:28:41 steve
|
||||
* All NetObj objects have lex_string base names.
|
||||
*
|
||||
* Revision 1.26 2001/02/18 01:07:32 steve
|
||||
* check signals in the cprop functor.
|
||||
* Revision 1.42 2003/02/26 01:29:24 steve
|
||||
* LPM objects store only their base names.
|
||||
*
|
||||
* Revision 1.25 2001/02/16 03:27:31 steve
|
||||
* Constant propagation for compare ==.
|
||||
* Revision 1.41 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.24 2001/02/10 04:50:54 steve
|
||||
* Catch constants driving root module ports. (PR#130)
|
||||
* Revision 1.40 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.23 2000/12/30 03:11:15 steve
|
||||
* Propagate initial value of constants into wires.
|
||||
* Revision 1.39 2002/08/20 04:12:22 steve
|
||||
* Copy gate delays when doing gate delay substitutions.
|
||||
*
|
||||
* Revision 1.22 2000/11/23 01:55:52 steve
|
||||
* Propagate constants through xnor gates. (PR#51)
|
||||
* Revision 1.38 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.21 2000/11/19 05:26:58 steve
|
||||
* Replace AND constand propagation.
|
||||
* Revision 1.37 2002/06/25 01:33:22 steve
|
||||
* Cache calculated driven value.
|
||||
*
|
||||
* Revision 1.20 2000/11/18 05:13:27 steve
|
||||
* Thorough constant propagation for or and nor gates.
|
||||
* 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.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.18 2000/11/11 00:03:36 steve
|
||||
* Add support for the t-dll backend grabing flip-flops.
|
||||
*
|
||||
* Revision 1.17 2000/10/07 19:45:42 steve
|
||||
* Put logic devices into scopes.
|
||||
*
|
||||
* Revision 1.16 2000/10/06 21:26:34 steve
|
||||
* Eliminate zero inputs to xor.
|
||||
*
|
||||
* Revision 1.15 2000/08/02 14:48:01 steve
|
||||
* use bufif0 if z is in true case of mux.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
+7
-1
@@ -1,6 +1,12 @@
|
||||
|
||||
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:
|
||||
@@ -8,7 +14,7 @@ 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
|
||||
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
|
||||
|
||||
+233
-42
@@ -16,8 +16,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: design_dump.cc,v 1.120 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: design_dump.cc,v 1.144 2003/07/26 03:34:42 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -93,7 +93,7 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
||||
o << " inout";
|
||||
break;
|
||||
}
|
||||
o << " (eref=" << get_eref() << ")";
|
||||
o << " (eref=" << peek_eref() << ", lref=" << peek_lref() << ")";
|
||||
if (scope())
|
||||
o << " scope=" << scope()->name();
|
||||
o << " #(" << rise_time() << "," << fall_time() << "," <<
|
||||
@@ -117,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_ << "] " <<
|
||||
@@ -174,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,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);
|
||||
@@ -353,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;
|
||||
@@ -405,6 +421,11 @@ 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);
|
||||
}
|
||||
|
||||
@@ -418,6 +439,16 @@ void NetAssign_::dump_lval(ostream&o) const
|
||||
} 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 << "";
|
||||
}
|
||||
@@ -464,30 +495,13 @@ void NetAssignNB::dump(ostream&o, unsigned ind) const
|
||||
|
||||
}
|
||||
|
||||
void NetAssignMem::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;
|
||||
}
|
||||
|
||||
/* 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_;
|
||||
@@ -647,8 +661,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
|
||||
@@ -679,22 +697,35 @@ 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<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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -708,6 +739,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="
|
||||
@@ -739,6 +775,8 @@ void NetScope::dump(ostream&o) const
|
||||
case TASK:
|
||||
task_def()->dump(o, 4);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Dump any sub-scopes. */
|
||||
@@ -783,7 +821,7 @@ 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 << "(?" << typeid(*this).name() << "?)";
|
||||
@@ -831,6 +869,9 @@ void NetEBinary::dump(ostream&o) const
|
||||
case 'r':
|
||||
o << ">>";
|
||||
break;
|
||||
case 'R':
|
||||
o << ">>>";
|
||||
break;
|
||||
case 'X':
|
||||
o << "~^";
|
||||
break;
|
||||
@@ -842,8 +883,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];
|
||||
@@ -867,11 +912,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_ << "(";
|
||||
@@ -884,6 +972,8 @@ void NetESFunc::dump(ostream&o) const
|
||||
|
||||
void NetESignal::dump(ostream&o) const
|
||||
{
|
||||
if (has_sign())
|
||||
o << "+";
|
||||
o << name() << "[" << msi_<<":"<<lsi_ << "]";
|
||||
}
|
||||
|
||||
@@ -904,7 +994,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
|
||||
@@ -941,6 +1034,11 @@ 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;
|
||||
@@ -970,6 +1068,99 @@ void Design::dump(ostream&o) const
|
||||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* 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.
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
* 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: dosify.c,v 1.1 2001/08/03 17:06:47 steve Exp $
|
||||
*/
|
||||
#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
|
||||
@@ -68,6 +69,18 @@ int main(int argc, char*argv[])
|
||||
|
||||
/*
|
||||
* $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,82 @@
|
||||
#
|
||||
# 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.5 2002/12/08 03:06:30 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@
|
||||
CXX = @CXX@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/.. -DVERSION='"$(VERSION)"'
|
||||
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)/..
|
||||
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) $(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 ([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
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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
|
||||
@@ -10,3 +10,6 @@ cfparse.output
|
||||
cflexor.c
|
||||
foo.*
|
||||
iverilog
|
||||
iverilog.ps
|
||||
iverilog.pdf
|
||||
tmp.pdf
|
||||
|
||||
+18
-22
@@ -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.10 2001/11/17 17:57:58 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.22 2003/11/18 06:31:46 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.0
|
||||
VERSION = 0.7
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
@@ -37,7 +35,6 @@ includedir = $(prefix)/include
|
||||
mandir = @mandir@
|
||||
|
||||
dllib=@DLLIB@
|
||||
rdynamic=@rdynamic@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
@@ -46,8 +43,8 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/..
|
||||
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)/..
|
||||
CFLAGS = @CFLAGS@ -Wall @ident_support@ -I. -I.. -I$(srcdir)/.. -I$(srcdir) -DVERSION='"$(VERSION)"'
|
||||
CXXFLAGS = @CXXFLAGS@ -I.. -I. -I$(srcdir)/.. -I$(srcdir)
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
all: iverilog@EXEEXT@
|
||||
@@ -55,18 +52,16 @@ 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 cflexor.o cfparse.o
|
||||
distclean: clean
|
||||
rm -f Makefile
|
||||
|
||||
O = main.o substit.o cflexor.o cfparse.o
|
||||
|
||||
iverilog@EXEEXT@: $O
|
||||
$(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@ @EXTRALIBS@
|
||||
|
||||
lexor.c: lexor.lex
|
||||
flex -s -olexor.c $(srcdir)/lexor.lex
|
||||
|
||||
parse.h parse.c: parse.y
|
||||
bison --verbose -t -d -o parse.c $(srcdir)/parse.y
|
||||
|
||||
cflexor.c: cflexor.lex
|
||||
flex -s -Pcf -ocflexor.c $(srcdir)/cflexor.lex
|
||||
|
||||
@@ -75,20 +70,21 @@ cfparse.h cfparse.c: cfparse.y
|
||||
|
||||
|
||||
main.o: main.c globals.h
|
||||
$(CC) $(CFLAGS) -c -DCXX='"@CXX@"' -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DRDYNAMIC=\"$(rdynamic)\" -DDLLIB='"@DLLIB@"' -DEXEEXT='"@EXEEXT@"' $(srcdir)/main.c
|
||||
$(CC) $(CFLAGS) -c -DCXX='"@CXX@"' -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.pdf: $(srcdir)/iverilog.man
|
||||
man -t $(srcdir)/iverilog.man | ps2pdf - iverilog.pdf
|
||||
iverilog.ps: $(srcdir)/iverilog.man
|
||||
man -t $(srcdir)/iverilog.man > iverilog.ps
|
||||
|
||||
iverilog.pdf: iverilog.ps
|
||||
ps2pdf iverilog.ps iverilog.pdf
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
INSTALL_DOC = $(prefix)/iverilog.pdf
|
||||
INSTALL_DOCDIR =
|
||||
INSTALL_DOC = $(prefix)/iverilog.pdf $(mandir)/man1/iverilog.1
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
all: iverilog.pdf
|
||||
else
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog.1
|
||||
|
||||
@@ -1,183 +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: build_string.c,v 1.6 2001/11/16 05:07:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# 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 == 'v') && verbose_flag)
|
||||
|| ((*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;
|
||||
|
||||
case 'y':
|
||||
if (library_flags) {
|
||||
strcpy(output, library_flags);
|
||||
output += strlen(library_flags);
|
||||
olen -= strlen(library_flags);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
if (library_flags2) {
|
||||
strcpy(output, library_flags2);
|
||||
output += strlen(library_flags2);
|
||||
olen -= strlen(library_flags2);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
pattern += 1;
|
||||
|
||||
} else {
|
||||
*output++ = *pattern++;
|
||||
olen -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
*output = 0;
|
||||
return output-output_save;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: build_string.c,v $
|
||||
* Revision 1.6 2001/11/16 05:07:19 steve
|
||||
* Add support for +libext+ in command files.
|
||||
*
|
||||
* Revision 1.5 2001/10/20 23:02:40 steve
|
||||
* Add automatic module libraries.
|
||||
*
|
||||
* Revision 1.4 2001/07/25 03:10:50 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.3 2001/07/03 04:09:25 steve
|
||||
* Generate verbuse status messages (Stephan Boettcher)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
+6
-2
@@ -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: cflexor.lex,v 1.5 2001/12/08 04:13:07 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cflexor.lex,v 1.7 2003/08/26 16:26:02 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "cfparse.h"
|
||||
@@ -70,6 +70,10 @@ static int comment_enter;
|
||||
|
||||
"+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; }
|
||||
|
||||
|
||||
|
||||
+36
-9
@@ -17,13 +17,17 @@
|
||||
* 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: cfparse.y,v 1.5 2001/12/08 04:13:07 steve Exp $"
|
||||
#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
|
||||
@@ -57,7 +61,7 @@ static void translate_file_name(char*text)
|
||||
};
|
||||
|
||||
%token TOK_Da TOK_Dv TOK_Dy
|
||||
%token TOK_DEFINE TOK_INCDIR TOK_LIBEXT
|
||||
%token TOK_DEFINE TOK_INCDIR TOK_LIBDIR TOK_LIBDIR_NOCASE TOK_LIBEXT
|
||||
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
|
||||
|
||||
%%
|
||||
@@ -77,9 +81,11 @@ item
|
||||
of a source file. Add the file to the file list. */
|
||||
|
||||
: TOK_STRING
|
||||
{ translate_file_name($1);
|
||||
process_file_name($1);
|
||||
{ char*tmp = substitutions($1);
|
||||
translate_file_name(tmp);
|
||||
process_file_name(tmp);
|
||||
free($1);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* The -a flag is completely ignored. */
|
||||
@@ -90,11 +96,13 @@ item
|
||||
as an ordinary source file. */
|
||||
|
||||
| TOK_Dv TOK_STRING
|
||||
{ translate_file_name($2);
|
||||
process_file_name($2);
|
||||
{ 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
|
||||
@@ -102,8 +110,24 @@ item
|
||||
directory list. */
|
||||
|
||||
| TOK_Dy TOK_STRING
|
||||
{ process_library_switch($2);
|
||||
{ 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
|
||||
@@ -150,8 +174,10 @@ inc_args
|
||||
;
|
||||
|
||||
inc_arg : TOK_PLUSARG
|
||||
{ process_include_dir($1);
|
||||
{ char*tmp = substitutions($1);
|
||||
process_include_dir(tmp);
|
||||
free($1);
|
||||
free(tmp);
|
||||
}
|
||||
;
|
||||
|
||||
@@ -184,4 +210,5 @@ skip_arg : TOK_PLUSARG
|
||||
|
||||
int yyerror(const char*msg)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
+27
-2
@@ -19,13 +19,38 @@
|
||||
* 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: cfparse_misc.h,v 1.2 2001/11/12 18:47:32 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: cfparse_misc.h,v 1.5 2003/09/26 21:25:58 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 cfparse(void);
|
||||
|
||||
/*
|
||||
* $Log: cfparse_misc.h,v $
|
||||
* 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.
|
||||
|
||||
+28
-39
@@ -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.10 2001/11/16 05:07:19 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;
|
||||
@@ -51,11 +49,15 @@ 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 */
|
||||
@@ -73,43 +75,30 @@ extern char warning_flags[];
|
||||
extern char* library_flags;
|
||||
extern char* library_flags2;
|
||||
|
||||
extern const char*lookup_pattern(const char*key);
|
||||
|
||||
extern int build_string(char*out, size_t olen, const char*pattern);
|
||||
|
||||
/*
|
||||
* $Log: globals.h,v $
|
||||
* Revision 1.10 2001/11/16 05:07:19 steve
|
||||
* Add support for +libext+ in command files.
|
||||
* Revision 1.19 2003/11/18 06:31:46 steve
|
||||
* Remove the iverilog.conf file.
|
||||
*
|
||||
* Revision 1.9 2001/11/13 03:30:26 steve
|
||||
* The +incdir+ plusarg can take multiple directores,
|
||||
* and add initial support for +define+ in the command file.
|
||||
* Revision 1.18 2003/11/13 04:09:49 steve
|
||||
* Pass flags through the temporary config file.
|
||||
*
|
||||
* Revision 1.8 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.17 2003/11/01 04:21:57 steve
|
||||
* Add support for a target static config file.
|
||||
*
|
||||
* Revision 1.7 2001/11/12 01:26:36 steve
|
||||
* More sophisticated command file parser.
|
||||
* Revision 1.16 2002/08/12 01:35:01 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.6 2001/10/23 00:37:30 steve
|
||||
* The -s flag can now be repeated on the iverilog command.
|
||||
* Revision 1.15 2002/06/23 20:10:51 steve
|
||||
* Variable substitution in command files.
|
||||
*
|
||||
* Revision 1.5 2001/10/20 23:02:40 steve
|
||||
* Add automatic module libraries.
|
||||
*
|
||||
* Revision 1.4 2001/07/03 04:09:25 steve
|
||||
* Generate verbuse status messages (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.3 2000/11/09 21:58:00 steve
|
||||
* Remember to include the -S condition.
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
|
||||
+94
-38
@@ -1,32 +1,32 @@
|
||||
.TH iverilog 1 "$Date: 2001/12/08 04:13:07 $" Version "$Date: 2001/12/08 04:13:07 $"
|
||||
.TH iverilog 1 "$Date: 2003/11/26 01:36:25 $" Version "$Date: 2003/11/26 01:36:25 $"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog
|
||||
[-ESv] [-Cpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value]
|
||||
[-Iincludedir] [-mmodule] [-Nfile] [-ooutputfilename] [-stopmodule]
|
||||
[-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] 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 currently supported targets are \fIvvm\fP (for
|
||||
executable simulation) and \fIvvp\fP for simulation, and \fIxnf\fP for
|
||||
synthesis. Other target types are added as code generators are
|
||||
implemented.
|
||||
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
|
||||
.l
|
||||
\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
|
||||
@@ -34,14 +34,6 @@ source files. This is similar to the \fIcommand file\fP of other
|
||||
Verilog simulators, in that it is a file that contains the file names
|
||||
instead of taking them on the command line. See \fBCommand Files\fP below.
|
||||
.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.
|
||||
.TP 8
|
||||
.B -D\fImacro\fP
|
||||
Defines macro \fImacro\fP with the string `1' as its definition. This
|
||||
form is normally only used to trigger ifdef conditionals in the
|
||||
@@ -56,12 +48,28 @@ is the Verilog input, but with file inclusions and macro references
|
||||
expanded and removed. This is useful, for example, to preprocess
|
||||
Verilog source for use by other compilers.
|
||||
.TP 8
|
||||
.B -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
|
||||
@@ -111,7 +119,15 @@ 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
|
||||
@@ -149,31 +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
|
||||
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.
|
||||
.TP 8
|
||||
.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
|
||||
(like with vvm) but must be run by the \fBvvp\fP command. This target
|
||||
is much faster then the \fBvvm\fP target, but not quite as complete.
|
||||
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 variant of the XNF code generator that supports a wider
|
||||
variety of target devices. It is intended as a future replacement for
|
||||
the existing \fBxnf\fP target, but for now is still experimental.
|
||||
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
|
||||
@@ -185,6 +198,20 @@ This enables warnings for creation of implicit declarations. For
|
||||
example, if a scalar wire X is used but not declared in the Verilog
|
||||
source, this will print a warning at its first use.
|
||||
|
||||
.TP 8
|
||||
.B 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 "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
|
||||
@@ -194,7 +221,8 @@ 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.
|
||||
source file. The path starts with the first non-white-space
|
||||
character. Variables are substitued in file names.
|
||||
|
||||
.TP 8
|
||||
.B -y\ \fIlibdir\fP
|
||||
@@ -202,6 +230,8 @@ 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
|
||||
@@ -210,6 +240,8 @@ 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
|
||||
@@ -217,6 +249,18 @@ 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
|
||||
@@ -233,6 +277,18 @@ become munged.
|
||||
.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
|
||||
@@ -264,7 +320,7 @@ vvp(1),
|
||||
|
||||
.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
|
||||
GNU General Public License version 2.0
|
||||
|
||||
@@ -1,80 +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.5 2001/07/25 03:10:50 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# 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;
|
||||
}
|
||||
+310
-278
@@ -16,13 +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
|
||||
*/
|
||||
#ident "$Id: main.c,v 1.31 2001/11/21 02:20:34 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: main.c,v 1.61 2003/11/18 06:31:46 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
const char NOTICE[] =
|
||||
" This program is free software; you can redistribute it and/or modify\n"
|
||||
" it under the terms of the GNU General Public License as published by\n"
|
||||
" the Free Software Foundation; either version 2 of the License, or\n"
|
||||
" (at your option) any later version.\n"
|
||||
"\n"
|
||||
" This program is distributed in the hope that it will be useful,\n"
|
||||
" but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
|
||||
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
|
||||
" GNU General Public License for more details.\n"
|
||||
"\n"
|
||||
" You should have received a copy of the GNU General Public License\n"
|
||||
" along with this program; if not, write to the Free Software\n"
|
||||
" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA\n"
|
||||
;
|
||||
|
||||
const char HELP[] =
|
||||
"Usage: iverilog [-ESv] [-B base] [-C path] [-c cmdfile]\n"
|
||||
" [-D macro[=defn]] [-I includedir] [-m module]\n"
|
||||
"Usage: iverilog [-ESvV] [-B base] [-c cmdfile] [-g1|-g2|-g3.0]\n"
|
||||
" [-D macro[=defn]] [-I includedir] [-M depfile] [-m module]\n"
|
||||
" [-N file] [-o filename] [-p flag=value]\n"
|
||||
" [-s topmodule] [-t target] [-T min|typ|max]\n"
|
||||
" [-W class] [-y dir] [-Y suf] source_file(s)\n"
|
||||
@@ -43,6 +61,9 @@ const char HELP[] =
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include <windows.h>
|
||||
#ifdef HAVE_LIBIBERTY_H
|
||||
#include <libiberty.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAVE_GETOPT_H
|
||||
@@ -67,10 +88,6 @@ extern const char*optarg;
|
||||
# define IVL_ROOT "."
|
||||
#endif
|
||||
|
||||
#ifndef RDYNAMIC
|
||||
# define RDYNAMIC "-rdynamic"
|
||||
#endif
|
||||
|
||||
# include "globals.h"
|
||||
|
||||
#ifdef __MINGW32__
|
||||
@@ -83,21 +100,19 @@ extern void cfreset(FILE*fd, const char*path);
|
||||
|
||||
const char*base = 0;
|
||||
const char*mtm = 0;
|
||||
const char*opath = "a.out" EXEEXT;
|
||||
const char*opath = "a.out";
|
||||
const char*npath = 0;
|
||||
const char*targ = "vvp";
|
||||
const char*depfile = 0;
|
||||
|
||||
const char*generation = "3.0";
|
||||
|
||||
char warning_flags[16] = "";
|
||||
char *library_flags = 0;
|
||||
char *library_flags2 = 0;
|
||||
|
||||
char*inc_list = 0;
|
||||
char*def_list = 0;
|
||||
char*mod_list = 0;
|
||||
char*command_filename = 0;
|
||||
char*start = 0;
|
||||
|
||||
char*f_list = 0;
|
||||
|
||||
/* These are used to collect the list of file names that will be
|
||||
passed to ivlpp. Keep the list in a file because it can be a long
|
||||
@@ -106,6 +121,12 @@ char*source_path = 0;
|
||||
FILE*source_file = 0;
|
||||
unsigned source_count = 0;
|
||||
|
||||
char*iconfig_path = 0;
|
||||
FILE*iconfig_file = 0;
|
||||
|
||||
static char iconfig_common_path_buf[4096] = "";
|
||||
char*iconfig_common_path = iconfig_common_path_buf;
|
||||
|
||||
int synth_flag = 0;
|
||||
int verbose_flag = 0;
|
||||
int command_file = 0;
|
||||
@@ -117,6 +138,72 @@ char tmp[MAXSIZE];
|
||||
|
||||
static char ivl_root[MAXSIZE];
|
||||
|
||||
#ifdef __MINGW32__
|
||||
# include <io.h>
|
||||
# include <fcntl.h>
|
||||
static FILE*fopen_safe(const char*path)
|
||||
{
|
||||
FILE*file = 0;
|
||||
int fd;
|
||||
|
||||
fd = _open(path, _O_WRONLY|_O_CREAT|_O_EXCL, 0700);
|
||||
if (fd != -1)
|
||||
file = _fdopen(fd, "w");
|
||||
|
||||
return file;
|
||||
}
|
||||
#else
|
||||
# include <fcntl.h>
|
||||
static FILE*fopen_safe(const char*path)
|
||||
{
|
||||
FILE*file = 0;
|
||||
int fd;
|
||||
|
||||
fd = open(path, O_WRONLY|O_CREAT|O_EXCL, 0700);
|
||||
if (fd != -1)
|
||||
file = fdopen(fd, "w");
|
||||
|
||||
return file;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char*my_tempfile(const char*str, FILE**fout)
|
||||
{
|
||||
FILE*file;
|
||||
int retry;
|
||||
|
||||
static char pathbuf[8192];
|
||||
|
||||
const char*tmpdir = getenv("TMP");
|
||||
if (tmpdir == 0)
|
||||
tmpdir = getenv("TMPDIR");
|
||||
if (tmpdir == 0)
|
||||
tmpdir = getenv("TEMP");
|
||||
#ifdef __MINGW32__
|
||||
if (tmpdir == 0)
|
||||
tmpdir = "C:\\TEMP";
|
||||
#else
|
||||
if (tmpdir == 0)
|
||||
tmpdir = "/tmp";
|
||||
#endif
|
||||
|
||||
assert(tmpdir);
|
||||
assert((strlen(tmpdir) + strlen(str)) < sizeof pathbuf - 10);
|
||||
|
||||
srand(getpid());
|
||||
retry = 100;
|
||||
file = NULL;
|
||||
while ((retry > 0) && (file == NULL)) {
|
||||
unsigned code = rand();
|
||||
sprintf(pathbuf, "%s%c%s%04x", tmpdir, sep, str, code);
|
||||
file = fopen_safe(pathbuf);
|
||||
retry -= 1;
|
||||
}
|
||||
|
||||
*fout = file;
|
||||
return pathbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the default target type. It looks up the bits that are
|
||||
* needed to run the command from the configuration file (which is
|
||||
@@ -124,32 +211,53 @@ static char ivl_root[MAXSIZE];
|
||||
*/
|
||||
static int t_default(char*cmd, unsigned ncmd)
|
||||
{
|
||||
int rc;
|
||||
const char*pattern;
|
||||
unsigned rc;
|
||||
unsigned ncmd_start = ncmd;
|
||||
|
||||
pattern = lookup_pattern("<ivl>");
|
||||
if (pattern == 0) {
|
||||
fprintf(stderr, "No such target: %s\n", targ);
|
||||
return -1;
|
||||
snprintf(tmp, sizeof tmp, " | %s/ivl", base);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
|
||||
if (verbose_flag) {
|
||||
const char*vv = " -v";
|
||||
rc = strlen(vv);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, vv);
|
||||
ncmd += rc;
|
||||
}
|
||||
|
||||
tmp[0] = ' ';
|
||||
tmp[1] = '|';
|
||||
tmp[2] = ' ';
|
||||
rc = build_string(tmp+3, sizeof tmp - 3, pattern);
|
||||
cmd = realloc(cmd, ncmd+3+rc+1);
|
||||
if (npath != 0) {
|
||||
snprintf(tmp, sizeof tmp, " -N%s", npath);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
}
|
||||
|
||||
snprintf(tmp, sizeof tmp, " -C%s", iconfig_path);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
|
||||
snprintf(tmp, sizeof tmp, " -C%s -- -", iconfig_common_path);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
|
||||
#ifdef __MINGW32__
|
||||
{
|
||||
char *t;
|
||||
for (t = tmp; *t; t++)
|
||||
for (t = cmd+ncmd_start; *t; t++)
|
||||
{
|
||||
if (*t == '/') *t = '\\';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
|
||||
|
||||
if (verbose_flag)
|
||||
printf("translate: %s\n", cmd);
|
||||
@@ -157,6 +265,8 @@ static int t_default(char*cmd, unsigned ncmd)
|
||||
|
||||
rc = system(cmd);
|
||||
remove(source_path);
|
||||
if ( ! getenv("IVERILOG_ICONFIG"))
|
||||
remove(iconfig_path);
|
||||
if (rc != 0) {
|
||||
if (rc == 127) {
|
||||
fprintf(stderr, "Failed to execute: %s\n", cmd);
|
||||
@@ -173,136 +283,55 @@ static int t_default(char*cmd, unsigned ncmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function handles the vvm target. After preprocessing, run the
|
||||
* ivl translator to get C++, then run g++ to make an executable
|
||||
* program out of that.
|
||||
*/
|
||||
static int t_vvm(char*cmd, unsigned ncmd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
const char*pattern = lookup_pattern("<ivl>");
|
||||
if (pattern == 0) {
|
||||
fprintf(stderr, "No such target: %s\n", targ);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tmp[0] = ' ';
|
||||
tmp[1] = '|';
|
||||
tmp[2] = ' ';
|
||||
rc = build_string(tmp+3, sizeof tmp - 3, pattern);
|
||||
cmd = realloc(cmd, ncmd+3+rc+1);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
{
|
||||
char *t;
|
||||
for (t = tmp; *t; t++)
|
||||
{
|
||||
if (*t == '/') *t = '\\';
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
|
||||
|
||||
if (verbose_flag)
|
||||
printf("translate: %s\n", cmd);
|
||||
|
||||
rc = system(cmd);
|
||||
remove(source_path);
|
||||
if (rc != 0) {
|
||||
if (WIFEXITED(rc)) {
|
||||
fprintf(stderr, "errors translating Verilog program.\n");
|
||||
return WEXITSTATUS(rc);
|
||||
} else {
|
||||
fprintf(stderr, "Command signaled: %s\n", cmd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
/* In the Windows world, the path to headers and libraries
|
||||
for vvm is relative the ivl_root, which is in something like:
|
||||
|
||||
d:\iverilog\lib\ivl <-- ivl_root
|
||||
d:\iverilog\include <-- vvm headers
|
||||
d:\iverilog\lib <-- vvm libraries
|
||||
|
||||
So we make up all the ugly references that are the g++
|
||||
command line to compile a .cc file generated by vvm. */
|
||||
sprintf(tmp, "%s " RDYNAMIC " -s -fno-exceptions -o %s "
|
||||
"-I%s\\..\\..\\include -L%s\\.. %s.cc -lvvm -lvpip %s",
|
||||
CXX, opath, ivl_root, ivl_root, opath, DLLIB);
|
||||
#else
|
||||
/* In the UNIX universe, life is easy. The configure script
|
||||
has figured everything out and wrote it into the Makefile,
|
||||
which passes it on as the IVL_INC and IVL_LIB defines. */
|
||||
sprintf(tmp, "%s " RDYNAMIC " -s -fno-exceptions -o %s -I%s "
|
||||
"-L%s %s.cc -lvvm -lvpip %s", CXX, opath, IVL_INC,
|
||||
IVL_LIB, opath, DLLIB);
|
||||
#endif
|
||||
if (verbose_flag)
|
||||
printf("compile: %s\n", tmp);
|
||||
|
||||
rc = system(tmp);
|
||||
if (rc != 0) {
|
||||
if (WIFEXITED(rc)) {
|
||||
fprintf(stderr, "errors compiling translated program.\n");
|
||||
return WEXITSTATUS(rc);
|
||||
} else {
|
||||
fprintf(stderr, "Command signaled: %s\n", tmp);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(tmp, "%s.cc", opath);
|
||||
unlink(tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void process_warning_switch(const char*name)
|
||||
{
|
||||
if (warning_flags[0] == 0)
|
||||
strcpy(warning_flags, "-W");
|
||||
|
||||
if (strcmp(name,"all") == 0) {
|
||||
strcat(warning_flags, "i");
|
||||
strcat(warning_flags, "ipt");
|
||||
|
||||
} else if (strcmp(name,"implicit") == 0) {
|
||||
if (! strchr(warning_flags+2, 'i'))
|
||||
strcat(warning_flags, "i");
|
||||
} else if (strcmp(name,"portbind") == 0) {
|
||||
if (! strchr(warning_flags+2, 'p'))
|
||||
strcat(warning_flags, "p");
|
||||
} else if (strcmp(name,"timescale") == 0) {
|
||||
if (! strchr(warning_flags+2, 't'))
|
||||
strcat(warning_flags, "t");
|
||||
} else if (strcmp(name,"no-implicit") == 0) {
|
||||
char*cp = strchr(warning_flags+2, 'i');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-portbind") == 0) {
|
||||
char*cp = strchr(warning_flags+2, 'p');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
} else if (strcmp(name,"no-timescale") == 0) {
|
||||
char*cp = strchr(warning_flags+2, 't');
|
||||
if (cp) while (*cp) {
|
||||
cp[0] = cp[1];
|
||||
cp += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void process_library_switch(const char *name)
|
||||
{
|
||||
if (library_flags) {
|
||||
library_flags = realloc(library_flags,
|
||||
strlen(library_flags) + strlen(name) + 5);
|
||||
strcat(library_flags, " -y ");
|
||||
} else {
|
||||
library_flags = malloc(strlen(name) + 4);
|
||||
strcpy(library_flags, "-y ");
|
||||
}
|
||||
strcat(library_flags, name);
|
||||
fprintf(iconfig_file, "-y:%s\n", name);
|
||||
}
|
||||
|
||||
void process_library_nocase_switch(const char *name)
|
||||
{
|
||||
fprintf(iconfig_file, "-yl:%s\n", name);
|
||||
}
|
||||
|
||||
void process_library2_switch(const char *name)
|
||||
{
|
||||
if (library_flags2) {
|
||||
library_flags2 = realloc(library_flags2,
|
||||
strlen(library_flags2) + strlen(name) + 5);
|
||||
strcat(library_flags2, " -Y ");
|
||||
} else {
|
||||
library_flags2 = malloc(strlen(name) + 4);
|
||||
strcpy(library_flags2, "-Y ");
|
||||
}
|
||||
strcat(library_flags2, name);
|
||||
fprintf(iconfig_file, "-Y:%s\n", name);
|
||||
}
|
||||
|
||||
void process_include_dir(const char *name)
|
||||
@@ -341,14 +370,37 @@ void process_file_name(const char*name)
|
||||
source_count += 1;
|
||||
}
|
||||
|
||||
int process_generation(const char*name)
|
||||
{
|
||||
if (strcmp(name,"1") == 0)
|
||||
generation = "1";
|
||||
|
||||
else if (strcmp(name,"2") == 0)
|
||||
generation = "2";
|
||||
|
||||
else if (strcmp(name,"3.0") == 0)
|
||||
generation = "3.0";
|
||||
|
||||
else {
|
||||
fprintf(stderr, "Unknown/Unsupported Language generation "
|
||||
"%s\n", name);
|
||||
fprintf(stderr, "Supported generations are:\n");
|
||||
fprintf(stderr, " 1 -- IEEE1364-1995 (Verilog 1)\n"
|
||||
" 2 -- IEEE1364-2001 (Verilog 2001)\n"
|
||||
" 3.0 -- SystemVerilog 3.0\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char*config_path = 0;
|
||||
char*cmd;
|
||||
unsigned ncmd;
|
||||
int e_flag = 0;
|
||||
int opt, idx;
|
||||
char*cp;
|
||||
int version_flag = 0;
|
||||
int opt, idx, rc;
|
||||
|
||||
#ifdef __MINGW32__
|
||||
{ char * s;
|
||||
@@ -379,6 +431,7 @@ int main(int argc, char **argv)
|
||||
|
||||
base = ivl_root;
|
||||
}
|
||||
|
||||
#else
|
||||
/* In a UNIX environment, the IVL_ROOT from the Makefile is
|
||||
dependable. It points to the $prefix/lib/ivl directory,
|
||||
@@ -387,20 +440,45 @@ int main(int argc, char **argv)
|
||||
base = ivl_root;
|
||||
#endif
|
||||
|
||||
source_path = strdup(tmpnam(0));
|
||||
assert(source_path);
|
||||
source_file = fopen(source_path, "w");
|
||||
assert(source_file);
|
||||
/* Create a temporary file for communicating input parameters
|
||||
to the preprocessor. */
|
||||
source_path = strdup(my_tempfile("ivrlg", &source_file));
|
||||
if (NULL == source_file) {
|
||||
fprintf(stderr, "%s: Error opening temporary file %s\n",
|
||||
argv[0], source_path);
|
||||
fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "B:C:c:D:Ef:hI:m:N::o:p:Ss:T:t:vW:y:")) != EOF) {
|
||||
/* Create another temporary file for passing configuration
|
||||
information to ivl. */
|
||||
|
||||
if ( (iconfig_path = getenv("IVERILOG_ICONFIG")) ) {
|
||||
fprintf(stderr, "%s: IVERILOG_ICONFIG=%s\n",
|
||||
argv[0], iconfig_path);
|
||||
|
||||
iconfig_file = fopen(iconfig_path, "w");
|
||||
|
||||
} else {
|
||||
|
||||
iconfig_path = strdup(my_tempfile("ivrlh", &iconfig_file));
|
||||
}
|
||||
|
||||
if (NULL == iconfig_file) {
|
||||
fprintf(stderr, "%s: Error opening temporary file %s\n",
|
||||
argv[0], iconfig_path);
|
||||
fprintf(stderr, "%s: Please check TMP or TMPDIR.\n", argv[0]);
|
||||
fclose(source_file);
|
||||
remove(source_path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while ((opt = getopt(argc, argv, "B:c:D:Ef:g:hI:M:m:N::o:p:Ss:T:t:vVW:y:Y:")) != EOF) {
|
||||
|
||||
switch (opt) {
|
||||
case 'B':
|
||||
base = optarg;
|
||||
break;
|
||||
case 'C':
|
||||
config_path = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
command_filename = malloc(strlen(optarg)+1);
|
||||
strcpy(command_filename, optarg);
|
||||
@@ -414,19 +492,14 @@ int main(int argc, char **argv)
|
||||
case 'f':
|
||||
fprintf(stderr, "warning: The -f flag is moved to -p\n");
|
||||
case 'p':
|
||||
if (f_list == 0) {
|
||||
f_list = malloc(strlen(" -p")+strlen(optarg)+1);
|
||||
strcpy(f_list, " -p");
|
||||
strcat(f_list, optarg);
|
||||
} else {
|
||||
f_list = realloc(f_list, strlen(f_list) +
|
||||
strlen(" -p") +
|
||||
strlen(optarg) + 1);
|
||||
strcat(f_list, " -p");
|
||||
strcat(f_list, optarg);
|
||||
}
|
||||
fprintf(iconfig_file, "flag:%s\n", optarg);
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
rc = process_generation(optarg);
|
||||
if (rc != 0)
|
||||
return -1;
|
||||
break;
|
||||
case 'h':
|
||||
fprintf(stderr, "%s\n", HELP);
|
||||
return 1;
|
||||
@@ -435,18 +508,12 @@ int main(int argc, char **argv)
|
||||
process_include_dir(optarg);
|
||||
break;
|
||||
|
||||
case 'M':
|
||||
depfile = optarg;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (mod_list == 0) {
|
||||
mod_list = malloc(strlen(" -m")+strlen(optarg)+1);
|
||||
strcpy(mod_list, " -m");
|
||||
strcat(mod_list, optarg);
|
||||
} else {
|
||||
mod_list = realloc(mod_list, strlen(mod_list)
|
||||
+ strlen(" -m")
|
||||
+ strlen(optarg) + 1);
|
||||
strcat(mod_list, " -m");
|
||||
strcat(mod_list, optarg);
|
||||
}
|
||||
fprintf(iconfig_file, "module:%s\n", optarg);
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
@@ -461,18 +528,7 @@ int main(int argc, char **argv)
|
||||
synth_flag = 1;
|
||||
break;
|
||||
case 's':
|
||||
if (start) {
|
||||
static const char *s = " -s ";
|
||||
size_t l = strlen(start);
|
||||
start = realloc(start, l + strlen(optarg) + strlen(s) + 1);
|
||||
strcpy(start + l, s);
|
||||
strcpy(start + l + strlen(s), optarg);
|
||||
} else {
|
||||
static const char *s = "-s ";
|
||||
start = malloc(strlen(optarg) + strlen(s) + 1);
|
||||
strcpy(start, s);
|
||||
strcpy(start + strlen(s), optarg);
|
||||
}
|
||||
fprintf(iconfig_file, "root:%s\n", optarg);
|
||||
break;
|
||||
case 'T':
|
||||
if (strcmp(optarg,"min") == 0) {
|
||||
@@ -493,6 +549,9 @@ int main(int argc, char **argv)
|
||||
case 'v':
|
||||
verbose_flag = 1;
|
||||
break;
|
||||
case 'V':
|
||||
version_flag = 1;
|
||||
break;
|
||||
case 'W':
|
||||
process_warning_switch(optarg);
|
||||
break;
|
||||
@@ -508,6 +567,27 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
if (version_flag || verbose_flag) {
|
||||
printf("Icarus Verilog version " VERSION " ($Name: $)\n");
|
||||
printf("Copyright 1998-2003 Stephen Williams\n");
|
||||
puts(NOTICE);
|
||||
|
||||
if (version_flag)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Make a common conf file path to reflect the target. */
|
||||
sprintf(iconfig_common_path, "%s%c%s%s.conf",
|
||||
base,sep, targ, synth_flag? "-s" : "");
|
||||
|
||||
/* Write values to the iconfig file. */
|
||||
fprintf(iconfig_file, "basedir:%s\n", base);
|
||||
if (mtm != 0) fprintf(iconfig_file, "-T:%s\n", mtm);
|
||||
fprintf(iconfig_file, "generation:%s\n", generation);
|
||||
fprintf(iconfig_file, "warnings:%s\n", warning_flags);
|
||||
fprintf(iconfig_file, "out:%s\n", opath);
|
||||
if (depfile) fprintf(iconfig_file, "depfile:%s\n", depfile);
|
||||
|
||||
if (command_filename) {
|
||||
int rc;
|
||||
|
||||
@@ -541,28 +621,10 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Load the iverilog.conf file to get our substitution
|
||||
strings. */
|
||||
|
||||
{ char path[1024];
|
||||
FILE*fd;
|
||||
if (config_path) {
|
||||
strcpy(path, config_path);
|
||||
} else {
|
||||
sprintf(path, "%s%civerilog.conf", base,sep);
|
||||
}
|
||||
fd = fopen(path, "r");
|
||||
if (fd == 0) {
|
||||
fprintf(stderr, "Config file \"%s\" not found\n",path);
|
||||
return 1;
|
||||
}
|
||||
reset_lexor(fd);
|
||||
yyparse();
|
||||
}
|
||||
|
||||
/* Start building the preprocess command line. */
|
||||
|
||||
sprintf(tmp, "%s%civlpp %s%s -f%s ", base,sep,
|
||||
sprintf(tmp, "%s%civlpp %s%s -D__ICARUS__=1 -f%s ", base,sep,
|
||||
verbose_flag?" -v":"",
|
||||
e_flag?"":" -L", source_path);
|
||||
|
||||
@@ -582,6 +644,12 @@ int main(int argc, char **argv)
|
||||
ncmd += strlen(def_list);
|
||||
}
|
||||
|
||||
if (depfile) {
|
||||
cmd = realloc(cmd, ncmd + strlen(depfile) + 5);
|
||||
strcat(cmd, " -M ");
|
||||
strcat(cmd, depfile);
|
||||
ncmd += strlen(depfile) + 4;
|
||||
}
|
||||
|
||||
/* If the -E flag was given on the command line, then all we
|
||||
do is run the preprocessor and put the output where the
|
||||
@@ -600,6 +668,10 @@ int main(int argc, char **argv)
|
||||
|
||||
rc = system(cmd);
|
||||
remove(source_path);
|
||||
fclose(iconfig_file);
|
||||
if ( ! getenv("IVERILOG_ICONFIG"))
|
||||
remove(iconfig_path);
|
||||
|
||||
if (rc != 0) {
|
||||
if (WIFEXITED(rc)) {
|
||||
fprintf(stderr, "errors preprocessing Verilog program.\n");
|
||||
@@ -613,95 +685,55 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(targ,"vvm") == 0)
|
||||
return t_vvm(cmd, ncmd);
|
||||
else {
|
||||
return t_default(cmd, ncmd);
|
||||
}
|
||||
/* Write the preprocessor command needed to preprocess a
|
||||
single file. This may be used to preprocess library
|
||||
files. */
|
||||
fprintf(iconfig_file, "ivlpp:%s%civlpp -D__ICARUS__ -L %s %s\n",
|
||||
base, sep,
|
||||
inc_list? inc_list : "",
|
||||
def_list? def_list : "");
|
||||
|
||||
/* Done writing to the iconfig file. Close it now. */
|
||||
fclose(iconfig_file);
|
||||
|
||||
return t_default(cmd, ncmd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: main.c,v $
|
||||
* Revision 1.31 2001/11/21 02:20:34 steve
|
||||
* Pass list of file to ivlpp via temporary file.
|
||||
* Revision 1.61 2003/11/18 06:31:46 steve
|
||||
* Remove the iverilog.conf file.
|
||||
*
|
||||
* Revision 1.30 2001/11/16 05:07:19 steve
|
||||
* Add support for +libext+ in command files.
|
||||
* Revision 1.60 2003/11/13 05:55:33 steve
|
||||
* Move the DLL= flag to target config files.
|
||||
*
|
||||
* Revision 1.29 2001/11/13 03:30:26 steve
|
||||
* The +incdir+ plusarg can take multiple directores,
|
||||
* and add initial support for +define+ in the command file.
|
||||
* Revision 1.59 2003/11/13 04:09:49 steve
|
||||
* Pass flags through the temporary config file.
|
||||
*
|
||||
* Revision 1.28 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.58 2003/11/01 04:21:57 steve
|
||||
* Add support for a target static config file.
|
||||
*
|
||||
* Revision 1.27 2001/11/12 01:26:36 steve
|
||||
* More sophisticated command file parser.
|
||||
* Revision 1.57 2003/10/26 22:43:42 steve
|
||||
* Improve -V messages,
|
||||
*
|
||||
* Revision 1.26 2001/11/11 00:10:05 steve
|
||||
* Remov XNF dead wood.
|
||||
* Revision 1.56 2003/09/26 21:25:58 steve
|
||||
* Warnings cleanup.
|
||||
*
|
||||
* Revision 1.25 2001/10/23 00:37:30 steve
|
||||
* The -s flag can now be repeated on the iverilog command.
|
||||
* Revision 1.55 2003/09/23 05:57:15 steve
|
||||
* Pass -m flag from driver via iconfig file.
|
||||
*
|
||||
* Revision 1.24 2001/10/20 23:02:40 steve
|
||||
* Add automatic module libraries.
|
||||
* Revision 1.54 2003/09/22 01:12:09 steve
|
||||
* Pass more ivl arguments through the iconfig file.
|
||||
*
|
||||
* Revision 1.23 2001/10/19 23:10:08 steve
|
||||
* Fix memory fault with -c flag.
|
||||
* Revision 1.53 2003/08/26 16:26:02 steve
|
||||
* ifdef idents correctly.
|
||||
*
|
||||
* Revision 1.22 2001/10/11 00:12:49 steve
|
||||
* Detect execv failures.
|
||||
* Revision 1.52 2003/02/22 04:55:36 steve
|
||||
* portbind adds p, not i, flag.
|
||||
*
|
||||
* Revision 1.21 2001/07/25 03:10:50 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.20 2001/06/30 21:53:42 steve
|
||||
* Make the vvp target the default.
|
||||
*
|
||||
* Revision 1.19 2001/06/30 04:23:02 steve
|
||||
* Get include and lib paths right for mingw and vvm.
|
||||
*
|
||||
* Revision 1.18 2001/06/30 00:59:24 steve
|
||||
* Redo the ivl_root calculator for mingw.
|
||||
*
|
||||
* Revision 1.17 2001/06/27 02:22:26 steve
|
||||
* Get include and lib paths from Makefile.
|
||||
*
|
||||
* Revision 1.16 2001/06/20 02:25:40 steve
|
||||
* Edit ivl_install_dir only on mingw
|
||||
*
|
||||
* Revision 1.15 2001/06/15 05:14:21 steve
|
||||
* Fix library path calculation on non Windows systems
|
||||
* to include the install directories. (Brendan Simon)
|
||||
*
|
||||
* Revision 1.14 2001/06/12 03:53:10 steve
|
||||
* Change the VPI call process so that loaded .vpi modules
|
||||
* use a function table instead of implicit binding.
|
||||
*
|
||||
* Revision 1.13 2001/05/20 18:22:02 steve
|
||||
* Fix WIFEXITED macro.
|
||||
*
|
||||
* Revision 1.12 2001/05/20 18:06:57 steve
|
||||
* local declares if the header is missing.
|
||||
*
|
||||
* Revision 1.11 2001/05/20 15:09:40 steve
|
||||
* Mingw32 support (Venkat Iyer)
|
||||
*
|
||||
* Revision 1.10 2001/05/17 03:14:26 steve
|
||||
* Update help message.
|
||||
*
|
||||
* Revision 1.9 2001/04/26 16:04:39 steve
|
||||
* Handle missing or uninstalled .conf files.
|
||||
*
|
||||
* Revision 1.8 2001/02/01 17:12:22 steve
|
||||
* Forgot to actually allow the -p flag.
|
||||
*
|
||||
* Revision 1.7 2001/01/20 19:02:05 steve
|
||||
* Switch hte -f flag to the -p flag.
|
||||
* Revision 1.51 2003/02/22 04:12:49 steve
|
||||
* Add the portbind warning.
|
||||
*/
|
||||
|
||||
|
||||
-167
@@ -1,167 +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.4 2001/09/15 18:27:04 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <stdio.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
# include <stdlib.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,112 @@
|
||||
/*
|
||||
* 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: substit.c,v 1.4 2002/08/12 01:35:01 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.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.
|
||||
*
|
||||
*/
|
||||
|
||||
+107
-11
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -16,8 +16,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: dup_expr.cc,v 1.6 2001/11/19 01:54:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: dup_expr.cc,v 1.16 2003/10/31 02:47:11 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -25,15 +25,55 @@
|
||||
# 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());
|
||||
NetESFunc*tmp = new NetESFunc(name_, type_, expr_width(), nparms());
|
||||
assert(tmp);
|
||||
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
|
||||
assert(tmp->parm(idx));
|
||||
@@ -59,6 +99,21 @@ NetETernary* NetETernary::dup_expr() const
|
||||
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 = new NetEUFunc(func_, result_->dup_expr(), tmp_parms);
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEUnary* NetEUnary::dup_expr() const
|
||||
{
|
||||
NetEUnary*tmp = new NetEUnary(op_, expr_->dup_expr());
|
||||
@@ -66,8 +121,56 @@ NetEUnary* NetEUnary::dup_expr() const
|
||||
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.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.
|
||||
@@ -83,12 +186,5 @@ NetEUnary* NetEUnary::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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+48
-15
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected].com)
|
||||
* Copyright (c) 2000-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,8 +16,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: elab_anet.cc,v 1.4 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_anet.cc,v 1.9 2003/09/19 03:50:12 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -29,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;
|
||||
}
|
||||
|
||||
@@ -86,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;
|
||||
@@ -104,17 +105,34 @@ NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
|
||||
|
||||
NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetNet*sig = des->find_signal(scope, path_);
|
||||
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, path_)) {
|
||||
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 ``" << path_ << "'' "
|
||||
<< "is undefined in this scope." << endl;
|
||||
des->errors += 1;
|
||||
@@ -138,7 +156,7 @@ 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."
|
||||
<< "on left side of procedural continuous assignment."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
@@ -149,6 +167,21 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_anet.cc,v $
|
||||
* 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.
|
||||
|
||||
+504
-101
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 1999-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,19 +16,43 @@
|
||||
* 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_expr.cc,v 1.46 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_expr.cc,v 1.82 2003/10/09 16:52:52 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "compiler.h"
|
||||
|
||||
# include "pform.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "util.h"
|
||||
|
||||
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*) const
|
||||
/*
|
||||
* 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;
|
||||
};
|
||||
|
||||
static const struct sfunc_return_type sfunc_table[] = {
|
||||
{ "$realtime", NetExpr::ET_REAL, 0, 0 },
|
||||
{ "$bitstoreal", NetExpr::ET_REAL, 0, 0 },
|
||||
{ "$itor", NetExpr::ET_REAL, 0, 0 },
|
||||
{ "$realtobits", NetExpr::ET_VECTOR, 64, 0 },
|
||||
{ "$time", NetExpr::ET_VECTOR, 64, 0 },
|
||||
{ "$stime", NetExpr::ET_VECTOR, 32, 0 },
|
||||
{ "$simtime", NetExpr::ET_VECTOR, 64, 0 },
|
||||
{ 0, NetExpr::ET_VECTOR, 32, 0 }
|
||||
};
|
||||
|
||||
|
||||
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*, bool) const
|
||||
{
|
||||
cerr << get_line() << ": internal error: I do not know how to elaborate"
|
||||
<< " expression. " << endl;
|
||||
@@ -43,7 +67,7 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*) const
|
||||
* and right sides, and creating one of a variety of different NetExpr
|
||||
* types.
|
||||
*/
|
||||
NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
{
|
||||
assert(left_);
|
||||
assert(right_);
|
||||
@@ -111,8 +135,9 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
case 'r':
|
||||
case 'l': // <<
|
||||
case 'r': // >>
|
||||
case 'R': // >>>
|
||||
tmp = new NetEBShift(op_, lp, rp);
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
@@ -120,7 +145,8 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
||||
case '^':
|
||||
case '&':
|
||||
case '|':
|
||||
case 'O':
|
||||
case 'O': // NOR (~|)
|
||||
case 'A': // NAND (~&)
|
||||
case 'X':
|
||||
tmp = new NetEBBits(op_, lp, rp);
|
||||
tmp->set_line(*this);
|
||||
@@ -136,6 +162,15 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
||||
case 'E': /* === */
|
||||
case 'n': /* != */
|
||||
case 'N': /* !== */
|
||||
if (dynamic_cast<NetEConst*>(rp)
|
||||
&& (lp->expr_width() > rp->expr_width()))
|
||||
rp->set_width(lp->expr_width());
|
||||
|
||||
if (dynamic_cast<NetEConst*>(lp)
|
||||
&& (lp->expr_width() < rp->expr_width()))
|
||||
lp->set_width(rp->expr_width());
|
||||
|
||||
/* from here, handle this like other compares. */
|
||||
case 'L': /* <= */
|
||||
case 'G': /* >= */
|
||||
case '<':
|
||||
@@ -162,10 +197,63 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
||||
*/
|
||||
NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||
{
|
||||
unsigned wid = 32;
|
||||
|
||||
if (strcmp(path_.peek_name(0), "$time") == 0)
|
||||
wid = 64;
|
||||
/* Catch the special case that the system function is the
|
||||
$signed function. This function is special, in that it does
|
||||
not lead to executable code but takes the single parameter
|
||||
and makes it into a signed expression. No bits are changed,
|
||||
it just changes the interpretation. */
|
||||
if (strcmp(path_.peek_name(0), "$signed") == 0) {
|
||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||
cerr << get_line() << ": error: The $signed() function "
|
||||
<< "takes exactly one(1) argument." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PExpr*expr = parms_[0];
|
||||
NetExpr*sub = expr->elaborate_expr(des, scope, true);
|
||||
sub->cast_signed(true);
|
||||
return sub;
|
||||
}
|
||||
|
||||
/* Interpret the internal $sizeof system function to return
|
||||
the bit width of the sub-expression. The value of the
|
||||
sub-expression is not used, so the expression itself can be
|
||||
deleted. */
|
||||
if ((strcmp(path_.peek_name(0), "$sizeof") == 0)
|
||||
|| (strcmp(path_.peek_name(0), "$bits") == 0)) {
|
||||
if ((parms_.count() != 1) || (parms_[0] == 0)) {
|
||||
cerr << get_line() << ": error: The $bits() function "
|
||||
<< "takes exactly one(1) argument." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (strcmp(path_.peek_name(0), "$sizeof") == 0)
|
||||
cerr << get_line() << ": warning: $sizeof is deprecated."
|
||||
<< " Use $bits() instead." << endl;
|
||||
|
||||
PExpr*expr = parms_[0];
|
||||
NetExpr*sub = expr->elaborate_expr(des, scope, true);
|
||||
verinum val (sub->expr_width(), 8*sizeof(unsigned));
|
||||
delete sub;
|
||||
|
||||
sub = new NetEConst(val);
|
||||
sub->set_line(*this);
|
||||
|
||||
return sub;
|
||||
}
|
||||
|
||||
/* Get the return type of the system function by looking it up
|
||||
in the sfunc_table. */
|
||||
unsigned sfunc_idx;
|
||||
for (sfunc_idx = 0 ; sfunc_table[sfunc_idx].name ; sfunc_idx += 1)
|
||||
if (strcmp(path_.peek_name(0), sfunc_table[sfunc_idx].name) == 0)
|
||||
break;
|
||||
|
||||
NetExpr::TYPE sfunc_type = sfunc_table[sfunc_idx].type;
|
||||
unsigned wid = sfunc_table[sfunc_idx].wid;
|
||||
|
||||
|
||||
/* How many parameters are there? The Verilog language allows
|
||||
@@ -174,13 +262,14 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||
be interpreted as a single empty parameter.
|
||||
|
||||
Functions cannot really take empty parameters, but the
|
||||
case ``func()'' is the same as no parmaters at all. So
|
||||
case ``func()'' is the same as no parameters at all. So
|
||||
catch that special case here. */
|
||||
unsigned nparms = parms_.count();
|
||||
if ((nparms == 1) && (parms_[0] == 0))
|
||||
nparms = 0;
|
||||
|
||||
NetESFunc*fun = new NetESFunc(path_.peek_name(0), wid, nparms);
|
||||
NetESFunc*fun = new NetESFunc(path_.peek_name(0), sfunc_type,
|
||||
wid, nparms);
|
||||
|
||||
/* Now run through the expected parameters. If we find that
|
||||
there are missing parameters, print an error message.
|
||||
@@ -193,7 +282,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||
for (unsigned idx = 0 ; idx < nparms ; idx += 1) {
|
||||
PExpr*expr = parms_[idx];
|
||||
if (expr) {
|
||||
NetExpr*tmp1 = expr->elaborate_expr(des, scope);
|
||||
NetExpr*tmp1 = expr->elaborate_expr(des, scope, true);
|
||||
if (NetExpr*tmp2 = tmp1->eval_tree()) {
|
||||
delete tmp1;
|
||||
fun->parm(idx, tmp2);
|
||||
@@ -219,7 +308,7 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||
return fun;
|
||||
}
|
||||
|
||||
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
|
||||
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
{
|
||||
if (path_.peek_name(0)[0] == '$')
|
||||
return elaborate_sfunc_(des, scope);
|
||||
@@ -236,30 +325,14 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
|
||||
NetScope*dscope = def->scope();
|
||||
assert(dscope);
|
||||
|
||||
/* How many parameters have I got? Normally the size of the
|
||||
list is correct, but there is the special case of a list of
|
||||
1 nil pointer. This is how the parser tells me of no
|
||||
parameter. In other words, ``func()'' is 1 nil parameter. */
|
||||
if (! check_call_matches_definition_(des, dscope))
|
||||
return 0;
|
||||
|
||||
unsigned parms_count = parms_.count();
|
||||
if ((parms_count == 1) && (parms_[0] == 0))
|
||||
parms_count = 0;
|
||||
|
||||
if (dscope->type() != NetScope::FUNC) {
|
||||
cerr << get_line() << ": error: Attempt to call scope "
|
||||
<< dscope->name() << " as a function." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((parms_count+1) != dscope->func_def()->port_count()) {
|
||||
cerr << get_line() << ": error: Function " << dscope->name()
|
||||
<< " expects " << (dscope->func_def()->port_count()-1)
|
||||
<< " parameters, you passed " << parms_count << "."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
svector<NetExpr*> parms (parms_count);
|
||||
|
||||
@@ -314,9 +387,9 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
|
||||
}
|
||||
|
||||
|
||||
NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope) const
|
||||
NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
{
|
||||
unsigned repeat = 1;
|
||||
NetExpr* repeat = 0;
|
||||
|
||||
/* If there is a repeat expression, then evaluate the constant
|
||||
value and set the repeat count. */
|
||||
@@ -332,20 +405,21 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope) const
|
||||
cerr << get_line() << ": : The expression is: "
|
||||
<< *tmp << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
repeat = rep->value().as_ulong();
|
||||
repeat = rep;
|
||||
}
|
||||
|
||||
/* Make the empty concat expression. */
|
||||
NetEConcat*tmp = new NetEConcat(parms_.count(), repeat);
|
||||
tmp->set_line(*this);
|
||||
|
||||
unsigned wid_sum = 0;
|
||||
|
||||
/* Elaborate all the parameters and attach them to the concat node. */
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
assert(parms_[idx]);
|
||||
NetExpr*ex = parms_[idx]->elaborate_expr(des, scope);
|
||||
NetExpr*ex = elab_and_eval(des, scope, parms_[idx]);
|
||||
if (ex == 0) continue;
|
||||
|
||||
ex->set_line(*parms_[idx]);
|
||||
@@ -357,32 +431,181 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope) const
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
wid_sum += ex->expr_width();
|
||||
tmp->set(idx, ex);
|
||||
}
|
||||
|
||||
tmp->set_width(wid_sum * tmp->repeat());
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope) const
|
||||
NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
{
|
||||
long val = value_->as_long();
|
||||
return new NetEConst(verinum(val));
|
||||
NetECReal*tmp = new NetECReal(*value_);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
/*
|
||||
* Elaborate an identifier in an expression. The identifier can be a
|
||||
* parameter name, a signal name or a memory name. It can also be a
|
||||
* scope name (Return a NetEScope) but only certain callers can use
|
||||
* scope names. However, we still support it here.
|
||||
*
|
||||
* Function names are not handled here, they are detected by the
|
||||
* parser and are elaborated by PECallFunction.
|
||||
*
|
||||
* The signal name may be escaped, but that affects nothing here.
|
||||
*/
|
||||
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope,
|
||||
bool sys_task_arg) const
|
||||
{
|
||||
assert(path_.peek_name(0)[0] != '$');
|
||||
|
||||
assert(scope);
|
||||
|
||||
NetNet* net = 0;
|
||||
NetMemory* mem = 0;
|
||||
NetVariable* var = 0;
|
||||
const NetExpr*par = 0;
|
||||
NetEvent* eve = 0;
|
||||
|
||||
NetScope*found_in = symbol_search(des, scope, path_,
|
||||
net, mem, var, par, eve);
|
||||
|
||||
// If the identifier name is a parameter name, then return
|
||||
// a reference to the parameter expression.
|
||||
if (const NetExpr*ex = des->find_parameter(scope, path_)) {
|
||||
if (par != 0) {
|
||||
NetExpr*tmp;
|
||||
if (dynamic_cast<const NetExpr*>(ex))
|
||||
tmp = ex->dup_expr();
|
||||
else
|
||||
tmp = new NetEParam(des, scope, path_);
|
||||
|
||||
tmp = par->dup_expr();
|
||||
|
||||
if (msb_ && lsb_) {
|
||||
/* If the parameter has a part select, we support
|
||||
it by pulling the right bits out and making a
|
||||
sized unsigned constant. This code assumes the
|
||||
lsb of a parameter is 0 and the msb is the
|
||||
width of the parameter. */
|
||||
|
||||
verinum*lsn = lsb_->eval_const(des, scope);
|
||||
verinum*msn = msb_->eval_const(des, scope);
|
||||
if ((lsn == 0) || (msn == 0)) {
|
||||
cerr << get_line() << ": error: "
|
||||
"Part select expressions must be "
|
||||
"constant expressions." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
long lsb = lsn->as_long();
|
||||
long msb = msn->as_long();
|
||||
if ((lsb < 0) || (msb < lsb)) {
|
||||
cerr << get_line() << ": error: invalid part "
|
||||
<< "select: " << path_
|
||||
<< "["<<msb<<":"<<lsb<<"]" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
unsigned long ulsb=lsb;
|
||||
unsigned long umsb=msb;
|
||||
|
||||
NetEConst*le = dynamic_cast<NetEConst*>(tmp);
|
||||
assert(le);
|
||||
|
||||
verinum result (verinum::V0, msb-lsb+1, true);
|
||||
verinum exl = le->value();
|
||||
|
||||
/* Pull the bits from the parameter, one at a
|
||||
time. If the bit is within the range, simply
|
||||
copy it to the result. If the bit is outside
|
||||
the range, we sign extend signed unsized
|
||||
numbers, zero extend unsigned unsigned numbers,
|
||||
and X extend sized numbers. */
|
||||
for (unsigned long idx = ulsb ; idx <= umsb ; idx += 1) {
|
||||
if (idx < exl.len())
|
||||
result.set(idx-lsb, exl.get(idx));
|
||||
else if (exl.is_string())
|
||||
result.set(idx-lsb, verinum::V0);
|
||||
else if (exl.has_len())
|
||||
result.set(idx-lsb, verinum::Vx);
|
||||
else if (exl.has_sign())
|
||||
result.set(idx-lsb, exl.get(exl.len()-1));
|
||||
else
|
||||
result.set(idx-lsb, verinum::V0);
|
||||
}
|
||||
|
||||
/* If the input is a string, and the part select
|
||||
is working on byte boundaries, then the result
|
||||
can be made into a string. */
|
||||
if (exl.is_string()
|
||||
&& (lsb%8 == 0)
|
||||
&& (result.len()%8 == 0))
|
||||
result = verinum(result.as_string());
|
||||
|
||||
delete tmp;
|
||||
tmp = new NetEConst(result);
|
||||
|
||||
} else if (msb_) {
|
||||
/* Handle the case where a parameter has a bit
|
||||
select attached to it. Generate a NetESelect
|
||||
object to select the bit as desired. */
|
||||
NetExpr*mtmp = msb_->elaborate_expr(des, scope);
|
||||
if (! dynamic_cast<NetEConst*>(mtmp)) {
|
||||
NetExpr*re = mtmp->eval_tree();
|
||||
if (re) {
|
||||
delete mtmp;
|
||||
mtmp = re;
|
||||
}
|
||||
}
|
||||
|
||||
/* Let's first try to get constant values for both
|
||||
the parameter and the bit select. If they are
|
||||
both constant, then evaluate the bit select and
|
||||
return instead a single-bit constant. */
|
||||
|
||||
NetEConst*le = dynamic_cast<NetEConst*>(tmp);
|
||||
NetEConst*re = dynamic_cast<NetEConst*>(mtmp);
|
||||
if (le && re) {
|
||||
|
||||
verinum lv = le->value();
|
||||
verinum rv = re->value();
|
||||
verinum::V rb = verinum::Vx;
|
||||
|
||||
long ridx = rv.as_long();
|
||||
if ((ridx >= 0) && ((unsigned long) ridx < lv.len())) {
|
||||
rb = lv[ridx];
|
||||
|
||||
} else if ((ridx >= 0) && (!lv.has_len())) {
|
||||
if (lv.has_sign())
|
||||
rb = lv[lv.len()-1];
|
||||
else
|
||||
rb = verinum::V0;
|
||||
}
|
||||
|
||||
NetEConst*re = new NetEConst(verinum(rb, 1));
|
||||
delete tmp;
|
||||
delete mtmp;
|
||||
tmp = re;
|
||||
|
||||
} else {
|
||||
|
||||
NetESelect*stmp = new NetESelect(tmp, mtmp, 1);
|
||||
tmp->set_line(*this);
|
||||
tmp = stmp;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* No bit or part select. Make the constant into a
|
||||
NetEConstParam if possible. */
|
||||
NetEConst*ctmp = dynamic_cast<NetEConst*>(tmp);
|
||||
if (ctmp != 0) {
|
||||
const char*name
|
||||
= lex_strings.add(path_.peek_tail_name());
|
||||
NetEConstParam*ptmp
|
||||
= new NetEConstParam(found_in, name, ctmp->value());
|
||||
delete tmp;
|
||||
tmp = ptmp;
|
||||
}
|
||||
}
|
||||
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
@@ -390,7 +613,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
|
||||
// If the identifier names a signal (a register or wire)
|
||||
// then create a NetESignal node to handle it.
|
||||
if (NetNet*net = des->find_signal(scope, path_)) {
|
||||
if (net != 0) {
|
||||
|
||||
// If this is a part select of a signal, then make a new
|
||||
// temporary signal that is connected to just the
|
||||
@@ -402,7 +625,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
verinum*msn = msb_->eval_const(des, scope);
|
||||
if ((lsn == 0) || (msn == 0)) {
|
||||
cerr << get_line() << ": error: "
|
||||
"Part select expresions must be "
|
||||
"Part select expressions must be "
|
||||
"constant expressions." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
@@ -415,7 +638,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
integers, so allow negative values. However,
|
||||
the width that they represent is
|
||||
unsigned. Remember that any order is possible,
|
||||
i.e. [1:0], [-4,6], etc. */
|
||||
i.e., [1:0], [-4,6], etc. */
|
||||
|
||||
long lsv = lsn->as_long();
|
||||
long msv = msn->as_long();
|
||||
@@ -466,15 +689,25 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
verinum*msn;
|
||||
if (msb_ && (msn = msb_->eval_const(des, scope))) {
|
||||
assert(idx_ == 0);
|
||||
unsigned long msv = msn->as_ulong();
|
||||
long msv = msn->as_long();
|
||||
unsigned idx = net->sb_to_idx(msv);
|
||||
|
||||
if (idx >= net->pin_count()) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "bit " << msv << " out of range of net "
|
||||
/* The bit select is out of range of the
|
||||
vector. This is legal, but returns a
|
||||
constant 1'bx value. */
|
||||
verinum x (verinum::Vx);
|
||||
NetEConst*tmp = new NetEConst(x);
|
||||
tmp->set_line(*this);
|
||||
|
||||
cerr << get_line() << ": warning: Bit select ["
|
||||
<< msv << "] out of range of vector "
|
||||
<< net->name() << "[" << net->msb()
|
||||
<< ":" << net->lsb() << "]." << endl;
|
||||
return 0;
|
||||
cerr << get_line() << ": : Replacing "
|
||||
<< "expression with a constant 1'bx." << endl;
|
||||
delete msn;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetESignal*tmp = new NetESignal(net, idx, idx);
|
||||
@@ -504,12 +737,25 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
// If the identifier names a memory, then this is a
|
||||
// memory reference and I must generate a NetEMemory
|
||||
// object to handle it.
|
||||
if (NetMemory*mem = des->find_memory(scope, path_)) {
|
||||
if (mem != 0) {
|
||||
if (msb_ == 0) {
|
||||
NetEMemory*node = new NetEMemory(mem);
|
||||
node->set_line(*this);
|
||||
return node;
|
||||
|
||||
// If this memory is an argument to a system task,
|
||||
// then it is OK for it to not have an index.
|
||||
if (sys_task_arg) {
|
||||
NetEMemory*node = new NetEMemory(mem);
|
||||
node->set_line(*this);
|
||||
return node;
|
||||
}
|
||||
|
||||
// If it is not a simple system task argument,
|
||||
// this a missing index is an error.
|
||||
cerr << get_line() << ": error: memory " << mem->name()
|
||||
<< " needs an index in this context." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(msb_ != 0);
|
||||
if (lsb_) {
|
||||
cerr << get_line() << ": error: part select of a memory: "
|
||||
@@ -522,7 +768,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
assert(idx_ == 0);
|
||||
NetExpr*i = msb_->elaborate_expr(des, scope);
|
||||
if (msb_ && i == 0) {
|
||||
cerr << get_line() << ": error: Unable to exaborate "
|
||||
cerr << get_line() << ": error: Unable to elaborate "
|
||||
"index expression `" << *msb_ << "'" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
@@ -533,9 +779,25 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
return node;
|
||||
}
|
||||
|
||||
// If the identifier names a variable of some sort, then this
|
||||
// is a variable reference.
|
||||
if (var != 0) {
|
||||
NetEVariable*node = new NetEVariable(var);
|
||||
node->set_line(*this);
|
||||
return node;
|
||||
}
|
||||
|
||||
// If the identifier is a named event.
|
||||
// is a variable reference.
|
||||
if (eve != 0) {
|
||||
NetEEvent*tmp = new NetEEvent(eve);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Finally, if this is a scope name, then return that. Look
|
||||
// first to see if this is a name of a local scope. Failing
|
||||
// that, search globally for a heirarchical name.
|
||||
// that, search globally for a hierarchical name.
|
||||
if ((path_.peek_name(1) == 0))
|
||||
if (NetScope*nsc = scope->child(path_.peek_name(0))) {
|
||||
NetEScope*tmp = new NetEScope(nsc);
|
||||
@@ -543,15 +805,20 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// NOTE: This search pretty much assumes that text_ is a
|
||||
// complete hierarchical name, since there is no mention of
|
||||
// the current scope in the call to find_scope.
|
||||
// Try full hierarchical scope name.
|
||||
if (NetScope*nsc = des->find_scope(path_)) {
|
||||
NetEScope*tmp = new NetEScope(nsc);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// Try relative scope name.
|
||||
if (NetScope*nsc = des->find_scope(scope, path_)) {
|
||||
NetEScope*tmp = new NetEScope(nsc);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
// I cannot interpret this identifier. Error message.
|
||||
cerr << get_line() << ": error: Unable to bind wire/reg/memory "
|
||||
"`" << path_ << "' in `" << scope->name() << "'" << endl;
|
||||
@@ -559,7 +826,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetEConst* PENumber::elaborate_expr(Design*des, NetScope*) const
|
||||
NetEConst* PENumber::elaborate_expr(Design*des, NetScope*, bool) const
|
||||
{
|
||||
assert(value_);
|
||||
NetEConst*tmp = new NetEConst(*value_);
|
||||
@@ -567,7 +834,7 @@ NetEConst* PENumber::elaborate_expr(Design*des, NetScope*) const
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEConst* PEString::elaborate_expr(Design*des, NetScope*) const
|
||||
NetEConst* PEString::elaborate_expr(Design*des, NetScope*, bool) const
|
||||
{
|
||||
NetEConst*tmp = new NetEConst(value());
|
||||
tmp->set_line(*this);
|
||||
@@ -579,7 +846,7 @@ NetEConst* PEString::elaborate_expr(Design*des, NetScope*) const
|
||||
* parsed so I can presume that they exist, and call elaboration
|
||||
* methods. If any elaboration fails, then give up and return 0.
|
||||
*/
|
||||
NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
{
|
||||
assert(expr_);
|
||||
assert(tru_);
|
||||
@@ -603,10 +870,11 @@ NetETernary*PETernary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
}
|
||||
|
||||
NetETernary*res = new NetETernary(con, tru, fal);
|
||||
res->set_line(*this);
|
||||
return res;
|
||||
}
|
||||
|
||||
NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
NetExpr* PEUnary::elaborate_expr(Design*des, NetScope*scope, bool) const
|
||||
{
|
||||
NetExpr*ip = expr_->elaborate_expr(des, scope);
|
||||
if (ip == 0) return 0;
|
||||
@@ -615,13 +883,72 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
* just like in PEBinary::elaborate_expr() ?
|
||||
*/
|
||||
|
||||
NetEUnary*tmp;
|
||||
NetExpr*tmp;
|
||||
switch (op_) {
|
||||
default:
|
||||
tmp = new NetEUnary(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
|
||||
case '-':
|
||||
if (NetEConst*ipc = dynamic_cast<NetEConst*>(ip)) {
|
||||
/* When taking the - of a number, turn it into a
|
||||
signed expression and extend it one bit to
|
||||
accommodate a possible sign bit. */
|
||||
verinum val = ipc->value();
|
||||
verinum zero (verinum::V0, val.len()+1, val.has_len());
|
||||
val = zero - val;
|
||||
val.has_sign(true);
|
||||
tmp = new NetEConst(val);
|
||||
delete ip;
|
||||
} else {
|
||||
tmp = new NetEUnary(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
}
|
||||
break;
|
||||
|
||||
case '+':
|
||||
tmp = ip;
|
||||
break;
|
||||
|
||||
case '!': // Logical NOT
|
||||
/* If the operand to unary ! is a constant, then I can
|
||||
evaluate this expression here and return a logical
|
||||
constant in its place. */
|
||||
if (NetEConst*ipc = dynamic_cast<NetEConst*>(ip)) {
|
||||
verinum val = ipc->value();
|
||||
unsigned v1 = 0;
|
||||
unsigned vx = 0;
|
||||
for (unsigned idx = 0 ; idx < val.len() ; idx += 1)
|
||||
switch (val[idx]) {
|
||||
case verinum::V0:
|
||||
break;
|
||||
case verinum::V1:
|
||||
v1 += 1;
|
||||
break;
|
||||
default:
|
||||
vx += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
verinum::V res;
|
||||
if (v1 > 0)
|
||||
res = verinum::V0;
|
||||
else if (vx > 0)
|
||||
res = verinum::Vx;
|
||||
else
|
||||
res = verinum::V1;
|
||||
|
||||
verinum vres (res, 1, true);
|
||||
tmp = new NetEConst(vres);
|
||||
tmp->set_line(*this);
|
||||
delete ip;
|
||||
} else {
|
||||
tmp = new NetEUReduce(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
}
|
||||
break;
|
||||
|
||||
case '&': // Reduction AND
|
||||
case '|': // Reduction OR
|
||||
case '^': // Reduction XOR
|
||||
@@ -631,6 +958,7 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
tmp = new NetEUReduce(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
|
||||
case '~':
|
||||
tmp = new NetEUBits(op_, ip);
|
||||
tmp->set_line(*this);
|
||||
@@ -642,44 +970,119 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_expr.cc,v $
|
||||
* Revision 1.46 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
* Revision 1.82 2003/10/09 16:52:52 steve
|
||||
* Put parameter name in NetEConstParam, not scope.
|
||||
*
|
||||
* Revision 1.45 2001/11/19 02:54:12 steve
|
||||
* Handle division and modulus by zero while
|
||||
* evaluating run-time constants.
|
||||
* Revision 1.81 2003/09/19 03:30:05 steve
|
||||
* Fix name search in elab_lval.
|
||||
*
|
||||
* Revision 1.44 2001/11/19 01:54:14 steve
|
||||
* Port close cropping behavior from mcrgb
|
||||
* Move window array reset to libmc.
|
||||
* Revision 1.80 2003/06/24 01:38:02 steve
|
||||
* Various warnings fixed.
|
||||
*
|
||||
* Revision 1.43 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
* Revision 1.79 2003/06/18 03:55:18 steve
|
||||
* Add arithmetic shift operators.
|
||||
*
|
||||
* Revision 1.42 2001/07/29 22:22:40 steve
|
||||
* support local reference to scope in expressions.
|
||||
* Revision 1.78 2003/06/10 04:29:57 steve
|
||||
* PR735: bit select indices are signed constants.
|
||||
*
|
||||
* Revision 1.41 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.77 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.40 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.76 2003/04/22 04:48:29 steve
|
||||
* Support event names as expressions elements.
|
||||
*
|
||||
* Revision 1.39 2001/06/30 21:28:35 steve
|
||||
* Detect parameter mismatches.
|
||||
* Revision 1.75 2003/04/19 04:19:38 steve
|
||||
* Set line number for ternary expressions.
|
||||
*
|
||||
* Revision 1.38 2001/06/23 19:53:03 steve
|
||||
* Look up functor return register with tail of name.
|
||||
* Revision 1.74 2003/04/02 04:25:26 steve
|
||||
* Fix xz extension of constants.
|
||||
*
|
||||
* Revision 1.37 2001/04/06 02:28:02 steve
|
||||
* Generate vvp code for functions with ports.
|
||||
* Revision 1.73 2003/03/25 03:00:04 steve
|
||||
* Scope names can be relative.
|
||||
*
|
||||
* Revision 1.36 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.72 2003/03/15 04:46:28 steve
|
||||
* Better organize the NetESFunc return type guesses.
|
||||
*
|
||||
* Revision 1.71 2003/03/10 23:40:53 steve
|
||||
* Keep parameter constants for the ivl_target API.
|
||||
*
|
||||
* Revision 1.70 2003/03/07 02:44:34 steve
|
||||
* Implement $realtobits.
|
||||
*
|
||||
* Revision 1.69 2003/01/27 05:09:17 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.68 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
* Revision 1.67 2002/12/21 00:55:57 steve
|
||||
* The $time system task returns the integer time
|
||||
* scaled to the local units. Change the internal
|
||||
* implementation of vpiSystemTime the $time functions
|
||||
* to properly account for this. Also add $simtime
|
||||
* to get the simulation time.
|
||||
*
|
||||
* Revision 1.66 2002/09/21 21:28:18 steve
|
||||
* Allow constant bit selects out of range.
|
||||
*
|
||||
* Revision 1.65 2002/09/18 04:08:45 steve
|
||||
* Spelling errors.
|
||||
*
|
||||
* Revision 1.64 2002/09/12 15:49:43 steve
|
||||
* Add support for binary nand operator.
|
||||
*
|
||||
* Revision 1.63 2002/08/19 02:39:16 steve
|
||||
* Support parameters with defined ranges.
|
||||
*
|
||||
* Revision 1.62 2002/08/12 01:34:58 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.61 2002/06/14 21:38:41 steve
|
||||
* Fix expression width for repeat concatenations.
|
||||
*
|
||||
* Revision 1.60 2002/05/24 00:44:54 steve
|
||||
* Add support for $bits (SystemVerilog)
|
||||
*
|
||||
* Revision 1.59 2002/05/06 02:30:27 steve
|
||||
* Allow parameters in concatenation of widths are defined.
|
||||
*
|
||||
* Revision 1.58 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.57 2002/04/27 05:03:46 steve
|
||||
* Preserve stringiness string part select and concatenation.
|
||||
*
|
||||
* Revision 1.56 2002/04/27 02:38:04 steve
|
||||
* Support selecting bits from parameters.
|
||||
*
|
||||
* Revision 1.55 2002/04/25 05:04:31 steve
|
||||
* Evaluate constant bit select of constants.
|
||||
*
|
||||
* Revision 1.54 2002/04/14 21:16:48 steve
|
||||
* Evaluate logical not at elaboration time.
|
||||
*
|
||||
* Revision 1.53 2002/04/14 03:55:25 steve
|
||||
* Precalculate unary - if possible.
|
||||
*
|
||||
* Revision 1.52 2002/04/13 02:33:17 steve
|
||||
* Detect missing indices to memories (PR#421)
|
||||
*
|
||||
* Revision 1.51 2002/03/09 02:10:22 steve
|
||||
* Add the NetUserFunc netlist node.
|
||||
*
|
||||
* Revision 1.50 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.49 2002/01/11 05:25:45 steve
|
||||
* The stime system function is 32bits.
|
||||
*/
|
||||
|
||||
|
||||
+132
-26
@@ -16,36 +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.17 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_lval.cc,v 1.27 2003/09/19 03:30:05 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.
|
||||
*
|
||||
* 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
|
||||
@@ -55,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.
|
||||
*/
|
||||
|
||||
@@ -67,7 +68,7 @@
|
||||
*/
|
||||
NetAssign_* PExpr::elaborate_lval(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetNet*ll = elaborate_net(des, scope, 0, 0, 0, 0);
|
||||
NetNet*ll = 0;
|
||||
if (ll == 0) {
|
||||
cerr << get_line() << ": Assignment l-value too complex."
|
||||
<< endl;
|
||||
@@ -103,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
|
||||
@@ -133,25 +142,36 @@ 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, path_);
|
||||
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, path_);
|
||||
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 ``"
|
||||
<< path_ << "'' 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: " << path_ <<
|
||||
" is not a reg/integer/time in " << scope->name() <<
|
||||
@@ -171,16 +191,20 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
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);
|
||||
if (vl == 0) {
|
||||
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;
|
||||
}
|
||||
@@ -275,8 +299,90 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
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.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.
|
||||
|
||||
+867
-249
File diff suppressed because it is too large
Load Diff
+65
-22
@@ -16,8 +16,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: elab_pexpr.cc,v 1.12 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_pexpr.cc,v 1.20 2003/05/30 02:55:32 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -61,33 +61,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);
|
||||
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. */
|
||||
@@ -104,17 +97,17 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
|
||||
ex->set_line(*parms_[idx]);
|
||||
|
||||
if (! ex->has_width()) {
|
||||
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;
|
||||
|
||||
} else if (ex->expr_width() == 0) {
|
||||
cerr << ex->get_line() << ": internal error: "
|
||||
<< "Operand of concatenation has no width: "
|
||||
<< *ex << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
tmp->set(idx, ex);
|
||||
@@ -153,8 +146,26 @@ NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
}
|
||||
|
||||
NetExpr*res = new NetEParam(des, pscope, hname_t(name));
|
||||
res->set_line(*this);
|
||||
assert(res);
|
||||
delete name;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -218,6 +229,38 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_pexpr.cc,v $
|
||||
* 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.
|
||||
|
||||
+165
-68
@@ -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,12 +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_scope.cc,v 1.12 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_scope.cc,v 1.27 2003/09/13 01:01:51 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "config.h"
|
||||
# include "compiler.h"
|
||||
# include <iostream>
|
||||
|
||||
/*
|
||||
@@ -32,6 +32,7 @@
|
||||
*/
|
||||
|
||||
# include "Module.h"
|
||||
# include "PData.h"
|
||||
# include "PEvent.h"
|
||||
# include "PExpr.h"
|
||||
# include "PGate.h"
|
||||
@@ -39,7 +40,9 @@
|
||||
# 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
|
||||
{
|
||||
@@ -54,7 +57,7 @@ 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<string,param_expr_t>::const_iterator mparm_it_t;
|
||||
typedef map<hname_t,PExpr*>::const_iterator hparm_it_t;
|
||||
|
||||
|
||||
@@ -64,13 +67,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -82,11 +95,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;
|
||||
}
|
||||
@@ -94,11 +125,11 @@ 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);
|
||||
val = scope->set_parameter((*cur).first, val, 0, 0, false);
|
||||
assert(val);
|
||||
delete val;
|
||||
}
|
||||
@@ -110,7 +141,7 @@ 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 (hparm_it_t cur = defparms.begin()
|
||||
@@ -124,6 +155,16 @@ 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
|
||||
@@ -191,6 +232,12 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
(*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;
|
||||
}
|
||||
|
||||
@@ -210,7 +257,7 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
// about to create, and if I find it then somebody beat me to
|
||||
// it.
|
||||
|
||||
if (NetScope*tmp = sc->child(get_name())) {
|
||||
if (sc->child(get_name())) {
|
||||
cerr << get_line() << ": error: Instance/Scope name " <<
|
||||
get_name() << " already used in this context." <<
|
||||
endl;
|
||||
@@ -256,8 +303,10 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
// later.)
|
||||
mod->elaborate_scope(des, my_scope);
|
||||
|
||||
// Look for module parameter replacements. This map receives
|
||||
// those replacements.
|
||||
// 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<string,PExpr*>::const_iterator mparm_it_t;
|
||||
map<string,PExpr*> replace;
|
||||
@@ -271,12 +320,18 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
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];
|
||||
}
|
||||
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
|
||||
@@ -298,12 +353,43 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
|
||||
PExpr*tmp = (*cur).second;
|
||||
NetExpr*val = tmp->elaborate_pexpr(des, sc);
|
||||
val = my_scope->set_parameter((*cur).first, val);
|
||||
assert(val);
|
||||
delete val;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
const char*basename = hname_.peek_tail_name();
|
||||
NetVariable*tmp = new NetVariable(lex_strings.add(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
|
||||
@@ -320,6 +406,10 @@ 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
|
||||
@@ -361,7 +451,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.
|
||||
*/
|
||||
@@ -459,51 +549,58 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_scope.cc,v $
|
||||
* 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.
|
||||
*
|
||||
* Revision 1.11 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
*
|
||||
* Revision 1.10 2001/10/09 02:01:04 steve
|
||||
* Tasks can have sub-scopes.
|
||||
*
|
||||
* 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/04/28 23:18:08 steve
|
||||
* UDP instances need not have user supplied names.
|
||||
*
|
||||
* Revision 1.7 2000/12/16 01:45:48 steve
|
||||
* Detect recursive instantiations (PR#2)
|
||||
*
|
||||
* 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.5 2000/07/22 22:09:03 steve
|
||||
* Parse and elaborate timescale to scopes.
|
||||
*
|
||||
* Revision 1.4 2000/04/09 17:44:30 steve
|
||||
* Catch event declarations during scope elaborate.
|
||||
*
|
||||
* Revision 1.3 2000/03/12 17:09:41 steve
|
||||
* Support localparam.
|
||||
*
|
||||
* Revision 1.2 2000/03/11 03:25:52 steve
|
||||
* Locate scopes in statements.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+128
-67
@@ -16,8 +16,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: elab_sig.cc,v 1.18 2001/12/03 04:47:14 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: elab_sig.cc,v 1.32 2003/09/20 05:24:00 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -71,8 +71,8 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
// 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];
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
Module::port_t*pp = ports[idx];
|
||||
if (pp == 0)
|
||||
continue;
|
||||
|
||||
@@ -122,7 +122,7 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
hname_t name = (*wt).first;
|
||||
|
||||
if (! signal_is_in_port(ports_, name)) {
|
||||
if (! signal_is_in_port(ports, name)) {
|
||||
|
||||
cerr << cur->get_line() << ": error: Signal "
|
||||
<< name << " has a declared direction "
|
||||
@@ -237,6 +237,17 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
string fname = scope->basename();
|
||||
assert(scope->type() == NetScope::FUNC);
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
svector<NetNet*>ports (ports_? ports_->count()+1 : 1);
|
||||
|
||||
/* Get the reg for the return value. I know the name of the
|
||||
@@ -349,7 +360,7 @@ 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.
|
||||
*/
|
||||
@@ -379,14 +390,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]);
|
||||
|
||||
@@ -417,6 +440,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) {
|
||||
@@ -440,15 +475,21 @@ 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, scope);
|
||||
verinum*rval = ridx_->eval_const(des, scope);
|
||||
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 ``"
|
||||
<< hname_.peek_tail_name() << "''." << endl;
|
||||
@@ -456,34 +497,95 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
return;
|
||||
}
|
||||
|
||||
assert(lval);
|
||||
assert(rval);
|
||||
NetEConst*lcon = dynamic_cast<NetEConst*> (lexp);
|
||||
NetEConst*rcon = dynamic_cast<NetEConst*> (rexp);
|
||||
|
||||
string name = scope->name();
|
||||
name = name + "." + hname_.peek_tail_name();
|
||||
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;
|
||||
}
|
||||
|
||||
long lnum = lval->as_long();
|
||||
long rnum = rval->as_long();
|
||||
delete lval;
|
||||
delete rval;
|
||||
NetMemory*sig = new NetMemory(scope, name, wid, lnum, rnum);
|
||||
verinum lval = lcon->value();
|
||||
verinum rval = rcon->value();
|
||||
|
||||
delete lexp;
|
||||
delete rexp;
|
||||
|
||||
string name = 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 {
|
||||
|
||||
/* Make a hierarchical make for the signal. */
|
||||
string name = scope->name();
|
||||
name = name + "." + hname_.peek_tail_name();
|
||||
|
||||
string name = 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.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.
|
||||
@@ -510,46 +612,5 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+722
-508
File diff suppressed because it is too large
Load Diff
@@ -16,8 +16,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: emit.cc,v 1.63 2001/10/19 21:53:24 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: emit.cc,v 1.75 2003/09/13 01:30:07 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -128,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);
|
||||
@@ -156,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);
|
||||
@@ -186,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
|
||||
@@ -263,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
|
||||
@@ -316,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);
|
||||
|
||||
@@ -351,6 +350,8 @@ void NetScope::emit_defs(struct target_t*tgt) const
|
||||
case TASK:
|
||||
tgt->task_def(this);
|
||||
break;
|
||||
default: /* BEGIN_END and FORK_JOIN, do nothing */
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -415,6 +416,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);
|
||||
@@ -426,11 +442,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);
|
||||
@@ -461,6 +487,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) {
|
||||
@@ -469,11 +500,60 @@ 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.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)
|
||||
*
|
||||
|
||||
@@ -16,8 +16,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: eval.cc,v 1.24 2001/12/03 04:47:15 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"
|
||||
@@ -46,46 +46,70 @@ verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
|
||||
|
||||
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());
|
||||
@@ -96,6 +120,17 @@ verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) 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;
|
||||
@@ -121,16 +156,20 @@ verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const
|
||||
if (expr == 0)
|
||||
return 0;
|
||||
|
||||
assert(msb_ == 0);
|
||||
|
||||
if (dynamic_cast<const NetEParam*>(expr)) {
|
||||
cerr << get_line() << ": sorry: I cannot evaluate ``" <<
|
||||
path_ << "'' 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());
|
||||
}
|
||||
|
||||
@@ -145,6 +184,11 @@ verinum* PENumber::eval_const(const Design*, const NetScope*) const
|
||||
return new verinum(value());
|
||||
}
|
||||
|
||||
verinum* PEString::eval_const(const Design*, const NetScope*) const
|
||||
{
|
||||
return new verinum(string(text_));
|
||||
}
|
||||
|
||||
verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verinum*test = expr_->eval_const(des, scope);
|
||||
@@ -196,6 +240,49 @@ verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) 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.
|
||||
|
||||
+101
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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: eval_attrib.cc,v 1.6 2003/01/27 05:09:17 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<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<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.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.
|
||||
*
|
||||
*/
|
||||
|
||||
-101
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: eval_rconst.cc,v 1.4 2001/11/07 04:01:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PExpr.h"
|
||||
|
||||
verireal* PExpr::eval_rconst(const Design*, const NetScope*) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
verireal* PEFNumber::eval_rconst(const Design*, const NetScope*) const
|
||||
{
|
||||
verireal*res = new verireal;
|
||||
*res = *value_;
|
||||
return res;
|
||||
}
|
||||
|
||||
verireal* PENumber::eval_rconst(const Design*, const NetScope*) const
|
||||
{
|
||||
verireal*res = new verireal(value_->as_long());
|
||||
return res;
|
||||
}
|
||||
|
||||
verireal* PEBinary::eval_rconst(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verireal*lef = left_->eval_rconst(des, scope);
|
||||
verireal*rig = right_->eval_rconst(des, scope);
|
||||
verireal*res = 0;
|
||||
|
||||
switch (op_) {
|
||||
case '*':
|
||||
if (lef == 0)
|
||||
break;
|
||||
if (rig == 0)
|
||||
break;
|
||||
res = new verireal;
|
||||
*res = (*lef) * (*rig);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
delete lef;
|
||||
delete rig;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
verireal* PEIdent::eval_rconst(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verinum* val = eval_const(des, scope);
|
||||
if (val == 0)
|
||||
return 0;
|
||||
|
||||
verireal*res = new verireal(val->as_long());
|
||||
delete val;
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: eval_rconst.cc,v $
|
||||
* Revision 1.4 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.3 2001/11/06 06:11:55 steve
|
||||
* Support more real arithmetic in delay constants.
|
||||
*
|
||||
* Revision 1.2 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.1 2001/01/14 23:04:56 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
*
|
||||
* Allow parameters to be referenced by hierarchical name.
|
||||
*
|
||||
*/
|
||||
|
||||
+605
-165
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
+1
-1
@@ -31,7 +31,7 @@
|
||||
* 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
|
||||
|
||||
@@ -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
|
||||
@@ -41,7 +41,7 @@
|
||||
* 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
|
||||
|
||||
@@ -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
|
||||
+1
-1
@@ -72,7 +72,7 @@ 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;
|
||||
|
||||
@@ -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 */
|
||||
+353
-135
@@ -16,8 +16,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: expr_synth.cc,v 1.29 2001/11/29 01:58:18 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: expr_synth.cc,v 1.52 2003/11/10 19:39:20 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -44,14 +44,21 @@ NetNet* NetEBAdd::synthesize(Design*des)
|
||||
|
||||
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();
|
||||
|
||||
string path = lsig->scope()->name()+"."+lsig->scope()->local_symbol();
|
||||
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);
|
||||
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));
|
||||
@@ -62,10 +69,10 @@ NetNet* NetEBAdd::synthesize(Design*des)
|
||||
|
||||
switch (op()) {
|
||||
case '+':
|
||||
adder->attribute("LPM_Direction", "ADD");
|
||||
adder->attribute("LPM_Direction", verinum("ADD"));
|
||||
break;
|
||||
case '-':
|
||||
adder->attribute("LPM_Direction", "SUB");
|
||||
adder->attribute("LPM_Direction", verinum("SUB"));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -99,14 +106,34 @@ NetNet* NetEBBits::synthesize(Design*des)
|
||||
}
|
||||
|
||||
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);
|
||||
string oname = scope->local_hsymbol();
|
||||
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);
|
||||
@@ -154,23 +181,50 @@ NetNet* NetEBComp::synthesize(Design*des)
|
||||
: right_->synthesize(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);
|
||||
|
||||
NetLogic*gate;
|
||||
switch (op_) {
|
||||
case 'e':
|
||||
case 'E':
|
||||
gate = new NetLogic(scope, des->local_symbol(path),
|
||||
gate = new NetLogic(scope, scope->local_hsymbol(),
|
||||
lsig->pin_count()+1, NetLogic::NOR);
|
||||
break;
|
||||
case 'n':
|
||||
case 'N':
|
||||
gate = new NetLogic(scope, des->local_symbol(path),
|
||||
gate = new NetLogic(scope, scope->local_hsymbol(),
|
||||
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_hsymbol(),
|
||||
lsig->pin_count()+1, NetLogic::OR);
|
||||
} else {
|
||||
assert(0);
|
||||
gate = new NetLogic(scope, scope->local_hsymbol(),
|
||||
lsig->pin_count()+1, NetLogic::NOR);
|
||||
}
|
||||
break;
|
||||
|
||||
case '<':
|
||||
/* 0 < sig is handled like sig > 0. */
|
||||
if (! rcon) {
|
||||
gate = new NetLogic(scope, scope->local_hsymbol(),
|
||||
lsig->pin_count()+1, NetLogic::OR);
|
||||
} else {
|
||||
assert(0);
|
||||
gate = new NetLogic(scope, scope->local_hsymbol(),
|
||||
lsig->pin_count()+1, NetLogic::NOR);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
@@ -188,7 +242,6 @@ NetNet* NetEBComp::synthesize(Design*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())
|
||||
@@ -197,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_hsymbol(),
|
||||
3, NetLogic::XNOR);
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
connect(gate->pin(1), lsig->pin(0));
|
||||
@@ -216,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_hsymbol(),
|
||||
3, NetLogic::XOR);
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
connect(gate->pin(1), lsig->pin(0));
|
||||
@@ -226,7 +280,7 @@ NetNet* NetEBComp::synthesize(Design*des)
|
||||
}
|
||||
|
||||
|
||||
NetCompare*dev = new NetCompare(scope, 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)
|
||||
@@ -268,6 +322,45 @@ 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), lsig->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: "
|
||||
@@ -289,9 +382,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);
|
||||
|
||||
|
||||
@@ -301,12 +394,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;
|
||||
string oname = scope->local_hsymbol();
|
||||
|
||||
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));
|
||||
|
||||
@@ -326,7 +418,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);
|
||||
string oname = scope->local_hsymbol();
|
||||
|
||||
olog = new NetLogic(scope, oname, 3, NetLogic::AND);
|
||||
|
||||
@@ -351,6 +443,102 @@ NetNet* NetEBLogic::synthesize(Design*des)
|
||||
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;
|
||||
|
||||
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());
|
||||
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));
|
||||
|
||||
verinum dir_v = (op() == 'r')? verinum::V1 : verinum::V0;
|
||||
NetNet*dir_n = new NetNet(scope, scope->local_symbol(),
|
||||
NetNet::WIRE, 1);
|
||||
NetConst*dir = new NetConst(scope, scope->local_symbol(), dir_v);
|
||||
des->add_node(dir);
|
||||
connect(dev->pin_Direction(), dir->pin(0));
|
||||
connect(dev->pin_Direction(), dir_n->pin(0));
|
||||
|
||||
return osig;
|
||||
}
|
||||
|
||||
NetNet* NetEConcat::synthesize(Design*des)
|
||||
{
|
||||
/* First, synthesize the operands. */
|
||||
@@ -363,7 +551,7 @@ NetNet* NetEConcat::synthesize(Design*des)
|
||||
assert(scope);
|
||||
|
||||
/* Make a NetNet object to carry the output vector. */
|
||||
string path = scope->name() + "." + scope->local_symbol();
|
||||
string path = scope->local_symbol();
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width());
|
||||
osig->local_flag(true);
|
||||
|
||||
@@ -378,7 +566,7 @@ NetNet* NetEConcat::synthesize(Design*des)
|
||||
obit += 1;
|
||||
}
|
||||
|
||||
if (tmp[idx-1]->local_flag() && tmp[idx-1]->get_eref() == 0)
|
||||
if (tmp[idx-1]->local_flag() && tmp[idx-1]->get_refs() == 0)
|
||||
delete tmp[idx-1];
|
||||
}
|
||||
|
||||
@@ -391,12 +579,12 @@ NetNet* NetEConst::synthesize(Design*des)
|
||||
NetScope*scope = des->find_root_scope();
|
||||
assert(scope);
|
||||
|
||||
string path = scope->name() + "." + scope->local_symbol();
|
||||
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(scope, des->local_symbol(path), value());
|
||||
NetConst*con = new NetConst(scope, scope->local_symbol(), value());
|
||||
for (unsigned idx = 0 ; idx < width; idx += 1)
|
||||
connect(osig->pin(idx), con->pin(idx));
|
||||
|
||||
@@ -404,6 +592,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.
|
||||
@@ -414,14 +610,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);
|
||||
string oname = scope->local_hsymbol();
|
||||
NetLogic*gate;
|
||||
|
||||
switch (op()) {
|
||||
@@ -447,12 +642,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);
|
||||
string oname = scope->local_hsymbol();
|
||||
NetLogic*gate;
|
||||
|
||||
switch (op()) {
|
||||
@@ -467,6 +662,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;
|
||||
@@ -481,22 +696,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)
|
||||
{
|
||||
NetNet*csig = cond_->synthesize(des);
|
||||
NetNet*tsig = true_val_->synthesize(des);
|
||||
NetNet*fsig = false_val_->synthesize(des);
|
||||
|
||||
string path = csig->scope()->name()+"."+csig->scope()->local_symbol();
|
||||
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());
|
||||
|
||||
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));
|
||||
@@ -550,8 +815,8 @@ NetNet* NetESignal::synthesize(Design*des)
|
||||
NetScope*scope = net_->scope();
|
||||
assert(scope);
|
||||
|
||||
string name = scope->name() + "." + scope->local_symbol();
|
||||
NetNet*tmp = new NetNet(scope, name, NetNet::NetNet::WIRE, wid);
|
||||
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)
|
||||
@@ -562,116 +827,69 @@ NetNet* NetESignal::synthesize(Design*des)
|
||||
|
||||
/*
|
||||
* $Log: expr_synth.cc,v $
|
||||
* Revision 1.29 2001/11/29 01:58:18 steve
|
||||
* Handle part selects in l-values of DFF devices.
|
||||
* Revision 1.52 2003/11/10 19:39:20 steve
|
||||
* Remove redundant scope tokens.
|
||||
*
|
||||
* Revision 1.28 2001/10/28 01:14:53 steve
|
||||
* NetObj constructor finally requires a scope.
|
||||
* Revision 1.51 2003/10/27 06:04:21 steve
|
||||
* More flexible width handling for synthesized add.
|
||||
*
|
||||
* Revision 1.27 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
* Revision 1.50 2003/09/26 02:44:27 steve
|
||||
* Assure ternary arguments are wide enough.
|
||||
*
|
||||
* Revision 1.26 2001/08/31 22:59:48 steve
|
||||
* synthesize the special case of compare with 0.
|
||||
* Revision 1.49 2003/09/03 23:31:36 steve
|
||||
* Support synthesis of constant downshifts.
|
||||
*
|
||||
* Revision 1.25 2001/08/05 02:49:07 steve
|
||||
* Properly synthesize part selects.
|
||||
* Revision 1.48 2003/08/28 04:11:18 steve
|
||||
* Spelling patch.
|
||||
*
|
||||
* Revision 1.24 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.47 2003/08/09 03:23:40 steve
|
||||
* Add support for IVL_LPM_MULT device.
|
||||
*
|
||||
* Revision 1.23 2001/07/07 01:38:45 steve
|
||||
* Put synthesized signals in proper scope.
|
||||
* Revision 1.46 2003/07/26 03:34:42 steve
|
||||
* Start handling pad of expressions in code generators.
|
||||
*
|
||||
* Revision 1.22 2001/06/15 04:14:18 steve
|
||||
* Generate vvp code for GT and GE comparisons.
|
||||
* Revision 1.45 2003/06/24 01:38:02 steve
|
||||
* Various warnings fixed.
|
||||
*
|
||||
* Revision 1.21 2001/06/07 02:12:43 steve
|
||||
* Support structural addition.
|
||||
* Revision 1.44 2003/04/19 04:52:56 steve
|
||||
* Less picky about expression widths while synthesizing ternary.
|
||||
*
|
||||
* Revision 1.20 2001/02/15 06:59:36 steve
|
||||
* FreeBSD port has a maintainer now.
|
||||
* Revision 1.43 2003/04/08 05:07:15 steve
|
||||
* Detect constant shift distances in synthesis.
|
||||
*
|
||||
* Revision 1.19 2001/01/18 03:16:35 steve
|
||||
* NetMux needs a scope. (PR#115)
|
||||
* Revision 1.42 2003/04/08 04:33:55 steve
|
||||
* Synthesize shift expressions.
|
||||
*
|
||||
* Revision 1.18 2000/11/29 23:16:18 steve
|
||||
* Do not delete synthesized signals used in expressions.
|
||||
* Revision 1.41 2003/03/06 00:28:41 steve
|
||||
* All NetObj objects have lex_string base names.
|
||||
*
|
||||
* Revision 1.17 2000/11/29 05:24:00 steve
|
||||
* synthesis for unary reduction ! and N operators.
|
||||
* Revision 1.40 2003/02/26 01:29:24 steve
|
||||
* LPM objects store only their base names.
|
||||
*
|
||||
* Revision 1.16 2000/11/29 02:09:52 steve
|
||||
* Add support for || synthesis (PR#53)
|
||||
* Revision 1.39 2003/01/30 16:23:07 steve
|
||||
* Spelling fixes.
|
||||
*
|
||||
* Revision 1.15 2000/10/07 19:45:43 steve
|
||||
* Put logic devices into scopes.
|
||||
* Revision 1.38 2003/01/26 21:15:58 steve
|
||||
* Rework expression parsing and elaboration to
|
||||
* accommodate real/realtime values and expressions.
|
||||
*
|
||||
* Revision 1.14 2000/05/02 00:58:12 steve
|
||||
* Move signal tables to the NetScope class.
|
||||
* Revision 1.37 2002/11/17 23:37:55 steve
|
||||
* Magnitude compare to 0.
|
||||
*
|
||||
* Revision 1.13 2000/04/28 18:43:23 steve
|
||||
* integer division in expressions properly get width.
|
||||
* Revision 1.36 2002/08/12 01:34:59 steve
|
||||
* conditional ident string using autoconfig.
|
||||
*
|
||||
* Revision 1.12 2000/04/20 00:28:03 steve
|
||||
* Catch some simple identity compareoptimizations.
|
||||
* Revision 1.35 2002/07/07 22:31:39 steve
|
||||
* Smart synthesis of binary AND expressions.
|
||||
*
|
||||
* Revision 1.11 2000/04/16 23:32:18 steve
|
||||
* Synthesis of comparator in expressions.
|
||||
* Revision 1.34 2002/07/05 21:26:17 steve
|
||||
* Avoid emitting to vvp local net symbols.
|
||||
*
|
||||
* Connect the NetEvent and related classes
|
||||
* together better.
|
||||
*
|
||||
* Revision 1.10 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.9 2000/01/01 06:18:00 steve
|
||||
* Handle synthesis of concatenation.
|
||||
*
|
||||
* Revision 1.8 1999/12/17 06:18:15 steve
|
||||
* Rewrite the cprop functor to use the functor_t interface.
|
||||
*
|
||||
* Revision 1.7 1999/12/17 03:38:46 steve
|
||||
* NetConst can now hold wide constants.
|
||||
*
|
||||
* 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.5 1999/11/27 19:07:57 steve
|
||||
* Support the creation of scopes.
|
||||
*
|
||||
* Revision 1.4 1999/11/19 03:00:59 steve
|
||||
* Whoops, created a signal with a duplicate name.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Synthesize adders in XNF, based on a patch from
|
||||
* Larry. Accept synthesis of constants from Larry
|
||||
* as is.
|
||||
*
|
||||
* 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>.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Rewrite elaborate_net for the PETernary class to
|
||||
* also use the LPM_MUX device.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Modify the XNF target to handle LPM_FF objects.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
+43
-117
@@ -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,8 +16,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.cc,v 1.26 2001/10/19 21:53:24 steve Exp $"
|
||||
#ifdef HAVE_CVS_IDENT
|
||||
#ident "$Id: functor.cc,v 1.31 2002/08/16 05:18:27 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
@@ -128,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));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,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);
|
||||
}
|
||||
|
||||
@@ -288,6 +267,25 @@ int proc_match_t::event_wait(NetEvWait*)
|
||||
|
||||
/*
|
||||
* $Log: functor.cc,v $
|
||||
* 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)
|
||||
*
|
||||
@@ -306,77 +304,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
|
||||
|
||||
+213
-5
@@ -86,7 +86,7 @@ tool so it is not clear that the standard really is at fault. It is
|
||||
clear, however, that somebody goofed somewhere.
|
||||
|
||||
My personal opinion is that there is no logical need to require that
|
||||
all module_item_declarations preceed any other module items. I
|
||||
all module_item_declarations precede any other module items. I
|
||||
personally would oppose such a restriction. It may make sense to
|
||||
require that declarations of variables within a module be preceded by
|
||||
their use, although even that is not necessary for the implementation
|
||||
@@ -97,7 +97,7 @@ sample2 can have implications that affect any declaration order
|
||||
rules. When reaching into a module with a hierarchical name, the
|
||||
module being referenced is already completely declared (or not
|
||||
declared at all, as in sample2) so module_item order is completely
|
||||
irrelevent. But a "declare before use" rule would infect module
|
||||
irrelevant. But a "declare before use" rule would infect module
|
||||
ordering, by requiring that modules that are used be first defined.
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ ports.
|
||||
|
||||
With the above in mind, I have decided to *allow* function and task
|
||||
ports to be declared with types, as long as the types are variable
|
||||
types, such ag reg or integer. Without this, there would be no
|
||||
types, such as reg or integer. Without this, there would be no
|
||||
portable way to pass integers into functions/tasks. The standard does
|
||||
not say it is allowed, but it doesn't *disallow* it, and other
|
||||
commercial tools seem to work similarly.
|
||||
@@ -172,7 +172,7 @@ take it that x is allowed, as that is what Verilog-XL does.
|
||||
|
||||
There seems to be ambiguity in how code like this should be parsed:
|
||||
|
||||
repeat (5) @(posedge clk) <statment>;
|
||||
repeat (5) @(posedge clk) <statement>;
|
||||
|
||||
There are two valid interpretations of this code, from the
|
||||
IEEE1364-1995 standard. One looks like this:
|
||||
@@ -203,6 +203,34 @@ interpreted as a loop head, and this is what Icarus Verilog does, as
|
||||
well as all the other major Verilog tools, but the standard does not
|
||||
say this.
|
||||
|
||||
* UNSIZED NUMERIC CONSTANTS ARE NOT LIMITED TO 32 BITS
|
||||
|
||||
The Verilog standard allows Verilog implementations to limit the size
|
||||
of unsized constants to a bit width of at least 32. That means that a
|
||||
constant 17179869183 (36'h3_ffff_ffff) may overflow some compilers. In
|
||||
fact, it is common to limit these values to 32bits. However, a
|
||||
compiler may just as easily choose another width limit, for example
|
||||
64bits. That value is equally good.
|
||||
|
||||
However, it is not *required* that an implementation truncate at 32
|
||||
bits, and in fact Icarus Verilog does not truncate at all. It will
|
||||
make the unsized constant as big as it needs to be to hold the value
|
||||
accurately. This is especially useful in situations like this;
|
||||
|
||||
reg [width-1:0] foo = 17179869183;
|
||||
|
||||
The programmer wants the constant to take on the width of the reg,
|
||||
which in this example is parameterized. Since constant sizes cannot be
|
||||
parameterized, the programmer ideally gives an unsized constant, which
|
||||
the compiler then expands/contracts to match the l-value.
|
||||
|
||||
Also, by choosing to not ever truncate, Icarus Verilog can handle code
|
||||
written for a 64bit compiler as easily as for a 32bit compiler. In
|
||||
particular, any constants that the user does not expect to be
|
||||
arbitrarily truncated by his compiler will also not be truncated by
|
||||
Icarus Verilog, no matter what that other compiler chooses as a
|
||||
truncation point.
|
||||
|
||||
|
||||
* UNSIZED EXPRESSIONS AS PARAMETERS TO CONCATENATION {}
|
||||
|
||||
@@ -318,8 +346,188 @@ the right length, and will therefore flag instances u5 and u6 as
|
||||
errors. The IEEE1364 standard should be more specific one way or the
|
||||
other.
|
||||
|
||||
$Id: ieee1364-notes.txt,v 1.8 2001/08/01 05:17:31 steve Exp $
|
||||
* UNKNOWN VALUES IN L-VALUE BIT SELECTS
|
||||
|
||||
Consider this example:
|
||||
|
||||
reg [7:0] vec;
|
||||
wire [4:0] idx = <expr>;
|
||||
[...]
|
||||
vec[idx] = 1;
|
||||
|
||||
So long as the value of idx is a valid bit select address, the
|
||||
behavior of this assignment is obvious. However, there is no explicit
|
||||
word in the standard as to what happens if the value is out of
|
||||
range. The standard clearly states the value of an expression when the
|
||||
bit-select or part select is out of range (the value is x) but does
|
||||
not address the behavior when the expression is an l-value.
|
||||
|
||||
Icarus Verilog will take the position that bit select expressions in
|
||||
the l-value will select oblivion if it is out of range. That is, if
|
||||
idx has a value that is not a valid bit select of vec, then the
|
||||
assignment will have no effect.
|
||||
|
||||
|
||||
* SCHEDULING VALUES IN LOGIC
|
||||
|
||||
The interaction between blocking assignments in procedural code and
|
||||
logic gates in gate-level code and expressions is poorly defined in
|
||||
Verilog. Consider this example:
|
||||
|
||||
reg a;
|
||||
reg b;
|
||||
wire q = a & b;
|
||||
|
||||
initial begin
|
||||
a = 1;
|
||||
b = 0;
|
||||
#1 b = 1;
|
||||
if (q !== 0) begin
|
||||
$display("FAILED -- q changed too soon? %b", q);
|
||||
$finish;
|
||||
end
|
||||
end
|
||||
|
||||
This is a confusing situation. It is clear from the Verilog standard
|
||||
that an assignment to a variable using a blocking assign causes the
|
||||
l-value to receive the value before the assignment completes. This
|
||||
means that a subsequent read of the assigned variable *must* read back
|
||||
what was blocking-assigned.
|
||||
|
||||
However, in the example above, the "wire q = a & b" expresses some
|
||||
gate logic between a/b and q. The standard does not say whether a read
|
||||
out of logic should read the value computed from previous assigns to
|
||||
the input from the same thread. Specifically, when "a" and "b" are
|
||||
assigned by blocking assignments, will a read of "q" get the computed
|
||||
value or the existing value?
|
||||
|
||||
In fact, existing commercial tools do it both ways. Some tools print
|
||||
the FAILED message in the above example, and some do not. Icarus
|
||||
Verilog does not print the FAILED message in the above example,
|
||||
because the gate value change is *scheduled* when inputs are assigned,
|
||||
but not propagated until the thread gives up the processor.
|
||||
|
||||
Icarus Verilog chooses this behavior in order to filter out zero-width
|
||||
pulses as early as possible. The implication of this is that a read of
|
||||
the output of combinational logic will most likely *not* reflect the
|
||||
changes in inputs until the thread that changed the inputs yields
|
||||
execution.
|
||||
|
||||
|
||||
* BIT AND PART SELECTS OF PARAMETERS
|
||||
|
||||
Bit and part selects are supposed to only be supported on vector nets
|
||||
and variables (wires, regs, etc.) However, it is common for Verilog
|
||||
compilers to also support bit and part select on parameters. Icarus
|
||||
Verilog also chooses to support bit and part selects on parameter
|
||||
names, but we need to define what that means.
|
||||
|
||||
A bit or a part select on a parameter expression returns an unsigned
|
||||
value with a defined size. The parameter value is considered be a
|
||||
constant vector of bits foo[X:0]. That is, zero based. The bit and
|
||||
part selects operate from that assumption.
|
||||
|
||||
Verilog 2001 adds syntax to allow the user to explicitly declare the
|
||||
parameter range (i.e. parameter [5:0] foo = 9;) so Icarus Verilog will
|
||||
(or should) use the explicitly declared vector dimensions to interpret
|
||||
bit and part selects.
|
||||
|
||||
|
||||
* EDGES OF VECTORS
|
||||
|
||||
Consider this example:
|
||||
|
||||
reg [ 5:0] clock;
|
||||
always @(posedge clock) [do stuff]
|
||||
|
||||
The IEEE1364 standard clearly states that the @(posedge clock) looks
|
||||
only at the bit clock[0] (the least significant bit) to search for
|
||||
edges. It has been pointed out by some that Verilog XL instead
|
||||
implements it as "@(posedge |clock)": it looks for a rise in the
|
||||
reduction or of the vector. Cadence Design Systems technical support
|
||||
has been rumored to claim that the IEEE1364 specification is wrong,
|
||||
but NC-Verilog behaves according to the specification, and thus
|
||||
different from XL.
|
||||
|
||||
Icarus Verilog, therefore, takes the position that the specification
|
||||
is clear and correct, and it behaves as does NC-Verilog in this
|
||||
matter.
|
||||
|
||||
|
||||
* REAL VARIABLES IN $dumpoff DEAD-ZONES
|
||||
|
||||
The IEEE1364 standard clearly states that in VCD files, the $dumpoff
|
||||
section checkpoints all the dumped variables as X values. For reg and
|
||||
wire bits/vectors, this obviously means 'bx values. Icarus Verilog
|
||||
does this, for example:
|
||||
|
||||
$dumpoff
|
||||
x!
|
||||
x"
|
||||
$end
|
||||
|
||||
Real variables can also be included in VCD dumps, but it is not at
|
||||
all obvious what is supposed to be dumped into the $dumpoff-$end
|
||||
section of the VCD file. Verilog-XL dumps "r0 !" to set the real
|
||||
variables to the dead-zone value of 0.0, whereas other tools, such as
|
||||
ModelTech, ignore real variables in this section.
|
||||
|
||||
For example (from XL):
|
||||
|
||||
$dumpoff
|
||||
r0 !
|
||||
r0 "
|
||||
$end
|
||||
|
||||
Icarus Verilog dumps NaN values for real variables in the
|
||||
$dumpoff-$end section of the VCD file. The NaN value is the IEEE754
|
||||
equivalent of an unknown value, and so better reflects the unknown
|
||||
(during the dead zone) status of the variable, like this:
|
||||
|
||||
$dumpoff
|
||||
rNaN !
|
||||
rNaN "
|
||||
$end
|
||||
|
||||
It turns out that NaN is conventionally accepted by scanf functions,
|
||||
and viewers that support real variables support NaN values. So while
|
||||
the IEEE1364 doesn't require this behavior, and given the variety that
|
||||
already seems to exist amongst VCD viewers in the wild, this behavior
|
||||
seems to be acceptable according to the standard, is a better mirror
|
||||
of 4-value behavior in the dead zone, and appears more user friendly
|
||||
when viewed by reasonable viewers.
|
||||
|
||||
|
||||
$Id: ieee1364-notes.txt,v 1.17 2003/07/15 03:49:22 steve Exp $
|
||||
$Log: ieee1364-notes.txt,v $
|
||||
Revision 1.17 2003/07/15 03:49:22 steve
|
||||
Spelling fixes.
|
||||
|
||||
Revision 1.16 2003/04/14 03:40:21 steve
|
||||
Make some effort to preserve bits while
|
||||
operating on constant values.
|
||||
|
||||
Revision 1.15 2003/02/16 23:39:08 steve
|
||||
NaN in dead zones of VCD dumps.
|
||||
|
||||
Revision 1.14 2003/02/06 17:51:36 steve
|
||||
Edge of vectors notes.
|
||||
|
||||
Revision 1.13 2002/08/20 04:11:53 steve
|
||||
Support parameters with defined ranges.
|
||||
|
||||
Revision 1.12 2002/06/11 03:34:33 steve
|
||||
Spelling patch (Larry Doolittle)
|
||||
|
||||
Revision 1.11 2002/04/27 02:38:04 steve
|
||||
Support selecting bits from parameters.
|
||||
|
||||
Revision 1.10 2002/03/31 01:54:13 steve
|
||||
Notes about scheduling
|
||||
|
||||
Revision 1.9 2002/01/26 02:08:07 steve
|
||||
Handle x in l-value of set/x
|
||||
|
||||
Revision 1.8 2001/08/01 05:17:31 steve
|
||||
Accept empty port lists to module instantiation.
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user