mirror of
https://github.com/steveicarus/iverilog.git
synced 2026-08-22 22:06:47 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e42775ea7f | ||
|
|
a8c4729cf5 | ||
|
|
c200c0c20e | ||
|
|
4b174fd996 | ||
|
|
dbf5509f4f | ||
|
|
ec4f8c80d5 | ||
|
|
c8319bcc02 | ||
|
|
7bf480be9a | ||
|
|
2d3e85d941 | ||
|
|
ab6c8cb4b8 | ||
|
|
33c7c47f73 | ||
|
|
64d7b1cee5 | ||
|
|
0cebef872a | ||
|
|
65f835f3eb | ||
|
|
8309c1f673 | ||
|
|
e85347bf8b | ||
|
|
86a4512848 | ||
|
|
82831ea9a5 | ||
|
|
98c145c3b6 | ||
|
|
a50fe36ef8 | ||
|
|
7cbd710f7b | ||
|
|
39ef2b7605 | ||
|
|
da4901bb17 | ||
|
|
f28f5e01e5 | ||
|
|
e00aedd99b | ||
|
|
9d1a81ce2c | ||
|
|
cfed3933fa | ||
|
|
659624c71f | ||
|
|
6e0b77a8da | ||
|
|
54bb59ae99 | ||
|
|
cac941b272 | ||
|
|
0be48388c2 | ||
|
|
d8970752b6 | ||
|
|
08f0f5a1f7 | ||
|
|
f8162be8c3 | ||
|
|
f50074de50 | ||
|
|
9866fd01bd | ||
|
|
d1ad10c90f | ||
|
|
0045d7d1bf | ||
|
|
4a74ae1795 | ||
|
|
4d0b840c26 | ||
|
|
0c7335a77d | ||
|
|
7e8a538c20 | ||
|
|
aca5afa95c | ||
|
|
7793a49854 | ||
|
|
6bfbcbdcf7 | ||
|
|
bf72f39fe9 | ||
|
|
fa23dafdae | ||
|
|
9572ddd7e8 | ||
|
|
1ff36dc892 | ||
|
|
bf9a8f5021 | ||
|
|
0c4bea473c | ||
|
|
649428962e | ||
|
|
cc5ddc0b6b | ||
|
|
b624b6002e | ||
|
|
af35736e04 | ||
|
|
58b5b583a7 | ||
|
|
9e385e6947 | ||
|
|
560c003e03 | ||
|
|
1d045eea0d | ||
|
|
7a0e73ef3d | ||
|
|
5d20dd63ec | ||
|
|
ab9a853d52 | ||
|
|
82c0a2ebac | ||
|
|
75e78e86d3 | ||
|
|
a75326e2e0 | ||
|
|
b3e430c751 | ||
|
|
faa3a62259 | ||
|
|
438605fad5 | ||
|
|
9505b586bf | ||
|
|
40e7bc2450 | ||
|
|
a9aaca1ffa | ||
|
|
ce61d12f60 | ||
|
|
874bab10e4 | ||
|
|
21194c909a | ||
|
|
96a50d635d | ||
|
|
8c9e0bafa9 | ||
|
|
b3bb79992a | ||
|
|
4e92501864 | ||
|
|
d83fb10774 | ||
|
|
5a6cca33a0 | ||
|
|
b2f6953259 | ||
|
|
b1f1f74920 | ||
|
|
2adea8de48 | ||
|
|
859318becd | ||
|
|
55fb219503 | ||
|
|
b01316ce12 | ||
|
|
1921e19635 | ||
|
|
990df42407 | ||
|
|
924b4e0062 | ||
|
|
0e43dfb285 | ||
|
|
46621d3c83 | ||
|
|
fa95f7ff3b | ||
|
|
e45546e6f3 | ||
|
|
d79d48ffeb | ||
|
|
467ecf5b33 | ||
|
|
9f3e64e11a | ||
|
|
56954356db | ||
|
|
6466d02eda | ||
|
|
7a149a6943 | ||
|
|
acf3a4ec16 | ||
|
|
5c4b87675f | ||
|
|
83d3a60d5c | ||
|
|
3e4eb17b15 | ||
|
|
1075b28f26 | ||
|
|
943527c526 | ||
|
|
d350620315 | ||
|
|
6fc556cefc | ||
|
|
73283768a5 | ||
|
|
ce7d64f427 | ||
|
|
84b70be7ee | ||
|
|
3924c51097 | ||
|
|
4bb1bd4315 | ||
|
|
0164ad78be | ||
|
|
36e1eab3f4 | ||
|
|
177fa4062b | ||
|
|
821c68696d | ||
|
|
a3217db7b2 | ||
|
|
42dab181cd | ||
|
|
98d71de50f | ||
|
|
c596e1cda1 | ||
|
|
706f2ffc89 | ||
|
|
a7054a91e5 | ||
|
|
ad44b411fb | ||
|
|
f7fa2f1f4d | ||
|
|
2fcab15704 | ||
|
|
cfbad49d33 | ||
|
|
9dbcb32808 | ||
|
|
1b69bb5d2f | ||
|
|
2326672b3a | ||
|
|
393a76d57a | ||
|
|
4b3b41cd79 | ||
|
|
eab5793dda | ||
|
|
6cf2ddf541 | ||
|
|
ad6bbe539f | ||
|
|
f12864f69e | ||
|
|
b61c89c104 | ||
|
|
0def3c9983 | ||
|
|
9e5dc17c1d | ||
|
|
36d36d99f3 | ||
|
|
de985ac3fd | ||
|
|
245905aeda | ||
|
|
ac6caaf29e | ||
|
|
3734b5e7f1 | ||
|
|
789efb9832 | ||
|
|
c7bc35ad75 | ||
|
|
5071ce8575 | ||
|
|
64ff74df37 | ||
|
|
181066311b | ||
|
|
20ad433f8c | ||
|
|
494b5ff1ee | ||
|
|
cbd501b865 | ||
|
|
41384a0e41 | ||
|
|
3854e12024 | ||
|
|
ff55af1e9e | ||
|
|
bdf643ddb1 | ||
|
|
d46465845c | ||
|
|
dd75595082 | ||
|
|
a73cfbc2b5 | ||
|
|
21c844363a | ||
|
|
3109906514 | ||
|
|
606eb2b3cd | ||
|
|
e99059e001 | ||
|
|
cefbb635c1 | ||
|
|
b2b8b89cd8 | ||
|
|
92760f2c5f | ||
|
|
176be94be9 | ||
|
|
9fda809fa6 | ||
|
|
3c8d598eed | ||
|
|
f2068e83d4 | ||
|
|
5976e7078c | ||
|
|
da9a84ed84 | ||
|
|
03b635604a | ||
|
|
167f94bdbf | ||
|
|
4507351d48 | ||
|
|
0253f92e7e | ||
|
|
432d4efc9b | ||
|
|
749c3eb5a7 | ||
|
|
e933b56507 | ||
|
|
0c5ce9dfec | ||
|
|
acde444439 | ||
|
|
298a352cbd | ||
|
|
356552faad | ||
|
|
5e1e79b3c4 | ||
|
|
2996d2eb19 | ||
|
|
16023cbbd6 | ||
|
|
77927972e5 | ||
|
|
d762a320dc | ||
|
|
a9e54e7553 | ||
|
|
8b8a3d83e0 | ||
|
|
3fbbd4080a | ||
|
|
e79a371f76 | ||
|
|
c507379f09 | ||
|
|
47031767fa | ||
|
|
af5e68448c | ||
|
|
c1c88f87c6 | ||
|
|
a9b5c9c037 | ||
|
|
03b428b6cb | ||
|
|
271a835305 | ||
|
|
a3c3019a04 | ||
|
|
f063bf833f | ||
|
|
2002c03cef | ||
|
|
b8be5e80cd | ||
|
|
c29e11ed36 | ||
|
|
e35ed6e91c | ||
|
|
794ce68a6c | ||
|
|
31aa85ce7d | ||
|
|
15c2b0317d | ||
|
|
820d8b9edc | ||
|
|
a3a0f5f432 | ||
|
|
a98b5023a8 | ||
|
|
645c8913f1 | ||
|
|
066284d5c2 | ||
|
|
2802601c44 | ||
|
|
962a77c6b8 | ||
|
|
ca801574e3 | ||
|
|
606c1d38bb | ||
|
|
147ee59940 | ||
|
|
2e3fc89831 | ||
|
|
82bccd335d | ||
|
|
bfc05e2d71 | ||
|
|
c8135595be | ||
|
|
d5658d4180 | ||
|
|
8356e6a51f | ||
|
|
fbf55b9df4 | ||
|
|
176e6d09ca | ||
|
|
b72d1c297d | ||
|
|
f5b9c26735 | ||
|
|
d8141252e9 | ||
|
|
ed86dee65d | ||
|
|
f535cd3077 | ||
|
|
537757a7b9 | ||
|
|
4fb354776e | ||
|
|
1583b1e84a | ||
|
|
45ff04ecb6 | ||
|
|
ef08e43cf2 | ||
|
|
e17f7f5146 | ||
|
|
8654412844 | ||
|
|
140533db50 | ||
|
|
00cacae2a3 | ||
|
|
7e0b0d7328 | ||
|
|
1be77d68ce | ||
|
|
c5a5a11b7f | ||
|
|
becc7cb56a | ||
|
|
629a02cccf | ||
|
|
f28b97ebfd | ||
|
|
c5234e95cd | ||
|
|
b825f8d2b2 | ||
|
|
eb08253ed0 | ||
|
|
7b79fd98e5 | ||
|
|
6d5fcf5853 | ||
|
|
bc284ee6d8 | ||
|
|
260b4166c1 | ||
|
|
b59cc5ff6d | ||
|
|
5c89fb71ae | ||
|
|
3baa8c0445 | ||
|
|
ce589da58a | ||
|
|
0bb9359c05 | ||
|
|
54140dadcf | ||
|
|
60c22aefeb | ||
|
|
69a2331791 | ||
|
|
29cfd8ccfe | ||
|
|
bf67f386de | ||
|
|
a2f07011c1 | ||
|
|
0bd6cf7b6f | ||
|
|
cd8e491028 | ||
|
|
e773ccfe49 | ||
|
|
83de770387 | ||
|
|
b3a8098506 | ||
|
|
05407f488f | ||
|
|
85d53ebbf4 | ||
|
|
e4139f4819 | ||
|
|
45c935af45 | ||
|
|
cfbfd9ec1d | ||
|
|
ae209a144f | ||
|
|
64837efac5 | ||
|
|
8d73df2b04 | ||
|
|
59117c2e42 | ||
|
|
e23dd57c9d | ||
|
|
0e20be774e | ||
|
|
c3ae00ae49 | ||
|
|
a7328ecce1 | ||
|
|
15a952a143 | ||
|
|
3154f07817 | ||
|
|
4e700bffb8 | ||
|
|
7b2d4c9ef6 | ||
|
|
da828a218f | ||
|
|
13ef84bc35 | ||
|
|
c7b36322f6 | ||
|
|
8cc89a3a1f | ||
|
|
b8c5aff0cb | ||
|
|
fb0c387b12 | ||
|
|
1628045b55 | ||
|
|
608e5a4dbb | ||
|
|
30787fd49e | ||
|
|
1e231c3338 | ||
|
|
370549a19a | ||
|
|
39c39f0162 | ||
|
|
bcaa122fb9 | ||
|
|
96403de903 | ||
|
|
ab5cad18de | ||
|
|
b1c548a981 | ||
|
|
039769dbaf | ||
|
|
a76d6dc352 | ||
|
|
7eab75ded1 | ||
|
|
ef9c7c4a30 | ||
|
|
4c54e070ed | ||
|
|
80c609853a | ||
|
|
eeabc7234c | ||
|
|
79b740284a | ||
|
|
ab7b353ace | ||
|
|
3b82a15521 | ||
|
|
97d972ebb3 | ||
|
|
5f5081827d | ||
|
|
6b7b4e700a | ||
|
|
baac893d22 | ||
|
|
d680e594ed | ||
|
|
42adc49e57 | ||
|
|
4a2168b352 | ||
|
|
44d4660fe8 | ||
|
|
45d4117c02 | ||
|
|
ae837a6347 | ||
|
|
426fc18d10 | ||
|
|
2531ed89cd | ||
|
|
566d5c9a93 | ||
|
|
a033c331b6 | ||
|
|
066b534307 | ||
|
|
64cabd8074 | ||
|
|
a0db52c69f | ||
|
|
7bbedd1b55 | ||
|
|
0340256b4c | ||
|
|
c4bd8b1463 | ||
|
|
a2d465804f | ||
|
|
3c5d32637c | ||
|
|
c93cb71162 | ||
|
|
c3960f8e6a | ||
|
|
96d04bb5a0 | ||
|
|
1f1bfd0eab | ||
|
|
8cdf51f913 | ||
|
|
1f3eedcfd7 | ||
|
|
541f269c20 | ||
|
|
68a7ddefd3 | ||
|
|
3961c68928 | ||
|
|
832b795826 | ||
|
|
7a6be47603 | ||
|
|
81536481cc | ||
|
|
6e703c5744 | ||
|
|
82e8e51736 | ||
|
|
905529081d | ||
|
|
4159c98c58 | ||
|
|
e40efec4bd | ||
|
|
e418625457 | ||
|
|
4b82d26f5e | ||
|
|
63a02d1c0a | ||
|
|
bf42772995 | ||
|
|
b75221e9bf | ||
|
|
1e9a54d134 | ||
|
|
ff0b59ff6b | ||
|
|
b3a5a0e5ab | ||
|
|
e002b1c1c4 | ||
|
|
7009dc8d9b | ||
|
|
e28b7f06c5 | ||
|
|
b6e1d63cb0 | ||
|
|
5a279dbdc8 | ||
|
|
3ad3a2ab57 | ||
|
|
5361efe8ed | ||
|
|
2f2657b765 | ||
|
|
19a7f3faeb | ||
|
|
f480943649 | ||
|
|
f3019ff5a0 | ||
|
|
33ee5c26b0 | ||
|
|
1e9184f0f9 | ||
|
|
19251f7a79 | ||
|
|
b79da2c4d6 | ||
|
|
e68ba4c73a | ||
|
|
39ffe91230 | ||
|
|
150fc6f3ee | ||
|
|
a7411eb00d | ||
|
|
660fd7c1d4 | ||
|
|
53772db66d | ||
|
|
93dd08bdf5 | ||
|
|
176d707e0a | ||
|
|
34dade1b65 | ||
|
|
4e815f8565 | ||
|
|
e69a3ed934 | ||
|
|
77d63aba74 | ||
|
|
de8c725890 | ||
|
|
d4b2958e50 | ||
|
|
8669b372e0 | ||
|
|
61991e6367 | ||
|
|
bdcb813727 | ||
|
|
e6f1510a40 | ||
|
|
224af78463 | ||
|
|
983bf5cbab | ||
|
|
96bcf6eac4 | ||
|
|
0872ad34cf | ||
|
|
5aee3b866a | ||
|
|
3ce86f5664 | ||
|
|
23e5394fb4 | ||
|
|
be7ac7a2ca | ||
|
|
a616cfd0c2 | ||
|
|
e85b669307 | ||
|
|
bc6dfeb4a9 | ||
|
|
bf96986c38 | ||
|
|
26cfbb2b7b | ||
|
|
35fc2a609d | ||
|
|
f05b13c630 | ||
|
|
4d8954be4c | ||
|
|
1d0a9871c2 | ||
|
|
2292751fc3 | ||
|
|
a6524e47e2 | ||
|
|
02b9aa9163 | ||
|
|
754adce4a4 | ||
|
|
f3fdf70b56 | ||
|
|
38db6fde0c | ||
|
|
4f804577f9 | ||
|
|
44a182d92c | ||
|
|
91d65d0e4e | ||
|
|
a88f030b52 | ||
|
|
4537de8120 | ||
|
|
100bdedac3 | ||
|
|
914ad85e63 | ||
|
|
b3c2ad0a65 | ||
|
|
2e12635494 | ||
|
|
4325b787c0 | ||
|
|
4e3c702cc7 | ||
|
|
213cb1b08a | ||
|
|
b7569f4d70 | ||
|
|
e328cf9fed | ||
|
|
78af3dbdc0 | ||
|
|
372674b4c0 | ||
|
|
8d0f7e1594 | ||
|
|
558fea33fb | ||
|
|
de5930f7d8 | ||
|
|
e09a14aa44 | ||
|
|
d45c7c58df | ||
|
|
b5e0f46229 | ||
|
|
12229e4826 | ||
|
|
8f88525819 | ||
|
|
a225fe304d | ||
|
|
0f9eb13245 | ||
|
|
06437b7fba | ||
|
|
ba910c0fac | ||
|
|
28278d3c09 | ||
|
|
2bf7653ab9 | ||
|
|
cb39b3b65c | ||
|
|
3e3757bde7 | ||
|
|
8b4befd4fc | ||
|
|
972e9c866b | ||
|
|
f758010f01 | ||
|
|
8057faccc1 | ||
|
|
3f952a2fd2 | ||
|
|
eb71c70c99 | ||
|
|
2a44cf70b1 | ||
|
|
431b16639d | ||
|
|
014e68b62f | ||
|
|
31291f5d8a | ||
|
|
a52b34cb64 | ||
|
|
3ca55bf327 | ||
|
|
9bb2cee686 | ||
|
|
4f3bdd9f38 | ||
|
|
efe41c2435 | ||
|
|
f855cb19b8 | ||
|
|
861ed55879 | ||
|
|
35e0dcdd3d | ||
|
|
a72a8607e6 | ||
|
|
904747acf5 | ||
|
|
4d40a336c0 | ||
|
|
32e9c8049a | ||
|
|
bb24624979 | ||
|
|
506bc87e82 | ||
|
|
986885bd70 | ||
|
|
73c4893ef7 | ||
|
|
62c9f39297 | ||
|
|
8b5f62a5e5 | ||
|
|
aec5841c7f | ||
|
|
c997c090a1 | ||
|
|
0ab60cd3c3 | ||
|
|
ae23a8f6bf | ||
|
|
46e868d313 | ||
|
|
8dfa322b8b | ||
|
|
2f2f08b02f | ||
|
|
102fd24dd2 | ||
|
|
66cf3ec8fa | ||
|
|
57b0d9691e | ||
|
|
7c6f496765 | ||
|
|
67e72ce77e | ||
|
|
c97692d715 | ||
|
|
66f83f3b08 | ||
|
|
3765bdd3ac | ||
|
|
39bcdfb7b4 | ||
|
|
57cd770650 | ||
|
|
3194b0c53a | ||
|
|
9e8005f7b7 | ||
|
|
41ce198a1f | ||
|
|
05e30ed43b | ||
|
|
09cd582cc5 | ||
|
|
235781ce08 | ||
|
|
70aeb980d8 | ||
|
|
d0d6189874 | ||
|
|
8205d0fcc9 | ||
|
|
60d068a33e | ||
|
|
e1a4b457c2 | ||
|
|
86e18226eb | ||
|
|
7fa2975c24 | ||
|
|
d39190243b | ||
|
|
0550287658 | ||
|
|
82947a9343 | ||
|
|
b7fb806611 | ||
|
|
6a236061de | ||
|
|
898639d7bf | ||
|
|
6322400b83 | ||
|
|
9b7341889d | ||
|
|
0653f859bc | ||
|
|
48ff66cbce | ||
|
|
1b2a6f8bed | ||
|
|
c6cf665c4a | ||
|
|
19c84ff9a2 | ||
|
|
15398a8f58 | ||
|
|
9d2e22576e | ||
|
|
3ffb3c7011 | ||
|
|
cac4c8d5ce | ||
|
|
f40d006c26 | ||
|
|
e6c36597eb | ||
|
|
141808b787 | ||
|
|
003f103408 | ||
|
|
ce66498c88 | ||
|
|
bf30a0bc07 | ||
|
|
f8e6d782e1 | ||
|
|
7a8135c703 | ||
|
|
311e1ce9ee | ||
|
|
9bce21ddb7 | ||
|
|
c4e438d4ba | ||
|
|
a2da2d59df | ||
|
|
56a4236576 | ||
|
|
2443c655f2 | ||
|
|
ae1d5227de | ||
|
|
5769bbe15e | ||
|
|
6dbf7333c8 | ||
|
|
4352ce6753 | ||
|
|
29a50a52ca | ||
|
|
d25690cc8e | ||
|
|
e29ecdc234 | ||
|
|
0f6eea7024 | ||
|
|
97dd559fca | ||
|
|
a4c722b195 | ||
|
|
b3a3b888d8 | ||
|
|
2f1d258acb | ||
|
|
7aa9bc9892 | ||
|
|
4a058632b2 | ||
|
|
6a72b4c10e | ||
|
|
00d44222dd | ||
|
|
b36b6d0ca0 | ||
|
|
386958f9a0 | ||
|
|
f6eb581aff | ||
|
|
966f7a4bff | ||
|
|
2cb76cabef | ||
|
|
609d5fe727 | ||
|
|
522d0ec864 | ||
|
|
ad8565f8a6 | ||
|
|
b0c003dc34 | ||
|
|
a4e528f0c3 | ||
|
|
c8d9ade58c | ||
|
|
61e3eed49c | ||
|
|
afb8e285db | ||
|
|
79ce94b585 | ||
|
|
f7f5ccce05 | ||
|
|
25d25ff7fe | ||
|
|
31b0037299 | ||
|
|
16f514739f | ||
|
|
604ce0db09 | ||
|
|
a71dbd3987 | ||
|
|
417186b06f | ||
|
|
ac91dc38b8 | ||
|
|
6d0be3de3a | ||
|
|
2d4f33a0dd | ||
|
|
c6088c8820 | ||
|
|
5134636932 | ||
|
|
5d051ffbde | ||
|
|
97985bba64 | ||
|
|
9ec5fa972e | ||
|
|
9e04ef4abd | ||
|
|
68dc83b322 | ||
|
|
97e9b62080 | ||
|
|
4072021ba4 | ||
|
|
c901945871 | ||
|
|
95281e5d82 | ||
|
|
2858c2f09b | ||
|
|
034cdae445 | ||
|
|
e71ea8c9de | ||
|
|
b2a136e07e | ||
|
|
c2dc3fe5c3 | ||
|
|
548ff4f89a | ||
|
|
b3c24adb11 | ||
|
|
e81d0d9f23 | ||
|
|
715d140d85 | ||
|
|
fa46de1021 | ||
|
|
aa31884d3b | ||
|
|
aacce5ef1b | ||
|
|
565088160e | ||
|
|
b24011b84b | ||
|
|
2b8d9abd3e | ||
|
|
e24facfaf6 | ||
|
|
27e717839a | ||
|
|
52c7108782 | ||
|
|
90ed3dd124 | ||
|
|
8118203766 | ||
|
|
e8518c5056 | ||
|
|
f02d4574f9 | ||
|
|
f1ff1149f7 | ||
|
|
034a38ea36 | ||
|
|
f8c3b84f68 | ||
|
|
d8ef63efd1 | ||
|
|
a240be73e7 | ||
|
|
1563643c92 | ||
|
|
5b89249f10 | ||
|
|
bf70673380 | ||
|
|
6779f01f3a | ||
|
|
66f7ef97da | ||
|
|
e03859b834 | ||
|
|
f2c1902984 | ||
|
|
32f3881344 | ||
|
|
264e629c74 | ||
|
|
8969ab03d7 | ||
|
|
952ebe8516 | ||
|
|
f355cf334c | ||
|
|
01c5321208 | ||
|
|
970ba895c9 | ||
|
|
cbc3be0304 | ||
|
|
cb65ee5e00 | ||
|
|
debe707097 | ||
|
|
79b60da54c | ||
|
|
84c7795d16 | ||
|
|
410a93b52c | ||
|
|
78355b6038 | ||
|
|
59b69c6dd1 | ||
|
|
d3bff8a451 | ||
|
|
43ddd97426 | ||
|
|
4399042b8d | ||
|
|
2b0aaec8ab | ||
|
|
7d7ccd4f08 | ||
|
|
93463b6ff5 | ||
|
|
4b0c56c3a8 | ||
|
|
1bae567728 | ||
|
|
7d7beeecc1 | ||
|
|
f5d0211864 | ||
|
|
1f4232187c | ||
|
|
f45ba008d8 | ||
|
|
ac629b313c | ||
|
|
563065053e | ||
|
|
2b903f5d0e | ||
|
|
7ef3b44ab1 | ||
|
|
8376553349 | ||
|
|
3885f17d0f | ||
|
|
4b0e5bd173 | ||
|
|
d78c7392c2 | ||
|
|
cf3f1b38c3 | ||
|
|
2fbc0af1ea | ||
|
|
94a1d59817 | ||
|
|
57d1bfaf29 |
@@ -10,6 +10,10 @@ ivl.exp
|
||||
dep
|
||||
configure
|
||||
Makefile
|
||||
check
|
||||
check.cc
|
||||
config.status
|
||||
config.log
|
||||
config.cache
|
||||
config.h
|
||||
dosify
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: Attrib.cc,v 1.1 2000/12/04 17:37:03 steve Exp $"
|
||||
#ident "$Id: Attrib.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "Attrib.h"
|
||||
# include <assert.h>
|
||||
|
||||
@@ -118,6 +120,10 @@ string Attrib::value(unsigned idx) const
|
||||
|
||||
/*
|
||||
* $Log: Attrib.cc,v $
|
||||
* Revision 1.2 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.1 2000/12/04 17:37:03 steve
|
||||
* Add Attrib class for holding NetObj attributes.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: HName.cc,v 1.1 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "HName.h"
|
||||
# include <iostream>
|
||||
# include <string.h>
|
||||
# include <malloc.h>
|
||||
|
||||
hname_t::hname_t()
|
||||
{
|
||||
item_ = 0;
|
||||
count_ = 0;
|
||||
}
|
||||
|
||||
hname_t::hname_t(const char*text)
|
||||
{
|
||||
item_ = strdup(text);
|
||||
count_ = 1;
|
||||
}
|
||||
|
||||
hname_t::hname_t(const hname_t&that)
|
||||
{
|
||||
count_ = that.count_;
|
||||
switch (count_) {
|
||||
case 0:
|
||||
item_ = 0;
|
||||
break;
|
||||
case 1:
|
||||
item_ = strdup(that.item_);
|
||||
break;
|
||||
default:
|
||||
array_ = new char*[count_];
|
||||
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
|
||||
array_[idx] = strdup(that.array_[idx]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
hname_t::~hname_t()
|
||||
{
|
||||
switch (count_) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
free(item_);
|
||||
break;
|
||||
default:
|
||||
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
|
||||
free(array_[idx]);
|
||||
delete[]array_;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void hname_t::append(const char*text)
|
||||
{
|
||||
char**tmp;
|
||||
|
||||
switch (count_) {
|
||||
case 0:
|
||||
count_ = 1;
|
||||
item_ = strdup(text);
|
||||
break;
|
||||
case 1:
|
||||
count_ = 2;
|
||||
tmp = new char*[2];
|
||||
tmp[0] = item_;
|
||||
tmp[1] = strdup(text);
|
||||
array_ = tmp;
|
||||
break;
|
||||
default:
|
||||
tmp = new char*[count_+1];
|
||||
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
|
||||
tmp[idx] = array_[idx];
|
||||
delete[]array_;
|
||||
array_ = tmp;
|
||||
array_[count_] = strdup(text);
|
||||
count_ += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void hname_t::prepend(const char*text)
|
||||
{
|
||||
char**tmp;
|
||||
|
||||
switch (count_) {
|
||||
case 0:
|
||||
count_ = 1;
|
||||
item_ = strdup(text);
|
||||
break;
|
||||
case 1:
|
||||
count_ = 2;
|
||||
tmp = new char*[2];
|
||||
tmp[0] = strdup(text);
|
||||
tmp[1] = item_;
|
||||
array_ = tmp;
|
||||
break;
|
||||
default:
|
||||
tmp = new char*[count_+1];
|
||||
tmp[0] = strdup(text);
|
||||
for (unsigned idx = 0 ; idx < count_ ; idx += 1)
|
||||
tmp[idx+1] = array_[idx];
|
||||
delete[]array_;
|
||||
array_ = tmp;
|
||||
count_ += 1;
|
||||
}
|
||||
}
|
||||
|
||||
char* hname_t::remove_tail_name()
|
||||
{
|
||||
if (count_ == 0)
|
||||
return 0;
|
||||
|
||||
if (count_ == 1) {
|
||||
char*tmp = item_;
|
||||
count_ = 0;
|
||||
item_ = 0;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
if (count_ == 2) {
|
||||
char*tmp1 = array_[0];
|
||||
char*tmp2 = array_[1];
|
||||
delete[]array_;
|
||||
count_ = 1;
|
||||
item_ = tmp1;
|
||||
return tmp2;
|
||||
}
|
||||
|
||||
char*tmpo = array_[count_-1];
|
||||
char**tmpa = new char*[count_-1];
|
||||
for (unsigned idx = 0 ; idx < count_-1 ; idx += 1)
|
||||
tmpa[idx] = array_[idx];
|
||||
|
||||
delete[]array_;
|
||||
array_ = tmpa;
|
||||
count_ -= 1;
|
||||
return tmpo;
|
||||
}
|
||||
|
||||
const char* hname_t::peek_name(unsigned idx) const
|
||||
{
|
||||
if (idx >= count_)
|
||||
return 0;
|
||||
|
||||
if (count_ == 1)
|
||||
return item_;
|
||||
|
||||
return array_[idx];
|
||||
}
|
||||
|
||||
const char* hname_t::peek_tail_name() const
|
||||
{
|
||||
switch (count_) {
|
||||
case 0:
|
||||
return 0;
|
||||
case 1:
|
||||
return item_;
|
||||
default:
|
||||
return array_[count_-1];
|
||||
}
|
||||
}
|
||||
|
||||
bool operator < (const hname_t&l, const hname_t&r)
|
||||
{
|
||||
unsigned idx = 0;
|
||||
const char*lc = l.peek_name(idx);
|
||||
const char*rc = r.peek_name(idx);
|
||||
|
||||
while (lc && rc) {
|
||||
int cmp = strcmp(lc, rc);
|
||||
if (cmp < 0)
|
||||
return true;
|
||||
if (cmp > 0)
|
||||
return false;
|
||||
idx += 1;
|
||||
lc = l.peek_name(idx);
|
||||
rc = r.peek_name(idx);
|
||||
}
|
||||
|
||||
if (lc && !rc)
|
||||
return false;
|
||||
if (rc && !lc)
|
||||
return true;
|
||||
|
||||
// Must be ==
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator == (const hname_t&l, const hname_t&r)
|
||||
{
|
||||
unsigned idx = 0;
|
||||
const char*lc = l.peek_name(idx);
|
||||
const char*rc = r.peek_name(idx);
|
||||
|
||||
while (lc && rc) {
|
||||
int cmp = strcmp(lc, rc);
|
||||
if (cmp != 0)
|
||||
return false;
|
||||
idx += 1;
|
||||
lc = l.peek_name(idx);
|
||||
rc = r.peek_name(idx);
|
||||
}
|
||||
|
||||
if (lc || rc)
|
||||
return false;
|
||||
|
||||
// Must be ==
|
||||
return true;
|
||||
}
|
||||
|
||||
ostream& operator<< (ostream&out, const hname_t&that)
|
||||
{
|
||||
switch (that.count_) {
|
||||
case 0:
|
||||
out << "";
|
||||
return out;
|
||||
case 1:
|
||||
out << that.item_;
|
||||
return out;
|
||||
|
||||
default:
|
||||
out << that.array_[0];
|
||||
for (unsigned idx = 1 ; idx < that.count_ ; idx += 1)
|
||||
out << "." << that.array_[idx];
|
||||
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: HName.cc,v $
|
||||
* Revision 1.1 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
#ifndef __HName_H
|
||||
#define __HName_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: HName.h,v 1.1 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IOSFWD
|
||||
# include <iosfwd>
|
||||
#else
|
||||
class ostream;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This class represents a Verilog hierarchical name. A hierarchical
|
||||
* name is an ordered list of simple names.
|
||||
*/
|
||||
|
||||
class hname_t {
|
||||
|
||||
public:
|
||||
hname_t ();
|
||||
explicit hname_t (const char*text);
|
||||
hname_t (const hname_t&that);
|
||||
~hname_t();
|
||||
|
||||
// This method adds a name to the end of the hierarchical
|
||||
// path. This becomes a new base name.
|
||||
void append(const char*text);
|
||||
|
||||
// This method adds a name to the *front* of the hierarchical
|
||||
// path. The base name remains the same, unless this is the
|
||||
// only component.
|
||||
void prepend(const char*text);
|
||||
|
||||
// This method removes the tail name from the hierarchy, and
|
||||
// returns a pointer to that tail name. That tail name now
|
||||
// must be removed by the caller.
|
||||
char* remove_tail_name();
|
||||
|
||||
// Return the given component in the hierarchical name. If the
|
||||
// idx is too large, return 0.
|
||||
const char*peek_name(unsigned idx) const;
|
||||
const char*peek_tail_name() const;
|
||||
|
||||
friend ostream& operator<< (ostream&, const hname_t&);
|
||||
|
||||
private:
|
||||
union {
|
||||
char**array_;
|
||||
char* item_;
|
||||
};
|
||||
unsigned count_;
|
||||
|
||||
private: // not implemented
|
||||
hname_t& operator= (const hname_t&);
|
||||
};
|
||||
|
||||
extern bool operator < (const hname_t&, const hname_t&);
|
||||
extern bool operator == (const hname_t&, const hname_t&);
|
||||
|
||||
/*
|
||||
* $Log: HName.h,v $
|
||||
* Revision 1.1 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+7
-1
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: LineInfo.cc,v 1.1 2000/11/30 17:31:42 steve Exp $"
|
||||
#ident "$Id: LineInfo.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "LineInfo.h"
|
||||
# include <cstdio>
|
||||
|
||||
@@ -42,6 +44,10 @@ void LineInfo::set_line(const LineInfo&that)
|
||||
|
||||
/*
|
||||
* $Log: LineInfo.cc,v $
|
||||
* Revision 1.2 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.1 2000/11/30 17:31:42 steve
|
||||
* Change LineInfo to store const C strings.
|
||||
*
|
||||
|
||||
+80
-18
@@ -16,17 +16,19 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.90 2001/01/14 23:04:55 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.109 2001/12/06 02:55:24 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
VERSION = 0.3
|
||||
VERSION = 0.5
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
srcdir = @srcdir@
|
||||
|
||||
SUBDIRS = @subdirs@
|
||||
|
||||
VPATH = $(srcdir)
|
||||
|
||||
bindir = @bindir@
|
||||
@@ -35,6 +37,7 @@ includedir = $(prefix)/include
|
||||
|
||||
dllib=@DLLIB@
|
||||
rdynamic=@rdynamic@
|
||||
strip_dynamic=@strip_dynamic@
|
||||
|
||||
CC = @CC@
|
||||
CXX = @CXX@
|
||||
@@ -46,6 +49,7 @@ STRIP = @STRIP@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)
|
||||
PICFLAGS = @PICFLAG@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
# The TARGETS variable lists the target modules that can be build and
|
||||
@@ -57,7 +61,8 @@ TARGETS += tgt-pal
|
||||
endif
|
||||
|
||||
|
||||
all: ivl@EXEEXT@
|
||||
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
|
||||
@@ -66,24 +71,36 @@ all: ivl@EXEEXT@
|
||||
cd tgt-stub ; $(MAKE) all
|
||||
for tgt in $(TARGETS); do (cd $$tgt ; $(MAKE) all); done
|
||||
|
||||
# In the windows world, the installer will need a dosify program to
|
||||
# dosify text files.
|
||||
ifeq (@WIN32@,yes)
|
||||
all: dosify.exe
|
||||
dosify.exe: dosify.c
|
||||
$(CC) -o dosify.exe dosify.c
|
||||
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 -Ivvm -Ivpi -Lvvm check.cc -lvvm -lvpip $(dllib)
|
||||
$(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'
|
||||
|
||||
clean:
|
||||
rm -f *.o parse.cc parse.cc.output parse.h dep/*.d lexor.cc lexor_keyword.cc ivl@EXEEXT@ libivl.a
|
||||
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
|
||||
|
||||
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
|
||||
@@ -98,29 +115,44 @@ O = main.o cprop.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 \
|
||||
eval_tree.o expr_synth.o functor.o lexor.o lexor_keyword.o link_const.o \
|
||||
mangle.o netlist.o net_assign.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 \
|
||||
parse.o parse_misc.o pform.o pform_dump.o \
|
||||
set_width.o \
|
||||
verinum.o verireal.o target.o targets.o util.o \
|
||||
Attrib.o LineInfo.o Module.o PDelays.o PEvent.o \
|
||||
verinum.o verireal.o target.o targets.o \
|
||||
Attrib.o HName.o LineInfo.o Module.o PDelays.o PEvent.o \
|
||||
PExpr.o PGate.o \
|
||||
PTask.o PFunction.o PWire.o Statement.o \
|
||||
$(FF) $(TT)
|
||||
|
||||
Makefile: Makefile.in config.status
|
||||
Makefile: Makefile.in config.h.in config.status
|
||||
./config.status
|
||||
|
||||
|
||||
ifeq (@CYGWIN@,yes)
|
||||
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
|
||||
# export and import library, and the last link makes a, ivl.exe
|
||||
# that really exports the things that the import library imports.
|
||||
ivl@EXEEXT@: $O ivl.def
|
||||
$(CXX) -o ivl@EXEEXT@ $O $(dllib) @EXTRALIBS@
|
||||
dlltool --dllname ivl@EXEEXT@ --def ivl.def \
|
||||
--output-lib libivl.a --output-exp ivl.exp
|
||||
# $(CXX) -o ivl@EXEEXT@ -Wl,--base-file,ivl.base ivl.exp $O $(dllib)
|
||||
# dlltool --dllname ivl@EXEEXT@ --base-file ivl.base \
|
||||
# --output-exp ivl.exp --def ivl.def
|
||||
$(CXX) -o ivl@EXEEXT@ ivl.exp $O $(dllib)
|
||||
$(CXX) -o ivl@EXEEXT@ ivl.exp $O $(dllib) @EXTRALIBS@
|
||||
else
|
||||
ivl@EXEEXT@: $O
|
||||
$(CXX) $(CXXFLAGS) $(rdynamic) $(LDFLAGS) -o ivl@EXEEXT@ $O $(dllib)
|
||||
@@ -138,8 +170,8 @@ lexor.o: lexor.cc parse.h
|
||||
parse.o: parse.cc
|
||||
|
||||
parse.h parse.cc: $(srcdir)/parse.y
|
||||
bison --verbose -t -p VL -d $(srcdir)/parse.y -o parse.cc
|
||||
mv parse.cc.h parse.h
|
||||
bison --verbose -t -p VL -d -o parse.cc $(srcdir)/parse.y
|
||||
mv parse.cc.h parse.h || mv parse.hh parse.h
|
||||
|
||||
syn-rules.cc: $(srcdir)/syn-rules.y
|
||||
bison --verbose -p syn_ -o syn-rules.cc $(srcdir)/syn-rules.y
|
||||
@@ -152,17 +184,24 @@ lexor_keyword.o: lexor_keyword.cc
|
||||
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)
|
||||
|
||||
ifeq (@WIN32@,yes)
|
||||
WIN32_INSTALL = $(prefix)/hello.vl $(prefix)/sqrt.vl $(prefix)/QUICK_START.txt
|
||||
endif
|
||||
|
||||
install: all installdirs $(libdir)/ivl/ivl@EXEEXT@ $(libdir)/ivl/iverilog.conf $(includedir)/ivl_target.h
|
||||
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
|
||||
|
||||
$(libdir)/libvpi.a : ./libvpi.a
|
||||
$(INSTALL_DATA) libvpi.a $(libdir)/libvpi.a
|
||||
|
||||
$(libdir)/ivl/ivl@EXEEXT@: ./ivl@EXEEXT@
|
||||
$(INSTALL_PROGRAM) ./ivl@EXEEXT@ $(libdir)/ivl/ivl@EXEEXT@
|
||||
$(STRIP) $(libdir)/ivl/ivl@EXEEXT@
|
||||
$(STRIP) $(strip_dynamic) $(libdir)/ivl/ivl@EXEEXT@
|
||||
|
||||
$(libdir)/ivl/iverilog.conf: $(srcdir)/iverilog.conf
|
||||
$(INSTALL_DATA) $(srcdir)/iverilog.conf $(libdir)/ivl/iverilog.conf
|
||||
@@ -170,19 +209,42 @@ $(libdir)/ivl/iverilog.conf: $(srcdir)/iverilog.conf
|
||||
$(includedir)/ivl_target.h: $(srcdir)/ivl_target.h
|
||||
$(INSTALL_DATA) $(srcdir)/ivl_target.h $(includedir)/ivl_target.h
|
||||
|
||||
$(includedir)/vpi_user.h: $(srcdir)/vpi_user.h
|
||||
$(INSTALL_DATA) $(srcdir)/vpi_user.h $(includedir)/vpi_user.h
|
||||
|
||||
# In windows installations, put a few examples and the quick_start
|
||||
# into the destination directory.
|
||||
ifeq (@WIN32@,yes)
|
||||
$(prefix)/hello.vl: $(srcdir)/examples/hello.vl
|
||||
./dosify.exe $(srcdir)/examples/hello.vl tmp.vl
|
||||
mv tmp.vl $(prefix)/hello.vl
|
||||
|
||||
$(prefix)/sqrt.vl: $(srcdir)/examples/sqrt.vl
|
||||
./dosify.exe $(srcdir)/examples/sqrt.vl tmp.vl
|
||||
mv tmp.vl $(prefix)/sqrt.vl
|
||||
|
||||
$(prefix)/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
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
-include $(patsubst %.o, dep/%.d, $O)
|
||||
-include $(patsubst %.o, dep/%.d, vpithunk.o)
|
||||
|
||||
@@ -17,22 +17,29 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Module.cc,v 1.14 2000/11/15 20:31:05 steve Exp $"
|
||||
#ident "$Id: Module.cc,v 1.17 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "Module.h"
|
||||
# include "PGate.h"
|
||||
# include "PWire.h"
|
||||
# include <assert.h>
|
||||
|
||||
Module::Module(const string&name, const svector<Module::port_t*>*pp)
|
||||
: name_(name)
|
||||
Module::Module(const char*name, const svector<Module::port_t*>*pp)
|
||||
: name_(strdup(name))
|
||||
{
|
||||
if (pp)
|
||||
ports_ = *pp;
|
||||
|
||||
}
|
||||
|
||||
Module::~Module()
|
||||
{
|
||||
free(name_);
|
||||
}
|
||||
|
||||
void Module::add_gate(PGate*gate)
|
||||
{
|
||||
gates_.push_back(gate);
|
||||
@@ -50,7 +57,7 @@ void Module::add_function(const string &name, PFunction *func)
|
||||
|
||||
PWire* Module::add_wire(PWire*wire)
|
||||
{
|
||||
PWire*&ep = wires_[wire->name()];
|
||||
PWire*&ep = wires_[wire->path()];
|
||||
if (ep) return ep;
|
||||
|
||||
assert(ep == 0);
|
||||
@@ -95,9 +102,9 @@ unsigned Module::find_port(const string&name) const
|
||||
}
|
||||
|
||||
|
||||
PWire* Module::get_wire(const string&name) const
|
||||
PWire* Module::get_wire(const hname_t&name) const
|
||||
{
|
||||
map<string,PWire*>::const_iterator obj = wires_.find(name);
|
||||
map<hname_t,PWire*>::const_iterator obj = wires_.find(name);
|
||||
if (obj == wires_.end())
|
||||
return 0;
|
||||
else
|
||||
@@ -117,7 +124,7 @@ PGate* Module::get_gate(const string&name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const map<string,PWire*>& Module::get_wires() const
|
||||
const map<hname_t,PWire*>& Module::get_wires() const
|
||||
{
|
||||
return wires_;
|
||||
}
|
||||
@@ -135,6 +142,17 @@ const list<PProcess*>& Module::get_behaviors() const
|
||||
|
||||
/*
|
||||
* $Log: Module.cc,v $
|
||||
* Revision 1.17 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.16 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
*
|
||||
* Revision 1.15 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.14 2000/11/15 20:31:05 steve
|
||||
* Fix warning about temporaries.
|
||||
*
|
||||
|
||||
@@ -19,13 +19,15 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Module.h,v 1.21 2000/11/05 06:05:59 steve Exp $"
|
||||
#ident "$Id: Module.h,v 1.24 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include "svector.h"
|
||||
# include "HName.h"
|
||||
# include "named.h"
|
||||
# include "LineInfo.h"
|
||||
# include <string>
|
||||
class PEvent;
|
||||
class PExpr;
|
||||
@@ -44,7 +46,7 @@ class NetScope;
|
||||
* therefore the handle for grasping the described circuit.
|
||||
*/
|
||||
|
||||
class Module {
|
||||
class Module : public LineInfo {
|
||||
|
||||
/* The module ports are in general a vector of port_t
|
||||
objects. Each port has a name and an ordered list of
|
||||
@@ -58,7 +60,8 @@ class Module {
|
||||
};
|
||||
|
||||
public:
|
||||
explicit Module(const string&name, const svector<port_t*>*);
|
||||
explicit Module(const char*name, const svector<port_t*>*);
|
||||
~Module();
|
||||
|
||||
|
||||
/* The module has parameters that are evaluated when the
|
||||
@@ -71,7 +74,7 @@ class Module {
|
||||
new parameters within the module, but may be used to set
|
||||
values within this module (when instantiated) or in other
|
||||
instantiated modules. */
|
||||
map<string,PExpr*>defparms;
|
||||
map<hname_t,PExpr*>defparms;
|
||||
|
||||
/* Parameters may be overridden at instantiation time;
|
||||
the overrides do not contain explicit parameter names,
|
||||
@@ -88,7 +91,7 @@ class Module {
|
||||
set by the `timescale directive. */
|
||||
int time_unit, time_precision;
|
||||
|
||||
const string&get_name() const { return name_; }
|
||||
const char*mod_name() const { return name_; }
|
||||
|
||||
void add_gate(PGate*gate);
|
||||
|
||||
@@ -107,10 +110,10 @@ class Module {
|
||||
|
||||
// Find a wire by name. This is used for connecting gates to
|
||||
// existing wires, etc.
|
||||
PWire* get_wire(const string&name) const;
|
||||
PWire* get_wire(const hname_t&name) const;
|
||||
PGate* get_gate(const string&name);
|
||||
|
||||
const map<string,PWire*>& get_wires() const;
|
||||
const map<hname_t,PWire*>& get_wires() const;
|
||||
const list<PGate*>& get_gates() const;
|
||||
const list<PProcess*>& get_behaviors() const;
|
||||
|
||||
@@ -122,13 +125,13 @@ class Module {
|
||||
bool elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
const string name_;
|
||||
char* name_;
|
||||
|
||||
/* This is an array of port descriptors, which is in turn a
|
||||
named array of PEident pointers. */
|
||||
svector<port_t*> ports_;
|
||||
|
||||
map<string,PWire*> wires_;
|
||||
map<hname_t,PWire*> wires_;
|
||||
list<PGate*> gates_;
|
||||
list<PProcess*> behaviors_;
|
||||
map<string,PTask*> tasks_;
|
||||
@@ -142,6 +145,16 @@ class Module {
|
||||
|
||||
/*
|
||||
* $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.23 2001/10/31 03:11:15 steve
|
||||
* detect module ports not declared within the module.
|
||||
*
|
||||
* Revision 1.22 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
*
|
||||
* Revision 1.21 2000/11/05 06:05:59 steve
|
||||
* Handle connectsion to internally unconnected modules (PR#38)
|
||||
*
|
||||
|
||||
+17
-4
@@ -17,9 +17,13 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PDelays.cc,v 1.4 2001/01/20 02:15:50 steve Exp $"
|
||||
#ident "$Id: PDelays.cc,v 1.7 2001/11/22 06:20:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "PDelays.h"
|
||||
# include "PExpr.h"
|
||||
# include "verinum.h"
|
||||
@@ -65,7 +69,7 @@ static unsigned long calculate_val(Design*des, const NetScope*scope,
|
||||
delete dr;
|
||||
|
||||
} else {
|
||||
verinum*dv = expr->eval_const(des, scope->name());
|
||||
verinum*dv = expr->eval_const(des, scope);
|
||||
if (dv == 0) {
|
||||
cerr << expr->get_line() << ": sorry: non-constant "
|
||||
<< "delays not supported here: " << *expr << endl;
|
||||
@@ -82,12 +86,11 @@ static unsigned long calculate_val(Design*des, const NetScope*scope,
|
||||
return val;
|
||||
}
|
||||
|
||||
void PDelays::eval_delays(Design*des, const string&path,
|
||||
void PDelays::eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
|
||||
int shift = scope->time_unit() - des->get_precision();
|
||||
@@ -122,6 +125,16 @@ void PDelays::eval_delays(Design*des, const string&path,
|
||||
|
||||
/*
|
||||
* $Log: PDelays.cc,v $
|
||||
* Revision 1.7 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.6 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.5 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.4 2001/01/20 02:15:50 steve
|
||||
* apologize for not supporting non-constant delays.
|
||||
*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PDelays.h,v 1.3 2001/01/16 02:44:17 steve Exp $"
|
||||
#ident "$Id: PDelays.h,v 1.4 2001/11/22 06:20:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
@@ -32,6 +32,7 @@ class ostream;
|
||||
#endif
|
||||
|
||||
class Design;
|
||||
class NetScope;
|
||||
class PExpr;
|
||||
|
||||
/*
|
||||
@@ -47,7 +48,7 @@ class PDelays {
|
||||
void set_delay(PExpr*);
|
||||
void set_delays(const svector<PExpr*>*del);
|
||||
|
||||
void eval_delays(Design*des, const string&path,
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const;
|
||||
@@ -66,6 +67,9 @@ ostream& operator << (ostream&o, const PDelays&);
|
||||
|
||||
/*
|
||||
* $Log: PDelays.h,v $
|
||||
* Revision 1.4 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.3 2001/01/16 02:44:17 steve
|
||||
* Use the iosfwd header if available.
|
||||
*
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PEvent.cc,v 1.1 2000/04/01 19:31:57 steve Exp $"
|
||||
#ident "$Id: PEvent.cc,v 1.2 2001/07/25 03:10:48 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PEvent.h"
|
||||
|
||||
PEvent::PEvent(const string&n)
|
||||
@@ -38,6 +40,10 @@ string PEvent::name() const
|
||||
|
||||
/*
|
||||
* $Log: PEvent.cc,v $
|
||||
* Revision 1.2 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.1 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PEvent.h,v 1.4 2001/01/16 02:44:18 steve Exp $"
|
||||
#ident "$Id: PEvent.h,v 1.5 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
@@ -30,7 +30,8 @@ class NetScope;
|
||||
|
||||
/*
|
||||
* The PEvent class represents event objects. These are things that
|
||||
* are declared in Verilog as ``event foo;''
|
||||
* are declared in Verilog as ``event foo;'' The name passed to the
|
||||
* constructure is the "foo" part of the declaration.
|
||||
*/
|
||||
class PEvent : public LineInfo {
|
||||
|
||||
@@ -52,6 +53,10 @@ class PEvent : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: PEvent.h,v $
|
||||
* Revision 1.5 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.4 2001/01/16 02:44:18 steve
|
||||
* Use the iosfwd header if available.
|
||||
*
|
||||
|
||||
@@ -17,9 +17,13 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PExpr.cc,v 1.23 2001/01/14 23:04:55 steve Exp $"
|
||||
#ident "$Id: PExpr.cc,v 1.28 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "Module.h"
|
||||
# include <typeinfo>
|
||||
@@ -42,7 +46,7 @@ bool PExpr::is_constant(Module*) const
|
||||
return false;
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_net(Design*des, const string&path, unsigned,
|
||||
NetNet* PExpr::elaborate_net(Design*des, NetScope*scope, unsigned,
|
||||
unsigned long,
|
||||
unsigned long,
|
||||
unsigned long,
|
||||
@@ -54,25 +58,34 @@ NetNet* PExpr::elaborate_net(Design*des, const string&path, unsigned,
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetNet* PExpr::elaborate_lnet(Design*des, const string&path) const
|
||||
NetNet* PExpr::elaborate_lnet(Design*des, NetScope*) const
|
||||
{
|
||||
cerr << get_line() << ": error: expression not valid in assign l-value: "
|
||||
<< *this << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PEBinary::PEBinary(char op, PExpr*l, PExpr*r)
|
||||
: op_(op), left_(l), right_(r)
|
||||
{
|
||||
}
|
||||
|
||||
PEBinary::~PEBinary()
|
||||
{
|
||||
}
|
||||
|
||||
bool PEBinary::is_constant(Module*mod) const
|
||||
{
|
||||
return left_->is_constant(mod) && right_->is_constant(mod);
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(const char*n, const svector<PExpr *> &parms)
|
||||
: name_(n), parms_(parms)
|
||||
PECallFunction::PECallFunction(const hname_t&n, const svector<PExpr *> &parms)
|
||||
: path_(n), parms_(parms)
|
||||
{
|
||||
}
|
||||
|
||||
PECallFunction::PECallFunction(const char*n)
|
||||
: name_(n)
|
||||
PECallFunction::PECallFunction(const hname_t&n)
|
||||
: path_(n)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -138,8 +151,8 @@ bool PEFNumber::is_constant(Module*) const
|
||||
return true;
|
||||
}
|
||||
|
||||
PEIdent::PEIdent(const string&s)
|
||||
: text_(s), msb_(0), lsb_(0), idx_(0)
|
||||
PEIdent::PEIdent(const hname_t&s)
|
||||
: path_(s), msb_(0), lsb_(0), idx_(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -147,9 +160,9 @@ PEIdent::~PEIdent()
|
||||
{
|
||||
}
|
||||
|
||||
string PEIdent::name() const
|
||||
const hname_t& PEIdent::path() const
|
||||
{
|
||||
return text_;
|
||||
return path_;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -158,14 +171,17 @@ string PEIdent::name() const
|
||||
*/
|
||||
bool PEIdent::is_constant(Module*mod) const
|
||||
{
|
||||
map<string,PExpr*>::const_iterator cur;
|
||||
if (mod == 0) return false;
|
||||
|
||||
cur = mod->parameters.find(text_);
|
||||
if (cur != mod->parameters.end()) return true;
|
||||
{ map<string,PExpr*>::const_iterator cur;
|
||||
cur = mod->parameters.find(path_.peek_name(0));
|
||||
if (cur != mod->parameters.end()) return true;
|
||||
}
|
||||
|
||||
cur = mod->localparams.find(text_);
|
||||
if (cur != mod->localparams.end()) return true;
|
||||
{ map<string,PExpr*>::const_iterator cur;
|
||||
cur = mod->localparams.find(path_.peek_name(0));
|
||||
if (cur != mod->localparams.end()) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -251,6 +267,23 @@ bool PEUnary::is_constant(Module*m) const
|
||||
|
||||
/*
|
||||
* $Log: PExpr.cc,v $
|
||||
* Revision 1.28 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.27 2001/11/08 05:15:50 steve
|
||||
* Remove string paths from PExpr elaboration.
|
||||
*
|
||||
* Revision 1.26 2001/11/07 04:26:46 steve
|
||||
* elaborate_lnet uses scope instead of string path.
|
||||
*
|
||||
* Revision 1.25 2001/11/06 06:11:55 steve
|
||||
* Support more real arithmetic in delay constants.
|
||||
*
|
||||
* Revision 1.24 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.23 2001/01/14 23:04:55 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PExpr.h,v 1.48 2001/01/14 23:04:55 steve Exp $"
|
||||
#ident "$Id: PExpr.h,v 1.53 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
@@ -62,7 +62,7 @@ class PExpr : public LineInfo {
|
||||
|
||||
// This method elaborate the expression as gates, for use in a
|
||||
// continuous assign or other wholly structural context.
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
@@ -77,7 +77,7 @@ class PExpr : public LineInfo {
|
||||
|
||||
// This method elaborates the expression as gates, but
|
||||
// restricted for use as l-values of continuous assignments.
|
||||
virtual NetNet* elaborate_lnet(Design*des, const string&path) const;
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
|
||||
|
||||
// Expressions that can be in the l-value of procedural
|
||||
// assignments can be elaborated with this method.
|
||||
@@ -86,7 +86,7 @@ class PExpr : public LineInfo {
|
||||
// This attempts to evaluate a constant expression, and return
|
||||
// a verinum as a result. If the expression cannot be
|
||||
// evaluated, return 0.
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
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
|
||||
@@ -123,8 +123,8 @@ class PEConcat : public PExpr {
|
||||
// continuous assignments.
|
||||
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
|
||||
|
||||
virtual NetNet* elaborate_lnet(Design*des, const string&path) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
@@ -182,7 +182,7 @@ class PEFNumber : public PExpr {
|
||||
/* The eval_const method as applied to a floating point number
|
||||
gets the *integer* value of the number. This accounts for
|
||||
any rounding that is needed to get the value. */
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
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;
|
||||
@@ -202,7 +202,7 @@ class PEFNumber : public PExpr {
|
||||
class PEIdent : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEIdent(const string&s);
|
||||
explicit PEIdent(const hname_t&s);
|
||||
~PEIdent();
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
@@ -211,13 +211,13 @@ class PEIdent : public PExpr {
|
||||
virtual NetNet* elaborate_anet(Design*des, NetScope*scope) const;
|
||||
|
||||
// Identifiers are allowed (with restrictions) is assign l-values.
|
||||
virtual NetNet* elaborate_lnet(Design*des, const string&path) const;
|
||||
virtual NetNet* elaborate_lnet(Design*des, NetScope*scope) const;
|
||||
|
||||
// Identifiers are also allowed as procedural assignment l-values.
|
||||
virtual NetAssign_* elaborate_lval(Design*des, NetScope*scope) const;
|
||||
|
||||
// Structural r-values are OK.
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
@@ -233,12 +233,13 @@ class PEIdent : public PExpr {
|
||||
NetNet* elaborate_port(Design*des, NetScope*sc) const;
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
verinum* eval_const(const Design*des, const string&path) const;
|
||||
verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
verireal*eval_rconst(const Design*des, const NetScope*sc) const;
|
||||
|
||||
string name() const;
|
||||
const hname_t& path() const;
|
||||
|
||||
private:
|
||||
string text_;
|
||||
hname_t path_;
|
||||
|
||||
public:
|
||||
// Use these to support bit- and part-select operators.
|
||||
@@ -249,7 +250,7 @@ class PEIdent : public PExpr {
|
||||
// expression.
|
||||
PExpr*idx_;
|
||||
|
||||
NetNet* elaborate_net_ram_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_ram_(Design*des, NetScope*scope,
|
||||
NetMemory*mem, unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
@@ -265,7 +266,7 @@ class PENumber : public PExpr {
|
||||
const verinum& value() const;
|
||||
|
||||
virtual void dump(ostream&) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
@@ -274,7 +275,8 @@ class PENumber : public PExpr {
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetEConst*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
virtual verireal*eval_rconst(const Design*, const NetScope*) const;
|
||||
|
||||
virtual bool is_the_same(const PExpr*that) const;
|
||||
virtual bool is_constant(Module*) const;
|
||||
@@ -307,7 +309,7 @@ class PEUnary : public PExpr {
|
||||
~PEUnary();
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
@@ -316,7 +318,7 @@ class PEUnary : public PExpr {
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetEUnary*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
@@ -328,13 +330,13 @@ class PEUnary : public PExpr {
|
||||
class PEBinary : public PExpr {
|
||||
|
||||
public:
|
||||
explicit PEBinary(char op, PExpr*l, PExpr*r)
|
||||
: op_(op), left_(l), right_(r) { }
|
||||
explicit PEBinary(char op, PExpr*l, PExpr*r);
|
||||
~PEBinary();
|
||||
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
@@ -343,7 +345,8 @@ class PEBinary : public PExpr {
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetEBinary*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetExpr*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
virtual verireal*eval_rconst(const Design*des, const NetScope*sc) const;
|
||||
|
||||
private:
|
||||
char op_;
|
||||
@@ -352,42 +355,42 @@ class PEBinary : public PExpr {
|
||||
|
||||
NetEBinary*elaborate_expr_base_(Design*, NetExpr*lp, NetExpr*rp) const;
|
||||
|
||||
NetNet* elaborate_net_add_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_add_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_bit_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_bit_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_cmp_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_cmp_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_div_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_div_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_mod_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_mod_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_log_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_log_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_mul_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_mul_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
unsigned long decay) const;
|
||||
NetNet* elaborate_net_shift_(Design*des, const string&path,
|
||||
NetNet* elaborate_net_shift_(Design*des, NetScope*scope,
|
||||
unsigned lwidth,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
@@ -407,7 +410,7 @@ class PETernary : public PExpr {
|
||||
virtual bool is_constant(Module*) const;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual NetNet* elaborate_net(Design*des, const string&path,
|
||||
virtual NetNet* elaborate_net(Design*des, NetScope*scope,
|
||||
unsigned width,
|
||||
unsigned long rise,
|
||||
unsigned long fall,
|
||||
@@ -416,7 +419,7 @@ class PETernary : public PExpr {
|
||||
Link::strength_t drive1) const;
|
||||
virtual NetETernary*elaborate_expr(Design*des, NetScope*) const;
|
||||
virtual NetETernary*elaborate_pexpr(Design*des, NetScope*sc) const;
|
||||
virtual verinum* eval_const(const Design*des, const string&path) const;
|
||||
virtual verinum* eval_const(const Design*des, const NetScope*sc) const;
|
||||
|
||||
private:
|
||||
PExpr*expr_;
|
||||
@@ -430,15 +433,15 @@ class PETernary : public PExpr {
|
||||
*/
|
||||
class PECallFunction : public PExpr {
|
||||
public:
|
||||
explicit PECallFunction(const char*n, const svector<PExpr *> &parms);
|
||||
explicit PECallFunction(const char*n);
|
||||
explicit PECallFunction(const hname_t&n, const svector<PExpr *> &parms);
|
||||
explicit PECallFunction(const hname_t&n);
|
||||
~PECallFunction();
|
||||
|
||||
virtual void dump(ostream &) const;
|
||||
virtual NetExpr*elaborate_expr(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
hname_t path_;
|
||||
svector<PExpr *> parms_;
|
||||
|
||||
NetExpr* elaborate_sfunc_(Design*des, NetScope*scope) const;
|
||||
@@ -446,6 +449,22 @@ class PECallFunction : public PExpr {
|
||||
|
||||
/*
|
||||
* $Log: PExpr.h,v $
|
||||
* Revision 1.53 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.52 2001/11/08 05:15:50 steve
|
||||
* Remove string paths from PExpr elaboration.
|
||||
*
|
||||
* Revision 1.51 2001/11/07 04:26:46 steve
|
||||
* elaborate_lnet uses scope instead of string path.
|
||||
*
|
||||
* Revision 1.50 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* 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.
|
||||
@@ -463,182 +482,5 @@ class PECallFunction : public PExpr {
|
||||
*
|
||||
* Revision 1.44 2000/09/17 21:26:15 steve
|
||||
* Add support for modulus (Eric Aardoom)
|
||||
*
|
||||
* Revision 1.43 2000/09/09 15:21:26 steve
|
||||
* move lval elaboration to PExpr virtual methods.
|
||||
*
|
||||
* Revision 1.42 2000/09/07 22:38:13 steve
|
||||
* Support unary + and - in constants.
|
||||
*
|
||||
* Revision 1.41 2000/06/30 15:50:20 steve
|
||||
* Allow unary operators in constant expressions.
|
||||
*
|
||||
* Revision 1.40 2000/06/13 05:22:16 steve
|
||||
* Support concatenation in parameter expressions.
|
||||
*
|
||||
* Revision 1.39 2000/06/01 02:31:39 steve
|
||||
* Parameters can be strings.
|
||||
*
|
||||
* Revision 1.38 2000/05/16 04:05:15 steve
|
||||
* Module ports are really special PEIdent
|
||||
* expressions, because a name can be used
|
||||
* many places in the port list.
|
||||
*
|
||||
* Revision 1.37 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.36 2000/05/04 03:37:58 steve
|
||||
* Add infrastructure for system functions, move
|
||||
* $time to that structure and add $random.
|
||||
*
|
||||
* Revision 1.35 2000/04/12 04:23:57 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
*
|
||||
* Handle named events within the mix of net events
|
||||
* and edges. As a unified lot they get caught together.
|
||||
* wait statements are broken into more complex statements
|
||||
* that include a conditional.
|
||||
*
|
||||
* Do not generate NetPEvent or NetNEvent objects in
|
||||
* elaboration. NetEvent, NetEvWait and NetEvProbe
|
||||
* take over those functions in the netlist.
|
||||
*
|
||||
* Revision 1.34 2000/04/01 21:40:22 steve
|
||||
* Add support for integer division.
|
||||
*
|
||||
* Revision 1.33 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
* Revision 1.32 2000/03/12 18:22:11 steve
|
||||
* Binary and unary operators in parameter expressions.
|
||||
*
|
||||
* Revision 1.31 2000/03/12 04:35:22 steve
|
||||
* Allow parameter identifiers in parameter expressions.
|
||||
*
|
||||
* Revision 1.30 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.29 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.28 2000/02/16 03:58:27 steve
|
||||
* Fix up width matching in structural bitwise operators.
|
||||
*
|
||||
* Revision 1.27 2000/01/13 03:35:35 steve
|
||||
* Multiplication all the way to simulation.
|
||||
*
|
||||
* Revision 1.26 1999/12/16 03:46:39 steve
|
||||
* Structural logical or.
|
||||
*
|
||||
* Revision 1.25 1999/11/21 00:13:08 steve
|
||||
* Support memories in continuous assignments.
|
||||
*
|
||||
* Revision 1.24 1999/11/14 20:24:28 steve
|
||||
* Add support for the LPM_CLSHIFT device.
|
||||
*
|
||||
* Revision 1.23 1999/11/05 21:45:19 steve
|
||||
* Fix NetConst being set to zero width, and clean
|
||||
* up elaborate_set_cmp_ for NetEBinary.
|
||||
*
|
||||
* Revision 1.22 1999/10/31 20:08:24 steve
|
||||
* Include subtraction in LPM_ADD_SUB device.
|
||||
*
|
||||
* Revision 1.21 1999/10/31 04:11:27 steve
|
||||
* Add to netlist links pin name and instance number,
|
||||
* and arrange in vvm for pin connections by name
|
||||
* and instance number.
|
||||
*
|
||||
* Revision 1.20 1999/09/25 02:57:29 steve
|
||||
* Parse system function calls.
|
||||
*
|
||||
* Revision 1.19 1999/09/15 04:17:52 steve
|
||||
* separate assign lval elaboration for error checking.
|
||||
*
|
||||
* Revision 1.18 1999/08/31 22:38:29 steve
|
||||
* Elaborate and emit to vvm procedural functions.
|
||||
*
|
||||
* Revision 1.17 1999/08/01 21:18:55 steve
|
||||
* elaborate rise/fall/decay for continuous assign.
|
||||
*
|
||||
* Revision 1.16 1999/07/31 19:14:47 steve
|
||||
* Add functions up to elaboration (Ed Carter)
|
||||
*
|
||||
* Revision 1.15 1999/07/22 02:05:20 steve
|
||||
* is_constant method for PEConcat.
|
||||
*
|
||||
* Revision 1.14 1999/07/17 19:50:59 steve
|
||||
* netlist support for ternary operator.
|
||||
*
|
||||
* Revision 1.13 1999/06/16 03:13:29 steve
|
||||
* More syntax parse with sorry stubs.
|
||||
*
|
||||
* Revision 1.12 1999/06/15 02:50:02 steve
|
||||
* Add lexical support for real numbers.
|
||||
*
|
||||
* Revision 1.11 1999/06/10 04:03:52 steve
|
||||
* Add support for the Ternary operator,
|
||||
* Add support for repeat concatenation,
|
||||
* Correct some seg faults cause by elaboration
|
||||
* errors,
|
||||
* Parse the casex anc casez statements.
|
||||
*
|
||||
* Revision 1.10 1999/06/09 03:00:05 steve
|
||||
* Add support for procedural concatenation expression.
|
||||
*
|
||||
* Revision 1.9 1999/05/16 05:08:42 steve
|
||||
* Redo constant expression detection to happen
|
||||
* after parsing.
|
||||
*
|
||||
* Parse more operators and expressions.
|
||||
*
|
||||
* Revision 1.8 1999/05/10 00:16:57 steve
|
||||
* Parse and elaborate the concatenate operator
|
||||
* in structural contexts, Replace vector<PExpr*>
|
||||
* and list<PExpr*> with svector<PExpr*>, evaluate
|
||||
* constant expressions with parameters, handle
|
||||
* memories as lvalues.
|
||||
*
|
||||
* Parse task declarations, integer types.
|
||||
*
|
||||
* Revision 1.7 1999/05/01 02:57:52 steve
|
||||
* Handle much more complex event expressions.
|
||||
*
|
||||
* Revision 1.6 1999/04/29 02:16:26 steve
|
||||
* Parse OR of event expressions.
|
||||
*
|
||||
* Revision 1.5 1999/04/19 01:59:36 steve
|
||||
* Add memories to the parse and elaboration phases.
|
||||
*
|
||||
* Revision 1.4 1998/11/11 00:01:51 steve
|
||||
* Check net ranges in declarations.
|
||||
*
|
||||
* Revision 1.3 1998/11/09 18:55:33 steve
|
||||
* Add procedural while loops,
|
||||
* Parse procedural for loops,
|
||||
* Add procedural wait statements,
|
||||
* Add constant nodes,
|
||||
* Add XNOR logic gate,
|
||||
* Make vvm output look a bit prettier.
|
||||
*
|
||||
* Revision 1.2 1998/11/07 17:05:05 steve
|
||||
* Handle procedural conditional, and some
|
||||
* of the conditional expressions.
|
||||
*
|
||||
* Elaborate signals and identifiers differently,
|
||||
* allowing the netlist to hold signal information.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:28:54 steve
|
||||
* Introduce verilog to CVS.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
+7
-1
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PFunction.cc,v 1.4 2001/01/13 22:20:08 steve Exp $"
|
||||
#ident "$Id: PFunction.cc,v 1.5 2001/07/25 03:10:48 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
#include "PTask.h"
|
||||
|
||||
PFunction::PFunction()
|
||||
@@ -52,6 +54,10 @@ void PFunction::set_output(PWire*o)
|
||||
|
||||
/*
|
||||
* $Log: PFunction.cc,v $
|
||||
* Revision 1.5 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.4 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PGate.cc,v 1.9 2000/05/06 15:41:56 steve Exp $"
|
||||
#ident "$Id: PGate.cc,v 1.13 2001/11/22 06:20:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PGate.h"
|
||||
# include "PExpr.h"
|
||||
# include "verinum.h"
|
||||
@@ -88,12 +90,12 @@ void PGate::elaborate_scope(Design*, NetScope*) const
|
||||
* parameters. This method understands how to handle the different
|
||||
* numbers of expressions.
|
||||
*/
|
||||
void PGate::eval_delays(Design*des, const string&path,
|
||||
void PGate::eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const
|
||||
{
|
||||
delay_.eval_delays(des, path, rise_time, fall_time, decay_time);
|
||||
delay_.eval_delays(des, scope, rise_time, fall_time, decay_time);
|
||||
}
|
||||
|
||||
PGAssign::PGAssign(svector<PExpr*>*pins)
|
||||
@@ -140,17 +142,24 @@ void PGBuiltin::set_range(PExpr*msb, PExpr*lsb)
|
||||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
PGModule::PGModule(const string&type, const string&name, svector<PExpr*>*pins)
|
||||
: PGate(name, pins), type_(type), overrides_(0), pins_(0),
|
||||
PGModule::PGModule(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);
|
||||
}
|
||||
|
||||
PGModule::PGModule(const string&type, const string&name,
|
||||
PGModule::PGModule(const char*type, const string&name,
|
||||
named<PExpr*>*pins, unsigned npins)
|
||||
: PGate(name, 0), type_(type), overrides_(0), pins_(pins),
|
||||
: PGate(name, 0), overrides_(0), pins_(pins),
|
||||
npins_(npins), parms_(0), nparms_(0), msb_(0), lsb_(0)
|
||||
{
|
||||
type_ = strdup(type);
|
||||
}
|
||||
|
||||
PGModule::~PGModule()
|
||||
{
|
||||
free(type_);
|
||||
}
|
||||
|
||||
void PGModule::set_parameters(svector<PExpr*>*o)
|
||||
@@ -176,8 +185,26 @@ void PGModule::set_range(PExpr*msb, PExpr*lsb)
|
||||
lsb_ = lsb;
|
||||
}
|
||||
|
||||
const char* PGModule::get_type()
|
||||
{
|
||||
return type_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: PGate.cc,v $
|
||||
* Revision 1.13 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.12 2001/10/21 00:42:47 steve
|
||||
* Module types in pform are char* instead of string.
|
||||
*
|
||||
* Revision 1.11 2001/10/19 01:55:32 steve
|
||||
* Method to get the type_ member
|
||||
*
|
||||
* Revision 1.10 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.9 2000/05/06 15:41:56 steve
|
||||
* Carry assignment strength to pform.
|
||||
*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PGate.h,v 1.18 2000/05/06 15:41:56 steve Exp $"
|
||||
#ident "$Id: PGate.h,v 1.22 2001/11/22 06:20:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "svector.h"
|
||||
@@ -65,7 +65,7 @@ class PGate : public LineInfo {
|
||||
|
||||
const string& get_name() const { return name_; }
|
||||
|
||||
void eval_delays(Design*des, const string&path,
|
||||
void eval_delays(Design*des, NetScope*scope,
|
||||
unsigned long&rise_time,
|
||||
unsigned long&fall_time,
|
||||
unsigned long&decay_time) const;
|
||||
@@ -82,7 +82,7 @@ class PGate : public LineInfo {
|
||||
map<string,string> attributes;
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*des, const string&path) const;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
@@ -116,7 +116,7 @@ class PGAssign : public PGate {
|
||||
~PGAssign();
|
||||
|
||||
void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*des, const string&path) const;
|
||||
virtual void elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
};
|
||||
@@ -153,7 +153,7 @@ class PGBuiltin : public PGate {
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*, const string&path) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
Type type_;
|
||||
@@ -173,15 +173,17 @@ class PGModule : public PGate {
|
||||
public:
|
||||
// If the binding of ports is by position, this constructor
|
||||
// builds everything all at once.
|
||||
explicit PGModule(const string&type, const string&name,
|
||||
explicit PGModule(const char*type, const string&name,
|
||||
svector<PExpr*>*pins);
|
||||
|
||||
// If the binding of ports is by name, this constructor takes
|
||||
// the bindings and stores them for later elaboration.
|
||||
explicit PGModule(const string&type, const string&name,
|
||||
explicit PGModule(const char*type, const string&name,
|
||||
named<PExpr*>*pins, unsigned npins);
|
||||
|
||||
|
||||
~PGModule();
|
||||
|
||||
// Parameter overrides can come as an ordered list, or a set
|
||||
// of named expressions.
|
||||
void set_parameters(svector<PExpr*>*o);
|
||||
@@ -192,12 +194,14 @@ class PGModule : public PGate {
|
||||
void set_range(PExpr*msb, PExpr*lsb);
|
||||
|
||||
virtual void dump(ostream&out) const;
|
||||
virtual void elaborate(Design*, const string&path) const;
|
||||
virtual void elaborate(Design*, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*sc) const;
|
||||
virtual bool elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
const char* get_type();
|
||||
|
||||
private:
|
||||
string type_;
|
||||
char* type_;
|
||||
svector<PExpr*>*overrides_;
|
||||
named<PExpr*>*pins_;
|
||||
unsigned npins_;
|
||||
@@ -210,15 +214,26 @@ class PGModule : public PGate {
|
||||
PExpr*msb_;
|
||||
PExpr*lsb_;
|
||||
|
||||
void elaborate_mod_(Design*, Module*mod, const string&path) const;
|
||||
void elaborate_sudp_(Design*, PUdp *udp, const string&path) const;
|
||||
void elaborate_cudp_(Design*, PUdp *udp, const string&path) const;
|
||||
void elaborate_mod_(Design*, Module*mod, NetScope*scope) const;
|
||||
void elaborate_udp_(Design*, PUdp *udp, NetScope*scope) const;
|
||||
void elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const;
|
||||
bool elaborate_sig_mod_(Design*des, NetScope*scope, Module*mod) const;
|
||||
};
|
||||
|
||||
/*
|
||||
* $Log: PGate.h,v $
|
||||
* Revision 1.22 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.21 2001/10/21 00:42:47 steve
|
||||
* Module types in pform are char* instead of string.
|
||||
*
|
||||
* Revision 1.20 2001/10/19 01:55:32 steve
|
||||
* Method to get the type_ member
|
||||
*
|
||||
* Revision 1.19 2001/04/22 23:09:45 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.18 2000/05/06 15:41:56 steve
|
||||
* Carry assignment strength to pform.
|
||||
*
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PTask.cc,v 1.4 2001/01/13 22:20:08 steve Exp $"
|
||||
#ident "$Id: PTask.cc,v 1.6 2001/07/25 03:10:48 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PTask.h"
|
||||
|
||||
PTask::PTask()
|
||||
@@ -40,13 +42,19 @@ void PTask::set_ports(svector<PWire*>*p)
|
||||
void PTask::set_statement(Statement*s)
|
||||
{
|
||||
assert(statement_ == 0);
|
||||
assert(s != 0);
|
||||
statement_ = s;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: PTask.cc,v $
|
||||
* Revision 1.6 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.5 2001/04/19 03:04:47 steve
|
||||
* Spurious assert of empty statemnt.
|
||||
*
|
||||
* Revision 1.4 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PTask.h,v 1.10 2001/01/13 22:20:08 steve Exp $"
|
||||
#ident "$Id: PTask.h,v 1.11 2001/11/22 06:20:59 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "LineInfo.h"
|
||||
@@ -52,7 +52,7 @@ class PTask : public LineInfo {
|
||||
void elaborate_sig(Design*des, NetScope*scope) const;
|
||||
|
||||
// Elaborate the statement to finish off the task definition.
|
||||
void elaborate(Design*des, const string&path) const;
|
||||
void elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
void dump(ostream&, unsigned) const;
|
||||
|
||||
@@ -98,6 +98,9 @@ class PFunction : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: PTask.h,v $
|
||||
* Revision 1.11 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.10 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PUdp.h,v 1.4 2000/02/23 02:56:53 steve Exp $"
|
||||
#ident "$Id: PUdp.h,v 1.5 2001/04/22 23:09:45 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <map>
|
||||
@@ -72,8 +72,8 @@ class PUdp {
|
||||
|
||||
void dump(ostream&out) const;
|
||||
|
||||
private:
|
||||
const string name_;
|
||||
private:
|
||||
|
||||
private: // Not implemented
|
||||
PUdp(const PUdp&);
|
||||
@@ -82,6 +82,9 @@ class PUdp {
|
||||
|
||||
/*
|
||||
* $Log: PUdp.h,v $
|
||||
* Revision 1.5 2001/04/22 23:09:45 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.4 2000/02/23 02:56:53 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
||||
@@ -17,14 +17,21 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PWire.cc,v 1.5 2001/01/06 02:29:35 steve Exp $"
|
||||
#ident "$Id: PWire.cc,v 1.7 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PWire.h"
|
||||
# include <assert.h>
|
||||
|
||||
PWire::PWire(const string&n, NetNet::Type t, NetNet::PortType pt)
|
||||
: name_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0)
|
||||
PWire::PWire(const hname_t&n, NetNet::Type t, NetNet::PortType pt)
|
||||
: hname_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0)
|
||||
{
|
||||
}
|
||||
|
||||
PWire::PWire(char*n, NetNet::Type t, NetNet::PortType pt)
|
||||
: hname_(n), type_(t), port_type_(pt), signed_(false), lidx_(0), ridx_(0)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -32,6 +39,18 @@ 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_;
|
||||
}
|
||||
|
||||
bool PWire::set_wire_type(NetNet::Type t)
|
||||
{
|
||||
@@ -108,6 +127,14 @@ void PWire::set_memory_idx(PExpr*ldx, PExpr*rdx)
|
||||
|
||||
/*
|
||||
* $Log: PWire.cc,v $
|
||||
* Revision 1.7 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.6 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.5 2001/01/06 02:29:35 steve
|
||||
* Support arrays of integers.
|
||||
*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: PWire.h,v 1.10 2001/01/16 02:44:18 steve Exp $"
|
||||
#ident "$Id: PWire.h,v 1.11 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
@@ -40,14 +40,21 @@ class Design;
|
||||
* Wires include nets, registers and ports. A net or register becomes
|
||||
* a port by declaration, so ports are not seperate. The module
|
||||
* identifies a port by keeping it in its port list.
|
||||
*
|
||||
* The hname parameter to the constructor is a hierarchical name. It
|
||||
* is an array of strings starting with the root, running towards
|
||||
* the base name, and terminated by a null pointer. The environment
|
||||
* allocates the memory for me.
|
||||
*/
|
||||
class PWire : public LineInfo {
|
||||
|
||||
public:
|
||||
PWire(const string&n, NetNet::Type t, NetNet::PortType pt);
|
||||
PWire(const hname_t&hname, NetNet::Type t, NetNet::PortType pt);
|
||||
PWire(char*name, NetNet::Type t, NetNet::PortType pt);
|
||||
|
||||
|
||||
const string&name() const { return name_; }
|
||||
// Return a hierarchical name.
|
||||
//const string name() const;
|
||||
const hname_t&path() const;
|
||||
|
||||
NetNet::Type get_wire_type() const;
|
||||
bool set_wire_type(NetNet::Type);
|
||||
@@ -70,7 +77,7 @@ class PWire : public LineInfo {
|
||||
void elaborate_sig(Design*, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
string name_;
|
||||
hname_t hname_;
|
||||
NetNet::Type type_;
|
||||
NetNet::PortType port_type_;
|
||||
bool signed_;
|
||||
@@ -92,6 +99,10 @@ class PWire : public LineInfo {
|
||||
|
||||
/*
|
||||
* $Log: PWire.h,v $
|
||||
* Revision 1.11 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.10 2001/01/16 02:44:18 steve
|
||||
* Use the iosfwd header if available.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
|
||||
* Getting Started with Icarus Verilog
|
||||
|
||||
Icarus Verilog is a Verilog compiler. It is suitable for use as a
|
||||
simulator, and, to some degree, synthesizer. Icarus Verilog runs under
|
||||
Linux and a variety of UNIX systems, as well as Windows as a command
|
||||
line tool, so the instructions are generally applicable to all
|
||||
environments. Note that this is only a quick start. For more detailed
|
||||
documentation, see the manual page for the iverilog command.
|
||||
|
||||
|
||||
* Hello, World!
|
||||
|
||||
The first thing you want to do as a user is learn how to compile and
|
||||
execute even the most trivial design. For the purposes of simulation,
|
||||
we use as our example *the* most trivial simulation:
|
||||
|
||||
module main;
|
||||
|
||||
initial
|
||||
begin
|
||||
$display("Hello, World");
|
||||
$finish ;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
By a text editor (or copy hello.vl from the Icarus Verilog examples
|
||||
directory) arrange for this program to be in a text file, "hello.vl".
|
||||
Next, compile this program with a command like this:
|
||||
|
||||
% iverilog -o hello hello.vl
|
||||
|
||||
The results of this compile are placed into the file "hello", as the
|
||||
"-o" flag tells the compiler where to place the compiled result. Next,
|
||||
execute the compiled program like so:
|
||||
|
||||
% vvp hello
|
||||
Hello, World
|
||||
|
||||
And there it is, the program has been executed. So what happened? The
|
||||
first step, the "iverilog" command, read and interpreted the source
|
||||
file, then generated a compiled result. The compiled form may be
|
||||
selected by command line switches, but the default form is the VVP
|
||||
format, which is actually run by the "vvp" command.
|
||||
|
||||
The "iverilog" and "vvp" commands are the only commands that users
|
||||
use to invoke Icarus Verilog. What the compiler actually does is
|
||||
controlled by command line switches. In our little example, we asked
|
||||
the compiler to compile the source program to the default vvp form,
|
||||
which is in turn executed by the vvp program.
|
||||
|
||||
|
||||
* Windows Install
|
||||
|
||||
The easiest way to install under Windows is to get a precompiled
|
||||
installer for the version you wish to install. Icarus Verilog is
|
||||
distributed for Windows users as a self-installing .exe. Just execute
|
||||
the installer and follow the instructions. During the install, take
|
||||
note of the directory where the program is installed: for example,
|
||||
C:\iverilog is a good place to install.
|
||||
|
||||
Once the binary is installed, you need to add the bin directory to
|
||||
your execution path. The executables you need are in C:\iverilog\bin,
|
||||
where the "C:\iverilog" part is actually the root of where you
|
||||
installed the package. The programs are in the bin subdirectory. Put
|
||||
this directory in your PATH environment variable, and the above
|
||||
commands become accessible to you at the command line prompt, or even
|
||||
in batch files.
|
||||
|
||||
|
||||
* Linux Install
|
||||
|
||||
Under Linux, the install is even easier. For RedHat and Mandrake based
|
||||
systems, there is the appropriate RPM file. Just install the package
|
||||
with the "rpm -U <file>" command. Debian users should get Icarus
|
||||
Verilog packages from the main Debian software site.
|
||||
|
||||
|
||||
* Install From Source
|
||||
|
||||
In this case, see the readme and other documentation that comes with
|
||||
the source.
|
||||
+80
-16
@@ -12,11 +12,15 @@ home page at <http://www.icarus.com/eda/verilog>.
|
||||
|
||||
Icarus Verilog is not aimed at being a simulator in the traditional
|
||||
sense, but a compiler that generates code employed by back-end
|
||||
tools. These back- end tools currently include a simulator written in
|
||||
C++ called VVM and an XNF (Xilinx Netlist Format) generator. See
|
||||
"vvm.txt" and "xnf.txt" for further details on these back-end
|
||||
processors. In the future, backends are expected for EDIF/LPM,
|
||||
structural Verilog, VHDL, etc.
|
||||
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.
|
||||
|
||||
For instructions on how to run Icarus Verilog, see the ``iverilog''
|
||||
man page.
|
||||
|
||||
|
||||
2.0 Building/Installing Icarus Verilog From Source
|
||||
|
||||
@@ -32,7 +36,7 @@ You need the following software to compile Icarus Verilog from source
|
||||
on a UNIX-like system:
|
||||
|
||||
- GNU Make
|
||||
The Makefiles use some GNU extensions to, so a basic POSIX
|
||||
The Makefiles use some GNU extensions, so a basic POSIX
|
||||
make will not work. Linux systems typically come with a
|
||||
satisfactory make. BSD based systems (i.e. NetBSD, FreeBSD)
|
||||
typically have GNU make as the gmake program.
|
||||
@@ -63,15 +67,47 @@ with the commands:
|
||||
./configure
|
||||
make
|
||||
|
||||
2.3 Installation
|
||||
Normally, this command automatically figures out every thing 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.
|
||||
|
||||
--prefix=<root>
|
||||
The default is /usr/local, which causes the tool suite to
|
||||
be compiled for install in /usr/local/bin,
|
||||
/usr/local/share/ivl, etc.
|
||||
|
||||
I recommend that if you are configuring for precompiled
|
||||
binaries, use --prefix=/usr. On Solaris systems, it is
|
||||
common to use --prefix=/opt.
|
||||
|
||||
2.3 (Optional) Testing
|
||||
|
||||
To run a simple test before installation, execute
|
||||
|
||||
make check
|
||||
|
||||
The commands printed by this run might help you in running Icarus
|
||||
Verilog on your own verilog sources before the package is installed
|
||||
by root.
|
||||
|
||||
2.4 Installation
|
||||
|
||||
Now install the files in an appropriate place. (The makefiles by
|
||||
default install in /usr/local unless you specify a different prefix
|
||||
with the --prefix=<path> flag to the configure command.) Do this as
|
||||
root.
|
||||
with the --prefix=<path> flag to the configure command.) You may need
|
||||
to do this as root to gain access to installation directories.
|
||||
|
||||
make install
|
||||
|
||||
2.5 Uninstallation
|
||||
|
||||
The generated Makefiles also include the uninstall target. This should
|
||||
remove all the files that ``make install'' creates.
|
||||
|
||||
3.0 How Icarus Verilog Works
|
||||
|
||||
This tool includes a parser which reads in Verilog (plus extensions)
|
||||
@@ -207,11 +243,16 @@ 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
|
||||
@@ -223,6 +264,9 @@ Usage: ivl <options>... file
|
||||
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
|
||||
@@ -264,10 +308,12 @@ Usage: ivl <options>... file
|
||||
options/parameters to optimization functions, if any are defined.
|
||||
|
||||
-s <module>
|
||||
Normally, ivl will elaborate the only module in the source
|
||||
file. If there are multiple modules, use this option to select
|
||||
the module to be used as the top-level module.
|
||||
|
||||
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
|
||||
@@ -277,8 +323,18 @@ Usage: ivl <options>... file
|
||||
Select the output format for the compiled result. Use the
|
||||
"ivl -h" command to get a list of configured targets.
|
||||
|
||||
-v
|
||||
Print version and copyright information for ivl.
|
||||
-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
|
||||
|
||||
@@ -363,6 +419,7 @@ Verilog guidance, and especially testing from many people, including
|
||||
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]>
|
||||
@@ -388,7 +445,7 @@ bundled it into neat packages.(+) If you want to be added to the list (or
|
||||
removed from the list) send e-mail to me.
|
||||
|
||||
FreeBSD/{Intel,alpha}
|
||||
*maintainer needed*
|
||||
Ying-Chieh Liao <[email protected]>
|
||||
|
||||
Linux/{alpha,Intel} (RPMS)
|
||||
Stephen Williams <[email protected]>
|
||||
@@ -399,6 +456,9 @@ removed from the list) send e-mail to me.
|
||||
Macintosh -- MacO/S
|
||||
Yasuhisa Kato <[email protected]>
|
||||
|
||||
Mac O/S X
|
||||
Timothy J. Wood <[email protected]>
|
||||
|
||||
NetBSD/*
|
||||
Dan McMahill <[email protected]>
|
||||
|
||||
@@ -408,9 +468,13 @@ removed from the list) send e-mail to me.
|
||||
Cygwin32/*
|
||||
Venkat Iyer <[email protected]>
|
||||
|
||||
Mingw32
|
||||
Venkat Iyer <[email protected]>
|
||||
|
||||
(+) These are not the only systems where Icarus Verilog has been run,
|
||||
just the systems where precompiled binaries are publicly available.
|
||||
|
||||
|
||||
6.2 TEST SUITE MANAGER
|
||||
|
||||
Steve Wilson <[email protected]> or <[email protected]> has taken on
|
||||
|
||||
+40
-103
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Statement.cc,v 1.22 2000/07/26 05:08:07 steve Exp $"
|
||||
#ident "$Id: Statement.cc,v 1.25 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "Statement.h"
|
||||
# include "PExpr.h"
|
||||
|
||||
@@ -103,11 +105,20 @@ PBlock::~PBlock()
|
||||
delete list_[idx];
|
||||
}
|
||||
|
||||
PCallTask::PCallTask(const string&n, const svector<PExpr*>&p)
|
||||
: name_(n), parms_(p)
|
||||
PCallTask::PCallTask(const hname_t&n, const svector<PExpr*>&p)
|
||||
: path_(n), parms_(p)
|
||||
{
|
||||
}
|
||||
|
||||
PCallTask::~PCallTask()
|
||||
{
|
||||
}
|
||||
|
||||
const hname_t& PCallTask::path() const
|
||||
{
|
||||
return path_;
|
||||
}
|
||||
|
||||
PCase::PCase(NetCase::TYPE t, PExpr*ex, svector<PCase::Item*>*l)
|
||||
: type_(t), expr_(ex), items_(l)
|
||||
{
|
||||
@@ -165,7 +176,7 @@ PDelayStatement::~PDelayStatement()
|
||||
{
|
||||
}
|
||||
|
||||
PDisable::PDisable(const string&sc)
|
||||
PDisable::PDisable(const hname_t&sc)
|
||||
: scope_(sc)
|
||||
{
|
||||
}
|
||||
@@ -217,6 +228,17 @@ PForever::~PForever()
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
PForStatement::PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
|
||||
PExpr*n2, PExpr*e2, Statement*st)
|
||||
: name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2),
|
||||
statement_(st)
|
||||
{
|
||||
}
|
||||
|
||||
PForStatement::~PForStatement()
|
||||
{
|
||||
}
|
||||
|
||||
PProcess::~PProcess()
|
||||
{
|
||||
delete statement_;
|
||||
@@ -243,7 +265,7 @@ PRepeat::~PRepeat()
|
||||
delete statement_;
|
||||
}
|
||||
|
||||
PTrigger::PTrigger(const string&e)
|
||||
PTrigger::PTrigger(const hname_t&e)
|
||||
: event_(e)
|
||||
{
|
||||
}
|
||||
@@ -252,6 +274,11 @@ PTrigger::~PTrigger()
|
||||
{
|
||||
}
|
||||
|
||||
PWhile::PWhile(PExpr*e1, Statement*st)
|
||||
: cond_(e1), statement_(st)
|
||||
{
|
||||
}
|
||||
|
||||
PWhile::~PWhile()
|
||||
{
|
||||
delete cond_;
|
||||
@@ -260,105 +287,15 @@ PWhile::~PWhile()
|
||||
|
||||
/*
|
||||
* $Log: Statement.cc,v $
|
||||
* Revision 1.22 2000/07/26 05:08:07 steve
|
||||
* Parse disable statements to pform.
|
||||
* Revision 1.25 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.21 2000/05/11 23:37:26 steve
|
||||
* Add support for procedural continuous assignment.
|
||||
*
|
||||
* Revision 1.20 2000/04/22 04:20:19 steve
|
||||
* Add support for force assignment.
|
||||
*
|
||||
* Revision 1.19 2000/04/12 04:23:57 steve
|
||||
* Named events really should be expressed with PEIdent
|
||||
* objects in the pform,
|
||||
*
|
||||
* Handle named events within the mix of net events
|
||||
* and edges. As a unified lot they get caught together.
|
||||
* wait statements are broken into more complex statements
|
||||
* that include a conditional.
|
||||
*
|
||||
* Do not generate NetPEvent or NetNEvent objects in
|
||||
* elaboration. NetEvent, NetEvWait and NetEvProbe
|
||||
* take over those functions in the netlist.
|
||||
*
|
||||
* Revision 1.18 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
* Revision 1.17 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.16 1999/09/29 18:36:02 steve
|
||||
* Full case support
|
||||
*
|
||||
* Revision 1.15 1999/09/22 02:00:48 steve
|
||||
* assignment with blocking event delay.
|
||||
*
|
||||
* Revision 1.14 1999/09/04 19:11:46 steve
|
||||
* Add support for delayed non-blocking assignments.
|
||||
*
|
||||
* Revision 1.13 1999/09/02 01:59:27 steve
|
||||
* Parse non-blocking assignment delays.
|
||||
*
|
||||
* Revision 1.12 1999/07/12 00:59:36 steve
|
||||
* procedural blocking assignment delays.
|
||||
*
|
||||
* Revision 1.11 1999/06/24 04:24:18 steve
|
||||
* Handle expression widths for EEE and NEE operators,
|
||||
* add named blocks and scope handling,
|
||||
* add registers declared in named blocks.
|
||||
*
|
||||
* Revision 1.10 1999/06/19 21:06:16 steve
|
||||
* Elaborate and supprort to vvm the forever
|
||||
* and repeat statements.
|
||||
*
|
||||
* Revision 1.9 1999/06/15 05:38:39 steve
|
||||
* Support case expression lists.
|
||||
*
|
||||
* Revision 1.8 1999/06/13 23:51:16 steve
|
||||
* l-value part select for procedural assignments.
|
||||
*
|
||||
* Revision 1.7 1999/06/06 20:45:38 steve
|
||||
* Add parse and elaboration of non-blocking assignments,
|
||||
* Replace list<PCase::Item*> with an svector version,
|
||||
* Add integer support.
|
||||
*
|
||||
* Revision 1.6 1999/05/10 00:16:58 steve
|
||||
* Parse and elaborate the concatenate operator
|
||||
* in structural contexts, Replace vector<PExpr*>
|
||||
* and list<PExpr*> with svector<PExpr*>, evaluate
|
||||
* constant expressions with parameters, handle
|
||||
* memories as lvalues.
|
||||
*
|
||||
* Parse task declarations, integer types.
|
||||
*
|
||||
* Revision 1.5 1999/02/03 04:20:11 steve
|
||||
* Parse and elaborate the Verilog CASE statement.
|
||||
*
|
||||
* Revision 1.4 1999/01/25 05:45:56 steve
|
||||
* Add the LineInfo class to carry the source file
|
||||
* location of things. PGate, Statement and PProcess.
|
||||
*
|
||||
* elaborate handles module parameter mismatches,
|
||||
* missing or incorrect lvalues for procedural
|
||||
* assignment, and errors are propogated to the
|
||||
* top of the elaboration call tree.
|
||||
*
|
||||
* Attach line numbers to processes, gates and
|
||||
* assignment statements.
|
||||
*
|
||||
* Revision 1.3 1998/11/11 03:13:04 steve
|
||||
* Handle while loops.
|
||||
*
|
||||
* Revision 1.2 1998/11/07 17:05:05 steve
|
||||
* Handle procedural conditional, and some
|
||||
* of the conditional expressions.
|
||||
*
|
||||
* Elaborate signals and identifiers differently,
|
||||
* allowing the netlist to hold signal information.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:28:55 steve
|
||||
* Introduce verilog to CVS.
|
||||
* Revision 1.24 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.23 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*/
|
||||
|
||||
|
||||
+44
-139
@@ -19,13 +19,14 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: Statement.h,v 1.29 2000/09/09 15:21:26 steve Exp $"
|
||||
#ident "$Id: Statement.h,v 1.31 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <string>
|
||||
# include "svector.h"
|
||||
# include "PDelays.h"
|
||||
# include "PExpr.h"
|
||||
# include "HName.h"
|
||||
# include "LineInfo.h"
|
||||
class PExpr;
|
||||
class Statement;
|
||||
@@ -74,7 +75,7 @@ class Statement : public LineInfo {
|
||||
virtual ~Statement() =0;
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
};
|
||||
|
||||
@@ -113,11 +114,11 @@ class PAssign : public PAssign_ {
|
||||
~PAssign();
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
NetProc*assign_to_memory_(class NetMemory*, PExpr*,
|
||||
Design*des, const string&path) const;
|
||||
Design*des, NetScope*scope) const;
|
||||
};
|
||||
|
||||
class PAssignNB : public PAssign_ {
|
||||
@@ -128,11 +129,11 @@ class PAssignNB : public PAssign_ {
|
||||
~PAssignNB();
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
NetProc*assign_to_memory_(class NetMemory*, PExpr*,
|
||||
Design*des, const string&path) const;
|
||||
Design*des, NetScope*scope) const;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -154,11 +155,9 @@ class PBlock : public Statement {
|
||||
|
||||
BL_TYPE bl_type() const { return bl_type_; }
|
||||
|
||||
//unsigned size() const { return list_.count(); }
|
||||
//const Statement*stat(unsigned idx) const { return list_[idx]; }
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
@@ -170,9 +169,10 @@ class PBlock : public Statement {
|
||||
class PCallTask : public Statement {
|
||||
|
||||
public:
|
||||
explicit PCallTask(const string&n, const svector<PExpr*>&parms);
|
||||
explicit PCallTask(const hname_t&n, const svector<PExpr*>&parms);
|
||||
~PCallTask();
|
||||
|
||||
string name() const { return name_; }
|
||||
const hname_t& path() const;
|
||||
|
||||
unsigned nparms() const { return parms_.count(); }
|
||||
|
||||
@@ -187,13 +187,13 @@ class PCallTask : public Statement {
|
||||
}
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
NetProc* elaborate_sys(Design*des, const string&path) const;
|
||||
NetProc* elaborate_usr(Design*des, const string&path) const;
|
||||
NetProc* elaborate_sys(Design*des, NetScope*scope) const;
|
||||
NetProc* elaborate_usr(Design*des, NetScope*scope) const;
|
||||
|
||||
const string name_;
|
||||
hname_t path_;
|
||||
svector<PExpr*> parms_;
|
||||
};
|
||||
|
||||
@@ -208,7 +208,7 @@ class PCase : public Statement {
|
||||
PCase(NetCase::TYPE, PExpr*ex, svector<Item*>*);
|
||||
~PCase();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
@@ -229,7 +229,7 @@ class PCAssign : public Statement {
|
||||
explicit PCAssign(PExpr*l, PExpr*r);
|
||||
~PCAssign();
|
||||
|
||||
virtual NetCAssign* elaborate(Design*des, const string&path) const;
|
||||
virtual NetCAssign* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -243,7 +243,7 @@ class PCondit : public Statement {
|
||||
PCondit(PExpr*ex, Statement*i, Statement*e);
|
||||
~PCondit();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
@@ -263,7 +263,7 @@ class PDeassign : public Statement {
|
||||
explicit PDeassign(PExpr*l);
|
||||
~PDeassign();
|
||||
|
||||
virtual NetDeassign* elaborate(Design*des, const string&path) const;
|
||||
virtual NetDeassign* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -277,7 +277,7 @@ class PDelayStatement : public Statement {
|
||||
~PDelayStatement();
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
@@ -292,14 +292,14 @@ class PDelayStatement : public Statement {
|
||||
class PDisable : public Statement {
|
||||
|
||||
public:
|
||||
explicit PDisable(const string&sc);
|
||||
explicit PDisable(const hname_t&sc);
|
||||
~PDisable();
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
|
||||
private:
|
||||
string scope_;
|
||||
hname_t scope_;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -321,12 +321,12 @@ class PEventStatement : public Statement {
|
||||
void set_statement(Statement*st);
|
||||
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
|
||||
// This method is used to elaborate, but attach a previously
|
||||
// elaborated statement to the event.
|
||||
NetProc* elaborate_st(Design*des, const string&path, NetProc*st) const;
|
||||
NetProc* elaborate_st(Design*des, NetScope*scope, NetProc*st) const;
|
||||
|
||||
private:
|
||||
svector<PEEvent*>expr_;
|
||||
@@ -339,7 +339,7 @@ class PForce : public Statement {
|
||||
explicit PForce(PExpr*l, PExpr*r);
|
||||
~PForce();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -352,7 +352,7 @@ class PForever : public Statement {
|
||||
explicit PForever(Statement*s);
|
||||
~PForever();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
@@ -364,12 +364,10 @@ class PForStatement : public Statement {
|
||||
|
||||
public:
|
||||
PForStatement(PExpr*n1, PExpr*e1, PExpr*cond,
|
||||
PExpr*n2, PExpr*e2, Statement*st)
|
||||
: name1_(n1), expr1_(e1), cond_(cond), name2_(n2), expr2_(e2),
|
||||
statement_(st)
|
||||
{ }
|
||||
PExpr*n2, PExpr*e2, Statement*st);
|
||||
~PForStatement();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
@@ -396,7 +394,7 @@ class PRepeat : public Statement {
|
||||
explicit PRepeat(PExpr*expr, Statement*s);
|
||||
~PRepeat();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
@@ -411,7 +409,7 @@ class PRelease : public Statement {
|
||||
explicit PRelease(PExpr*l);
|
||||
~PRelease();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
@@ -425,24 +423,23 @@ class PRelease : public Statement {
|
||||
class PTrigger : public Statement {
|
||||
|
||||
public:
|
||||
explicit PTrigger(const string&ev);
|
||||
explicit PTrigger(const hname_t&ev);
|
||||
~PTrigger();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
private:
|
||||
string event_;
|
||||
hname_t event_;
|
||||
};
|
||||
|
||||
class PWhile : public Statement {
|
||||
|
||||
public:
|
||||
PWhile(PExpr*e1, Statement*st)
|
||||
: cond_(e1), statement_(st) { }
|
||||
PWhile(PExpr*e1, Statement*st);
|
||||
~PWhile();
|
||||
|
||||
virtual NetProc* elaborate(Design*des, const string&path) const;
|
||||
virtual NetProc* elaborate(Design*des, NetScope*scope) const;
|
||||
virtual void elaborate_scope(Design*des, NetScope*scope) const;
|
||||
virtual void dump(ostream&out, unsigned ind) const;
|
||||
|
||||
@@ -453,6 +450,13 @@ class PWhile : public Statement {
|
||||
|
||||
/*
|
||||
* $Log: Statement.h,v $
|
||||
* Revision 1.31 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.30 2001/11/22 06:20:59 steve
|
||||
* Use NetScope instead of string for scope path.
|
||||
*
|
||||
* Revision 1.29 2000/09/09 15:21:26 steve
|
||||
* move lval elaboration to PExpr virtual methods.
|
||||
*
|
||||
@@ -480,104 +484,5 @@ class PWhile : public Statement {
|
||||
* Do not generate NetPEvent or NetNEvent objects in
|
||||
* elaboration. NetEvent, NetEvWait and NetEvProbe
|
||||
* take over those functions in the netlist.
|
||||
*
|
||||
* Revision 1.23 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
* Revision 1.22 2000/03/11 03:25:51 steve
|
||||
* Locate scopes in statements.
|
||||
*
|
||||
* Revision 1.21 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.20 1999/09/29 18:36:02 steve
|
||||
* Full case support
|
||||
*
|
||||
* Revision 1.19 1999/09/22 02:00:48 steve
|
||||
* assignment with blocking event delay.
|
||||
*
|
||||
* Revision 1.18 1999/09/15 01:55:06 steve
|
||||
* Elaborate non-blocking assignment to memories.
|
||||
*
|
||||
* Revision 1.17 1999/09/04 19:11:46 steve
|
||||
* Add support for delayed non-blocking assignments.
|
||||
*
|
||||
* Revision 1.16 1999/09/02 01:59:27 steve
|
||||
* Parse non-blocking assignment delays.
|
||||
*
|
||||
* Revision 1.15 1999/07/12 00:59:36 steve
|
||||
* procedural blocking assignment delays.
|
||||
*
|
||||
* Revision 1.14 1999/07/03 02:12:51 steve
|
||||
* Elaborate user defined tasks.
|
||||
*
|
||||
* Revision 1.13 1999/06/24 04:24:18 steve
|
||||
* Handle expression widths for EEE and NEE operators,
|
||||
* add named blocks and scope handling,
|
||||
* add registers declared in named blocks.
|
||||
*
|
||||
* Revision 1.12 1999/06/19 21:06:16 steve
|
||||
* Elaborate and supprort to vvm the forever
|
||||
* and repeat statements.
|
||||
*
|
||||
* Revision 1.11 1999/06/15 05:38:39 steve
|
||||
* Support case expression lists.
|
||||
*
|
||||
* Revision 1.10 1999/06/13 23:51:16 steve
|
||||
* l-value part select for procedural assignments.
|
||||
*
|
||||
* Revision 1.9 1999/06/06 20:45:38 steve
|
||||
* Add parse and elaboration of non-blocking assignments,
|
||||
* Replace list<PCase::Item*> with an svector version,
|
||||
* Add integer support.
|
||||
*
|
||||
* Revision 1.8 1999/05/10 00:16:58 steve
|
||||
* Parse and elaborate the concatenate operator
|
||||
* in structural contexts, Replace vector<PExpr*>
|
||||
* and list<PExpr*> with svector<PExpr*>, evaluate
|
||||
* constant expressions with parameters, handle
|
||||
* memories as lvalues.
|
||||
*
|
||||
* Parse task declarations, integer types.
|
||||
*
|
||||
* Revision 1.7 1999/04/29 02:16:26 steve
|
||||
* Parse OR of event expressions.
|
||||
*
|
||||
* Revision 1.6 1999/02/03 04:20:11 steve
|
||||
* Parse and elaborate the Verilog CASE statement.
|
||||
*
|
||||
* Revision 1.5 1999/01/25 05:45:56 steve
|
||||
* Add the LineInfo class to carry the source file
|
||||
* location of things. PGate, Statement and PProcess.
|
||||
*
|
||||
* elaborate handles module parameter mismatches,
|
||||
* missing or incorrect lvalues for procedural
|
||||
* assignment, and errors are propogated to the
|
||||
* top of the elaboration call tree.
|
||||
*
|
||||
* Attach line numbers to processes, gates and
|
||||
* assignment statements.
|
||||
*
|
||||
* Revision 1.4 1998/11/11 03:13:04 steve
|
||||
* Handle while loops.
|
||||
*
|
||||
* Revision 1.3 1998/11/09 18:55:33 steve
|
||||
* Add procedural while loops,
|
||||
* Parse procedural for loops,
|
||||
* Add procedural wait statements,
|
||||
* Add constant nodes,
|
||||
* Add XNOR logic gate,
|
||||
* Make vvm output look a bit prettier.
|
||||
*
|
||||
* Revision 1.2 1998/11/07 17:05:05 steve
|
||||
* Handle procedural conditional, and some
|
||||
* of the conditional expressions.
|
||||
*
|
||||
* Elaborate signals and identifiers differently,
|
||||
* allowing the netlist to hold signal information.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:28:56 steve
|
||||
* Introduce verilog to CVS.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# This shell script exists to run autoconf on source distributions
|
||||
# that are pulled from CVS. The configure scripts are not included
|
||||
# in CVS, and there are several configure.in files, so it is easiest
|
||||
# to just run this script to autoconf wherever needed.
|
||||
#
|
||||
echo "Autoconf in root..."
|
||||
autoconf
|
||||
|
||||
for dir in vpip vvp tgt-vvp tgt-fpga
|
||||
do
|
||||
echo "Autoconf in $dir..."
|
||||
( cd $dir ; autoconf )
|
||||
done
|
||||
+16
-1
@@ -19,9 +19,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: compiler.h,v 1.5 2000/10/31 17:49:02 steve Exp $"
|
||||
#ident "$Id: compiler.h,v 1.7 2001/11/16 05:07:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <list>
|
||||
|
||||
/*
|
||||
* This defines constants and defaults for the compiler in general.
|
||||
*/
|
||||
@@ -66,8 +68,21 @@
|
||||
/* Implicit definitions of wires. */
|
||||
extern bool warn_implicit;
|
||||
|
||||
/* 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;
|
||||
extern list<const char*>library_suff;
|
||||
|
||||
/*
|
||||
* $Log: compiler.h,v $
|
||||
* 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.
|
||||
*
|
||||
|
||||
Vendored
+411
-140
@@ -1,6 +1,7 @@
|
||||
#! /bin/sh
|
||||
# Attempt to guess a canonical system name.
|
||||
# Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# This file is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by
|
||||
@@ -22,7 +23,7 @@
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# Written by Per Bothner <[email protected]>.
|
||||
# The master version of this file is at the FSF in /home/gd/gnu/lib.
|
||||
# Please send patches to <[email protected]>.
|
||||
#
|
||||
# This script attempts to guess a canonical system name similar to
|
||||
# config.sub. If it succeeds, it prints the system name on stdout, and
|
||||
@@ -35,6 +36,20 @@
|
||||
# (but try to keep the structure clean).
|
||||
#
|
||||
|
||||
# Use $HOST_CC if defined. $CC may point to a cross-compiler
|
||||
if test x"$CC_FOR_BUILD" = x; then
|
||||
if test x"$HOST_CC" != x; then
|
||||
CC_FOR_BUILD="$HOST_CC"
|
||||
else
|
||||
if test x"$CC" != x; then
|
||||
CC_FOR_BUILD="$CC"
|
||||
else
|
||||
CC_FOR_BUILD=cc
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
|
||||
# ([email protected] 8/24/94.)
|
||||
if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
|
||||
@@ -46,11 +61,49 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
|
||||
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
|
||||
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
|
||||
|
||||
trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
|
||||
dummy=dummy-$$
|
||||
trap 'rm -f $dummy.c $dummy.o $dummy; exit 1' 1 2 15
|
||||
|
||||
# Note: order is significant - the case branches are not exclusive.
|
||||
|
||||
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
*:NetBSD:*:*)
|
||||
# Netbsd (nbsd) targets should (where applicable) match one or
|
||||
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
|
||||
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
|
||||
# switched to ELF, *-*-netbsd* would select the old
|
||||
# object file format. This provides both forward
|
||||
# compatibility and a consistent mechanism for selecting the
|
||||
# object file format.
|
||||
# Determine the machine/vendor (is the vendor relevant).
|
||||
case "${UNAME_MACHINE}" in
|
||||
amiga) machine=m68k-cbm ;;
|
||||
arm32) machine=arm-unknown ;;
|
||||
atari*) machine=m68k-atari ;;
|
||||
sun3*) machine=m68k-sun ;;
|
||||
mac68k) machine=m68k-apple ;;
|
||||
macppc) machine=powerpc-apple ;;
|
||||
hp3[0-9][05]) machine=m68k-hp ;;
|
||||
ibmrt|romp-ibm) machine=romp-ibm ;;
|
||||
*) machine=${UNAME_MACHINE}-unknown ;;
|
||||
esac
|
||||
# The Operating System including object format.
|
||||
if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
|
||||
| grep __ELF__ >/dev/null
|
||||
then
|
||||
# Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
|
||||
# Return netbsd for either. FIX?
|
||||
os=netbsd
|
||||
else
|
||||
os=netbsdelf
|
||||
fi
|
||||
# The OS release
|
||||
release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
|
||||
# contains redundant information, the shorter form:
|
||||
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
|
||||
echo "${machine}-${os}${release}"
|
||||
exit 0 ;;
|
||||
alpha:OSF1:*:*)
|
||||
if test $UNAME_RELEASE = "V4.0"; then
|
||||
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
|
||||
@@ -59,46 +112,62 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
|
||||
# A Tn.n version is a released field test version.
|
||||
# A Xn.n version is an unreleased experimental baselevel.
|
||||
# 1.2 uses "1.2" for uname -r.
|
||||
cat <<EOF >dummy.s
|
||||
cat <<EOF >$dummy.s
|
||||
.data
|
||||
\$Lformat:
|
||||
.byte 37,100,45,37,120,10,0 # "%d-%x\n"
|
||||
|
||||
.text
|
||||
.globl main
|
||||
.align 4
|
||||
.ent main
|
||||
main:
|
||||
.frame \$30,0,\$26,0
|
||||
.prologue 0
|
||||
.long 0x47e03d80 # implver $0
|
||||
lda \$2,259
|
||||
.long 0x47e20c21 # amask $2,$1
|
||||
srl \$1,8,\$2
|
||||
sll \$2,2,\$2
|
||||
sll \$0,3,\$0
|
||||
addl \$1,\$0,\$0
|
||||
addl \$2,\$0,\$0
|
||||
ret \$31,(\$26),1
|
||||
.frame \$30,16,\$26,0
|
||||
ldgp \$29,0(\$27)
|
||||
.prologue 1
|
||||
.long 0x47e03d80 # implver \$0
|
||||
lda \$2,-1
|
||||
.long 0x47e20c21 # amask \$2,\$1
|
||||
lda \$16,\$Lformat
|
||||
mov \$0,\$17
|
||||
not \$1,\$18
|
||||
jsr \$26,printf
|
||||
ldgp \$29,0(\$26)
|
||||
mov 0,\$16
|
||||
jsr \$26,exit
|
||||
.end main
|
||||
EOF
|
||||
${CC-cc} dummy.s -o dummy 2>/dev/null
|
||||
$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
|
||||
if test "$?" = 0 ; then
|
||||
./dummy
|
||||
case "$?" in
|
||||
7)
|
||||
case `./$dummy` in
|
||||
0-0)
|
||||
UNAME_MACHINE="alpha"
|
||||
;;
|
||||
15)
|
||||
1-0)
|
||||
UNAME_MACHINE="alphaev5"
|
||||
;;
|
||||
14)
|
||||
1-1)
|
||||
UNAME_MACHINE="alphaev56"
|
||||
;;
|
||||
10)
|
||||
1-101)
|
||||
UNAME_MACHINE="alphapca56"
|
||||
;;
|
||||
16)
|
||||
2-303)
|
||||
UNAME_MACHINE="alphaev6"
|
||||
;;
|
||||
2-307)
|
||||
UNAME_MACHINE="alphaev67"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
rm -f dummy.s dummy
|
||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
|
||||
rm -f $dummy.s $dummy
|
||||
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
|
||||
exit 0 ;;
|
||||
Alpha\ *:Windows_NT*:*)
|
||||
# How do we know it's Interix rather than the generic POSIX subsystem?
|
||||
# Should we change UNAME_MACHINE based on the output of uname instead
|
||||
# of the specific Alpha model?
|
||||
echo alpha-pc-interix
|
||||
exit 0 ;;
|
||||
21064:Windows_NT:50:3)
|
||||
echo alpha-dec-winnt3.5
|
||||
@@ -106,12 +175,12 @@ EOF
|
||||
Amiga*:UNIX_System_V:4.0:*)
|
||||
echo m68k-cbm-sysv4
|
||||
exit 0;;
|
||||
amiga:NetBSD:*:*)
|
||||
echo m68k-cbm-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
amiga:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:[Aa]miga[Oo][Ss]:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-amigaos
|
||||
exit 0 ;;
|
||||
arc64:OpenBSD:*:*)
|
||||
echo mips64el-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@@ -130,16 +199,16 @@ EOF
|
||||
wgrisc:OpenBSD:*:*)
|
||||
echo mipsel-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:OS/390:*:*)
|
||||
echo i370-ibm-openedition
|
||||
exit 0 ;;
|
||||
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
|
||||
echo arm-acorn-riscix${UNAME_RELEASE}
|
||||
exit 0;;
|
||||
arm32:NetBSD:*:*)
|
||||
echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
exit 0 ;;
|
||||
SR2?01:HI-UX/MPP:*:*)
|
||||
echo hppa1.1-hitachi-hiuxmpp
|
||||
exit 0;;
|
||||
Pyramid*:OSx*:*:*|MIS*:OSx*:*:*)
|
||||
Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
|
||||
# [email protected] (Earle F. Ake) contributed MIS and NILE.
|
||||
if test "`(/bin/universe) 2>/dev/null`" = att ; then
|
||||
echo pyramid-pyramid-sysv3
|
||||
@@ -147,9 +216,12 @@ EOF
|
||||
echo pyramid-pyramid-bsd
|
||||
fi
|
||||
exit 0 ;;
|
||||
NILE:*:*:dcosx)
|
||||
NILE*:*:*:dcosx)
|
||||
echo pyramid-pyramid-svr4
|
||||
exit 0 ;;
|
||||
sun4H:SunOS:5.*:*)
|
||||
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit 0 ;;
|
||||
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
|
||||
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
exit 0 ;;
|
||||
@@ -189,21 +261,38 @@ EOF
|
||||
aushp:SunOS:*:*)
|
||||
echo sparc-auspex-sunos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
atari*:NetBSD:*:*)
|
||||
echo m68k-atari-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
atari*:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun3*:NetBSD:*:*)
|
||||
echo m68k-sun-netbsd${UNAME_RELEASE}
|
||||
# The situation for MiNT is a little confusing. The machine name
|
||||
# can be virtually everything (everything which is not
|
||||
# "atarist" or "atariste" at least should have a processor
|
||||
# > m68000). The system name ranges from "MiNT" over "FreeMiNT"
|
||||
# to the lowercase version "mint" (or "freemint"). Finally
|
||||
# the system name "TOS" denotes a system which is actually not
|
||||
# MiNT. But MiNT is downward compatible to TOS, so this should
|
||||
# be no problem.
|
||||
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
|
||||
echo m68k-atari-mint${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
|
||||
echo m68k-milan-mint${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
|
||||
echo m68k-hades-mint${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
|
||||
echo m68k-unknown-mint${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sun3*:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mac68k:NetBSD:*:*)
|
||||
echo m68k-apple-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mac68k:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
@@ -225,12 +314,17 @@ EOF
|
||||
VAX*:ULTRIX*:*:*)
|
||||
echo vax-dec-ultrix${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
2020:CLIX:*:*)
|
||||
2020:CLIX:*:* | 2430:CLIX:*:*)
|
||||
echo clipper-intergraph-clix${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
mips:*:*:UMIPS | mips:*:*:RISCos)
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
int main (argc, argv) int argc; char **argv; {
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#ifdef __cplusplus
|
||||
#include <stdio.h> /* for printf() prototype */
|
||||
int main (int argc, char *argv[]) {
|
||||
#else
|
||||
int main (argc, argv) int argc; char *argv[]; {
|
||||
#endif
|
||||
#if defined (host_mips) && defined (MIPSEB)
|
||||
#if defined (SYSTYPE_SYSV)
|
||||
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
|
||||
@@ -245,10 +339,10 @@ EOF
|
||||
exit (-1);
|
||||
}
|
||||
EOF
|
||||
${CC-cc} dummy.c -o dummy \
|
||||
&& ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
|
||||
&& rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy \
|
||||
&& ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
|
||||
&& rm $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
echo mips-mips-riscos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
Night_Hawk:Power_UNIX:*:*)
|
||||
@@ -266,15 +360,18 @@ EOF
|
||||
AViiON:dgux:*:*)
|
||||
# DG/UX returns AViiON for all architectures
|
||||
UNAME_PROCESSOR=`/usr/bin/uname -p`
|
||||
if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
|
||||
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
|
||||
-o ${TARGET_BINARY_INTERFACE}x = x ] ; then
|
||||
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
|
||||
then
|
||||
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
|
||||
[ ${TARGET_BINARY_INTERFACE}x = x ]
|
||||
then
|
||||
echo m88k-dg-dgux${UNAME_RELEASE}
|
||||
else
|
||||
else
|
||||
echo m88k-dg-dguxbcs${UNAME_RELEASE}
|
||||
fi
|
||||
else
|
||||
echo i586-dg-dgux${UNAME_RELEASE}
|
||||
fi
|
||||
else echo i586-dg-dgux${UNAME_RELEASE}
|
||||
fi
|
||||
exit 0 ;;
|
||||
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
|
||||
echo m88k-dolphin-sysv3
|
||||
@@ -300,7 +397,7 @@ EOF
|
||||
exit 0 ;;
|
||||
*:AIX:2:3)
|
||||
if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#include <sys/systemcfg.h>
|
||||
|
||||
main()
|
||||
@@ -311,8 +408,8 @@ EOF
|
||||
exit(0);
|
||||
}
|
||||
EOF
|
||||
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
echo rs6000-ibm-aix3.2.5
|
||||
elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
|
||||
echo rs6000-ibm-aix3.2.4
|
||||
@@ -321,7 +418,8 @@ EOF
|
||||
fi
|
||||
exit 0 ;;
|
||||
*:AIX:*:4)
|
||||
if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then
|
||||
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
|
||||
if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
|
||||
IBM_ARCH=rs6000
|
||||
else
|
||||
IBM_ARCH=powerpc
|
||||
@@ -339,7 +437,7 @@ EOF
|
||||
ibmrt:4.4BSD:*|romp-ibm:BSD:*)
|
||||
echo romp-ibm-bsd4.4
|
||||
exit 0 ;;
|
||||
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
|
||||
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
|
||||
echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
|
||||
exit 0 ;; # report: romp-ibm BSD 4.3
|
||||
*:BOSX:*:*)
|
||||
@@ -354,18 +452,52 @@ EOF
|
||||
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
|
||||
echo m68k-hp-bsd4.4
|
||||
exit 0 ;;
|
||||
9000/[3478]??:HP-UX:*:*)
|
||||
9000/[34678]??:HP-UX:*:*)
|
||||
case "${UNAME_MACHINE}" in
|
||||
9000/31? ) HP_ARCH=m68000 ;;
|
||||
9000/[34]?? ) HP_ARCH=m68k ;;
|
||||
9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;;
|
||||
9000/8?? ) HP_ARCH=hppa1.0 ;;
|
||||
9000/[678][0-9][0-9])
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
|
||||
#define _HPUX_SOURCE
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int main ()
|
||||
{
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
long bits = sysconf(_SC_KERNEL_BITS);
|
||||
#endif
|
||||
long cpu = sysconf (_SC_CPU_VERSION);
|
||||
|
||||
switch (cpu)
|
||||
{
|
||||
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
|
||||
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
|
||||
case CPU_PA_RISC2_0:
|
||||
#if defined(_SC_KERNEL_BITS)
|
||||
switch (bits)
|
||||
{
|
||||
case 64: puts ("hppa2.0w"); break;
|
||||
case 32: puts ("hppa2.0n"); break;
|
||||
default: puts ("hppa2.0"); break;
|
||||
} break;
|
||||
#else /* !defined(_SC_KERNEL_BITS) */
|
||||
puts ("hppa2.0"); break;
|
||||
#endif
|
||||
default: puts ("hppa1.0"); break;
|
||||
}
|
||||
exit (0);
|
||||
}
|
||||
EOF
|
||||
(CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy`
|
||||
rm -f $dummy.c $dummy
|
||||
esac
|
||||
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
|
||||
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
|
||||
exit 0 ;;
|
||||
3050*:HI-UX:*:*)
|
||||
sed 's/^ //' << EOF >dummy.c
|
||||
sed 's/^ //' << EOF >$dummy.c
|
||||
#include <unistd.h>
|
||||
int
|
||||
main ()
|
||||
@@ -390,8 +522,8 @@ EOF
|
||||
exit (0);
|
||||
}
|
||||
EOF
|
||||
${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
echo unknown-hitachi-hiuxwe2
|
||||
exit 0 ;;
|
||||
9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
|
||||
@@ -400,6 +532,9 @@ EOF
|
||||
9000/8??:4.3bsd:*:*)
|
||||
echo hppa1.0-hp-bsd
|
||||
exit 0 ;;
|
||||
*9??*:MPE/iX:*:*)
|
||||
echo hppa1.0-hp-mpeix
|
||||
exit 0 ;;
|
||||
hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
|
||||
echo hppa1.1-hp-osf
|
||||
exit 0 ;;
|
||||
@@ -416,6 +551,9 @@ EOF
|
||||
parisc*:Lites*:*:*)
|
||||
echo hppa1.1-hp-lites
|
||||
exit 0 ;;
|
||||
hppa*:OpenBSD:*:*)
|
||||
echo hppa-unknown-openbsd
|
||||
exit 0 ;;
|
||||
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
|
||||
echo c1-convex-bsd
|
||||
exit 0 ;;
|
||||
@@ -446,45 +584,60 @@ EOF
|
||||
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
|
||||
exit 0 ;;
|
||||
CRAY*TS:*:*:*)
|
||||
echo t90-cray-unicos${UNAME_RELEASE}
|
||||
echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit 0 ;;
|
||||
CRAY*T3E:*:*:*)
|
||||
echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit 0 ;;
|
||||
CRAY*SV1:*:*:*)
|
||||
echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
|
||||
exit 0 ;;
|
||||
CRAY-2:*:*:*)
|
||||
echo cray2-cray-unicos
|
||||
exit 0 ;;
|
||||
F300:UNIX_System_V:*:*)
|
||||
FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
|
||||
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
|
||||
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
|
||||
echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
|
||||
exit 0 ;;
|
||||
F301:UNIX_System_V:*:*)
|
||||
echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
|
||||
exit 0 ;;
|
||||
hp3[0-9][05]:NetBSD:*:*)
|
||||
echo m68k-hp-netbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
hp300:OpenBSD:*:*)
|
||||
echo m68k-unknown-openbsd${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
i?86:BSD/386:*:* | *:BSD/OS:*:*)
|
||||
i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
sparc*:BSD/OS:*:*)
|
||||
echo sparc-unknown-bsdi${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:BSD/OS:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:FreeBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
|
||||
exit 0 ;;
|
||||
*:NetBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
exit 0 ;;
|
||||
*:OpenBSD:*:*)
|
||||
echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
|
||||
exit 0 ;;
|
||||
i*:CYGWIN*:*)
|
||||
echo i386-pc-cygwin32
|
||||
echo ${UNAME_MACHINE}-pc-cygwin
|
||||
exit 0 ;;
|
||||
i*:MINGW*:*)
|
||||
echo i386-pc-mingw32
|
||||
echo ${UNAME_MACHINE}-pc-mingw32
|
||||
exit 0 ;;
|
||||
i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
|
||||
# How do we know it's Interix rather than the generic POSIX subsystem?
|
||||
# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
|
||||
# UNAME_MACHINE based on the output of uname instead of i386?
|
||||
echo i386-pc-interix
|
||||
exit 0 ;;
|
||||
i*:UWIN*:*)
|
||||
echo ${UNAME_MACHINE}-pc-uwin
|
||||
exit 0 ;;
|
||||
p*:CYGWIN*:*)
|
||||
echo powerpcle-unknown-cygwin32
|
||||
echo powerpcle-unknown-cygwin
|
||||
exit 0 ;;
|
||||
prep*:SunOS:5.*:*)
|
||||
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
|
||||
@@ -493,9 +646,11 @@ EOF
|
||||
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
|
||||
exit 0 ;;
|
||||
*:Linux:*:*)
|
||||
|
||||
# The BFD linker knows what the default object file format is, so
|
||||
# first see if it will tell us.
|
||||
ld_help_string=`ld --help 2>&1`
|
||||
# first see if it will tell us. cd to the root directory to prevent
|
||||
# problems with other programs or directories called `ld' in the path.
|
||||
ld_help_string=`cd /; ld --help 2>&1`
|
||||
ld_supported_emulations=`echo $ld_help_string \
|
||||
| sed -ne '/supported emulations:/!d
|
||||
s/[ ][ ]*/ /g
|
||||
@@ -503,13 +658,45 @@ EOF
|
||||
s/ .*//
|
||||
p'`
|
||||
case "$ld_supported_emulations" in
|
||||
i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;;
|
||||
i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;;
|
||||
sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
|
||||
m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;;
|
||||
elf32ppc)
|
||||
*ia64)
|
||||
echo "${UNAME_MACHINE}-unknown-linux"
|
||||
exit 0
|
||||
;;
|
||||
i?86linux)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnuaout"
|
||||
exit 0
|
||||
;;
|
||||
elf_i?86)
|
||||
echo "${UNAME_MACHINE}-pc-linux"
|
||||
exit 0
|
||||
;;
|
||||
i?86coff)
|
||||
echo "${UNAME_MACHINE}-pc-linux-gnucoff"
|
||||
exit 0
|
||||
;;
|
||||
sparclinux)
|
||||
echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
|
||||
exit 0
|
||||
;;
|
||||
armlinux)
|
||||
echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
|
||||
exit 0
|
||||
;;
|
||||
elf32arm*)
|
||||
echo "${UNAME_MACHINE}-unknown-linux-gnuoldld"
|
||||
exit 0
|
||||
;;
|
||||
armelf_linux*)
|
||||
echo "${UNAME_MACHINE}-unknown-linux-gnu"
|
||||
exit 0
|
||||
;;
|
||||
m68klinux)
|
||||
echo "${UNAME_MACHINE}-unknown-linux-gnuaout"
|
||||
exit 0
|
||||
;;
|
||||
elf32ppc | elf32ppclinux)
|
||||
# Determine Lib Version
|
||||
cat >dummy.c <<EOF
|
||||
cat >$dummy.c <<EOF
|
||||
#include <features.h>
|
||||
#if defined(__GLIBC__)
|
||||
extern char __libc_version[];
|
||||
@@ -528,71 +715,85 @@ main(argc, argv)
|
||||
}
|
||||
EOF
|
||||
LIBC=""
|
||||
${CC-cc} dummy.c -o dummy 2>/dev/null
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null
|
||||
if test "$?" = 0 ; then
|
||||
./dummy | grep 1\.99 > /dev/null
|
||||
./$dummy | grep 1\.99 > /dev/null
|
||||
if test "$?" = 0 ; then
|
||||
LIBC="libc1"
|
||||
fi
|
||||
fi
|
||||
rm -f dummy.c dummy
|
||||
echo powerpc-unknown-linux-gnu${LIBC} ; exit 0 ;;
|
||||
fi
|
||||
rm -f $dummy.c $dummy
|
||||
echo powerpc-unknown-linux-gnu${LIBC}
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
if test "${UNAME_MACHINE}" = "alpha" ; then
|
||||
sed 's/^ //' <<EOF >dummy.s
|
||||
.globl main
|
||||
.ent main
|
||||
main:
|
||||
.frame \$30,0,\$26,0
|
||||
.prologue 0
|
||||
.long 0x47e03d80 # implver $0
|
||||
lda \$2,259
|
||||
.long 0x47e20c21 # amask $2,$1
|
||||
srl \$1,8,\$2
|
||||
sll \$2,2,\$2
|
||||
sll \$0,3,\$0
|
||||
addl \$1,\$0,\$0
|
||||
addl \$2,\$0,\$0
|
||||
ret \$31,(\$26),1
|
||||
.end main
|
||||
cat <<EOF >$dummy.s
|
||||
.data
|
||||
\$Lformat:
|
||||
.byte 37,100,45,37,120,10,0 # "%d-%x\n"
|
||||
|
||||
.text
|
||||
.globl main
|
||||
.align 4
|
||||
.ent main
|
||||
main:
|
||||
.frame \$30,16,\$26,0
|
||||
ldgp \$29,0(\$27)
|
||||
.prologue 1
|
||||
.long 0x47e03d80 # implver \$0
|
||||
lda \$2,-1
|
||||
.long 0x47e20c21 # amask \$2,\$1
|
||||
lda \$16,\$Lformat
|
||||
mov \$0,\$17
|
||||
not \$1,\$18
|
||||
jsr \$26,printf
|
||||
ldgp \$29,0(\$26)
|
||||
mov 0,\$16
|
||||
jsr \$26,exit
|
||||
.end main
|
||||
EOF
|
||||
LIBC=""
|
||||
${CC-cc} dummy.s -o dummy 2>/dev/null
|
||||
$CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null
|
||||
if test "$?" = 0 ; then
|
||||
./dummy
|
||||
case "$?" in
|
||||
7)
|
||||
case `./$dummy` in
|
||||
0-0)
|
||||
UNAME_MACHINE="alpha"
|
||||
;;
|
||||
15)
|
||||
1-0)
|
||||
UNAME_MACHINE="alphaev5"
|
||||
;;
|
||||
14)
|
||||
1-1)
|
||||
UNAME_MACHINE="alphaev56"
|
||||
;;
|
||||
10)
|
||||
1-101)
|
||||
UNAME_MACHINE="alphapca56"
|
||||
;;
|
||||
16)
|
||||
2-303)
|
||||
UNAME_MACHINE="alphaev6"
|
||||
;;
|
||||
esac
|
||||
2-307)
|
||||
UNAME_MACHINE="alphaev67"
|
||||
;;
|
||||
esac
|
||||
|
||||
objdump --private-headers dummy | \
|
||||
objdump --private-headers $dummy | \
|
||||
grep ld.so.1 > /dev/null
|
||||
if test "$?" = 0 ; then
|
||||
LIBC="libc1"
|
||||
fi
|
||||
fi
|
||||
rm -f dummy.s dummy
|
||||
fi
|
||||
rm -f $dummy.s $dummy
|
||||
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
|
||||
elif test "${UNAME_MACHINE}" = "mips" ; then
|
||||
cat >dummy.c <<EOF
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
cat >$dummy.c <<EOF
|
||||
#ifdef __cplusplus
|
||||
#include <stdio.h> /* for printf() prototype */
|
||||
int main (int argc, char *argv[]) {
|
||||
#else
|
||||
int main (argc, argv) int argc; char *argv[]; {
|
||||
#endif
|
||||
#ifdef __MIPSEB__
|
||||
printf ("%s-unknown-linux-gnu\n", argv[1]);
|
||||
#endif
|
||||
@@ -602,8 +803,10 @@ main(argc, argv)
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
elif test "${UNAME_MACHINE}" = "s390"; then
|
||||
echo s390-ibm-linux && exit 0
|
||||
else
|
||||
# Either a pre-BFD a.out linker (linux-gnuoldld)
|
||||
# or one that does not give us useful --help.
|
||||
@@ -622,12 +825,14 @@ EOF
|
||||
;;
|
||||
esac
|
||||
# Determine whether the default compiler is a.out or elf
|
||||
cat >dummy.c <<EOF
|
||||
cat >$dummy.c <<EOF
|
||||
#include <features.h>
|
||||
main(argc, argv)
|
||||
int argc;
|
||||
char *argv[];
|
||||
{
|
||||
#ifdef __cplusplus
|
||||
#include <stdio.h> /* for printf() prototype */
|
||||
int main (int argc, char *argv[]) {
|
||||
#else
|
||||
int main (argc, argv) int argc; char *argv[]; {
|
||||
#endif
|
||||
#ifdef __ELF__
|
||||
# ifdef __GLIBC__
|
||||
# if __GLIBC__ >= 2
|
||||
@@ -644,8 +849,8 @@ main(argc, argv)
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
fi ;;
|
||||
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
|
||||
# are messed up and put the nodename in both sysname and nodename.
|
||||
@@ -661,10 +866,20 @@ EOF
|
||||
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
|
||||
exit 0 ;;
|
||||
i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
|
||||
UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
|
||||
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
|
||||
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
|
||||
echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
|
||||
else
|
||||
echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
|
||||
echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
|
||||
fi
|
||||
exit 0 ;;
|
||||
i?86:*:5:7*)
|
||||
# Fixed at (any) Pentium or better
|
||||
UNAME_MACHINE=i586
|
||||
if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then
|
||||
echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION}
|
||||
else
|
||||
echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
|
||||
fi
|
||||
exit 0 ;;
|
||||
i?86:*:3.2:*)
|
||||
@@ -676,12 +891,20 @@ EOF
|
||||
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
|
||||
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
|
||||
&& UNAME_MACHINE=i586
|
||||
(/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \
|
||||
&& UNAME_MACHINE=i686
|
||||
(/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \
|
||||
&& UNAME_MACHINE=i686
|
||||
echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
|
||||
else
|
||||
echo ${UNAME_MACHINE}-pc-sysv32
|
||||
fi
|
||||
exit 0 ;;
|
||||
i?86:*DOS:*:*)
|
||||
echo ${UNAME_MACHINE}-pc-msdosdjgpp
|
||||
exit 0 ;;
|
||||
pc:*:*:*)
|
||||
# Left here for compatibility:
|
||||
# uname -m prints for DJGPP always 'pc', but it prints nothing about
|
||||
# the processor, so we play safe by assuming i386.
|
||||
echo i386-pc-msdosdjgpp
|
||||
@@ -722,7 +945,7 @@ EOF
|
||||
mc68030:UNIX_System_V:4.*:*)
|
||||
echo m68k-atari-sysv4
|
||||
exit 0 ;;
|
||||
i?86:LynxOS:2.*:*)
|
||||
i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*)
|
||||
echo i386-unknown-lynxos${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
TSUNAMI:LynxOS:2.*:*)
|
||||
@@ -734,6 +957,9 @@ EOF
|
||||
SM[BE]S:UNIX_SV:*:*)
|
||||
echo mips-dde-sysv${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
RM*:ReliantUNIX-*:*:*)
|
||||
echo mips-sni-sysv4
|
||||
exit 0 ;;
|
||||
RM*:SINIX-*:*:*)
|
||||
echo mips-sni-sysv4
|
||||
exit 0 ;;
|
||||
@@ -764,19 +990,61 @@ EOF
|
||||
news*:NEWS-OS:*:6*)
|
||||
echo mips-sony-newsos6
|
||||
exit 0 ;;
|
||||
R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*)
|
||||
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
|
||||
if [ -d /usr/nec ]; then
|
||||
echo mips-nec-sysv${UNAME_RELEASE}
|
||||
else
|
||||
echo mips-unknown-sysv${UNAME_RELEASE}
|
||||
fi
|
||||
exit 0 ;;
|
||||
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
|
||||
echo powerpc-be-beos
|
||||
exit 0 ;;
|
||||
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
|
||||
echo powerpc-apple-beos
|
||||
exit 0 ;;
|
||||
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
|
||||
echo i586-pc-beos
|
||||
exit 0 ;;
|
||||
SX-4:SUPER-UX:*:*)
|
||||
echo sx4-nec-superux${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
SX-5:SUPER-UX:*:*)
|
||||
echo sx5-nec-superux${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
Power*:Rhapsody:*:*)
|
||||
echo powerpc-apple-rhapsody${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:Rhapsody:*:*)
|
||||
echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:Darwin:*:*)
|
||||
echo `uname -p`-apple-darwin${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
*:procnto*:*:* | *:QNX:[0123456789]*:*)
|
||||
if test "${UNAME_MACHINE}" = "x86pc"; then
|
||||
UNAME_MACHINE=pc
|
||||
fi
|
||||
echo `uname -p`-${UNAME_MACHINE}-nto-qnx
|
||||
exit 0 ;;
|
||||
*:QNX:*:4*)
|
||||
echo i386-pc-qnx
|
||||
exit 0 ;;
|
||||
NSR-W:NONSTOP_KERNEL:*:*)
|
||||
echo nsr-tandem-nsk${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
BS2000:POSIX*:*:*)
|
||||
echo bs2000-siemens-sysv
|
||||
exit 0 ;;
|
||||
DS/*:UNIX_System_V:*:*)
|
||||
echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
|
||||
exit 0 ;;
|
||||
esac
|
||||
|
||||
#echo '(No uname command or uname output not recognized.)' 1>&2
|
||||
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
|
||||
|
||||
cat >dummy.c <<EOF
|
||||
cat >$dummy.c <<EOF
|
||||
#ifdef _SEQUENT_
|
||||
# include <sys/types.h>
|
||||
# include <sys/utsname.h>
|
||||
@@ -814,7 +1082,10 @@ main ()
|
||||
#endif
|
||||
int version;
|
||||
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
|
||||
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
|
||||
if (version < 4)
|
||||
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
|
||||
else
|
||||
printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
|
||||
exit (0);
|
||||
#endif
|
||||
|
||||
@@ -874,8 +1145,8 @@ main ()
|
||||
}
|
||||
EOF
|
||||
|
||||
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
|
||||
rm -f dummy.c dummy
|
||||
$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0
|
||||
rm -f $dummy.c $dummy
|
||||
|
||||
# Apollos put the system type in the environment.
|
||||
|
||||
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
#ifndef __config_H /* -*- c++ -*- */
|
||||
#define __config_H
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT)
|
||||
#ident "$Id: config.h.in,v 1.3 2001/10/18 16:16:23 steve Exp $"
|
||||
#endif
|
||||
|
||||
#if defined(__cplusplus)
|
||||
# if !defined(__GNUC__)
|
||||
using namespace std;
|
||||
# elif (__GNUC__ == 3)
|
||||
using namespace std;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
# undef NEED_LU
|
||||
# undef NEED_TU
|
||||
# undef WLU
|
||||
# undef WTU
|
||||
# undef HAVE_TIMES
|
||||
# undef HAVE_IOSFWD
|
||||
# undef HAVE_GETOPT_H
|
||||
# undef HAVE_MALLOC_H
|
||||
# undef HAVE_DLFCN_H
|
||||
# undef HAVE_DL_H
|
||||
# undef HAVE_FCHMOD
|
||||
# undef HAVE_LIBREADLINE
|
||||
# undef HAVE_SYS_WAIT_H
|
||||
|
||||
/*
|
||||
* $Log: config.h.in,v $
|
||||
* Revision 1.3 2001/10/18 16:16:23 steve
|
||||
* Include HAVE_SYS_WAIT in config.h (PR#306)
|
||||
*
|
||||
* Revision 1.2 2001/09/15 18:27:04 steve
|
||||
* Make configure detect malloc.h
|
||||
*
|
||||
* Revision 1.1 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
*/
|
||||
#endif // __config_H
|
||||
Vendored
+236
-146
@@ -1,6 +1,8 @@
|
||||
#! /bin/sh
|
||||
# Configuration validation subroutine script, version 1.1.
|
||||
# Copyright (C) 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000
|
||||
# Free Software Foundation, Inc.
|
||||
#
|
||||
# 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.
|
||||
@@ -25,6 +27,9 @@
|
||||
# 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]>.
|
||||
#
|
||||
# Configuration subroutine to validate and canonicalize a configuration type.
|
||||
# Supply the specified configuration type as an argument.
|
||||
# If it is invalid, we print an error message on stderr and exit with code 1.
|
||||
@@ -68,7 +73,7 @@ esac
|
||||
# Here we must recognize all the valid KERNEL-OS combinations.
|
||||
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
|
||||
case $maybe_os in
|
||||
linux-gnu*)
|
||||
nto-qnx* | linux-gnu*)
|
||||
os=-$maybe_os
|
||||
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
|
||||
;;
|
||||
@@ -98,21 +103,21 @@ case $os in
|
||||
os=
|
||||
basic_machine=$1
|
||||
;;
|
||||
-sim | -cisco | -oki | -wec | -winbond ) # CYGNUS LOCAL
|
||||
-sim | -cisco | -oki | -wec | -winbond)
|
||||
os=
|
||||
basic_machine=$1
|
||||
;;
|
||||
-scout) # CYGNUS LOCAL
|
||||
-scout)
|
||||
;;
|
||||
-wrs) # CYGNUS LOCAL
|
||||
os=vxworks
|
||||
-wrs)
|
||||
os=-vxworks
|
||||
basic_machine=$1
|
||||
;;
|
||||
-hiux*)
|
||||
os=-hiuxwe2
|
||||
;;
|
||||
-sco5)
|
||||
os=sco3.2v5
|
||||
os=-sco3.2v5
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-sco4)
|
||||
@@ -131,6 +136,9 @@ case $os in
|
||||
os=-sco3.2v2
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-udk*)
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
;;
|
||||
-isc)
|
||||
os=-isc2.2
|
||||
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
|
||||
@@ -153,44 +161,40 @@ case $os in
|
||||
-psos*)
|
||||
os=-psos
|
||||
;;
|
||||
-mint | -mint[0-9]*)
|
||||
basic_machine=m68k-atari
|
||||
os=-mint
|
||||
;;
|
||||
esac
|
||||
|
||||
# Decode aliases for certain CPU-COMPANY combinations.
|
||||
case $basic_machine in
|
||||
# Recognize the basic CPU types without company name.
|
||||
# Some are omitted here because they have special meanings below.
|
||||
tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
|
||||
| arme[lb] | pyramid | mn10200 | mn10300 \
|
||||
| tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \
|
||||
| alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
|
||||
| i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
|
||||
| mips64 | mipsel | mips64el | mips64orion | mips64orionel \
|
||||
| mipstx39 | mipstx39el \
|
||||
| sparc | sparclet | sparclite | sparc64 | v850)
|
||||
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)
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
m88110 | m680[01234]0 | m683?2 | m68360 | z8k | v70 | h8500 | w65) # CYGNUS LOCAL
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
mips64vr4300 | mips64vr4300el) # CYGNUS LOCAL jsmith/vr4300
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
mips64vr4100 | mips64vr4100el) # CYGNUS LOCAL jsmith/vr4100
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
mips64vr5000 | mips64vr5000el) # CYGNUS LOCAL ian/vr5000
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
mips16) # CYGNUS LOCAL krk/mips16
|
||||
basic_machine=$basic_machine-unknown
|
||||
;;
|
||||
d10v) # CYGNUS LOCAL meissner/d10v
|
||||
basic_machine=$basic_machine-unknown
|
||||
m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl)
|
||||
;;
|
||||
|
||||
# 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[3456]86)
|
||||
i[34567]86)
|
||||
basic_machine=$basic_machine-pc
|
||||
;;
|
||||
# Object if more than one company name word.
|
||||
@@ -199,30 +203,32 @@ case $basic_machine in
|
||||
exit 1
|
||||
;;
|
||||
# Recognize the basic CPU types with company name.
|
||||
vax-* | tahoe-* | i[3456]86-* | i860-* | m32r-* | m68k-* | m68000-* \
|
||||
# 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-* | i960-* \
|
||||
| xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \
|
||||
| alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
|
||||
| ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
|
||||
| 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-* | mips64-* | mipsel-* \
|
||||
| sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \
|
||||
| mips64el-* | mips64orion-* | mips64orionel-* \
|
||||
| mipstx39-* | mipstx39el-* \
|
||||
| f301-*)
|
||||
;;
|
||||
m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | h8500-* | d10v-*) # CYGNUS LOCAL
|
||||
;;
|
||||
mips64vr4300-* | mips64vr4300el-*) # CYGNUS LOCAL jsmith/vr4300
|
||||
;;
|
||||
mips64vr4100-* | mips64vr4100el-*) # CYGNUS LOCAL jsmith/vr4100
|
||||
;;
|
||||
mips16-*) # CYGNUS LOCAL krk/mips16
|
||||
| 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-*)
|
||||
;;
|
||||
# Recognize the various machine names and aliases which stand
|
||||
# for a CPU type and a company and sometimes even an OS.
|
||||
386bsd) # CYGNUS LOCAL
|
||||
386bsd)
|
||||
basic_machine=i386-unknown
|
||||
os=-bsd
|
||||
;;
|
||||
@@ -232,11 +238,11 @@ case $basic_machine in
|
||||
3b*)
|
||||
basic_machine=we32k-att
|
||||
;;
|
||||
a29khif) # CYGNUS LOCAL
|
||||
a29khif)
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
adobe68k) # CYGNUS LOCAL
|
||||
adobe68k)
|
||||
basic_machine=m68010-adobe
|
||||
os=-scout
|
||||
;;
|
||||
@@ -269,7 +275,7 @@ case $basic_machine in
|
||||
basic_machine=m68k-apollo
|
||||
os=-sysv
|
||||
;;
|
||||
apollo68bsd) # CYGNUS LOCAL
|
||||
apollo68bsd)
|
||||
basic_machine=m68k-apollo
|
||||
os=-bsd
|
||||
;;
|
||||
@@ -349,7 +355,7 @@ case $basic_machine in
|
||||
encore | umax | mmax)
|
||||
basic_machine=ns32k-encore
|
||||
;;
|
||||
es1800 | OSE68k | ose68k | ose | OSE) # CYGNUS LOCAL
|
||||
es1800 | OSE68k | ose68k | ose | OSE)
|
||||
basic_machine=m68k-ericsson
|
||||
os=-ose
|
||||
;;
|
||||
@@ -371,11 +377,11 @@ case $basic_machine in
|
||||
basic_machine=h8300-hitachi
|
||||
os=-hms
|
||||
;;
|
||||
h8300xray) # CYGNUS LOCAL
|
||||
h8300xray)
|
||||
basic_machine=h8300-hitachi
|
||||
os=-xray
|
||||
;;
|
||||
h8500hms) # CYGNUS LOCAL
|
||||
h8500hms)
|
||||
basic_machine=h8500-hitachi
|
||||
os=-hms
|
||||
;;
|
||||
@@ -394,29 +400,30 @@ case $basic_machine in
|
||||
basic_machine=m68k-hp
|
||||
os=-hpux
|
||||
;;
|
||||
w89k-*) # CYGNUS LOCAL
|
||||
basic_machine=hppa1.1-winbond
|
||||
os=-proelf
|
||||
;;
|
||||
op50n-*) # CYGNUS LOCAL
|
||||
basic_machine=hppa1.1-oki
|
||||
os=-proelf
|
||||
;;
|
||||
op60c-*) # CYGNUS LOCAL
|
||||
basic_machine=hppa1.1-oki
|
||||
os=-proelf
|
||||
;;
|
||||
hppro) # CYGNUS LOCAL
|
||||
basic_machine=hppa1.1-hp
|
||||
os=-proelf
|
||||
;;
|
||||
hp3k9[0-9][0-9] | hp9[0-9][0-9])
|
||||
basic_machine=hppa1.0-hp
|
||||
;;
|
||||
hp9k2[0-9][0-9] | hp9k31[0-9])
|
||||
basic_machine=m68000-hp
|
||||
;;
|
||||
hp9k3[2-9][0-9])
|
||||
basic_machine=m68k-hp
|
||||
;;
|
||||
hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7)
|
||||
hp9k6[0-9][0-9] | hp6[0-9][0-9])
|
||||
basic_machine=hppa1.0-hp
|
||||
;;
|
||||
hp9k7[0-79][0-9] | hp7[0-79][0-9])
|
||||
basic_machine=hppa1.1-hp
|
||||
;;
|
||||
hp9k78[0-9] | hp78[0-9])
|
||||
# FIXME: really hppa2.0-hp
|
||||
basic_machine=hppa1.1-hp
|
||||
;;
|
||||
hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
|
||||
# FIXME: really hppa2.0-hp
|
||||
basic_machine=hppa1.1-hp
|
||||
;;
|
||||
hp9k8[0-9][13679] | hp8[0-9][13679])
|
||||
basic_machine=hppa1.1-hp
|
||||
;;
|
||||
hp9k8[0-9][0-9] | hp8[0-9][0-9])
|
||||
@@ -425,43 +432,50 @@ case $basic_machine in
|
||||
hppa-next)
|
||||
os=-nextstep3
|
||||
;;
|
||||
hppaosf) # CYGNUS LOCAL
|
||||
hppaosf)
|
||||
basic_machine=hppa1.1-hp
|
||||
os=-osf
|
||||
;;
|
||||
hppro)
|
||||
basic_machine=hppa1.1-hp
|
||||
os=-proelf
|
||||
;;
|
||||
i370-ibm* | ibm*)
|
||||
basic_machine=i370-ibm
|
||||
os=-mvs
|
||||
;;
|
||||
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
|
||||
i[3456]86v32)
|
||||
i[34567]86v32)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-sysv32
|
||||
;;
|
||||
i[3456]86v4*)
|
||||
i[34567]86v4*)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-sysv4
|
||||
;;
|
||||
i[3456]86v)
|
||||
i[34567]86v)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-sysv
|
||||
;;
|
||||
i[3456]86sol2)
|
||||
i[34567]86sol2)
|
||||
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
|
||||
os=-solaris2
|
||||
;;
|
||||
i386mach) # CYGNUS LOCAL
|
||||
i386mach)
|
||||
basic_machine=i386-mach
|
||||
os=-mach
|
||||
;;
|
||||
i386-vsta | vsta) # CYGNUS LOCAL
|
||||
i386-vsta | vsta)
|
||||
basic_machine=i386-unknown
|
||||
os=-vsta
|
||||
;;
|
||||
i386-go32 | go32) # CYGNUS LOCAL
|
||||
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
|
||||
@@ -490,6 +504,10 @@ case $basic_machine in
|
||||
miniframe)
|
||||
basic_machine=m68000-convergent
|
||||
;;
|
||||
*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
|
||||
basic_machine=m68k-atari
|
||||
os=-mint
|
||||
;;
|
||||
mipsel*-linux*)
|
||||
basic_machine=mipsel-unknown
|
||||
os=-linux-gnu
|
||||
@@ -504,22 +522,34 @@ case $basic_machine in
|
||||
mips3*)
|
||||
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
|
||||
;;
|
||||
monitor) # CYGNUS LOCAL
|
||||
mmix*)
|
||||
basic_machine=mmix-knuth
|
||||
os=-mmixware
|
||||
;;
|
||||
monitor)
|
||||
basic_machine=m68k-rom68k
|
||||
os=-coff
|
||||
;;
|
||||
msdos) # CYGNUS LOCAL
|
||||
basic_machine=i386-unknown
|
||||
msdos)
|
||||
basic_machine=i386-unknown
|
||||
os=-msdos
|
||||
;;
|
||||
mvs)
|
||||
basic_machine=i370-ibm
|
||||
os=-mvs
|
||||
;;
|
||||
ncr3000)
|
||||
basic_machine=i486-ncr
|
||||
os=-sysv4
|
||||
;;
|
||||
netbsd386)
|
||||
basic_machine=i386-unknown # CYGNUS LOCAL
|
||||
basic_machine=i386-unknown
|
||||
os=-netbsd
|
||||
;;
|
||||
netwinder)
|
||||
basic_machine=armv4l-rebel
|
||||
os=-linux
|
||||
;;
|
||||
news | news700 | news800 | news900)
|
||||
basic_machine=m68k-sony
|
||||
os=-newsos
|
||||
@@ -532,7 +562,7 @@ case $basic_machine in
|
||||
basic_machine=mips-sony
|
||||
os=-newsos
|
||||
;;
|
||||
necv70) # CYGNUS LOCAL
|
||||
necv70)
|
||||
basic_machine=v70-nec
|
||||
os=-sysv
|
||||
;;
|
||||
@@ -561,18 +591,25 @@ case $basic_machine in
|
||||
basic_machine=i960-intel
|
||||
os=-nindy
|
||||
;;
|
||||
mon960) # CYGNUS LOCAL
|
||||
mon960)
|
||||
basic_machine=i960-intel
|
||||
os=-mon960
|
||||
;;
|
||||
np1)
|
||||
basic_machine=np1-gould
|
||||
;;
|
||||
OSE68000 | ose68000) # CYGNUS LOCAL
|
||||
nsr-tandem)
|
||||
basic_machine=nsr-tandem
|
||||
;;
|
||||
op50n-* | op60c-*)
|
||||
basic_machine=hppa1.1-oki
|
||||
os=-proelf
|
||||
;;
|
||||
OSE68000 | ose68000)
|
||||
basic_machine=m68000-ericsson
|
||||
os=-ose
|
||||
;;
|
||||
os68k) # CYGNUS LOCAL
|
||||
os68k)
|
||||
basic_machine=m68k-none
|
||||
os=-os68k
|
||||
;;
|
||||
@@ -593,25 +630,23 @@ case $basic_machine in
|
||||
pc532 | pc532-*)
|
||||
basic_machine=ns32k-pc532
|
||||
;;
|
||||
pentium | p5)
|
||||
basic_machine=i586-intel
|
||||
pentium | p5 | k5 | k6 | nexen)
|
||||
basic_machine=i586-pc
|
||||
;;
|
||||
pentiumpro | p6)
|
||||
basic_machine=i686-intel
|
||||
pentiumpro | p6 | 6x86)
|
||||
basic_machine=i686-pc
|
||||
;;
|
||||
pentium-* | p5-*)
|
||||
pentiumii | pentium2)
|
||||
basic_machine=i786-pc
|
||||
;;
|
||||
pentium-* | p5-* | k5-* | k6-* | nexen-*)
|
||||
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pentiumpro-* | p6-*)
|
||||
pentiumpro-* | p6-* | 6x86-*)
|
||||
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
k5)
|
||||
# We don't have specific support for AMD's K5 yet, so just call it a Pentium
|
||||
basic_machine=i586-amd
|
||||
;;
|
||||
nexen)
|
||||
# We don't have specific support for Nexgen yet, so just call it a Pentium
|
||||
basic_machine=i586-nexgen
|
||||
pentiumii-* | pentium2-*)
|
||||
basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
|
||||
;;
|
||||
pn)
|
||||
basic_machine=pn-gould
|
||||
@@ -631,7 +666,7 @@ case $basic_machine in
|
||||
ps2)
|
||||
basic_machine=i386-ibm
|
||||
;;
|
||||
rom68k) # CYGNUS LOCAL
|
||||
rom68k)
|
||||
basic_machine=m68k-rom68k
|
||||
os=-coff
|
||||
;;
|
||||
@@ -641,7 +676,7 @@ case $basic_machine in
|
||||
rtpc | rtpc-*)
|
||||
basic_machine=romp-ibm
|
||||
;;
|
||||
sa29200) # CYGNUS LOCAL
|
||||
sa29200)
|
||||
basic_machine=a29k-amd
|
||||
os=-udi
|
||||
;;
|
||||
@@ -652,7 +687,7 @@ case $basic_machine in
|
||||
basic_machine=sh-hitachi
|
||||
os=-hms
|
||||
;;
|
||||
sparclite-wrs) # CYGNUS LOCAL
|
||||
sparclite-wrs)
|
||||
basic_machine=sparclite-wrs
|
||||
os=-vxworks
|
||||
;;
|
||||
@@ -663,10 +698,10 @@ case $basic_machine in
|
||||
spur)
|
||||
basic_machine=spur-unknown
|
||||
;;
|
||||
st2000) # CYGNUS LOCAL
|
||||
st2000)
|
||||
basic_machine=m68k-tandem
|
||||
;;
|
||||
stratus) # CYGNUS LOCAL
|
||||
stratus)
|
||||
basic_machine=i860-stratus
|
||||
os=-sysv4
|
||||
;;
|
||||
@@ -710,10 +745,18 @@ case $basic_machine in
|
||||
sun386 | sun386i | roadrunner)
|
||||
basic_machine=i386-sun
|
||||
;;
|
||||
sv1)
|
||||
basic_machine=sv1-cray
|
||||
os=-unicos
|
||||
;;
|
||||
symmetry)
|
||||
basic_machine=i386-sequent
|
||||
os=-dynix
|
||||
;;
|
||||
t3e)
|
||||
basic_machine=t3e-cray
|
||||
os=-unicos
|
||||
;;
|
||||
tx39)
|
||||
basic_machine=mipstx39-unknown
|
||||
;;
|
||||
@@ -731,7 +774,7 @@ case $basic_machine in
|
||||
basic_machine=a29k-nyu
|
||||
os=-sym1
|
||||
;;
|
||||
v810 | necv810) # CYGNUS LOCAL
|
||||
v810 | necv810)
|
||||
basic_machine=v810-nec
|
||||
os=-none
|
||||
;;
|
||||
@@ -758,9 +801,13 @@ case $basic_machine in
|
||||
basic_machine=a29k-wrs
|
||||
os=-vxworks
|
||||
;;
|
||||
w65*) # CYGNUS LOCAL
|
||||
basic_machine=w65-wdc
|
||||
os=-none
|
||||
w65*)
|
||||
basic_machine=w65-wdc
|
||||
os=-none
|
||||
;;
|
||||
w89k-*)
|
||||
basic_machine=hppa1.1-winbond
|
||||
os=-proelf
|
||||
;;
|
||||
xmp)
|
||||
basic_machine=xmp-cray
|
||||
@@ -769,7 +816,7 @@ case $basic_machine in
|
||||
xps | xps100)
|
||||
basic_machine=xps100-honeywell
|
||||
;;
|
||||
z8k-*-coff) # CYGNUS LOCAL
|
||||
z8k-*-coff)
|
||||
basic_machine=z8k-unknown
|
||||
os=-sim
|
||||
;;
|
||||
@@ -780,13 +827,13 @@ case $basic_machine in
|
||||
|
||||
# Here we handle the default manufacturer of certain CPU types. It is in
|
||||
# some cases the only manufacturer, in others, it is the most popular.
|
||||
w89k) # CYGNUS LOCAL
|
||||
w89k)
|
||||
basic_machine=hppa1.1-winbond
|
||||
;;
|
||||
op50n) # CYGNUS LOCAL
|
||||
op50n)
|
||||
basic_machine=hppa1.1-oki
|
||||
;;
|
||||
op60c) # CYGNUS LOCAL
|
||||
op60c)
|
||||
basic_machine=hppa1.1-oki
|
||||
;;
|
||||
mips)
|
||||
@@ -811,7 +858,7 @@ case $basic_machine in
|
||||
we32k)
|
||||
basic_machine=we32k-att
|
||||
;;
|
||||
sparc)
|
||||
sparc | sparcv9)
|
||||
basic_machine=sparc-sun
|
||||
;;
|
||||
cydra)
|
||||
@@ -823,12 +870,16 @@ case $basic_machine in
|
||||
orion105)
|
||||
basic_machine=clipper-highlevel
|
||||
;;
|
||||
mac | mpw | mac-mpw) # CYGNUS LOCAL
|
||||
mac | mpw | mac-mpw)
|
||||
basic_machine=m68k-apple
|
||||
;;
|
||||
pmac | pmac-mpw) # CYGNUS LOCAL
|
||||
pmac | pmac-mpw)
|
||||
basic_machine=powerpc-apple
|
||||
;;
|
||||
c4x*)
|
||||
basic_machine=c4x-none
|
||||
os=-coff
|
||||
;;
|
||||
*)
|
||||
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
|
||||
exit 1
|
||||
@@ -861,9 +912,12 @@ case $os in
|
||||
-solaris)
|
||||
os=-solaris2
|
||||
;;
|
||||
-unixware* | svr4*)
|
||||
-svr4*)
|
||||
os=-sysv4
|
||||
;;
|
||||
-unixware*)
|
||||
os=-sysv4.2uw
|
||||
;;
|
||||
-gnu/linux*)
|
||||
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
|
||||
;;
|
||||
@@ -879,22 +933,34 @@ case $os in
|
||||
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
|
||||
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
|
||||
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
|
||||
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
|
||||
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
|
||||
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
|
||||
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
|
||||
| -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -uxpv*)
|
||||
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
|
||||
| -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \
|
||||
| -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \
|
||||
| -openstep* | -oskit*)
|
||||
# Remember, each alternative MUST END IN *, to match a version number.
|
||||
;;
|
||||
# CYGNUS LOCAL
|
||||
-qnx*)
|
||||
case $basic_machine in
|
||||
x86-* | i[34567]86-*)
|
||||
;;
|
||||
*)
|
||||
os=-nto$os
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
-nto*)
|
||||
os=-nto-qnx
|
||||
;;
|
||||
-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
|
||||
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
|
||||
| -macos* | -mpw* | -magic* | -mon960* | -lnews* )
|
||||
| -windows* | -osx | -abug | -netware* | -os9* | -beos* \
|
||||
| -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
|
||||
;;
|
||||
-mac*)
|
||||
os=`echo $os | sed -e 's|mac|macos|'`
|
||||
;;
|
||||
# END CYGNUS LOCAL
|
||||
-linux*)
|
||||
os=`echo $os | sed -e 's|linux|linux-gnu|'`
|
||||
;;
|
||||
@@ -904,6 +970,12 @@ case $os in
|
||||
-sunos6*)
|
||||
os=`echo $os | sed -e 's|sunos6|solaris3|'`
|
||||
;;
|
||||
-opened*)
|
||||
os=-openedition
|
||||
;;
|
||||
-wince*)
|
||||
os=-wince
|
||||
;;
|
||||
-osfrose*)
|
||||
os=-osfrose
|
||||
;;
|
||||
@@ -919,7 +991,7 @@ case $os in
|
||||
-acis*)
|
||||
os=-aos
|
||||
;;
|
||||
-386bsd) # CYGNUS LOCAL
|
||||
-386bsd)
|
||||
os=-bsd
|
||||
;;
|
||||
-ctix* | -uts*)
|
||||
@@ -928,6 +1000,9 @@ case $os in
|
||||
-ns2 )
|
||||
os=-nextstep2
|
||||
;;
|
||||
-nsk)
|
||||
os=-nsk
|
||||
;;
|
||||
# Preserve the version number of sinix5.
|
||||
-sinix5.*)
|
||||
os=`echo $os | sed -e 's|sinix|sysv|'`
|
||||
@@ -953,15 +1028,18 @@ case $os in
|
||||
# This must come after -sysvr4.
|
||||
-sysv*)
|
||||
;;
|
||||
-ose*) # CYGNUS LOCAL
|
||||
-ose*)
|
||||
os=-ose
|
||||
;;
|
||||
-es1800*) # CYGNUS LOCAL
|
||||
-es1800*)
|
||||
os=-ose
|
||||
;;
|
||||
-xenix)
|
||||
os=-xenix
|
||||
;;
|
||||
-*mint | -*MiNT)
|
||||
os=-mint
|
||||
;;
|
||||
-none)
|
||||
;;
|
||||
*)
|
||||
@@ -987,6 +1065,9 @@ case $basic_machine in
|
||||
*-acorn)
|
||||
os=-riscix1.2
|
||||
;;
|
||||
arm*-rebel)
|
||||
os=-linux
|
||||
;;
|
||||
arm*-semi)
|
||||
os=-aout
|
||||
;;
|
||||
@@ -1008,34 +1089,34 @@ case $basic_machine in
|
||||
# default.
|
||||
# os=-sunos4
|
||||
;;
|
||||
m68*-cisco) # CYGNUS LOCAL
|
||||
m68*-cisco)
|
||||
os=-aout
|
||||
;;
|
||||
mips*-cisco) # CYGNUS LOCAL
|
||||
mips*-cisco)
|
||||
os=-elf
|
||||
;;
|
||||
mips*-*)
|
||||
os=-elf
|
||||
;;
|
||||
mips*-*) # CYGNUS LOCAL
|
||||
os=-elf
|
||||
;;
|
||||
*-tti) # must be before sparc entry or we get the wrong os.
|
||||
os=-sysv3
|
||||
;;
|
||||
sparc-* | *-sun)
|
||||
os=-sunos4.1.1
|
||||
;;
|
||||
*-be) # CYGNUS LOCAL
|
||||
*-be)
|
||||
os=-beos
|
||||
;;
|
||||
*-ibm)
|
||||
os=-aix
|
||||
;;
|
||||
*-wec) # CYGNUS LOCAL
|
||||
*-wec)
|
||||
os=-proelf
|
||||
;;
|
||||
*-winbond) # CYGNUS LOCAL
|
||||
*-winbond)
|
||||
os=-proelf
|
||||
;;
|
||||
*-oki) # CYGNUS LOCAL
|
||||
*-oki)
|
||||
os=-proelf
|
||||
;;
|
||||
*-hp)
|
||||
@@ -1101,15 +1182,18 @@ case $basic_machine in
|
||||
f301-fujitsu)
|
||||
os=-uxpv
|
||||
;;
|
||||
*-rom68k) # CYGNUS LOCAL
|
||||
*-rom68k)
|
||||
os=-coff
|
||||
;;
|
||||
*-*bug) # CYGNUS LOCAL
|
||||
*-*bug)
|
||||
os=-coff
|
||||
;;
|
||||
*-apple) # CYGNUS LOCAL
|
||||
*-apple)
|
||||
os=-macos
|
||||
;;
|
||||
*-atari*)
|
||||
os=-mint
|
||||
;;
|
||||
*)
|
||||
os=-none
|
||||
;;
|
||||
@@ -1131,12 +1215,15 @@ case $basic_machine in
|
||||
-aix*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-beos*) # CYGNUS LOCAL
|
||||
-beos*)
|
||||
vendor=be
|
||||
;;
|
||||
-hpux*)
|
||||
vendor=hp
|
||||
;;
|
||||
-mpeix*)
|
||||
vendor=hp
|
||||
;;
|
||||
-hiux*)
|
||||
vendor=hitachi
|
||||
;;
|
||||
@@ -1152,7 +1239,7 @@ case $basic_machine in
|
||||
-genix*)
|
||||
vendor=ns
|
||||
;;
|
||||
-mvs*)
|
||||
-mvs* | -opened*)
|
||||
vendor=ibm
|
||||
;;
|
||||
-ptx*)
|
||||
@@ -1164,12 +1251,15 @@ case $basic_machine in
|
||||
-aux*)
|
||||
vendor=apple
|
||||
;;
|
||||
-hms*) # CYGNUS LOCAL
|
||||
-hms*)
|
||||
vendor=hitachi
|
||||
;;
|
||||
-mpw* | -macos*) # CYGNUS LOCAL
|
||||
-mpw* | -macos*)
|
||||
vendor=apple
|
||||
;;
|
||||
-*mint | -*MiNT)
|
||||
vendor=atari
|
||||
;;
|
||||
esac
|
||||
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
|
||||
;;
|
||||
|
||||
+76
-4
@@ -1,16 +1,41 @@
|
||||
dnl Process this file with autoconf to produce a configure script.
|
||||
AC_INIT(netlist.h)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
|
||||
dnl Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_CXX
|
||||
AC_CHECK_TOOL(STRIP, strip, true)
|
||||
AC_CHECK_PROGS(XGPERF,gperf,none)
|
||||
if test "$XGPERF" = "none"
|
||||
then
|
||||
echo "*** Error: No suitable gperf found. ***"
|
||||
echo " Please install the 'gperf' package."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
AC_LANG_CPLUSPLUS
|
||||
|
||||
AC_CHECK_HEADERS(getopt.h iosfwd)
|
||||
AC_CHECK_HEADERS(getopt.h malloc.h iosfwd sys/wait.h)
|
||||
|
||||
AC_MSG_CHECKING(for sys/times)
|
||||
AC_TRY_LINK(
|
||||
#include <unistd.h>
|
||||
#include <sys/times.h>
|
||||
,{clock_t a = times(0)/sysconf(_SC_CLK_TCK);},
|
||||
do_times=yes
|
||||
AC_DEFINE(HAVE_TIMES,1),
|
||||
do_times=no
|
||||
)
|
||||
AC_MSG_RESULT($do_times)
|
||||
|
||||
AC_CHECK_HEADER(ipal.h, HAVE_IPAL=yes, HAVE_IPAL=)
|
||||
AC_ARG_WITH(ipal,enable PAL target,
|
||||
if test "$with_ipal" = no; then
|
||||
echo Disabling ipal support
|
||||
HAVE_IPAL=
|
||||
fi
|
||||
)
|
||||
AC_SUBST(HAVE_IPAL)
|
||||
|
||||
# --
|
||||
@@ -41,9 +66,20 @@ AC_CANONICAL_HOST
|
||||
|
||||
AC_CYGWIN
|
||||
AC_EXEEXT
|
||||
AC_SUBST(CYGWIN)
|
||||
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){}
|
||||
@@ -54,7 +90,7 @@ CC_LEADING_UNDERSCORE=no
|
||||
CC_TRAILING_UNDERSCORE=no
|
||||
|
||||
output=`nm underscore.o|grep _underscore 2>&1`
|
||||
if test ! -z "$output" -a -z "$CYGWIN" ; then
|
||||
if test ! -z "$output" -a -z "$CYGWIN" -a -z "$MINGW32"; then
|
||||
CC_LEADING_UNDERSCORE=yes
|
||||
AC_DEFINE(NEED_LU)
|
||||
fi
|
||||
@@ -102,6 +138,26 @@ AC_SUBST(PICFLAG)
|
||||
AC_MSG_RESULT($PICFLAG)
|
||||
|
||||
|
||||
# mingw needs to link with libiberty.a, cygwin can tolerate it
|
||||
|
||||
AC_MSG_CHECKING("for extra libs needed")
|
||||
EXTRALIBS=
|
||||
case "${host}" in
|
||||
*-*-cygwin*)
|
||||
EXTRALIBS="-liberty"
|
||||
;;
|
||||
esac
|
||||
AC_SUBST(EXTRALIBS)
|
||||
AC_MSG_RESULT($EXTRALIBS)
|
||||
|
||||
# Darwin requires -no-cpp-precomp
|
||||
case "${host}" in
|
||||
*-*-darwin*)
|
||||
CPPFLAGS="-no-cpp-precomp"
|
||||
CFLAGS="-no-cpp-precomp"
|
||||
;;
|
||||
esac
|
||||
|
||||
# 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
|
||||
@@ -125,22 +181,37 @@ case "${host}" in
|
||||
*-*-hpux*)
|
||||
rdynamic="-E"
|
||||
;;
|
||||
|
||||
*-*-darwin*)
|
||||
rdynamic="-Wl,-all_load"
|
||||
strip_dynamic="-SX"
|
||||
;;
|
||||
|
||||
esac
|
||||
AC_SUBST(rdynamic)
|
||||
AC_MSG_RESULT($rdynamic)
|
||||
AC_SUBST(strip_dynamic)
|
||||
AC_MSG_RESULT($strip_dynamic)
|
||||
|
||||
AC_MSG_CHECKING("for shared library link flag")
|
||||
shared=-shared
|
||||
case "${host}" in
|
||||
|
||||
*-*-cygwin*)
|
||||
shared="-mdll -Wl,--enable-auto-image-base"
|
||||
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)
|
||||
@@ -148,5 +219,6 @@ AC_SUBST(shared)
|
||||
AC_MSG_RESULT($shared)
|
||||
|
||||
|
||||
AC_CONFIG_SUBDIRS(vpip vvp tgt-vvp tgt-fpga)
|
||||
|
||||
AC_OUTPUT(Makefile vpi/Makefile ivlpp/Makefile vvm/Makefile driver/Makefile tgt-null/Makefile tgt-stub/Makefile tgt-verilog/Makefile tgt-pal/Makefile)
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: cprop.cc,v 1.23 2000/12/30 03:11:15 steve Exp $"
|
||||
#ident "$Id: cprop.cc,v 1.30 2001/10/28 01:14:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "functor.h"
|
||||
@@ -38,12 +40,19 @@ struct cprop_functor : public functor_t {
|
||||
|
||||
unsigned count;
|
||||
|
||||
virtual void signal(Design*des, NetNet*obj);
|
||||
virtual void lpm_add_sub(Design*des, NetAddSub*obj);
|
||||
virtual void lpm_compare(Design*des, NetCompare*obj);
|
||||
virtual void lpm_compare_eq_(Design*des, NetCompare*obj);
|
||||
virtual void lpm_ff(Design*des, NetFF*obj);
|
||||
virtual void lpm_logic(Design*des, NetLogic*obj);
|
||||
virtual void lpm_mux(Design*des, NetMux*obj);
|
||||
};
|
||||
|
||||
void cprop_functor::signal(Design*des, NetNet*obj)
|
||||
{
|
||||
}
|
||||
|
||||
void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
|
||||
{
|
||||
// For now, only additions are handled.
|
||||
@@ -59,7 +68,7 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
|
||||
&& (driven_value(obj->pin_DataA(0)) == verinum::V0)) {
|
||||
|
||||
NetAddSub*tmp = 0;
|
||||
tmp = new NetAddSub(obj->name(), obj->width()-1);
|
||||
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
|
||||
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
|
||||
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
|
||||
//connect(tmp->pin_Clock(), obj->pin_Clock());
|
||||
@@ -84,7 +93,7 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
|
||||
&& (driven_value(obj->pin_DataB(0)) == verinum::V0)) {
|
||||
|
||||
NetAddSub*tmp = 0;
|
||||
tmp = new NetAddSub(obj->name(), obj->width()-1);
|
||||
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
|
||||
//connect(tmp->pin_Aclr(), obj->pin_Aclr());
|
||||
//connect(tmp->pin_Add_Sub(), obj->pin_Add_Sub());
|
||||
//connect(tmp->pin_Clock(), obj->pin_Clock());
|
||||
@@ -128,6 +137,111 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
|
||||
|
||||
}
|
||||
|
||||
void cprop_functor::lpm_compare(Design*des, NetCompare*obj)
|
||||
{
|
||||
if (obj->pin_AEB().is_linked()) {
|
||||
assert( ! obj->pin_AGB().is_linked() );
|
||||
assert( ! obj->pin_AGEB().is_linked() );
|
||||
assert( ! obj->pin_ALB().is_linked() );
|
||||
assert( ! obj->pin_ALEB().is_linked() );
|
||||
assert( ! obj->pin_AGB().is_linked() );
|
||||
assert( ! obj->pin_ANEB().is_linked() );
|
||||
lpm_compare_eq_(des, obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
|
||||
{
|
||||
NetScope*scope = obj->scope();
|
||||
|
||||
/* 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)))
|
||||
continue;
|
||||
if (! link_drivers_constant(obj->pin_DataB(idx)))
|
||||
continue;
|
||||
if (driven_value(obj->pin_DataA(idx)) ==
|
||||
driven_value(obj->pin_DataB(idx)))
|
||||
continue;
|
||||
|
||||
NetConst*zero = new NetConst(scope, obj->name(), verinum::V0);
|
||||
connect(zero->pin(0), obj->pin_AEB());
|
||||
delete obj;
|
||||
des->add_node(zero);
|
||||
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))) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
if (! link_drivers_constant(obj->pin_DataB(idx))) {
|
||||
idx += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
obj->pin_DataA(idx).unlink();
|
||||
obj->pin_DataB(idx).unlink();
|
||||
|
||||
top -= 1;
|
||||
for (unsigned jj = idx ; jj < top ; jj += 1) {
|
||||
connect(obj->pin_DataA(jj), obj->pin_DataA(jj+1));
|
||||
connect(obj->pin_DataB(jj), obj->pin_DataB(jj+1));
|
||||
obj->pin_DataA(jj+1).unlink();
|
||||
obj->pin_DataB(jj+1).unlink();
|
||||
}
|
||||
}
|
||||
|
||||
/* If we wound up disconnecting all the inputs, then remove
|
||||
the device and replace it with a constant. */
|
||||
if (top == 0) {
|
||||
NetConst*one = new NetConst(scope, obj->name(), verinum::V1);
|
||||
connect(one->pin(0), obj->pin_AEB());
|
||||
delete obj;
|
||||
des->add_node(one);
|
||||
count += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* If there is only one bit left, then replace the comparator
|
||||
with a simple XOR gate. */
|
||||
if (top == 1) {
|
||||
NetLogic*tmp = new NetLogic(scope, obj->name(), 3,
|
||||
NetLogic::XOR);
|
||||
connect(tmp->pin(0), obj->pin_AEB());
|
||||
connect(tmp->pin(1), obj->pin_DataA(0));
|
||||
connect(tmp->pin(2), obj->pin_DataB(0));
|
||||
delete obj;
|
||||
des->add_node(tmp);
|
||||
count += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (top == obj->width())
|
||||
return;
|
||||
|
||||
NetCompare*tmp = new NetCompare(scope, obj->name(), top);
|
||||
connect(tmp->pin_AEB(), obj->pin_AEB());
|
||||
for (unsigned idx = 0 ; idx < top ; idx += 1) {
|
||||
connect(tmp->pin_DataA(idx), obj->pin_DataA(idx));
|
||||
connect(tmp->pin_DataB(idx), obj->pin_DataB(idx));
|
||||
}
|
||||
delete obj;
|
||||
des->add_node(tmp);
|
||||
count += 1;
|
||||
}
|
||||
|
||||
void cprop_functor::lpm_ff(Design*des, NetFF*obj)
|
||||
{
|
||||
// Look for and count unlinked FF outputs. Note that if the
|
||||
@@ -182,6 +296,8 @@ void cprop_functor::lpm_ff(Design*des, NetFF*obj)
|
||||
|
||||
void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
{
|
||||
NetScope*scope = obj->scope();
|
||||
|
||||
switch (obj->type()) {
|
||||
|
||||
case NetLogic::NAND:
|
||||
@@ -223,10 +339,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetConst*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::AND:
|
||||
tmp = new NetConst(obj->name(), verinum::V0);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V0);
|
||||
break;
|
||||
case NetLogic::NAND:
|
||||
tmp = new NetConst(obj->name(), verinum::V1);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V1);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
@@ -248,10 +364,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetConst*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::AND:
|
||||
tmp = new NetConst(obj->name(), verinum::V1);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V1);
|
||||
break;
|
||||
case NetLogic::NAND:
|
||||
tmp = new NetConst(obj->name(), verinum::V0);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
@@ -271,7 +387,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
gate with a Vx. */
|
||||
if (xs == (top-1)) {
|
||||
NetConst*tmp;
|
||||
tmp = new NetConst(obj->name(), verinum::Vx);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::Vx);
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
tmp->pin(0).drive1(obj->pin(0).drive1());
|
||||
@@ -288,12 +404,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetLogic*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::AND:
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
break;
|
||||
case NetLogic::NAND:
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
break;
|
||||
@@ -314,7 +430,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
new [N]OR gate that has the right number of
|
||||
inputs, connected in the right place. */
|
||||
if (top < obj->pin_count()) {
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
NetLogic*tmp = new NetLogic(scope,
|
||||
obj->name(), top,
|
||||
obj->type());
|
||||
des->add_node(tmp);
|
||||
@@ -369,10 +485,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetConst*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::OR:
|
||||
tmp = new NetConst(obj->name(), verinum::V1);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V1);
|
||||
break;
|
||||
case NetLogic::NOR:
|
||||
tmp = new NetConst(obj->name(), verinum::V0);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V0);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
@@ -394,10 +510,10 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetConst*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::OR:
|
||||
tmp = new NetConst(obj->name(), verinum::V0);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V0);
|
||||
break;
|
||||
case NetLogic::NOR:
|
||||
tmp = new NetConst(obj->name(), verinum::V1);
|
||||
tmp = new NetConst(scope, obj->name(), verinum::V1);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
@@ -419,12 +535,12 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetLogic*tmp;
|
||||
switch (obj->type()) {
|
||||
case NetLogic::OR:
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
break;
|
||||
case NetLogic::NOR:
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
break;
|
||||
@@ -445,7 +561,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
new [N]OR gate that has the right number of
|
||||
inputs, connected in the right place. */
|
||||
if (top < obj->pin_count()) {
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
NetLogic*tmp = new NetLogic(scope,
|
||||
obj->name(), top,
|
||||
obj->type());
|
||||
des->add_node(tmp);
|
||||
@@ -540,7 +656,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
verinum::V out = obj->type()==NetLogic::XNOR
|
||||
? verinum::V1
|
||||
: verinum::V0;
|
||||
NetConst*tmp = new NetConst(obj->name(), out);
|
||||
NetConst*tmp = new NetConst(scope, obj->name(), out);
|
||||
|
||||
des->add_node(tmp);
|
||||
tmp->pin(0).drive0(obj->pin(0).drive0());
|
||||
@@ -568,11 +684,11 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetLogic*tmp;
|
||||
|
||||
if (obj->type() == NetLogic::XOR)
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
else
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
|
||||
@@ -593,11 +709,11 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
NetLogic*tmp;
|
||||
|
||||
if (obj->type() == NetLogic::XOR)
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::BUF);
|
||||
else
|
||||
tmp = new NetLogic(obj->scope(),
|
||||
tmp = new NetLogic(scope,
|
||||
obj->name(), 2,
|
||||
NetLogic::NOT);
|
||||
|
||||
@@ -615,7 +731,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
|
||||
new XOR gate that has the right number of
|
||||
inputs, connected in the right place. */
|
||||
if (top < obj->pin_count()) {
|
||||
NetLogic*tmp = new NetLogic(obj->scope(),
|
||||
NetLogic*tmp = new NetLogic(scope,
|
||||
obj->name(), top,
|
||||
obj->type());
|
||||
des->add_node(tmp);
|
||||
@@ -783,7 +899,22 @@ void cprop_dc_functor::lpm_const(Design*des, NetConst*obj)
|
||||
clnk->cur_link(cur, pin);
|
||||
|
||||
NetNet*tmp = dynamic_cast<NetNet*>(cur);
|
||||
if (tmp && tmp->get_eref() > 0)
|
||||
if (tmp == 0)
|
||||
continue;
|
||||
|
||||
assert(tmp->scope());
|
||||
|
||||
// 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)
|
||||
return;
|
||||
|
||||
// If the net is a port of the root module, then
|
||||
// the constant may be driving something outside
|
||||
// the design, so do not eliminate it.
|
||||
if ((tmp->port_type() != NetNet::NOT_A_PORT)
|
||||
&& (tmp->scope()->parent() == 0))
|
||||
return;
|
||||
|
||||
}
|
||||
@@ -811,6 +942,28 @@ 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.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.28 2001/06/15 04:14:18 steve
|
||||
* Generate vvp code for GT and GE comparisons.
|
||||
*
|
||||
* Revision 1.27 2001/06/07 02:12:43 steve
|
||||
* Support structural addition.
|
||||
*
|
||||
* Revision 1.26 2001/02/18 01:07:32 steve
|
||||
* check signals in the cprop functor.
|
||||
*
|
||||
* Revision 1.25 2001/02/16 03:27:31 steve
|
||||
* Constant propagation for compare ==.
|
||||
*
|
||||
* Revision 1.24 2001/02/10 04:50:54 steve
|
||||
* Catch constants driving root module ports. (PR#130)
|
||||
*
|
||||
* Revision 1.23 2000/12/30 03:11:15 steve
|
||||
* Propagate initial value of constants into wires.
|
||||
*
|
||||
|
||||
+2
-26
@@ -6,41 +6,17 @@ To build using cygwin:
|
||||
Prerequisites:
|
||||
|
||||
o Latest net release (1.1.4) of cygwin (sources.redhat.com/cygwin)
|
||||
o autoconf version 2.13 (or later) from cygutils (cygutils.netpedia.net)
|
||||
o cvs (1.10.8 or later) also from cygutils
|
||||
|
||||
Procedure:
|
||||
o Get the source code - see the main icarus verilog page for how to
|
||||
do this
|
||||
o cd to the verilog directory
|
||||
o autoconf
|
||||
o autoconf.sh
|
||||
o ./configure
|
||||
o make
|
||||
o make install
|
||||
|
||||
That's all that's needed. But there're two common problems during
|
||||
the make phase. All steps are in the verilog directory.
|
||||
|
||||
1.
|
||||
|
||||
If gcc dies saying virtual memory exhausted while compiling parse.c
|
||||
then recompile with -O1 or without -O flag and do these steps to
|
||||
continue
|
||||
o make CXXFLAGS='' parse.o
|
||||
o make
|
||||
|
||||
2.
|
||||
|
||||
If gcc dies in the vpi directory while compiling vpi_systask.c with the
|
||||
error, conflicting types for `_cygwin_dll_entry', then fix the line in
|
||||
/usr/include/cygwin/cygwin_dll.h. Change the line:
|
||||
|
||||
int WINAPI _cygwin_dll_entry (HANDLE h, DWORD reason, void *ptr); \
|
||||
to
|
||||
int WINAPI _cygwin_dll_entry (HINSTANCE h, DWORD reason, void *ptr); \
|
||||
|
||||
Note the change from HANDLE to HINSTANCE. Then do
|
||||
o make
|
||||
That's all that's needed.
|
||||
|
||||
To build your own extensions - just include vpi_user.h and link with
|
||||
a command like this:
|
||||
|
||||
+97
-87
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: design_dump.cc,v 1.110 2001/01/18 03:16:35 steve Exp $"
|
||||
#ident "$Id: design_dump.cc,v 1.120 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
/*
|
||||
* This file contains all the dump methods of the netlist classes.
|
||||
*/
|
||||
@@ -75,6 +77,22 @@ void NetNet::dump_net(ostream&o, unsigned ind) const
|
||||
o << " (local)";
|
||||
if (signed_)
|
||||
o << " signed";
|
||||
switch (port_type_) {
|
||||
case NetNet::NOT_A_PORT:
|
||||
break;
|
||||
case NetNet::PIMPLICIT:
|
||||
o << " implicit-port?";
|
||||
break;
|
||||
case NetNet::PINPUT:
|
||||
o << " input";
|
||||
break;
|
||||
case NetNet::POUTPUT:
|
||||
o << " output";
|
||||
break;
|
||||
case NetNet::PINOUT:
|
||||
o << " inout";
|
||||
break;
|
||||
}
|
||||
o << " (eref=" << get_eref() << ")";
|
||||
if (scope())
|
||||
o << " scope=" << scope()->name();
|
||||
@@ -219,15 +237,6 @@ void NetMux::dump_node(ostream&o, unsigned ind) const
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetAssign_::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "Procedural assign (NetAssign_): " << name();
|
||||
if (bmux())
|
||||
o << "[" << *bmux() << "]";
|
||||
o << endl;
|
||||
dump_node_pins(o, ind+4);
|
||||
}
|
||||
|
||||
void NetBUFZ::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "NetBUFZ: " << name()
|
||||
@@ -298,6 +307,12 @@ void NetLogic::dump_node(ostream&o, unsigned ind) const
|
||||
case OR:
|
||||
o << "or";
|
||||
break;
|
||||
case PULLDOWN:
|
||||
o << "pulldown";
|
||||
break;
|
||||
case PULLUP:
|
||||
o << "pullup";
|
||||
break;
|
||||
case RNMOS:
|
||||
o << "rnmos";
|
||||
break;
|
||||
@@ -344,6 +359,7 @@ void NetTaskDef::dump(ostream&o, unsigned ind) const
|
||||
|
||||
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1) {
|
||||
o << setw(ind+4) << "";
|
||||
assert(ports_[idx]);
|
||||
switch (ports_[idx]->port_type()) {
|
||||
case NetNet::PINPUT:
|
||||
o << "input ";
|
||||
@@ -366,77 +382,12 @@ void NetTaskDef::dump(ostream&o, unsigned ind) const
|
||||
o << setw(ind) << "" << "endtask" << endl;
|
||||
}
|
||||
|
||||
void NetUDP::dump_sequ_(ostream&o, unsigned ind) const
|
||||
{
|
||||
string tmp = "";
|
||||
for (unsigned idx = 0 ; idx < ind ; idx += 1)
|
||||
tmp += " ";
|
||||
|
||||
o << tmp << "Sequential UDP" << " #(" << rise_time() <<
|
||||
"," << fall_time() << "," << decay_time() << ") " << name() <<
|
||||
endl;
|
||||
|
||||
for (FSM_::const_iterator ent = fsm_.begin()
|
||||
; ent != fsm_.end() ; ent++) {
|
||||
o << setw(ind+6) << "" << (*ent).first << " -->";
|
||||
|
||||
state_t_*st = (*ent).second;
|
||||
assert((*ent).first[0] == st->out);
|
||||
for (unsigned idx = 1 ; idx < pin_count() ; idx += 1) {
|
||||
string tmp = (*ent).first;
|
||||
if (st->pins[idx].zer) {
|
||||
tmp[0] = st->pins[idx].zer->out;
|
||||
tmp[idx] = '0';
|
||||
o << " " << tmp;
|
||||
}
|
||||
|
||||
if (st->pins[idx].one) {
|
||||
tmp[0] = st->pins[idx].one->out;
|
||||
tmp[idx] = '1';
|
||||
o << " " << tmp;
|
||||
}
|
||||
|
||||
if (st->pins[idx].xxx) {
|
||||
tmp[0] = st->pins[idx].xxx->out;
|
||||
tmp[idx] = 'x';
|
||||
o << " " << tmp;
|
||||
}
|
||||
}
|
||||
|
||||
o << endl;
|
||||
}
|
||||
|
||||
o << setw(ind+6) << "" << "initial value == " << init_ << endl;
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
|
||||
void NetUDP::dump_comb_(ostream&o, unsigned ind) const
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void NetUDP::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
if (is_sequential())
|
||||
dump_sequ_(o, ind);
|
||||
else
|
||||
dump_comb_(o, ind);
|
||||
}
|
||||
|
||||
void NetUDP_COMB::dump_node(ostream&o, unsigned ind) const
|
||||
{
|
||||
o << setw(ind) << "" << "Combinational primitive: ";
|
||||
o << setw(ind) << "" << "UDP (" << udp_name() << "): ";
|
||||
o << " #(" << rise_time() << "," << fall_time() << "," << decay_time() <<
|
||||
") " << name() << endl;
|
||||
|
||||
for (map<string,char>::const_iterator ent = cm_.begin()
|
||||
; ent != cm_.end() ; ent++) {
|
||||
o << setw(ind+6) << "" << (*ent).first << " --> " <<
|
||||
(*ent).second << endl;
|
||||
}
|
||||
|
||||
dump_node_pins(o, ind+4);
|
||||
dump_obj_attr(o, ind+4);
|
||||
}
|
||||
@@ -457,16 +408,29 @@ void NetProcTop::dump(ostream&o, unsigned ind) const
|
||||
statement_->dump(o, ind+2);
|
||||
}
|
||||
|
||||
void NetAssign_::dump_lval(ostream&o) const
|
||||
{
|
||||
if (sig_) {
|
||||
o << sig_->name();
|
||||
if (bmux_) {
|
||||
o << "[" << *bmux_ << "]";
|
||||
|
||||
} else {
|
||||
o << "[" << (loff_+lwid_-1) << ":" << loff_ << "]";
|
||||
}
|
||||
} else {
|
||||
o << "";
|
||||
}
|
||||
}
|
||||
|
||||
void NetAssignBase::dump_lval(ostream&o) const
|
||||
{
|
||||
o << "" << "{" << lval_->name();
|
||||
if (lval_->bmux())
|
||||
o << "[" << *lval_->bmux() << "]";
|
||||
o << "{";
|
||||
lval_->dump_lval(o);
|
||||
|
||||
for (NetAssign_*cur = lval_->more ; cur ; cur = cur->more) {
|
||||
o << ", " << cur->name();
|
||||
if (cur->bmux())
|
||||
o << "[" << *cur->bmux() << "]";
|
||||
o << ", ";
|
||||
cur->dump_lval(o);
|
||||
}
|
||||
|
||||
o << "}";
|
||||
@@ -479,8 +443,10 @@ void NetAssign::dump(ostream&o, unsigned ind) const
|
||||
dump_lval(o);
|
||||
|
||||
o << " = ";
|
||||
#if 0
|
||||
if (l_val(0)->rise_time())
|
||||
o << "#" << l_val(0)->rise_time() << " ";
|
||||
#endif
|
||||
o << *rval() << ";" << endl;
|
||||
}
|
||||
|
||||
@@ -490,8 +456,10 @@ void NetAssignNB::dump(ostream&o, unsigned ind) const
|
||||
dump_lval(o);
|
||||
|
||||
o << " <= ";
|
||||
#if 0
|
||||
if (l_val(0)->rise_time())
|
||||
o << "#" << l_val(0)->rise_time() << " ";
|
||||
#endif
|
||||
o << *rval() << ";" << endl;
|
||||
|
||||
}
|
||||
@@ -732,7 +700,7 @@ void NetScope::dump(ostream&o) const
|
||||
|
||||
/* Dump the saved defparam assignments here. */
|
||||
{
|
||||
map<string,NetExpr*>::const_iterator pp;
|
||||
map<hname_t,NetExpr*>::const_iterator pp;
|
||||
for (pp = defparams.begin()
|
||||
; pp != defparams.end() ; pp ++ ) {
|
||||
o << " defparam " << (*pp).first << " = " <<
|
||||
@@ -818,7 +786,7 @@ void NetProc::dump(ostream&o, unsigned ind) const
|
||||
/* Dump an expression that noone wrote a dump method for. */
|
||||
void NetExpr::dump(ostream&o) const
|
||||
{
|
||||
o << "(?)";
|
||||
o << "(?" << typeid(*this).name() << "?)";
|
||||
}
|
||||
|
||||
void NetEBinary::dump(ostream&o) const
|
||||
@@ -916,10 +884,10 @@ void NetESFunc::dump(ostream&o) const
|
||||
|
||||
void NetESignal::dump(ostream&o) const
|
||||
{
|
||||
o << name();
|
||||
o << name() << "[" << msi_<<":"<<lsi_ << "]";
|
||||
}
|
||||
|
||||
void NetESubSignal::dump(ostream&o) const
|
||||
void NetEBitSel::dump(ostream&o) const
|
||||
{
|
||||
sig_->dump(o);
|
||||
o << "[";
|
||||
@@ -977,7 +945,9 @@ void Design::dump(ostream&o) const
|
||||
{
|
||||
o << "DESIGN TIME PRECISION: 10e" << get_precision() << endl;
|
||||
o << "SCOPES:" << endl;
|
||||
root_scope_->dump(o);
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->dump(o);
|
||||
|
||||
o << "ELABORATED NODES:" << endl;
|
||||
|
||||
@@ -1000,6 +970,46 @@ void Design::dump(ostream&o) const
|
||||
|
||||
/*
|
||||
* $Log: design_dump.cc,v $
|
||||
* Revision 1.120 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.119 2001/11/19 01:46:38 steve
|
||||
* Print typename is fallback expression node dump.
|
||||
*
|
||||
* Revision 1.118 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
* Revision 1.117 2001/08/25 23:50:02 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.116 2001/07/27 04:51:44 steve
|
||||
* Handle part select expressions as variants of
|
||||
* NetESignal/IVL_EX_SIGNAL objects, instead of
|
||||
* creating new and useless temporary signals.
|
||||
*
|
||||
* Revision 1.115 2001/07/27 02:41:55 steve
|
||||
* Fix binding of dangling function ports. do not elide them.
|
||||
*
|
||||
* Revision 1.114 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.113 2001/04/29 20:19:10 steve
|
||||
* Add pullup and pulldown devices.
|
||||
*
|
||||
* Revision 1.112 2001/04/22 23:09:46 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.111 2001/02/17 05:13:36 steve
|
||||
* Check that the port really exists here.
|
||||
*
|
||||
* Revision 1.110 2001/01/18 03:16:35 steve
|
||||
* NetMux needs a scope. (PR#115)
|
||||
*
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*
|
||||
* $Id: dosify.c,v 1.1 2001/08/03 17:06:47 steve Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a simple program to make a dosified copy of the
|
||||
* original. That is, it converts unix style line ends to DOS
|
||||
* style. This is useful for installing text files.
|
||||
*
|
||||
* The exact substitution is to replace \n with \r\n. If the line
|
||||
* already ends with \r\n then it is not changed to \r\r\n.
|
||||
*/
|
||||
|
||||
# include <stdio.h>
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
FILE*ifile;
|
||||
FILE*ofile;
|
||||
int ch, pr;
|
||||
|
||||
if (argc != 3) {
|
||||
fprintf(stderr, "Usage: %s <input> <output>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
ifile = fopen(argv[1], "rb");
|
||||
if (ifile == 0) {
|
||||
fprintf(stderr, "Unable to open %s for input.\n", argv[1]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
ofile = fopen(argv[2], "wb");
|
||||
if (ofile == 0) {
|
||||
fprintf(stderr, "Unable to open %s for output.\n", argv[2]);
|
||||
return 2;
|
||||
}
|
||||
|
||||
pr = 0;
|
||||
while ((ch = fgetc(ifile)) != EOF) {
|
||||
|
||||
if ((ch == '\n') && (pr != '\r'))
|
||||
fputc('\r', ofile);
|
||||
|
||||
fputc(ch, ofile);
|
||||
pr = ch;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: dosify.c,v $
|
||||
* Revision 1.1 2001/08/03 17:06:47 steve
|
||||
* Add install of examples for Windows.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
a.out
|
||||
Makefile
|
||||
parse.c
|
||||
parse.h
|
||||
parse.output
|
||||
lexor.c
|
||||
cfparse.c
|
||||
cfparse.h
|
||||
cfparse.output
|
||||
cflexor.c
|
||||
foo.*
|
||||
iverilog
|
||||
|
||||
+32
-8
@@ -18,7 +18,7 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.3 2001/01/09 03:11:27 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.10 2001/11/17 17:57:58 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
@@ -46,35 +46,56 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @CFLAGS@ -I.
|
||||
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/..
|
||||
CXXFLAGS = @CXXFLAGS@ -I. -I$(srcdir)/..
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
all: iverilog@EXEEXT@
|
||||
|
||||
clean:
|
||||
rm -f *.o lexor.c parse.c parse.h parse.output
|
||||
rm -f cflexor.c cfparse.c cfparse.h cfparse.output
|
||||
|
||||
O = main.o build_string.o lexor.o parse.o
|
||||
O = main.o build_string.o lexor.o parse.o cflexor.o cfparse.o
|
||||
|
||||
iverilog@EXEEXT@: $O
|
||||
$(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@
|
||||
$(CC) $(LDFLAGS) $O -o iverilog@EXEEXT@ @EXTRALIBS@
|
||||
|
||||
lexor.c: lexor.lex
|
||||
flex -s -olexor.c $(srcdir)/lexor.lex
|
||||
|
||||
parse.h parse.c: parse.y
|
||||
bison --verbose -t -d $(srcdir)/parse.y -o parse.c
|
||||
bison --verbose -t -d -o parse.c $(srcdir)/parse.y
|
||||
|
||||
cflexor.c: cflexor.lex
|
||||
flex -s -Pcf -ocflexor.c $(srcdir)/cflexor.lex
|
||||
|
||||
cfparse.h cfparse.c: cfparse.y
|
||||
bison --verbose -t -d -o cfparse.c --name-prefix=cf $(srcdir)/cfparse.y
|
||||
|
||||
|
||||
main.o: main.c globals.h
|
||||
$(CC) $(CPPFLAGS) -c -DCXX='"@CXX@"' -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DRDYNAMIC=\"$(rdynamic)\" -DDLLIB='"@DLLIB@"' $(srcdir)/main.c
|
||||
$(CC) $(CFLAGS) -c -DCXX='"@CXX@"' -DIVL_ROOT='"@libdir@/ivl"' -DIVL_INC='"@includedir@"' -DIVL_LIB='"@libdir@"' -DRDYNAMIC=\"$(rdynamic)\" -DDLLIB='"@DLLIB@"' -DEXEEXT='"@EXEEXT@"' $(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
|
||||
|
||||
install: all installdirs $(bindir)/iverilog@EXEEXT@ $(mandir)/man1/iverilog.1
|
||||
ifeq (@WIN32@,yes)
|
||||
INSTALL_DOC = $(prefix)/iverilog.pdf
|
||||
INSTALL_DOCDIR =
|
||||
all: iverilog.pdf
|
||||
else
|
||||
INSTALL_DOC = $(mandir)/man1/iverilog.1
|
||||
INSTALL_DOCDIR = $(mandir)/man1
|
||||
endif
|
||||
|
||||
install: all installdirs $(bindir)/iverilog@EXEEXT@ $(INSTALL_DOC)
|
||||
|
||||
$(bindir)/iverilog@EXEEXT@: ./iverilog@EXEEXT@
|
||||
$(INSTALL_PROGRAM) ./iverilog@EXEEXT@ $(bindir)/iverilog@EXEEXT@
|
||||
@@ -82,8 +103,11 @@ $(bindir)/iverilog@EXEEXT@: ./iverilog@EXEEXT@
|
||||
$(mandir)/man1/iverilog.1: $(srcdir)/iverilog.man
|
||||
$(INSTALL_DATA) $(srcdir)/iverilog.man $(mandir)/man1/iverilog.1
|
||||
|
||||
$(prefix)/iverilog.pdf: iverilog.pdf
|
||||
$(INSTALL_DATA) iverilog.pdf $(prefix)/iverilog.pdf
|
||||
|
||||
installdirs: ../mkinstalldirs
|
||||
$(srcdir)/../mkinstalldirs $(bindir) $(mandir)/man1
|
||||
$(srcdir)/../mkinstalldirs $(bindir) $(INSTALL_DOCDIR)
|
||||
|
||||
uninstall:
|
||||
rm -f $(bindir)/iverilog@EXEEXT@
|
||||
|
||||
+33
-1
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: build_string.c,v 1.2 2000/10/28 03:45:47 steve Exp $"
|
||||
#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>
|
||||
@@ -51,6 +53,7 @@ int build_string(char*output, size_t olen, const char*pattern)
|
||||
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,
|
||||
@@ -126,6 +129,22 @@ int build_string(char*output, size_t olen, const char*pattern)
|
||||
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;
|
||||
|
||||
@@ -141,6 +160,19 @@ int build_string(char*output, size_t olen, const char*pattern)
|
||||
|
||||
/*
|
||||
* $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.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,133 @@
|
||||
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: cflexor.lex,v 1.5 2001/12/08 04:13:07 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "cfparse.h"
|
||||
# include "cfparse_misc.h"
|
||||
# include "globals.h"
|
||||
# include <string.h>
|
||||
|
||||
/*
|
||||
* Lexical location information is passed in the yylloc variable to th
|
||||
* parser. The file names, strings, are kept in a list so that I can
|
||||
* re-use them. The set_file_name function will return a pointer to
|
||||
* the name as it exists in the list (and delete the passed string.)
|
||||
* If the name is new, it will be added to the list.
|
||||
*/
|
||||
YYLTYPE yylloc;
|
||||
|
||||
static int comment_enter;
|
||||
|
||||
%}
|
||||
|
||||
%x CCOMMENT
|
||||
%x LCOMMENT
|
||||
%x PLUS_ARGS
|
||||
|
||||
%%
|
||||
|
||||
/* Accept C++ style comments. */
|
||||
"//".* { comment_enter = YY_START; BEGIN(LCOMMENT); }
|
||||
<LCOMMENT>. { yymore(); }
|
||||
<LCOMMENT>\n { yylloc.first_line += 1; BEGIN(comment_enter); }
|
||||
|
||||
/* Accept C style comments. */
|
||||
"/*" { comment_enter = YY_START; BEGIN(CCOMMENT); }
|
||||
<CCOMMENT>. { yymore(); }
|
||||
<CCOMMENT>\n { yylloc.first_line += 1; yymore(); }
|
||||
<CCOMMENT>"*/" { BEGIN(comment_enter); }
|
||||
|
||||
/* Accept shell type comments. */
|
||||
^"#".* { ; }
|
||||
|
||||
/* Skip white space. */
|
||||
[ \t\f\r] { ; }
|
||||
/* Skip line ends, but also count the line. */
|
||||
\n { yylloc.first_line += 1; }
|
||||
|
||||
|
||||
"+define+" { BEGIN(PLUS_ARGS); return TOK_DEFINE; }
|
||||
|
||||
"+incdir+" { BEGIN(PLUS_ARGS); return TOK_INCDIR; }
|
||||
|
||||
"+libext+" { BEGIN(PLUS_ARGS); return TOK_LIBEXT; }
|
||||
|
||||
|
||||
/* If it is not any known plus-flag, return the generic form. */
|
||||
"+"[^\n \t\b\f\r+]* {
|
||||
cflval.text = strdup(yytext);
|
||||
BEGIN(PLUS_ARGS);
|
||||
return TOK_PLUSWORD; }
|
||||
|
||||
/* Once in PLUS_ARGS mode, words are delimited by +
|
||||
characters. White space and line end terminate PLUS_ARGS mode,
|
||||
but + terminates only the word. */
|
||||
<PLUS_ARGS>[^\n \t\b\f\r+]* {
|
||||
cflval.text = strdup(yytext);
|
||||
return TOK_PLUSARG; }
|
||||
|
||||
/* Within plusargs, this is a delimiter. */
|
||||
<PLUS_ARGS>"+" { }
|
||||
|
||||
/* White space end plus_args mode. */
|
||||
<PLUS_ARGS>[ \t\b\f\r] { BEGIN(0); }
|
||||
|
||||
<PLUS_ARGS>\n {
|
||||
yylloc.first_line += 1;
|
||||
BEGIN(0); }
|
||||
|
||||
/* Notice the -a flag. */
|
||||
"-a" { return TOK_Da; }
|
||||
|
||||
/* Notice the -v flag. */
|
||||
"-v" { return TOK_Dv; }
|
||||
|
||||
/* Notice the -y flag. */
|
||||
"-y" { return TOK_Dy; }
|
||||
|
||||
/* This rule matches paths and strings that may be file names. This
|
||||
is a little bit tricky, as we don't want to mistake a comment for
|
||||
a string word. */
|
||||
"/"[^\*\/].* { cflval.text = strdup(yytext);
|
||||
return TOK_STRING; }
|
||||
|
||||
[^/\n \t\b\r+-].* { cflval.text = strdup(yytext);
|
||||
return TOK_STRING; }
|
||||
|
||||
/* Fallback match. */
|
||||
. { return yytext[0]; }
|
||||
|
||||
%%
|
||||
|
||||
int yywrap()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
void cfreset(FILE*fd, const char*path)
|
||||
{
|
||||
yyin = fd;
|
||||
yyrestart(fd);
|
||||
yylloc.first_line = 1;
|
||||
yylloc.text = (char*)path;
|
||||
}
|
||||
@@ -0,0 +1,187 @@
|
||||
%{
|
||||
/*
|
||||
* Copyright (c) 20001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
* General Public License as published by the Free Software
|
||||
* Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: cfparse.y,v 1.5 2001/12/08 04:13:07 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
# include "globals.h"
|
||||
# include <ctype.h>
|
||||
|
||||
/*
|
||||
* This flag is set to 0, 1 or 2 if file names are to be translated to
|
||||
* uppercase(1) or lowercase(2).
|
||||
*/
|
||||
static int setcase_filename_flag = 0;
|
||||
static void translate_file_name(char*text)
|
||||
{
|
||||
switch (setcase_filename_flag) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
while (*text) {
|
||||
*text = toupper(*text);
|
||||
text += 1;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
while (*text) {
|
||||
*text = tolower(*text);
|
||||
text += 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
char*text;
|
||||
};
|
||||
|
||||
%token TOK_Da TOK_Dv TOK_Dy
|
||||
%token TOK_DEFINE TOK_INCDIR TOK_LIBEXT
|
||||
%token <text> TOK_PLUSARG TOK_PLUSWORD TOK_STRING
|
||||
|
||||
%%
|
||||
|
||||
start
|
||||
:
|
||||
| item_list
|
||||
;
|
||||
|
||||
item_list
|
||||
: item_list item
|
||||
| item
|
||||
;
|
||||
|
||||
item
|
||||
/* Absent any other matching, a token string is taken to be the name
|
||||
of a source file. Add the file to the file list. */
|
||||
|
||||
: TOK_STRING
|
||||
{ translate_file_name($1);
|
||||
process_file_name($1);
|
||||
free($1);
|
||||
}
|
||||
|
||||
/* The -a flag is completely ignored. */
|
||||
|
||||
| TOK_Da { }
|
||||
|
||||
/* The -v <libfile> flag is ignored, and the <libfile> is processed
|
||||
as an ordinary source file. */
|
||||
|
||||
| TOK_Dv TOK_STRING
|
||||
{ translate_file_name($2);
|
||||
process_file_name($2);
|
||||
fprintf(stderr, "%s:%u: Ignoring -v in front of %s\n",
|
||||
@1.text, @1.first_line, $2);
|
||||
free($2);
|
||||
}
|
||||
|
||||
/* This rule matches "-y <path>" sequences. This does the same thing
|
||||
as -y on the command line, so add the path to the library
|
||||
directory list. */
|
||||
|
||||
| TOK_Dy TOK_STRING
|
||||
{ process_library_switch($2);
|
||||
free($2);
|
||||
}
|
||||
|
||||
| TOK_DEFINE TOK_PLUSARG
|
||||
{ process_define($2);
|
||||
free($2);
|
||||
}
|
||||
|
||||
/* The +incdir token introduces a list of +<path> arguments that are
|
||||
the include directories to search. */
|
||||
|
||||
| TOK_INCDIR inc_args
|
||||
|
||||
/* The +libext token introduces a list of +<ext> arguments that
|
||||
become individual -Y flags to ivl. */
|
||||
|
||||
| TOK_LIBEXT libext_args
|
||||
|
||||
/* The +<word> tokens that are not otherwise matched, are
|
||||
ignored. The skip_args rule arranges for all the argument words
|
||||
to be consumed. */
|
||||
|
||||
| TOK_PLUSWORD skip_args
|
||||
{ fprintf(stderr, "%s:%u: Ignoring %s\n",
|
||||
@1.text, @1.first_line, $1);
|
||||
free($1);
|
||||
}
|
||||
| TOK_PLUSWORD
|
||||
{ if (strcmp($1, "+toupper-filenames") == 0) {
|
||||
setcase_filename_flag = 1;
|
||||
} else if (strcmp($1, "+tolower-filenames") == 0) {
|
||||
setcase_filename_flag = 2;
|
||||
} else {
|
||||
fprintf(stderr, "%s:%u: Ignoring %s\n",
|
||||
@1.text, @1.first_line, $1);
|
||||
}
|
||||
free($1);
|
||||
}
|
||||
;
|
||||
|
||||
/* inc_args are +incdir+ arguments in order. */
|
||||
inc_args
|
||||
: inc_args inc_arg
|
||||
| inc_arg
|
||||
;
|
||||
|
||||
inc_arg : TOK_PLUSARG
|
||||
{ process_include_dir($1);
|
||||
free($1);
|
||||
}
|
||||
;
|
||||
|
||||
/* inc_args are +incdir+ arguments in order. */
|
||||
libext_args
|
||||
: libext_args libext_arg
|
||||
| libext_arg
|
||||
;
|
||||
|
||||
libext_arg : TOK_PLUSARG
|
||||
{ process_library2_switch($1);
|
||||
free($1);
|
||||
}
|
||||
;
|
||||
|
||||
/* skip_args are arguments to a +word flag that is not otherwise
|
||||
parsed. This rule matches them and releases the strings, so that
|
||||
they can be safely ignored. */
|
||||
skip_args
|
||||
: skip_args skip_arg
|
||||
| skip_arg
|
||||
;
|
||||
|
||||
skip_arg : TOK_PLUSARG
|
||||
{ free($1);
|
||||
}
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
int yyerror(const char*msg)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef __cfparse_misc_H
|
||||
#define __cfparse_misc_H
|
||||
/*
|
||||
* Copyright (c) 2001 Picture Elements, Inc.
|
||||
* 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)
|
||||
#ident "$Id: cfparse_misc.h,v 1.2 2001/11/12 18:47:32 steve Exp $"
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* $Log: cfparse_misc.h,v $
|
||||
* Revision 1.2 2001/11/12 18:47:32 steve
|
||||
* Support +incdir in command files, and ignore other
|
||||
* +args flags. Also ignore -a and -v flags.
|
||||
*
|
||||
* Revision 1.1 2001/11/12 01:26:36 steve
|
||||
* More sophisticated command file parser.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+46
-3
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: globals.h,v 1.3 2000/11/09 21:58:00 steve Exp $"
|
||||
#ident "$Id: globals.h,v 1.10 2001/11/16 05:07:19 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stddef.h>
|
||||
@@ -42,8 +42,8 @@ extern const char*npath;
|
||||
/* This is the name of the output file that the user selected. */
|
||||
extern const char*opath;
|
||||
|
||||
/* This pointer is set if there was a -s<value> parameter. */
|
||||
extern const char*start;
|
||||
/* This pointer is set if there were -s<value> parameters. */
|
||||
extern char*start;
|
||||
|
||||
/* This flag is true if the -S flag was used on the command line. */
|
||||
extern int synth_flag;
|
||||
@@ -51,14 +51,57 @@ extern int synth_flag;
|
||||
/* This is the name of the selected target. */
|
||||
extern const char*targ;
|
||||
|
||||
/* 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_library2_switch(const char*name);
|
||||
|
||||
/* Add a new include file search directory */
|
||||
extern void process_include_dir(const char*name);
|
||||
|
||||
/* Add a new -D define. */
|
||||
extern void process_define(const char*name);
|
||||
|
||||
/* -v */
|
||||
extern int verbose_flag;
|
||||
|
||||
extern char warning_flags[];
|
||||
|
||||
/* -y and -Y flags from the command line. */
|
||||
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.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.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.7 2001/11/12 01:26:36 steve
|
||||
* More sophisticated command file parser.
|
||||
*
|
||||
* Revision 1.6 2001/10/23 00:37:30 steve
|
||||
* The -s flag can now be repeated on the iverilog command.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
|
||||
+108
-23
@@ -1,18 +1,21 @@
|
||||
.TH iverilog 1 "$Date: 2001/01/20 19:02:05 $" Version "$Date: 2001/01/20 19:02:05 $"
|
||||
.TH iverilog 1 "$Date: 2001/12/08 04:13:07 $" Version "$Date: 2001/12/08 04:13:07 $"
|
||||
.SH NAME
|
||||
iverilog - Icarus Verilog compiler
|
||||
|
||||
.SH SYNOPSIS
|
||||
.B iverilog
|
||||
[-ESv] [-Cpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value] [-Iincludepath] [-mmodule] [-Nfile] [-ooutputfilename] [-stopmodule] [-ttype] [-Tmin/typ/max] [-Wclass] sourcefile
|
||||
[-ESv] [-Cpath] [-ccmdfile] [-Dmacro[=defn]] [-pflag=value]
|
||||
[-Iincludedir] [-mmodule] [-Nfile] [-ooutputfilename] [-stopmodule]
|
||||
[-ttype] [-Tmin/typ/max] [-Wclass] [-ypath] sourcefile
|
||||
|
||||
.SH DESCRIPTION
|
||||
.PP
|
||||
\fIiverilog\fP is a compiler that translates Verilog source code into
|
||||
executable programs for simulation, or other netlist formats for
|
||||
further processing. The currenty supported targets are \fIvvm\fP (for
|
||||
executable simulation) and \fIxnf\fP for synthesis. Other target
|
||||
types are added as code generators are implemented.
|
||||
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.
|
||||
|
||||
.SH OPTIONS
|
||||
.l
|
||||
@@ -20,7 +23,7 @@ types are added as code generators are implemented.
|
||||
.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
|
||||
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.
|
||||
@@ -29,9 +32,7 @@ given is used to locate \fIivlpp\fP, \fIivl\fP and the VPI modules.
|
||||
This flag specifies an input file that contains a list of Verilog
|
||||
source files. This is similar to the \fIcommand file\fP of other
|
||||
Verilog simulators, in that it is a file that contains the file names
|
||||
instead of taking them on the command line. The command file may
|
||||
contain C-style comments (/*-*/) or shell-style comments (# to the end
|
||||
of the line.)
|
||||
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
|
||||
@@ -53,10 +54,10 @@ Defines macro \fImacro\fP as \fIdefn\fP.
|
||||
Preprocess the Verilog source, but do not compile it. The output file
|
||||
is the Verilog input, but with file inclusions and macro references
|
||||
expanded and removed. This is useful, for example, to preprocess
|
||||
verilog source for use by other compilers.
|
||||
Verilog source for use by other compilers.
|
||||
.TP 8
|
||||
.B -I\fIincludedir\fP
|
||||
Append directory \fIincludepdir\fP to list of directoriess searched
|
||||
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.
|
||||
@@ -64,7 +65,7 @@ in the order they appear on the command line.
|
||||
.B -m\fImodule\fP
|
||||
Add this module to the list of VPI modules to be loaded by the
|
||||
simulation. Many modules can be specified, and all will be loaded, in
|
||||
the order specified.
|
||||
the order specified. The system module is implicit and always included.
|
||||
.TP 8
|
||||
.B -N\fIpath\fP
|
||||
This is used for debugging the compiler proper. Dump the final netlist
|
||||
@@ -91,9 +92,10 @@ netlist format, the \fB-S\fP switch is unnecessary and has no effect.
|
||||
.TP 8
|
||||
.B -s \fItopmodule\fP
|
||||
Specify the top level module to elaborate. Icarus Verilog will by default
|
||||
choose the only module that has no ports. However, this simplistic
|
||||
heuristic is often not sufficient, and sometimes not what is wanted
|
||||
anyhow.
|
||||
choose modules that are not instantiated in any other modules, but
|
||||
sometimes that is not sufficient, or instantiates too many modules. If
|
||||
the user specifies one or more root modules with \fB-s\fP flags, then
|
||||
they will be used as root modules instead.
|
||||
.TP 8
|
||||
.B -T\fImin|typ|max\fP
|
||||
Use this switch to select min, typ or max times from min:typ:max
|
||||
@@ -113,9 +115,28 @@ information from the various components.
|
||||
.TP 8
|
||||
.B -W\fIclass\fP
|
||||
Turn on different classes of warnings. See the \fBWARNING TYPES\fP
|
||||
section below for desctriptions of the different warning groups. If
|
||||
section below for descriptions of the different warning groups. If
|
||||
multiple \fB-W\fP switches are used, the warning set is the union of
|
||||
all the requested classes.
|
||||
.TP 8
|
||||
.B -y\fIlibdir\fP
|
||||
Append the directory to the library module search path. When the
|
||||
compiler finds an undefined module, it looks in these directories for
|
||||
files with the right name.
|
||||
|
||||
.SH MODULE LIBRARIES
|
||||
|
||||
The Icarus Verilog compiler supports module libraries as directories
|
||||
that contain Verilog source files. During elaboration, the compiler
|
||||
notices the instantiation of undefined module types. If the user
|
||||
specifies library search directories, the compiler will search the
|
||||
directory for files with the name of the missing module type. If it
|
||||
finds such a file, it loads it as a Verilog source file, they tries
|
||||
again to elaborate the module.
|
||||
|
||||
Library module files should contain only a single module, but this is
|
||||
not a requirement. Library modules may reference other modules in the
|
||||
library or in the main design.
|
||||
|
||||
.SH TARGETS
|
||||
|
||||
@@ -129,15 +150,26 @@ The null target causes no code to be generated. It is useful for
|
||||
checking the syntax of the Verilog source.
|
||||
.TP 8
|
||||
.B vvm
|
||||
This is the default. The target is an executable program that uses the
|
||||
vvm simulation runtime. The compiler actually generates C++ code, then
|
||||
compiles and links that code to make the output executable.
|
||||
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.
|
||||
.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.
|
||||
.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.
|
||||
|
||||
.SH "WARNING TYPES"
|
||||
These are the types of warnings that can be selected by the \fB-W\fP
|
||||
@@ -150,24 +182,76 @@ This enables all supported warning categories.
|
||||
.TP 8
|
||||
.B implicit
|
||||
This enables warnings for creation of implicit declarations. For
|
||||
example, if a scaler wire X is used but not declared in the Verilog
|
||||
example, if a scalar wire X is used but not declared in the Verilog
|
||||
source, this will print a warning at its first use.
|
||||
|
||||
.SH "COMMAND FILES"
|
||||
The command file allows the user to place source file names and
|
||||
certain command line switches into a text file instead of on a long
|
||||
command line. Command files can include C or C++ style comments, as
|
||||
well as # comments, if the # starts the line.
|
||||
|
||||
.TP 8
|
||||
.I "file name"
|
||||
A simple file name or file path is taken to be the name of a Verilog
|
||||
source file. The path starts with the first non-white-space character.
|
||||
|
||||
.TP 8
|
||||
.B -y\ \fIlibdir\fP
|
||||
A \fB-y\fP token prefixes a library directory in the command file,
|
||||
exactly like it does on the command line. The parameter to the \fB-y\fP
|
||||
flag may be on the same line or the next non-comment line.
|
||||
|
||||
.TP 8
|
||||
.B +incdir+\fIincludedir\fP
|
||||
The \fB+incdir+\fP token in command files gives directories to search
|
||||
for include files in much the same way that \fB-I\fP flags work on the
|
||||
command line. The difference is that multiple \fI+includedir\fP
|
||||
directories are valid parameters to a single \fB+incdir+\fP token,
|
||||
although you may also have multiple \fB+incdir+\fP lines.
|
||||
|
||||
.TP 8
|
||||
.B +libext+\fIext\fP
|
||||
The \fB+libext\fP token in command files fives file extensions to try
|
||||
when looking for a library file. This is useful in conjunction with
|
||||
\fB-y\fP flags to list suffixes to try in each directory before moving
|
||||
on to the next library directory.
|
||||
|
||||
.TP 8
|
||||
.B +define+\fINAME\fP=\fIvalue\fP
|
||||
The \fB+define+\fP token is the same as the \fB-D\fP option on the
|
||||
command line. The value part of the token is optional.
|
||||
|
||||
.TP 8
|
||||
.B +toupper-filename\fP
|
||||
This token causes file names after this in the command file to be
|
||||
translated to uppercase. This helps with situations where a directory
|
||||
has passed through a DOS machine, and in the process the file names
|
||||
become munged.
|
||||
|
||||
.TP 8
|
||||
.B +tolower-filename\fP
|
||||
This is similar to the \fB+toupper-filename\fP hack described above.
|
||||
|
||||
.SH EXAMPLES
|
||||
These examples assume that you have a Verilog source file called hello.v in
|
||||
the current directory
|
||||
|
||||
To compile hello.v to an executable file called a.out:
|
||||
|
||||
verilog hello.v
|
||||
iverilog hello.v
|
||||
|
||||
To compile hello.v to an executable file called hello:
|
||||
|
||||
verilog -o hello hello.v
|
||||
iverilog -o hello hello.v
|
||||
|
||||
To compile and run explicitly using the vvp runtime:
|
||||
|
||||
iverilog -ohello.vvp -tvvp hello.v
|
||||
|
||||
To compile hello.v to a file in XNF-format called hello.xnf
|
||||
|
||||
verilog -txnf -ohello.xnf hello.v
|
||||
iverilog -txnf -ohello.xnf hello.v
|
||||
|
||||
|
||||
.SH "AUTHOR"
|
||||
@@ -175,6 +259,7 @@ To compile hello.v to a file in XNF-format called hello.xnf
|
||||
Steve Williams ([email protected])
|
||||
|
||||
.SH SEE ALSO
|
||||
vvp(1),
|
||||
.BR "<http://www.icarus.com/eda/verilog/>"
|
||||
|
||||
.SH COPYRIGHT
|
||||
|
||||
+3
-1
@@ -19,9 +19,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: lexor.lex,v 1.4 2000/12/15 02:00:11 steve Exp $"
|
||||
#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"
|
||||
|
||||
|
||||
+340
-181
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams ([email protected])
|
||||
* Copyright (c) 2000-2001 Stephen Williams ([email protected])
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -16,16 +16,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)
|
||||
#ident "$Id: main.c,v 1.8 2001/02/01 17:12:22 steve Exp $"
|
||||
#endif
|
||||
#ident "$Id: main.c,v 1.31 2001/11/21 02:20:34 steve Exp $"
|
||||
|
||||
# include "config.h"
|
||||
|
||||
const char HELP[] =
|
||||
"Usage: iverilog [-ESv] [-c <path>] [-Dmacro[=defn]]
|
||||
[-p flag=value] [-I<dir>] [-m module]
|
||||
[-o <output>] [-s top_module] [-t<type>]
|
||||
[-W class] source_file(s)
|
||||
See man page for details.";
|
||||
"Usage: iverilog [-ESv] [-B base] [-C path] [-c cmdfile]\n"
|
||||
" [-D macro[=defn]] [-I includedir] [-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"
|
||||
"See man page for details.";
|
||||
|
||||
#define MAXSIZE 4096
|
||||
|
||||
@@ -36,12 +37,32 @@ See man page for details.";
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_GETOPT_H
|
||||
#include <getopt.h>
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
|
||||
extern int getopt(int argc, char*argv[], const char*fmt);
|
||||
extern int optind;
|
||||
extern const char*optarg;
|
||||
#endif
|
||||
|
||||
#if !defined(WIFEXITED)
|
||||
# define WIFEXITED(rc) ((rc&0x7f) == 0)
|
||||
#endif
|
||||
|
||||
#if !defined(WEXITSTATUS)
|
||||
# define WEXITSTATUS(rc) (rc>>8)
|
||||
#endif
|
||||
|
||||
#ifndef IVL_ROOT
|
||||
# define IVL_ROOT "."
|
||||
#endif
|
||||
@@ -52,32 +73,50 @@ See man page for details.";
|
||||
|
||||
# include "globals.h"
|
||||
|
||||
const char*base = IVL_ROOT;
|
||||
#ifdef __MINGW32__
|
||||
const char sep = '\\';
|
||||
#else
|
||||
const char sep = '/';
|
||||
#endif
|
||||
|
||||
extern void cfreset(FILE*fd, const char*path);
|
||||
|
||||
const char*base = 0;
|
||||
const char*mtm = 0;
|
||||
const char*opath = "a.out";
|
||||
const char*opath = "a.out" EXEEXT;
|
||||
const char*npath = 0;
|
||||
const char*targ = "vvm";
|
||||
const char*start = 0;
|
||||
const char*targ = "vvp";
|
||||
|
||||
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
|
||||
list. */
|
||||
char*source_path = 0;
|
||||
FILE*source_file = 0;
|
||||
unsigned source_count = 0;
|
||||
|
||||
int synth_flag = 0;
|
||||
int verbose_flag = 0;
|
||||
int command_file = 0;
|
||||
int inside_c_comment = 0;
|
||||
|
||||
FILE *fp;
|
||||
|
||||
char line[MAXSIZE];
|
||||
char tmp[MAXSIZE];
|
||||
|
||||
static char ivl_root[MAXSIZE];
|
||||
|
||||
/*
|
||||
* This is the default target type. It looks up the bits that are
|
||||
* needed to run the command from the configuration file (which is
|
||||
@@ -99,6 +138,16 @@ static int t_default(char*cmd, unsigned ncmd)
|
||||
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);
|
||||
|
||||
|
||||
@@ -107,7 +156,13 @@ static int t_default(char*cmd, unsigned ncmd)
|
||||
|
||||
|
||||
rc = system(cmd);
|
||||
remove(source_path);
|
||||
if (rc != 0) {
|
||||
if (rc == 127) {
|
||||
fprintf(stderr, "Failed to execute: %s\n", cmd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (WIFEXITED(rc))
|
||||
return WEXITSTATUS(rc);
|
||||
|
||||
@@ -138,12 +193,26 @@ static int t_vvm(char*cmd, unsigned ncmd)
|
||||
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");
|
||||
@@ -154,10 +223,27 @@ static int t_vvm(char*cmd, unsigned ncmd)
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(tmp, "%s " RDYNAMIC " -fno-exceptions -o %s -I%s "
|
||||
"-L%s %s.cc -lvvm -lvpip %s", CXX, opath, IVL_INC, IVL_LIB,
|
||||
opath, DLLIB);
|
||||
#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);
|
||||
|
||||
@@ -178,70 +264,6 @@ static int t_vvm(char*cmd, unsigned ncmd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int t_xnf(char*cmd, unsigned ncmd)
|
||||
{
|
||||
int rc;
|
||||
|
||||
sprintf(tmp, " | %s/ivl %s -o %s -txnf -Fcprop -Fsynth -Fsyn-rules "
|
||||
"-Fnodangle -Fxnfio", base, warning_flags, opath);
|
||||
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
|
||||
if (f_list) {
|
||||
rc = strlen(f_list);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, f_list);
|
||||
ncmd += rc;
|
||||
}
|
||||
|
||||
if (mtm) {
|
||||
sprintf(tmp, " -T%s", mtm);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
}
|
||||
|
||||
if (npath) {
|
||||
sprintf(tmp, " -N%s", npath);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
}
|
||||
|
||||
if (start) {
|
||||
sprintf(tmp, " -s%s", start);
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
}
|
||||
sprintf(tmp, " -- -");
|
||||
rc = strlen(tmp);
|
||||
cmd = realloc(cmd, ncmd+rc+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += rc;
|
||||
|
||||
if (verbose_flag)
|
||||
printf("translate: %s\n", cmd);
|
||||
|
||||
rc = system(cmd);
|
||||
if (rc != 0) {
|
||||
if (WIFEXITED(rc)) {
|
||||
fprintf(stderr, "errors translating Verilog program.\n");
|
||||
return WEXITSTATUS(rc);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Command signaled: %s\n", cmd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void process_warning_switch(const char*name)
|
||||
{
|
||||
@@ -257,6 +279,68 @@ static void process_warning_switch(const char*name)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void process_include_dir(const char *name)
|
||||
{
|
||||
if (inc_list == 0) {
|
||||
inc_list = malloc(strlen(" -I")+strlen(name)+1);
|
||||
strcpy(inc_list, " -I");
|
||||
strcat(inc_list, name);
|
||||
} else {
|
||||
inc_list = realloc(inc_list, strlen(inc_list)
|
||||
+ strlen(" -I")
|
||||
+ strlen(name) + 1);
|
||||
strcat(inc_list, " -I");
|
||||
strcat(inc_list, name);
|
||||
}
|
||||
}
|
||||
|
||||
void process_define(const char*name)
|
||||
{
|
||||
if (def_list == 0) {
|
||||
def_list = malloc(strlen(" -D")+strlen(name)+1);
|
||||
strcpy(def_list, " -D");
|
||||
strcat(def_list, name);
|
||||
} else {
|
||||
def_list = realloc(def_list, strlen(def_list)
|
||||
+ strlen(" -D")
|
||||
+ strlen(name) + 1);
|
||||
strcat(def_list, " -D");
|
||||
strcat(def_list, name);
|
||||
}
|
||||
}
|
||||
|
||||
void process_file_name(const char*name)
|
||||
{
|
||||
fprintf(source_file, "%s\n", name);
|
||||
source_count += 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
const char*config_path = 0;
|
||||
@@ -266,7 +350,49 @@ int main(int argc, char **argv)
|
||||
int opt, idx;
|
||||
char*cp;
|
||||
|
||||
while ((opt = getopt(argc, argv, "B:C:c:D:Ef:hI:m:N::o:p:Ss:T:t:vW:")) != EOF) {
|
||||
#ifdef __MINGW32__
|
||||
{ char * s;
|
||||
char basepath[1024];
|
||||
GetModuleFileName(NULL,basepath,1024);
|
||||
|
||||
/* Calculate the ivl_root from the path to the command. This
|
||||
is necessary because of the installation process in
|
||||
Windows. Mostly, it is those darn drive letters, but oh
|
||||
well. We know the command path is formed like this:
|
||||
|
||||
D:\iverilog\bin\iverilog.exe
|
||||
|
||||
The IVL_ROOT in a Windows installation is the path:
|
||||
|
||||
D:\iverilog\lib\ivl
|
||||
|
||||
so we chop the file name and the last directory by
|
||||
turning the last two \ characters to null. Then we append
|
||||
the lib\ivl to finish. */
|
||||
|
||||
strncpy(ivl_root, basepath, MAXSIZE);
|
||||
s = strrchr(ivl_root, sep);
|
||||
if (s) *s = 0;
|
||||
s = strrchr(ivl_root, sep);
|
||||
if (s) *s = 0;
|
||||
strcat(ivl_root, "\\lib\\ivl");
|
||||
|
||||
base = ivl_root;
|
||||
}
|
||||
#else
|
||||
/* In a UNIX environment, the IVL_ROOT from the Makefile is
|
||||
dependable. It points to the $prefix/lib/ivl directory,
|
||||
where the sub-parts are installed. */
|
||||
strcpy(ivl_root, IVL_ROOT);
|
||||
base = ivl_root;
|
||||
#endif
|
||||
|
||||
source_path = strdup(tmpnam(0));
|
||||
assert(source_path);
|
||||
source_file = fopen(source_path, "w");
|
||||
assert(source_file);
|
||||
|
||||
while ((opt = getopt(argc, argv, "B:C:c:D:Ef:hI:m:N::o:p:Ss:T:t:vW:y:")) != EOF) {
|
||||
|
||||
switch (opt) {
|
||||
case 'B':
|
||||
@@ -277,20 +403,10 @@ int main(int argc, char **argv)
|
||||
break;
|
||||
case 'c':
|
||||
command_filename = malloc(strlen(optarg)+1);
|
||||
strcat(command_filename, optarg);
|
||||
strcpy(command_filename, optarg);
|
||||
break;
|
||||
case 'D':
|
||||
if (def_list == 0) {
|
||||
def_list = malloc(strlen(" -D")+strlen(optarg)+1);
|
||||
strcpy(def_list, " -D");
|
||||
strcat(def_list, optarg);
|
||||
} else {
|
||||
def_list = realloc(def_list, strlen(def_list)
|
||||
+ strlen(" -D")
|
||||
+ strlen(optarg) + 1);
|
||||
strcat(def_list, " -D");
|
||||
strcat(def_list, optarg);
|
||||
}
|
||||
process_define(optarg);
|
||||
break;
|
||||
case 'E':
|
||||
e_flag = 1;
|
||||
@@ -316,18 +432,9 @@ int main(int argc, char **argv)
|
||||
return 1;
|
||||
|
||||
case 'I':
|
||||
if (inc_list == 0) {
|
||||
inc_list = malloc(strlen(" -I")+strlen(optarg)+1);
|
||||
strcpy(inc_list, " -I");
|
||||
strcat(inc_list, optarg);
|
||||
} else {
|
||||
inc_list = realloc(inc_list, strlen(inc_list)
|
||||
+ strlen(" -I")
|
||||
+ strlen(optarg) + 1);
|
||||
strcat(inc_list, " -I");
|
||||
strcat(inc_list, optarg);
|
||||
}
|
||||
process_include_dir(optarg);
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
if (mod_list == 0) {
|
||||
mod_list = malloc(strlen(" -m")+strlen(optarg)+1);
|
||||
@@ -354,7 +461,18 @@ int main(int argc, char **argv)
|
||||
synth_flag = 1;
|
||||
break;
|
||||
case 's':
|
||||
start = optarg;
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case 'T':
|
||||
if (strcmp(optarg,"min") == 0) {
|
||||
@@ -378,13 +496,46 @@ int main(int argc, char **argv)
|
||||
case 'W':
|
||||
process_warning_switch(optarg);
|
||||
break;
|
||||
case 'y':
|
||||
process_library_switch(optarg);
|
||||
break;
|
||||
case 'Y':
|
||||
process_library2_switch(optarg);
|
||||
break;
|
||||
case '?':
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if ((optind == argc) && !command_filename) {
|
||||
if (command_filename) {
|
||||
int rc;
|
||||
|
||||
if (( fp = fopen(command_filename, "r")) == NULL ) {
|
||||
fprintf(stderr, "%s: Can't open %s\n",
|
||||
argv[0], command_filename);
|
||||
return 1;
|
||||
}
|
||||
|
||||
cfreset(fp, command_filename);
|
||||
rc = cfparse();
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "%s: error reading command file\n",
|
||||
command_filename);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Finally, process all the remaining words on the command
|
||||
line as file names. */
|
||||
for (idx = optind ; idx < argc ; idx += 1)
|
||||
process_file_name(argv[idx]);
|
||||
|
||||
|
||||
fclose(source_file);
|
||||
source_file = 0;
|
||||
|
||||
if (source_count == 0) {
|
||||
fprintf(stderr, "%s: No input files.\n", argv[0]);
|
||||
fprintf(stderr, "%s\n", HELP);
|
||||
return 1;
|
||||
@@ -398,18 +549,22 @@ int main(int argc, char **argv)
|
||||
if (config_path) {
|
||||
strcpy(path, config_path);
|
||||
} else {
|
||||
sprintf(path, "%s/iverilog.conf", base);
|
||||
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/ivlpp %s%s", base,
|
||||
sprintf(tmp, "%s%civlpp %s%s -f%s ", base,sep,
|
||||
verbose_flag?" -v":"",
|
||||
e_flag?"":" -L");
|
||||
e_flag?"":" -L", source_path);
|
||||
|
||||
ncmd = strlen(tmp);
|
||||
cmd = malloc(ncmd + 1);
|
||||
@@ -427,56 +582,6 @@ int main(int argc, char **argv)
|
||||
ncmd += strlen(def_list);
|
||||
}
|
||||
|
||||
/* If user supplied a command file, retain its contents -- this
|
||||
process supersedes command line source files. */
|
||||
|
||||
if (command_filename != 0) {
|
||||
if (( fp = fopen(command_filename, "r")) == NULL ) {
|
||||
fprintf(stderr, "%s: Can't open %s\n",
|
||||
argv[0], command_filename);
|
||||
return 1;
|
||||
|
||||
} else {
|
||||
/* Process file and skip over commented-out lines.
|
||||
Skips over c-like comment as well as '//' or
|
||||
'#' lines. */
|
||||
|
||||
sprintf(tmp, "");
|
||||
while (fgets(line, MAXSIZE, fp) != NULL) {
|
||||
if ( strstr(line, "*/") != NULL ) {
|
||||
inside_c_comment = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (inside_c_comment || (strstr(line, "/*") != NULL)) {
|
||||
inside_c_comment = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (line[0] != '/' || line[1] != '/')
|
||||
&& line[0] != '#' ) {
|
||||
strcat (tmp, " ");
|
||||
strncat (tmp, line, (strlen(line)-1));
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
cmd = realloc(cmd, ncmd+strlen(tmp)+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += strlen(tmp);
|
||||
|
||||
} else {
|
||||
|
||||
/* Add all verilog source files to the preprocess
|
||||
command line. */
|
||||
|
||||
for (idx = optind ; idx < argc ; idx += 1) {
|
||||
sprintf(tmp, " %s", argv[idx]);
|
||||
cmd = realloc(cmd, ncmd+strlen(tmp)+1);
|
||||
strcpy(cmd+ncmd, tmp);
|
||||
ncmd += strlen(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
/* If the -E flag was given on the command line, then all we
|
||||
do is run the preprocessor and put the output where the
|
||||
@@ -494,6 +599,7 @@ int main(int argc, char **argv)
|
||||
printf("preprocess: %s\n", cmd);
|
||||
|
||||
rc = system(cmd);
|
||||
remove(source_path);
|
||||
if (rc != 0) {
|
||||
if (WIFEXITED(rc)) {
|
||||
fprintf(stderr, "errors preprocessing Verilog program.\n");
|
||||
@@ -509,8 +615,6 @@ int main(int argc, char **argv)
|
||||
|
||||
if (strcmp(targ,"vvm") == 0)
|
||||
return t_vvm(cmd, ncmd);
|
||||
else if (strcmp(targ,"xnf") == 0)
|
||||
return t_xnf(cmd, ncmd);
|
||||
else {
|
||||
return t_default(cmd, ncmd);
|
||||
}
|
||||
@@ -520,29 +624,84 @@ int main(int argc, char **argv)
|
||||
|
||||
/*
|
||||
* $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.30 2001/11/16 05:07:19 steve
|
||||
* Add support for +libext+ in command 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.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.27 2001/11/12 01:26:36 steve
|
||||
* More sophisticated command file parser.
|
||||
*
|
||||
* Revision 1.26 2001/11/11 00:10:05 steve
|
||||
* Remov XNF dead wood.
|
||||
*
|
||||
* Revision 1.25 2001/10/23 00:37:30 steve
|
||||
* The -s flag can now be repeated on the iverilog command.
|
||||
*
|
||||
* Revision 1.24 2001/10/20 23:02:40 steve
|
||||
* Add automatic module libraries.
|
||||
*
|
||||
* Revision 1.23 2001/10/19 23:10:08 steve
|
||||
* Fix memory fault with -c flag.
|
||||
*
|
||||
* Revision 1.22 2001/10/11 00:12:49 steve
|
||||
* Detect execv failures.
|
||||
*
|
||||
* 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.6 2001/01/20 02:15:51 steve
|
||||
* apologize for not supporting non-constant delays.
|
||||
*
|
||||
* Revision 1.5 2000/11/30 02:50:54 steve
|
||||
* Add command file (-c) support from Nadim Shaikli.
|
||||
*
|
||||
* Revision 1.4 2000/10/28 17:28:16 steve
|
||||
* Split vpip for everybody.
|
||||
*
|
||||
* Revision 1.3 2000/10/28 03:47:25 steve
|
||||
* Use the conf file to generate the vvm ivl string.
|
||||
*
|
||||
* 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
-1
@@ -18,11 +18,16 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: parse.y,v 1.2 2000/11/09 21:58:00 steve Exp $"
|
||||
#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"
|
||||
|
||||
|
||||
|
||||
+38
-2
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: dup_expr.cc,v 1.4 2000/05/07 18:20:07 steve Exp $"
|
||||
#ident "$Id: dup_expr.cc,v 1.6 2001/11/19 01:54:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
# include <cassert>
|
||||
|
||||
@@ -32,14 +34,48 @@ NetEScope* NetEScope::dup_expr() const
|
||||
NetESFunc* NetESFunc::dup_expr() const
|
||||
{
|
||||
NetESFunc*tmp = new NetESFunc(name_, expr_width(), nparms());
|
||||
for (unsigned idx = 0 ; idx < nparms() ; idx += 1)
|
||||
assert(tmp);
|
||||
for (unsigned idx = 0 ; idx < nparms() ; idx += 1) {
|
||||
assert(tmp->parm(idx));
|
||||
tmp->parm(idx, tmp->parm(idx)->dup_expr());
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetESignal* NetESignal::dup_expr() const
|
||||
{
|
||||
NetESignal*tmp = new NetESignal(net_, msi_, lsi_);
|
||||
assert(tmp);
|
||||
tmp->expr_width(expr_width());
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetETernary* NetETernary::dup_expr() const
|
||||
{
|
||||
NetETernary*tmp = new NetETernary(cond_->dup_expr(),
|
||||
true_val_->dup_expr(),
|
||||
false_val_->dup_expr());
|
||||
return tmp;
|
||||
}
|
||||
|
||||
NetEUnary* NetEUnary::dup_expr() const
|
||||
{
|
||||
NetEUnary*tmp = new NetEUnary(op_, expr_->dup_expr());
|
||||
assert(tmp);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: dup_expr.cc,v $
|
||||
* Revision 1.6 2001/11/19 01:54:14 steve
|
||||
* Port close cropping behavior from mcrgb
|
||||
* Move window array reset to libmc.
|
||||
*
|
||||
* Revision 1.5 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.4 2000/05/07 18:20:07 steve
|
||||
* Import MCD support from Stephen Tell, and add
|
||||
* system function parameter support to the IVL core.
|
||||
|
||||
+15
-5
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_anet.cc,v 1.2 2001/01/06 02:29:36 steve Exp $"
|
||||
#ident "$Id: elab_anet.cc,v 1.4 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
/*
|
||||
* The elaborate_anet methods elaborate expressions that are intended
|
||||
* to be the left side of procedural continuous assignments.
|
||||
@@ -102,10 +104,10 @@ NetNet* PEConcat::elaborate_anet(Design*des, NetScope*scope) const
|
||||
|
||||
NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetNet*sig = des->find_signal(scope, text_);
|
||||
NetNet*sig = des->find_signal(scope, path_);
|
||||
|
||||
if (sig == 0) {
|
||||
if (NetMemory*mem = des->find_memory(scope, text_)) {
|
||||
if (NetMemory*mem = des->find_memory(scope, path_)) {
|
||||
cerr << get_line() << ": error: memories not allowed "
|
||||
<< "on left side of procedural continuous "
|
||||
<< "asignment." << endl;
|
||||
@@ -113,7 +115,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
cerr << get_line() << ": error: reg ``" << text_ << "'' "
|
||||
cerr << get_line() << ": error: reg ``" << path_ << "'' "
|
||||
<< "is undefined in this scope." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
@@ -125,7 +127,7 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
break;
|
||||
|
||||
default:
|
||||
cerr << get_line() << ": error: " << text_ << " is not "
|
||||
cerr << get_line() << ": error: " << path_ << " is not "
|
||||
<< "a reg in this context." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
@@ -147,6 +149,14 @@ NetNet* PEIdent::elaborate_anet(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_anet.cc,v $
|
||||
* Revision 1.4 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.3 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.2 2001/01/06 02:29:36 steve
|
||||
* Support arrays of integers.
|
||||
*
|
||||
|
||||
+172
-148
@@ -17,12 +17,16 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_expr.cc,v 1.34 2001/01/14 23:04:55 steve Exp $"
|
||||
#ident "$Id: elab_expr.cc,v 1.46 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
|
||||
# include "pform.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "util.h"
|
||||
|
||||
NetExpr* PExpr::elaborate_expr(Design*des, NetScope*) const
|
||||
{
|
||||
@@ -41,6 +45,9 @@ NetExpr* PExpr::elaborate_expr(Design*des, NetScope*) const
|
||||
*/
|
||||
NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(left_);
|
||||
assert(right_);
|
||||
|
||||
NetExpr*lp = left_->elaborate_expr(des, scope);
|
||||
NetExpr*rp = right_->elaborate_expr(des, scope);
|
||||
if ((lp == 0) || (rp == 0)) {
|
||||
@@ -49,6 +56,7 @@ NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* If either expression can be evaluated ahead of time, then
|
||||
do so. This can prove helpful later. */
|
||||
{ NetExpr*tmp;
|
||||
@@ -57,6 +65,7 @@ NetEBinary* PEBinary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
delete lp;
|
||||
lp = tmp;
|
||||
}
|
||||
|
||||
tmp = rp->eval_tree();
|
||||
if (tmp) {
|
||||
delete rp;
|
||||
@@ -145,18 +154,66 @@ NetEBinary* PEBinary::elaborate_expr_base_(Design*des,
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a call to a system function, generate the proper expression
|
||||
* nodes to represent the call in the netlist. Since we don't support
|
||||
* size_tf functions, make assumptions about widths based on some
|
||||
* known function names.
|
||||
*/
|
||||
NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||
{
|
||||
unsigned wid = 32;
|
||||
|
||||
if (name_ == "$time")
|
||||
if (strcmp(path_.peek_name(0), "$time") == 0)
|
||||
wid = 64;
|
||||
|
||||
NetESFunc*fun = new NetESFunc(name_, wid, parms_.count());
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1) {
|
||||
|
||||
/* How many parameters are there? The Verilog language allows
|
||||
empty parameters in certain contexts, so the parser will
|
||||
allow things like func(1,,3). It will also cause func() to
|
||||
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
|
||||
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);
|
||||
|
||||
/* Now run through the expected parameters. If we find that
|
||||
there are missing parameters, print an error message.
|
||||
|
||||
While we're at it, try to evaluate the function parameter
|
||||
expression as much as possible, and use the reduced
|
||||
expression if one is created. */
|
||||
|
||||
unsigned missing_parms = 0;
|
||||
for (unsigned idx = 0 ; idx < nparms ; idx += 1) {
|
||||
PExpr*expr = parms_[idx];
|
||||
NetExpr*tmp = expr->elaborate_expr(des, scope);
|
||||
fun->parm(idx, tmp);
|
||||
if (expr) {
|
||||
NetExpr*tmp1 = expr->elaborate_expr(des, scope);
|
||||
if (NetExpr*tmp2 = tmp1->eval_tree()) {
|
||||
delete tmp1;
|
||||
fun->parm(idx, tmp2);
|
||||
} else {
|
||||
fun->parm(idx, tmp1);
|
||||
}
|
||||
|
||||
} else {
|
||||
missing_parms += 1;
|
||||
fun->parm(idx, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (missing_parms > 0) {
|
||||
cerr << get_line() << ": error: The function "
|
||||
<< path_.peek_name(0)
|
||||
<< " has been called with empty parameters." << endl;
|
||||
cerr << get_line() << ": : Verilog doesn't allow "
|
||||
<< "passing empty parameters to functions." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
return fun;
|
||||
@@ -164,19 +221,19 @@ NetExpr* PECallFunction::elaborate_sfunc_(Design*des, NetScope*scope) const
|
||||
|
||||
NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
|
||||
{
|
||||
if (name_[0] == '$')
|
||||
if (path_.peek_name(0)[0] == '$')
|
||||
return elaborate_sfunc_(des, scope);
|
||||
|
||||
NetFuncDef*def = des->find_function(scope, name_);
|
||||
NetFuncDef*def = des->find_function(scope, path_);
|
||||
if (def == 0) {
|
||||
cerr << get_line() << ": error: No function " << name_ <<
|
||||
cerr << get_line() << ": error: No function " << path_ <<
|
||||
" in this context (" << scope->name() << ")." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
assert(def);
|
||||
|
||||
NetScope*dscope = des->find_scope(def->name());
|
||||
NetScope*dscope = def->scope();
|
||||
assert(dscope);
|
||||
|
||||
/* How many parameters have I got? Normally the size of the
|
||||
@@ -188,6 +245,22 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
|
||||
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);
|
||||
|
||||
/* Elaborate the input expressions for the function. This is
|
||||
@@ -195,22 +268,39 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
|
||||
of the function being called. The scope of the called
|
||||
function is elaborated when the definition is elaborated. */
|
||||
|
||||
unsigned missing_parms = 0;
|
||||
for (unsigned idx = 0 ; idx < parms.count() ; idx += 1) {
|
||||
PExpr*tmp = parms_[idx];
|
||||
assert(tmp);
|
||||
parms[idx] = tmp->elaborate_expr(des, scope);
|
||||
if (tmp) {
|
||||
parms[idx] = tmp->elaborate_expr(des, scope);
|
||||
|
||||
} else {
|
||||
missing_parms += 1;
|
||||
parms[idx] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (missing_parms > 0) {
|
||||
cerr << get_line() << ": error: The function " << path_
|
||||
<< " has been called with empty parameters." << endl;
|
||||
cerr << get_line() << ": : Verilog doesn't allow "
|
||||
<< "passing empty parameters to functions." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
|
||||
/* Look for the return value signal for the called
|
||||
function. This return value is a magic signal in the scope
|
||||
of the function, that has the name of the function. The
|
||||
function code assigns to this signal to return a value. */
|
||||
function code assigns to this signal to return a value.
|
||||
|
||||
NetNet*res = des->find_signal(dscope, name_);
|
||||
dscope, in this case, is the scope of the function, so the
|
||||
return value is the name within that scope. */
|
||||
|
||||
NetNet*res = dscope->find_signal(dscope->basename());
|
||||
if (res == 0) {
|
||||
cerr << get_line() << ": internal error: Unable to locate "
|
||||
"function return value for " << name_ << " in " <<
|
||||
"function return value for " << path_ << " in " <<
|
||||
def->name() << "." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
@@ -219,7 +309,7 @@ NetExpr* PECallFunction::elaborate_expr(Design*des, NetScope*scope) const
|
||||
assert(res);
|
||||
NetESignal*eres = new NetESignal(res);
|
||||
assert(eres);
|
||||
NetEUFunc*func = new NetEUFunc(def, eres, parms);
|
||||
NetEUFunc*func = new NetEUFunc(dscope, eres, parms);
|
||||
return func;
|
||||
}
|
||||
|
||||
@@ -231,17 +321,21 @@ NetExpr* PEConcat::elaborate_expr(Design*des, NetScope*scope) const
|
||||
/* If there is a repeat expression, then evaluate the constant
|
||||
value and set the repeat count. */
|
||||
if (repeat_) {
|
||||
verinum*vrep = repeat_->eval_const(des, scope->name());
|
||||
if (vrep == 0) {
|
||||
NetExpr*tmp = elab_and_eval(des, scope, repeat_);
|
||||
assert(tmp);
|
||||
NetEConst*rep = dynamic_cast<NetEConst*>(tmp);
|
||||
|
||||
if (rep == 0) {
|
||||
cerr << get_line() << ": error: "
|
||||
"concatenation repeat expression cannot be evaluated."
|
||||
<< endl;
|
||||
cerr << get_line() << ": : The expression is: "
|
||||
<< *tmp << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
repeat = vrep->as_ulong();
|
||||
delete vrep;
|
||||
repeat = rep->value().as_ulong();
|
||||
}
|
||||
|
||||
/* Make the empty concat expression. */
|
||||
@@ -277,19 +371,18 @@ NetExpr* PEFNumber::elaborate_expr(Design*des, NetScope*scope) const
|
||||
|
||||
NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(text_[0] != '$');
|
||||
assert(path_.peek_name(0)[0] != '$');
|
||||
|
||||
//string name = path+"."+text_;
|
||||
assert(scope);
|
||||
|
||||
// If the identifier name is a parameter name, then return
|
||||
// a reference to the parameter expression.
|
||||
if (const NetExpr*ex = des->find_parameter(scope, text_)) {
|
||||
if (const NetExpr*ex = des->find_parameter(scope, path_)) {
|
||||
NetExpr*tmp;
|
||||
if (dynamic_cast<const NetExpr*>(ex))
|
||||
tmp = ex->dup_expr();
|
||||
else
|
||||
tmp = new NetEParam(des, scope, text_);
|
||||
tmp = new NetEParam(des, scope, path_);
|
||||
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
@@ -297,7 +390,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, text_)) {
|
||||
if (NetNet*net = des->find_signal(scope, path_)) {
|
||||
|
||||
// If this is a part select of a signal, then make a new
|
||||
// temporary signal that is connected to just the
|
||||
@@ -305,8 +398,8 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
// the foo[msb:lsb] expression in the original.
|
||||
if (lsb_) {
|
||||
assert(msb_);
|
||||
verinum*lsn = lsb_->eval_const(des, scope->name());
|
||||
verinum*msn = msb_->eval_const(des, scope->name());
|
||||
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 expresions must be "
|
||||
@@ -359,15 +452,9 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
string tname = des->local_symbol(scope->name());
|
||||
NetTmp*tsig = new NetTmp(scope, tname, wid);
|
||||
|
||||
// Connect the pins from the lsb up to the msb.
|
||||
unsigned off = net->sb_to_idx(lsv);
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
||||
connect(tsig->pin(idx), net->pin(idx+off));
|
||||
|
||||
NetESignal*tmp = new NetESignal(tsig);
|
||||
NetESignal*tmp = new NetESignal(net,
|
||||
net->sb_to_idx(msv),
|
||||
net->sb_to_idx(lsv));
|
||||
tmp->set_line(*this);
|
||||
|
||||
return tmp;
|
||||
@@ -377,7 +464,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
// to the part select, so that I save the effort of
|
||||
// making a mux part in the netlist.
|
||||
verinum*msn;
|
||||
if (msb_ && (msn = msb_->eval_const(des, scope->name()))) {
|
||||
if (msb_ && (msn = msb_->eval_const(des, scope))) {
|
||||
assert(idx_ == 0);
|
||||
unsigned long msv = msn->as_ulong();
|
||||
unsigned idx = net->sb_to_idx(msv);
|
||||
@@ -390,10 +477,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
string tname = des->local_symbol(scope->name());
|
||||
NetTmp*tsig = new NetTmp(scope, tname);
|
||||
connect(tsig->pin(0), net->pin(idx));
|
||||
NetESignal*tmp = new NetESignal(tsig);
|
||||
NetESignal*tmp = new NetESignal(net, idx, idx);
|
||||
tmp->set_line(*this);
|
||||
|
||||
return tmp;
|
||||
@@ -406,7 +490,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
// device to mux the bit in the net.
|
||||
if (msb_) {
|
||||
NetExpr*ex = msb_->elaborate_expr(des, scope);
|
||||
NetESubSignal*ss = new NetESubSignal(node, ex);
|
||||
NetEBitSel*ss = new NetEBitSel(node, ex);
|
||||
ss->set_line(*this);
|
||||
return ss;
|
||||
}
|
||||
@@ -420,7 +504,7 @@ 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, text_)) {
|
||||
if (NetMemory*mem = des->find_memory(scope, path_)) {
|
||||
if (msb_ == 0) {
|
||||
NetEMemory*node = new NetEMemory(mem);
|
||||
node->set_line(*this);
|
||||
@@ -449,8 +533,20 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
return node;
|
||||
}
|
||||
|
||||
// Finally, if this is a scope name, then return that.
|
||||
if (NetScope*nsc = des->find_scope(text_)) {
|
||||
// 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.
|
||||
if ((path_.peek_name(1) == 0))
|
||||
if (NetScope*nsc = scope->child(path_.peek_name(0))) {
|
||||
NetEScope*tmp = new NetEScope(nsc);
|
||||
tmp->set_line(*this);
|
||||
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.
|
||||
if (NetScope*nsc = des->find_scope(path_)) {
|
||||
NetEScope*tmp = new NetEScope(nsc);
|
||||
tmp->set_line(*this);
|
||||
return tmp;
|
||||
@@ -458,7 +554,7 @@ NetExpr* PEIdent::elaborate_expr(Design*des, NetScope*scope) const
|
||||
|
||||
// I cannot interpret this identifier. Error message.
|
||||
cerr << get_line() << ": error: Unable to bind wire/reg/memory "
|
||||
"`" << text_ << "' in `" << scope->name() << "'" << endl;
|
||||
"`" << path_ << "' in `" << scope->name() << "'" << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -540,122 +636,50 @@ NetEUnary* PEUnary::elaborate_expr(Design*des, NetScope*scope) const
|
||||
tmp->set_line(*this);
|
||||
break;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: elab_expr.cc,v $
|
||||
* Revision 1.34 2001/01/14 23:04:55 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
* Revision 1.46 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Allow parameters to be referenced by hierarchical name.
|
||||
* Revision 1.45 2001/11/19 02:54:12 steve
|
||||
* Handle division and modulus by zero while
|
||||
* evaluating run-time constants.
|
||||
*
|
||||
* Revision 1.33 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
* Revision 1.44 2001/11/19 01:54:14 steve
|
||||
* Port close cropping behavior from mcrgb
|
||||
* Move window array reset to libmc.
|
||||
*
|
||||
* Revision 1.32 2001/01/02 04:21:13 steve
|
||||
* Support a bunch of unary operators in parameter expressions.
|
||||
* Revision 1.43 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.31 2000/12/10 22:01:35 steve
|
||||
* Support decimal constants in behavioral delays.
|
||||
* Revision 1.42 2001/07/29 22:22:40 steve
|
||||
* support local reference to scope in expressions.
|
||||
*
|
||||
* Revision 1.30 2000/11/29 05:24:00 steve
|
||||
* synthesis for unary reduction ! and N operators.
|
||||
* 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.29 2000/09/26 05:05:58 steve
|
||||
* Detect indefinite widths where definite widths are required.
|
||||
* 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.28 2000/09/24 17:41:13 steve
|
||||
* fix null pointer when elaborating undefined task.
|
||||
* Revision 1.39 2001/06/30 21:28:35 steve
|
||||
* Detect parameter mismatches.
|
||||
*
|
||||
* Revision 1.27 2000/08/26 01:31:29 steve
|
||||
* Handle out of range part select expressions.
|
||||
* Revision 1.38 2001/06/23 19:53:03 steve
|
||||
* Look up functor return register with tail of name.
|
||||
*
|
||||
* Revision 1.26 2000/05/19 01:55:09 steve
|
||||
* Catch part select of memories as an error.
|
||||
*
|
||||
* Revision 1.25 2000/05/07 18:20:07 steve
|
||||
* Import MCD support from Stephen Tell, and add
|
||||
* system function parameter support to the IVL core.
|
||||
*
|
||||
* Revision 1.24 2000/05/04 03:37:58 steve
|
||||
* Add infrastructure for system functions, move
|
||||
* $time to that structure and add $random.
|
||||
*
|
||||
* Revision 1.23 2000/05/02 03:13:30 steve
|
||||
* Move memories to the NetScope object.
|
||||
*
|
||||
* Revision 1.22 2000/05/02 00:58:11 steve
|
||||
* Move signal tables to the NetScope class.
|
||||
*
|
||||
* Revision 1.21 2000/04/28 18:43:23 steve
|
||||
* integer division in expressions properly get width.
|
||||
*
|
||||
* Revision 1.20 2000/03/29 04:06:28 steve
|
||||
* Forgot to return elaborate result (Dan Nelsen)
|
||||
*
|
||||
* Revision 1.19 2000/03/20 16:57:22 steve
|
||||
* select correct bit when reg has non-zero lsb.
|
||||
*
|
||||
* Revision 1.18 2000/03/12 18:22:11 steve
|
||||
* Binary and unary operators in parameter expressions.
|
||||
*
|
||||
* Revision 1.17 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.16 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.15 2000/01/13 03:35:35 steve
|
||||
* Multiplication all the way to simulation.
|
||||
*
|
||||
* Revision 1.14 2000/01/01 06:18:00 steve
|
||||
* Handle synthesis of concatenation.
|
||||
*
|
||||
* Revision 1.13 1999/12/12 06:03:14 steve
|
||||
* Allow memories without indices in expressions.
|
||||
*
|
||||
* Revision 1.12 1999/11/30 04:54:01 steve
|
||||
* Match scope names as last resort.
|
||||
*
|
||||
* Revision 1.11 1999/11/28 23:42:02 steve
|
||||
* NetESignal object no longer need to be NetNode
|
||||
* objects. Let them keep a pointer to NetNet objects.
|
||||
*
|
||||
* Revision 1.10 1999/11/27 19:07:57 steve
|
||||
* Support the creation of scopes.
|
||||
*
|
||||
* Revision 1.9 1999/11/21 17:35:37 steve
|
||||
* Memory name lookup handles scopes.
|
||||
*
|
||||
* Revision 1.8 1999/11/10 02:52:24 steve
|
||||
* Create the vpiMemory handle type.
|
||||
*
|
||||
* Revision 1.7 1999/10/18 00:02:21 steve
|
||||
* Catch unindexed memory reference.
|
||||
*
|
||||
* Revision 1.6 1999/09/30 02:43:02 steve
|
||||
* Elaborate ~^ and ~| operators.
|
||||
*
|
||||
* Revision 1.5 1999/09/30 00:48:49 steve
|
||||
* Cope with errors during ternary operator elaboration.
|
||||
*
|
||||
* Revision 1.4 1999/09/29 22:57:10 steve
|
||||
* Move code to elab_expr.cc
|
||||
*
|
||||
* Revision 1.3 1999/09/25 02:57:30 steve
|
||||
* Parse system function calls.
|
||||
*
|
||||
* Revision 1.2 1999/09/21 00:13:40 steve
|
||||
* Support parameters that reference other paramters.
|
||||
*
|
||||
* Revision 1.1 1999/09/20 02:21:10 steve
|
||||
* Elaborate parameters in phases.
|
||||
* Revision 1.37 2001/04/06 02:28:02 steve
|
||||
* Generate vvp code for functions with ports.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
|
||||
+58
-61
@@ -17,12 +17,16 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_lval.cc,v 1.11 2001/01/10 03:13:23 steve Exp $"
|
||||
#ident "$Id: elab_lval.cc,v 1.17 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "netlist.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
/*
|
||||
* These methods generate a NetAssign_ object for the l-value of the
|
||||
* assignemnt. This is common code for the = and <= statements.
|
||||
@@ -63,17 +67,14 @@
|
||||
*/
|
||||
NetAssign_* PExpr::elaborate_lval(Design*des, NetScope*scope) const
|
||||
{
|
||||
NetNet*ll = elaborate_net(des, scope->name(), 0, 0, 0, 0);
|
||||
NetNet*ll = elaborate_net(des, scope, 0, 0, 0, 0);
|
||||
if (ll == 0) {
|
||||
cerr << get_line() << ": Assignment l-value too complex."
|
||||
<< endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetAssign_*lv = new NetAssign_(scope->local_symbol(), ll->pin_count());
|
||||
for (unsigned idx = 0 ; idx < ll->pin_count() ; idx += 1)
|
||||
connect(lv->pin(idx), ll->pin(idx));
|
||||
des->add_node(lv);
|
||||
NetAssign_*lv = new NetAssign_(ll);
|
||||
return lv;
|
||||
}
|
||||
|
||||
@@ -112,42 +113,15 @@ NetAssign_* PEConcat::elaborate_lval(Design*des, NetScope*scope) const
|
||||
|
||||
assert(tmp);
|
||||
|
||||
/* If adjacent l-values in the concatenation are not bit
|
||||
selects, then merge them into a single NetAssign_
|
||||
object.
|
||||
|
||||
If we cannot merge, then just link the new one to the
|
||||
previous one. */
|
||||
/* Link the new l-value to the previous one. */
|
||||
|
||||
if (res && (res->bmux() == 0) && (tmp->bmux() == 0)) {
|
||||
unsigned wid1 = tmp->pin_count();
|
||||
unsigned wid2 = res->pin_count() + tmp->pin_count();
|
||||
NetAssign_*tmp2 = new NetAssign_(res->name(), wid2);
|
||||
NetAssign_*last = tmp;
|
||||
while (last->more)
|
||||
last = last->more;
|
||||
|
||||
assert(tmp->more == 0);
|
||||
|
||||
tmp2->more = res->more;
|
||||
res->more = 0;
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid1 ; idx += 1)
|
||||
connect(tmp2->pin(idx), tmp->pin(idx));
|
||||
|
||||
for (unsigned idx = 0 ; idx < res->pin_count() ; idx += 1)
|
||||
connect(tmp2->pin(idx+wid1), res->pin(idx));
|
||||
|
||||
delete res;
|
||||
delete tmp;
|
||||
res = tmp2;
|
||||
des->add_node(res);
|
||||
|
||||
} else {
|
||||
NetAssign_*last = tmp;
|
||||
while (last->more)
|
||||
last = last->more;
|
||||
|
||||
last->more = res;
|
||||
res = tmp;
|
||||
}
|
||||
last->more = res;
|
||||
res = tmp;
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -161,16 +135,16 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
{
|
||||
/* Get the signal referenced by the identifier, and make sure
|
||||
it is a register. (Wires are not allows in this context. */
|
||||
NetNet*reg = des->find_signal(scope, name());
|
||||
NetNet*reg = des->find_signal(scope, path_);
|
||||
|
||||
if (reg == 0) {
|
||||
NetMemory*mem = des->find_memory(scope, name());
|
||||
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 ``"
|
||||
<< name() << "'' in ``" << scope->name() <<
|
||||
<< path_ << "'' in ``" << scope->name() <<
|
||||
"''" << endl;
|
||||
}
|
||||
des->errors += 1;
|
||||
@@ -179,7 +153,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
assert(reg);
|
||||
|
||||
if (reg->type() != NetNet::REG) {
|
||||
cerr << get_line() << ": error: " << name() <<
|
||||
cerr << get_line() << ": error: " << path_ <<
|
||||
" is not a reg/integer/time in " << scope->name() <<
|
||||
"." << endl;
|
||||
des->errors += 1;
|
||||
@@ -194,7 +168,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
two bit select expressions, and both must be
|
||||
constant. Evaluate them and pass the results back to
|
||||
the caller. */
|
||||
verinum*vl = lsb_->eval_const(des, scope->name());
|
||||
verinum*vl = lsb_->eval_const(des, scope);
|
||||
if (vl == 0) {
|
||||
cerr << lsb_->get_line() << ": error: "
|
||||
"Part select expressions must be constant: "
|
||||
@@ -202,7 +176,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
verinum*vm = msb_->eval_const(des, scope->name());
|
||||
verinum*vm = msb_->eval_const(des, scope);
|
||||
if (vl == 0) {
|
||||
cerr << msb_->get_line() << ": error: "
|
||||
"Part select expressions must be constant: "
|
||||
@@ -223,7 +197,7 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
expression it not constant, then return the
|
||||
expression as a mux. */
|
||||
assert(lsb_ == 0);
|
||||
verinum*v = msb_->eval_const(des, scope->name());
|
||||
verinum*v = msb_->eval_const(des, scope);
|
||||
if (v == 0) {
|
||||
NetExpr*m = msb_->elaborate_expr(des, scope);
|
||||
assert(m);
|
||||
@@ -255,13 +229,9 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
if (mux) {
|
||||
|
||||
/* If there is a non-constant bit select, make a
|
||||
NetAssign_ the width of the target reg and attach a
|
||||
NetAssign_ to the target reg and attach a
|
||||
bmux to select the target bit. */
|
||||
unsigned wid = reg->pin_count();
|
||||
lv = new NetAssign_(des->local_symbol(scope->name()), wid);
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
||||
connect(lv->pin(idx), reg->pin(idx));
|
||||
lv = new NetAssign_(reg);
|
||||
|
||||
lv->set_bmux(mux);
|
||||
|
||||
@@ -274,8 +244,6 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
unsigned moff = reg->sb_to_idx(msb);
|
||||
unsigned wid = moff - loff + 1;
|
||||
|
||||
lv = new NetAssign_(des->local_symbol(scope->name()), wid);
|
||||
|
||||
if (moff < loff) {
|
||||
cerr << get_line() << ": error: part select "
|
||||
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
|
||||
@@ -284,28 +252,57 @@ NetAssign_* PEIdent::elaborate_lval(Design*des, NetScope*scope) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (wid > reg->pin_count()) {
|
||||
cerr << get_line() << ": error: part select "
|
||||
/* If the part select extends beyond the extreme of the
|
||||
variable, then report an error. Note that loff is
|
||||
converted to normalized form so is relative the
|
||||
variable pins. */
|
||||
|
||||
if ((wid + loff) > reg->pin_count()) {
|
||||
cerr << get_line() << ": error: bit/part select "
|
||||
<< reg->name() << "[" << msb<<":"<<lsb<<"]"
|
||||
<< " is out of range." << endl;
|
||||
des->errors += 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(moff < reg->pin_count());
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
||||
connect(lv->pin(idx), reg->pin(idx+loff));
|
||||
lv = new NetAssign_(reg);
|
||||
lv->set_part(loff, wid);
|
||||
|
||||
assert(moff < reg->pin_count());
|
||||
}
|
||||
|
||||
|
||||
des->add_node(lv);
|
||||
|
||||
return lv;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: elab_lval.cc,v $
|
||||
* Revision 1.17 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.16 2001/11/08 05:15:50 steve
|
||||
* Remove string paths from PExpr elaboration.
|
||||
*
|
||||
* Revision 1.15 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.14 2001/08/25 23:50:02 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.13 2001/07/25 03:10:48 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.12 2001/02/09 03:16:48 steve
|
||||
* Report bit/part select out of range errors. (PR#133)
|
||||
*
|
||||
* Revision 1.11 2001/01/10 03:13:23 steve
|
||||
* Build task outputs as lval instead of nets. (PR#98)
|
||||
*
|
||||
|
||||
+273
-481
File diff suppressed because it is too large
Load Diff
+42
-9
@@ -17,12 +17,16 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_pexpr.cc,v 1.8 2001/01/14 23:04:56 steve Exp $"
|
||||
#ident "$Id: elab_pexpr.cc,v 1.12 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "util.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
NetExpr*PExpr::elaborate_pexpr(Design*des, NetScope*sc) const
|
||||
{
|
||||
cerr << get_line() << ": error: invalid parameter expression: "
|
||||
@@ -73,7 +77,7 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
accurately evaluate such expressions. So eventually, I will
|
||||
need to be able to defer the evaluation of the expression. */
|
||||
if (repeat_) {
|
||||
verinum*vrep = repeat_->eval_const(des, scope->name());
|
||||
verinum*vrep = repeat_->eval_const(des, scope);
|
||||
if (vrep == 0) {
|
||||
cerr << get_line() << ": error: "
|
||||
"concatenation repeat expression cannot be evaluated."
|
||||
@@ -97,7 +101,22 @@ NetEConcat* PEConcat::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
assert(parms_[idx]);
|
||||
NetExpr*ex = parms_[idx]->elaborate_pexpr(des, scope);
|
||||
if (ex == 0) continue;
|
||||
|
||||
ex->set_line(*parms_[idx]);
|
||||
|
||||
if (! 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);
|
||||
}
|
||||
|
||||
@@ -117,25 +136,25 @@ NetExpr*PEFNumber::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
*/
|
||||
NetExpr*PEIdent::elaborate_pexpr(Design*des, NetScope*scope) const
|
||||
{
|
||||
string path = text_;
|
||||
string name = parse_last_name(path);
|
||||
hname_t path = path_;
|
||||
char*name = path.remove_tail_name();
|
||||
|
||||
NetScope*pscope = scope;
|
||||
if (path != "")
|
||||
if (path.peek_name(0))
|
||||
pscope = des->find_scope(scope, path);
|
||||
|
||||
assert(pscope);
|
||||
|
||||
const NetExpr*ex = pscope->get_parameter(name);
|
||||
if (ex == 0) {
|
||||
cerr << get_line() << ": error: identifier ``" << text_ <<
|
||||
cerr << get_line() << ": error: identifier ``" << path_ <<
|
||||
"'' is not a parameter in " << scope->name() << "." << endl;
|
||||
des->errors += 1;
|
||||
delete name;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetExpr*res = new NetEParam(des, pscope, name);
|
||||
NetExpr*res = new NetEParam(des, pscope, hname_t(name));
|
||||
assert(res);
|
||||
delete name;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -199,6 +218,20 @@ NetExpr*PEUnary::elaborate_pexpr (Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_pexpr.cc,v $
|
||||
* Revision 1.12 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.11 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.10 2001/10/07 03:38:08 steve
|
||||
* parameter names do not have defined size.
|
||||
*
|
||||
* Revision 1.9 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.8 2001/01/14 23:04:56 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
|
||||
+45
-13
@@ -17,9 +17,13 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_scope.cc,v 1.7 2000/12/16 01:45:48 steve Exp $"
|
||||
#ident "$Id: elab_scope.cc,v 1.12 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
/*
|
||||
* Elaboration happens in two passes, generally. The first scans the
|
||||
* pform to generate the NetScope tree and attach it to the Design
|
||||
@@ -51,6 +55,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// place of the elaborated expression.
|
||||
|
||||
typedef map<string,PExpr*>::const_iterator mparm_it_t;
|
||||
typedef map<hname_t,PExpr*>::const_iterator hparm_it_t;
|
||||
|
||||
|
||||
// This loop scans the parameters in the module, and creates
|
||||
@@ -108,7 +113,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
// here becuase the parameter receiving the assignment may be
|
||||
// in a scope not discovered by this pass.
|
||||
|
||||
for (mparm_it_t cur = defparms.begin()
|
||||
for (hparm_it_t cur = defparms.begin()
|
||||
; cur != defparms.end() ; cur ++ ) {
|
||||
|
||||
PExpr*ex = (*cur).second;
|
||||
@@ -130,7 +135,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
for (tasks_it_t cur = tasks_.begin()
|
||||
; cur != tasks_.end() ; cur ++ ) {
|
||||
|
||||
NetScope*task_scope = new NetScope(scope, (*cur).first,
|
||||
NetScope*task_scope = new NetScope(scope, (*cur).first.c_str(),
|
||||
NetScope::TASK);
|
||||
(*cur).second->elaborate_scope(des, task_scope);
|
||||
}
|
||||
@@ -145,7 +150,7 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
for (funcs_it_t cur = funcs_.begin()
|
||||
; cur != funcs_.end() ; cur ++ ) {
|
||||
|
||||
NetScope*func_scope = new NetScope(scope, (*cur).first,
|
||||
NetScope*func_scope = new NetScope(scope, (*cur).first.c_str(),
|
||||
NetScope::FUNC);
|
||||
(*cur).second->elaborate_scope(des, func_scope);
|
||||
}
|
||||
@@ -191,16 +196,21 @@ bool Module::elaborate_scope(Design*des, NetScope*scope) const
|
||||
|
||||
void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
{
|
||||
if (get_name() == "") {
|
||||
cerr << get_line() << ": error: Instantiation of module "
|
||||
<< mod->mod_name() << " requires an instance name." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
// Missing module instance names have already been rejected.
|
||||
assert(get_name() != "");
|
||||
|
||||
string path = sc->name();
|
||||
|
||||
// Check for duplicate scopes. Simply look up the scope I'm
|
||||
// about to create, and if I find it then somebody beat me to
|
||||
// it.
|
||||
|
||||
if (NetScope*tmp = des->find_scope(path + "." + get_name())) {
|
||||
if (NetScope*tmp = sc->child(get_name())) {
|
||||
cerr << get_line() << ": error: Instance/Scope name " <<
|
||||
get_name() << " already used in this context." <<
|
||||
endl;
|
||||
@@ -216,11 +226,11 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
if (scn->type() != NetScope::MODULE)
|
||||
continue;
|
||||
|
||||
if (mod->get_name() != scn->module_name())
|
||||
if (strcmp(mod->mod_name(), scn->module_name()) != 0)
|
||||
continue;
|
||||
|
||||
cerr << get_line() << ": error: You cannot instantiate "
|
||||
<< "module " << mod->get_name() << " within itself." << endl;
|
||||
<< "module " << mod->mod_name() << " within itself." << endl;
|
||||
|
||||
cerr << get_line() << ": : The offending instance is "
|
||||
<< sc->name() << "." << get_name() << " within "
|
||||
@@ -231,8 +241,8 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
}
|
||||
|
||||
// Create the new scope as a MODULE with my name.
|
||||
NetScope*my_scope = new NetScope(sc, get_name(), NetScope::MODULE);
|
||||
my_scope->set_module_name(mod->get_name().c_str());
|
||||
NetScope*my_scope = new NetScope(sc, get_name().c_str(), NetScope::MODULE);
|
||||
my_scope->set_module_name(mod->mod_name());
|
||||
|
||||
// Set time units and precision.
|
||||
my_scope->time_unit(mod->time_unit);
|
||||
@@ -297,7 +307,9 @@ void PGModule::elaborate_scope_mod_(Design*des, Module*mod, NetScope*sc) const
|
||||
/*
|
||||
* The isn't really able to create new scopes, but it does create the
|
||||
* event name in the current scope, so can be done during the
|
||||
* elaborate_scope scan.
|
||||
* elaborate_scope scan. Note that the name_ of the PEvent object has
|
||||
* no hierarchy, but neither does the NetEvent, until it is stored in
|
||||
* the NetScope object.
|
||||
*/
|
||||
void PEvent::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
@@ -313,6 +325,9 @@ void PFunction::elaborate_scope(Design*des, NetScope*scope) const
|
||||
void PTask::elaborate_scope(Design*des, NetScope*scope) const
|
||||
{
|
||||
assert(scope->type() == NetScope::TASK);
|
||||
|
||||
if (statement_)
|
||||
statement_->elaborate_scope(des, scope);
|
||||
}
|
||||
|
||||
|
||||
@@ -335,7 +350,7 @@ void PBlock::elaborate_scope(Design*des, NetScope*scope) const
|
||||
NetScope*my_scope = scope;
|
||||
|
||||
if (name_ != "") {
|
||||
my_scope = new NetScope(scope, name_, bl_type_==BL_PAR
|
||||
my_scope = new NetScope(scope, name_.c_str(), bl_type_==BL_PAR
|
||||
? NetScope::FORK_JOIN
|
||||
: NetScope::BEGIN_END);
|
||||
}
|
||||
@@ -444,6 +459,23 @@ void PWhile::elaborate_scope(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_scope.cc,v $
|
||||
* 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)
|
||||
*
|
||||
|
||||
+152
-45
@@ -17,15 +17,20 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: elab_sig.cc,v 1.10 2001/01/13 22:20:08 steve Exp $"
|
||||
#ident "$Id: elab_sig.cc,v 1.18 2001/12/03 04:47:14 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "Module.h"
|
||||
# include "PExpr.h"
|
||||
# include "PGate.h"
|
||||
# include "PTask.h"
|
||||
# include "PWire.h"
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "util.h"
|
||||
|
||||
/*
|
||||
@@ -34,7 +39,7 @@
|
||||
* within the port_t that have a matching name.
|
||||
*/
|
||||
static bool signal_is_in_port(const svector<Module::port_t*>&ports,
|
||||
const string&name)
|
||||
const hname_t&name)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < ports.count() ; idx += 1) {
|
||||
|
||||
@@ -48,7 +53,7 @@ static bool signal_is_in_port(const svector<Module::port_t*>&ports,
|
||||
// together that form the port.
|
||||
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
|
||||
assert(pp->expr[cc]);
|
||||
if (pp->expr[cc]->name() == name)
|
||||
if (pp->expr[cc]->path() == name)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -62,22 +67,60 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
// Get all the explicitly declared wires of the module and
|
||||
// start the signals list with them.
|
||||
const map<string,PWire*>&wl = get_wires();
|
||||
const map<hname_t,PWire*>&wl = get_wires();
|
||||
|
||||
for (map<string,PWire*>::const_iterator wt = wl.begin()
|
||||
// Scan all the ports of the module, and make sure that each
|
||||
// is connected to wires that have port declarations.
|
||||
for (unsigned idx = 0 ; idx < ports_.count() ; idx += 1) {
|
||||
Module::port_t*pp = ports_[idx];
|
||||
if (pp == 0)
|
||||
continue;
|
||||
|
||||
map<hname_t,PWire*>::const_iterator wt;
|
||||
for (unsigned cc = 0 ; cc < pp->expr.count() ; cc += 1) {
|
||||
hname_t port_path (pp->expr[cc]->path());
|
||||
wt = wl.find(port_path);
|
||||
|
||||
if (wt == wl.end()) {
|
||||
cerr << get_line() << ": error: "
|
||||
<< "Port " << pp->expr[cc]->path() << " ("
|
||||
<< (idx+1) << ") of module " << name_
|
||||
<< " is not declared within module." << endl;
|
||||
des->errors += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((*wt).second->get_port_type() == NetNet::NOT_A_PORT) {
|
||||
cerr << get_line() << ": error: "
|
||||
<< "Port " << pp->expr[cc]->path() << " ("
|
||||
<< (idx+1) << ") of module " << name_
|
||||
<< " has no direction declaration."
|
||||
<< endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (map<hname_t,PWire*>::const_iterator wt = wl.begin()
|
||||
; wt != wl.end()
|
||||
; wt ++ ) {
|
||||
|
||||
PWire*cur = (*wt).second;
|
||||
cur->elaborate_sig(des, scope);
|
||||
|
||||
NetNet*sig = scope->find_signal_in_child(cur->path());
|
||||
|
||||
// If this wire is a signal of the module (as opposed to
|
||||
// a port of a function) and is a port, then check that
|
||||
// the module knows about it.
|
||||
NetNet*sig = scope->find_signal(cur->name());
|
||||
// the module knows about it. We know that the signal is
|
||||
// the name of a signal within a subscope of a module
|
||||
// (a task, a function, etc.) if the name for the PWire
|
||||
// has hierarchy.
|
||||
|
||||
if (sig && (sig->scope() == scope)
|
||||
&& (cur->get_port_type() != NetNet::NOT_A_PORT)) {
|
||||
string name = (*wt).first;
|
||||
|
||||
hname_t name = (*wt).first;
|
||||
|
||||
if (! signal_is_in_port(ports_, name)) {
|
||||
|
||||
@@ -87,6 +130,33 @@ bool Module::elaborate_sig(Design*des, NetScope*scope) const
|
||||
des->errors += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* If the signal is an input and is also declared as a
|
||||
reg, then report an error. */
|
||||
|
||||
if (sig && (sig->scope() == scope)
|
||||
&& (sig->port_type() == NetNet::PINPUT)
|
||||
&& (sig->type() == NetNet::REG)) {
|
||||
|
||||
cerr << cur->get_line() << ": error: "
|
||||
<< cur->path() << " in module "
|
||||
<< scope->module_name()
|
||||
<< " declared as input and as a reg type." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
if (sig && (sig->scope() == scope)
|
||||
&& (sig->port_type() == NetNet::PINOUT)
|
||||
&& (sig->type() == NetNet::REG)) {
|
||||
|
||||
cerr << cur->get_line() << ": error: "
|
||||
<< cur->path() << " in module "
|
||||
<< scope->module_name()
|
||||
<< " declared as inout and as a reg type." << endl;
|
||||
des->errors += 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Get all the gates of the module and elaborate them by
|
||||
@@ -189,12 +259,13 @@ void PFunction::elaborate_sig(Design*des, NetScope*scope) const
|
||||
name. We know by design that the port name is given
|
||||
as two components: <func>.<port>. */
|
||||
|
||||
string pname = (*ports_)[idx]->name();
|
||||
string ppath = parse_first_name(pname);
|
||||
hname_t path = (*ports_)[idx]->path();
|
||||
string pname = path.peek_name(1);
|
||||
string ppath = path.peek_name(0);
|
||||
|
||||
if (ppath != scope->basename()) {
|
||||
cerr << get_line() << ": internal error: function "
|
||||
<< "port " << (*ports_)[idx]->name()
|
||||
<< "port " << (*ports_)[idx]->path()
|
||||
<< " has wrong name for function "
|
||||
<< scope->name() << "." << endl;
|
||||
des->errors += 1;
|
||||
@@ -237,16 +308,15 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
|
||||
name. We know by design that the port name is given
|
||||
as two components: <task>.<port>. */
|
||||
|
||||
string pname = (*ports_)[idx]->name();
|
||||
string ppath = parse_first_name(pname);
|
||||
assert(pname != "");
|
||||
hname_t path = (*ports_)[idx]->path();
|
||||
assert(path.peek_name(0) && path.peek_name(1));
|
||||
|
||||
/* check that the current scope really does have the
|
||||
name of the first component of the task port name. Do
|
||||
this by looking up the task scope in the parent of
|
||||
the current scope. */
|
||||
if (scope->parent()->child(ppath) != scope) {
|
||||
cerr << "internal error: task scope " << ppath
|
||||
if (scope->parent()->child(path.peek_name(0)) != scope) {
|
||||
cerr << "internal error: task scope " << path
|
||||
<< " not the same as scope " << scope->name()
|
||||
<< "?!" << endl;
|
||||
return;
|
||||
@@ -255,11 +325,11 @@ void PTask::elaborate_sig(Design*des, NetScope*scope) const
|
||||
/* Find the signal for the port. We know by definition
|
||||
that it is in the scope of the task, so look only in
|
||||
the scope. */
|
||||
NetNet*tmp = scope->find_signal(pname);
|
||||
NetNet*tmp = scope->find_signal(path.peek_name(1));
|
||||
|
||||
if (tmp == 0) {
|
||||
cerr << get_line() << ": internal error: "
|
||||
<< "Could not find port " << pname
|
||||
<< "Could not find port " << path.peek_name(1)
|
||||
<< " in scope " << scope->name() << endl;
|
||||
scope->dump(cerr);
|
||||
}
|
||||
@@ -288,19 +358,14 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
/* The parser may produce hierarchical names for wires. I here
|
||||
follow the scopes down to the base where I actually want to
|
||||
elaborate the NetNet object. */
|
||||
string basename = name_;
|
||||
for (;;) {
|
||||
string p = parse_first_name(basename);
|
||||
if (basename == "") {
|
||||
basename = p;
|
||||
break;
|
||||
}
|
||||
|
||||
scope = scope->child(p);
|
||||
assert(scope);
|
||||
{ hname_t tmp_path = hname_;
|
||||
free(tmp_path.remove_tail_name());
|
||||
for (unsigned idx = 0 ; tmp_path.peek_name(idx) ; idx += 1) {
|
||||
scope = scope->child(tmp_path.peek_name(idx));
|
||||
assert(scope);
|
||||
}
|
||||
}
|
||||
|
||||
const string path = scope->name();
|
||||
NetNet::Type wtype = type_;
|
||||
if (wtype == NetNet::IMPLICIT)
|
||||
wtype = NetNet::WIRE;
|
||||
@@ -310,6 +375,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
unsigned wid = 1;
|
||||
long lsb = 0, msb = 0;
|
||||
|
||||
assert(msb_.count() == lsb_.count());
|
||||
if (msb_.count()) {
|
||||
svector<long>mnum (msb_.count());
|
||||
svector<long>lnum (msb_.count());
|
||||
@@ -320,27 +386,35 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
here. I will resolve the values later. */
|
||||
|
||||
for (unsigned idx = 0 ; idx < msb_.count() ; idx += 1) {
|
||||
verinum*mval = msb_[idx]->eval_const(des,path);
|
||||
if (mval == 0) {
|
||||
|
||||
NetEConst*tmp;
|
||||
NetExpr*texpr = elab_and_eval(des, scope, msb_[idx]);
|
||||
|
||||
tmp = dynamic_cast<NetEConst*>(texpr);
|
||||
if (tmp == 0) {
|
||||
cerr << msb_[idx]->get_line() << ": error: "
|
||||
"Unable to evaluate constant expression ``" <<
|
||||
*msb_[idx] << "''." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
verinum*lval = lsb_[idx]->eval_const(des, path);
|
||||
if (lval == 0) {
|
||||
cerr << lsb_[idx]->get_line() << ": error: "
|
||||
|
||||
mnum[idx] = tmp->value().as_long();
|
||||
delete texpr;
|
||||
|
||||
texpr = elab_and_eval(des, scope, lsb_[idx]);
|
||||
tmp = dynamic_cast<NetEConst*>(texpr);
|
||||
if (tmp == 0) {
|
||||
cerr << msb_[idx]->get_line() << ": error: "
|
||||
"Unable to evaluate constant expression ``" <<
|
||||
*lsb_[idx] << "''." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
mnum[idx] = mval->as_long();
|
||||
lnum[idx] = lval->as_long();
|
||||
delete mval;
|
||||
delete lval;
|
||||
lnum[idx] = tmp->value().as_long();
|
||||
delete texpr;
|
||||
|
||||
}
|
||||
|
||||
/* Make sure all the values for msb and lsb match by
|
||||
@@ -350,7 +424,7 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
cerr << get_line() << ": error: Inconsistent width, "
|
||||
"[" << mnum[idx] << ":" << lnum[idx] << "]"
|
||||
" vs. [" << mnum[0] << ":" << lnum[0] << "]"
|
||||
" for signal ``" << basename << "''" << endl;
|
||||
" for signal ``" << hname_ << "''" << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
@@ -371,13 +445,13 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
// If the register has indices, then this is a
|
||||
// memory. Create the memory object.
|
||||
verinum*lval = lidx_->eval_const(des, path);
|
||||
verinum*rval = ridx_->eval_const(des, path);
|
||||
verinum*lval = lidx_->eval_const(des, scope);
|
||||
verinum*rval = ridx_->eval_const(des, scope);
|
||||
|
||||
if ((lval == 0) || (rval == 0)) {
|
||||
cerr << get_line() << ": internal error: There is "
|
||||
<< "a problem evaluating indices for ``"
|
||||
<< basename << "''." << endl;
|
||||
<< hname_.peek_tail_name() << "''." << endl;
|
||||
des->errors += 1;
|
||||
return;
|
||||
}
|
||||
@@ -385,16 +459,22 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
assert(lval);
|
||||
assert(rval);
|
||||
|
||||
string name = scope->name();
|
||||
name = name + "." + hname_.peek_tail_name();
|
||||
|
||||
long lnum = lval->as_long();
|
||||
long rnum = rval->as_long();
|
||||
delete lval;
|
||||
delete rval;
|
||||
NetMemory*sig = new NetMemory(scope, path+"."+basename,
|
||||
wid, lnum, rnum);
|
||||
NetMemory*sig = new NetMemory(scope, name, wid, lnum, rnum);
|
||||
|
||||
} else {
|
||||
|
||||
NetNet*sig = new NetNet(scope, path + "." +basename, wtype, msb, lsb);
|
||||
/* Make a hierarchical make for the signal. */
|
||||
string name = scope->name();
|
||||
name = 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());
|
||||
@@ -404,6 +484,33 @@ void PWire::elaborate_sig(Design*des, NetScope*scope) const
|
||||
|
||||
/*
|
||||
* $Log: elab_sig.cc,v $
|
||||
* Revision 1.18 2001/12/03 04:47:14 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.17 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.16 2001/11/01 05:21:26 steve
|
||||
* Catch ports that have no direction.
|
||||
*
|
||||
* Revision 1.15 2001/10/31 03:11:15 steve
|
||||
* detect module ports not declared within the module.
|
||||
*
|
||||
* Revision 1.14 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.13 2001/05/25 02:21:34 steve
|
||||
* Detect input and input ports declared as reg.
|
||||
*
|
||||
* Revision 1.12 2001/02/17 05:15:33 steve
|
||||
* Allow task ports to be given real types.
|
||||
*
|
||||
* Revision 1.11 2001/02/10 20:29:39 steve
|
||||
* In the context of range declarations, use elab_and_eval instead
|
||||
* of the less robust eval_const methods.
|
||||
*
|
||||
* Revision 1.10 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
|
||||
+383
-481
File diff suppressed because it is too large
Load Diff
@@ -17,9 +17,13 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: emit.cc,v 1.55 2000/11/04 01:54:01 steve Exp $"
|
||||
#ident "$Id: emit.cc,v 1.63 2001/10/19 21:53:24 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
/*
|
||||
* The emit function is called to generate the output required of the
|
||||
* target.
|
||||
@@ -41,12 +45,6 @@ bool NetLogic::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetUDP_COMB::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->udp_comb(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetUDP::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->udp(this);
|
||||
@@ -59,12 +57,6 @@ bool NetAddSub::emit_node(struct target_t*tgt) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetAssign_::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->net_assign(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetCaseCmp::emit_node(struct target_t*tgt) const
|
||||
{
|
||||
tgt->net_case_cmp(this);
|
||||
@@ -354,10 +346,10 @@ void NetScope::emit_defs(struct target_t*tgt) const
|
||||
break;
|
||||
|
||||
case FUNC:
|
||||
tgt->func_def(this->func_def());
|
||||
tgt->func_def(this);
|
||||
break;
|
||||
case TASK:
|
||||
tgt->task_def(this->task_def());
|
||||
tgt->task_def(this);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -377,7 +369,9 @@ bool Design::emit(struct target_t*tgt) const
|
||||
return false;
|
||||
|
||||
// enumerate the scopes
|
||||
root_scope_->emit_scope(tgt);
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->emit_scope(tgt);
|
||||
|
||||
|
||||
// emit nodes
|
||||
@@ -391,14 +385,18 @@ bool Design::emit(struct target_t*tgt) const
|
||||
|
||||
|
||||
// emit task and function definitions
|
||||
root_scope_->emit_defs(tgt);
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->emit_defs(tgt);
|
||||
|
||||
|
||||
// emit the processes
|
||||
for (const NetProcTop*idx = procs_ ; idx ; idx = idx->next_)
|
||||
rc = rc && idx->emit(tgt);
|
||||
|
||||
tgt->end_design(this);
|
||||
if (tgt->end_design(this) != 0)
|
||||
rc = false;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -448,7 +446,7 @@ void NetESignal::expr_scan(struct expr_scan_t*tgt) const
|
||||
tgt->expr_signal(this);
|
||||
}
|
||||
|
||||
void NetESubSignal::expr_scan(struct expr_scan_t*tgt) const
|
||||
void NetEBitSel::expr_scan(struct expr_scan_t*tgt) const
|
||||
{
|
||||
tgt->expr_subsignal(this);
|
||||
}
|
||||
@@ -476,6 +474,39 @@ bool emit(const Design*des, const char*type)
|
||||
|
||||
/*
|
||||
* $Log: emit.cc,v $
|
||||
* Revision 1.63 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
* Revision 1.62 2001/08/25 23:50:02 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.61 2001/07/27 04:51:44 steve
|
||||
* Handle part select expressions as variants of
|
||||
* NetESignal/IVL_EX_SIGNAL objects, instead of
|
||||
* creating new and useless temporary signals.
|
||||
*
|
||||
* Revision 1.60 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.59 2001/04/22 23:09:46 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.58 2001/04/06 02:28:02 steve
|
||||
* Generate vvp code for functions with ports.
|
||||
*
|
||||
* Revision 1.57 2001/04/02 02:28:12 steve
|
||||
* Generate code for task calls.
|
||||
*
|
||||
* Revision 1.56 2001/03/27 03:31:06 steve
|
||||
* Support error code from target_t::end_design method.
|
||||
*
|
||||
* Revision 1.55 2000/11/04 01:54:01 steve
|
||||
* Modifications in support of gcc 2.96
|
||||
*
|
||||
|
||||
@@ -17,28 +17,31 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: eval.cc,v 1.19 2001/01/27 05:41:48 steve Exp $"
|
||||
#ident "$Id: eval.cc,v 1.24 2001/12/03 04:47:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "PExpr.h"
|
||||
# include "netlist.h"
|
||||
# include "compiler.h"
|
||||
|
||||
verinum* PExpr::eval_const(const Design*, const string&) const
|
||||
verinum* PExpr::eval_const(const Design*, const NetScope*) const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum* PEBinary::eval_const(const Design*des, const string&path) const
|
||||
verinum* PEBinary::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verinum*l = left_->eval_const(des, path);
|
||||
verinum*l = left_->eval_const(des, scope);
|
||||
if (l == 0) return 0;
|
||||
verinum*r = right_->eval_const(des, path);
|
||||
verinum*r = right_->eval_const(des, scope);
|
||||
if (r == 0) {
|
||||
delete l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
verinum*res;
|
||||
|
||||
switch (op_) {
|
||||
@@ -110,11 +113,10 @@ verinum* PEBinary::eval_const(const Design*des, const string&path) const
|
||||
* Evaluate an identifier as a constant expression. This is only
|
||||
* possible if the identifier is that of a parameter.
|
||||
*/
|
||||
verinum* PEIdent::eval_const(const Design*des, const string&path) const
|
||||
verinum* PEIdent::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
const NetScope*scope = des->find_scope(path);
|
||||
assert(scope);
|
||||
const NetExpr*expr = des->find_parameter(scope, text_);
|
||||
const NetExpr*expr = des->find_parameter(scope, path_);
|
||||
|
||||
if (expr == 0)
|
||||
return 0;
|
||||
@@ -123,7 +125,7 @@ verinum* PEIdent::eval_const(const Design*des, const string&path) const
|
||||
|
||||
if (dynamic_cast<const NetEParam*>(expr)) {
|
||||
cerr << get_line() << ": sorry: I cannot evaluate ``" <<
|
||||
text_ << "'' in this context." << endl;
|
||||
path_ << "'' in this scope: " << scope->name() << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -132,20 +134,20 @@ verinum* PEIdent::eval_const(const Design*des, const string&path) const
|
||||
return new verinum(eval->value());
|
||||
}
|
||||
|
||||
verinum* PEFNumber::eval_const(const Design*, const string&) const
|
||||
verinum* PEFNumber::eval_const(const Design*, const NetScope*) const
|
||||
{
|
||||
long val = value_->as_long();
|
||||
return new verinum(val);
|
||||
}
|
||||
|
||||
verinum* PENumber::eval_const(const Design*, const string&) const
|
||||
verinum* PENumber::eval_const(const Design*, const NetScope*) const
|
||||
{
|
||||
return new verinum(value());
|
||||
}
|
||||
|
||||
verinum* PETernary::eval_const(const Design*des, const string&path) const
|
||||
verinum* PETernary::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verinum*test = expr_->eval_const(des, path);
|
||||
verinum*test = expr_->eval_const(des, scope);
|
||||
if (test == 0)
|
||||
return 0;
|
||||
|
||||
@@ -153,9 +155,9 @@ verinum* PETernary::eval_const(const Design*des, const string&path) const
|
||||
delete test;
|
||||
switch (bit) {
|
||||
case verinum::V0:
|
||||
return fal_->eval_const(des, path);
|
||||
return fal_->eval_const(des, scope);
|
||||
case verinum::V1:
|
||||
return tru_->eval_const(des, path);
|
||||
return tru_->eval_const(des, scope);
|
||||
default:
|
||||
return 0;
|
||||
// XXXX It is possible to handle this case if both fal_
|
||||
@@ -163,9 +165,9 @@ verinum* PETernary::eval_const(const Design*des, const string&path) const
|
||||
}
|
||||
}
|
||||
|
||||
verinum* PEUnary::eval_const(const Design*des, const string&path) const
|
||||
verinum* PEUnary::eval_const(const Design*des, const NetScope*scope) const
|
||||
{
|
||||
verinum*val = expr_->eval_const(des, path);
|
||||
verinum*val = expr_->eval_const(des, scope);
|
||||
if (val == 0)
|
||||
return 0;
|
||||
|
||||
@@ -194,6 +196,23 @@ verinum* PEUnary::eval_const(const Design*des, const string&path) const
|
||||
|
||||
/*
|
||||
* $Log: eval.cc,v $
|
||||
* Revision 1.24 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.23 2001/11/07 04:01:59 steve
|
||||
* eval_const uses scope instead of a string path.
|
||||
*
|
||||
* Revision 1.22 2001/11/06 06:11:55 steve
|
||||
* Support more real arithmetic in delay constants.
|
||||
*
|
||||
* Revision 1.21 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.20 2001/02/09 02:49:59 steve
|
||||
* Be more clear about scope of failure.
|
||||
*
|
||||
* Revision 1.19 2001/01/27 05:41:48 steve
|
||||
* Fix sign extension of evaluated constants. (PR#91)
|
||||
*
|
||||
@@ -211,59 +230,5 @@ verinum* PEUnary::eval_const(const Design*des, const string&path) const
|
||||
*
|
||||
* Revision 1.15 2000/09/07 22:38:13 steve
|
||||
* Support unary + and - in constants.
|
||||
*
|
||||
* Revision 1.14 2000/03/08 04:36:53 steve
|
||||
* Redesign the implementation of scopes and parameters.
|
||||
* I now generate the scopes and notice the parameters
|
||||
* in a separate pass over the pform. Once the scopes
|
||||
* are generated, I can process overrides and evalutate
|
||||
* paremeters before elaboration begins.
|
||||
*
|
||||
* Revision 1.13 2000/02/23 02:56:54 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.12 1999/11/30 04:48:17 steve
|
||||
* Handle evaluation of ternary during elaboration.
|
||||
*
|
||||
* Revision 1.11 1999/11/28 23:42:02 steve
|
||||
* NetESignal object no longer need to be NetNode
|
||||
* objects. Let them keep a pointer to NetNet objects.
|
||||
*
|
||||
* Revision 1.10 1999/11/21 20:03:24 steve
|
||||
* Handle multiply in constant expressions.
|
||||
*
|
||||
* Revision 1.9 1999/10/08 17:48:09 steve
|
||||
* Support + in constant expressions.
|
||||
*
|
||||
* Revision 1.8 1999/09/20 02:21:10 steve
|
||||
* Elaborate parameters in phases.
|
||||
*
|
||||
* Revision 1.7 1999/09/18 01:52:48 steve
|
||||
* Remove spurious message.
|
||||
*
|
||||
* Revision 1.6 1999/09/16 04:18:15 steve
|
||||
* elaborate concatenation repeats.
|
||||
*
|
||||
* Revision 1.5 1999/08/06 04:05:28 steve
|
||||
* Handle scope of parameters.
|
||||
*
|
||||
* Revision 1.4 1999/07/17 19:51:00 steve
|
||||
* netlist support for ternary operator.
|
||||
*
|
||||
* Revision 1.3 1999/05/30 01:11:46 steve
|
||||
* Exressions are trees that can duplicate, and not DAGS.
|
||||
*
|
||||
* Revision 1.2 1999/05/10 00:16:58 steve
|
||||
* Parse and elaborate the concatenate operator
|
||||
* in structural contexts, Replace vector<PExpr*>
|
||||
* and list<PExpr*> with svector<PExpr*>, evaluate
|
||||
* constant expressions with parameters, handle
|
||||
* memories as lvalues.
|
||||
*
|
||||
* Parse task declarations, integer types.
|
||||
*
|
||||
* Revision 1.1 1998/11/03 23:28:58 steve
|
||||
* Introduce verilog to CVS.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+56
-1
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: eval_rconst.cc,v 1.1 2001/01/14 23:04:56 steve Exp $"
|
||||
#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
|
||||
@@ -34,8 +36,61 @@ verireal* PEFNumber::eval_rconst(const Design*, const NetScope*) const
|
||||
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.
|
||||
|
||||
+267
-56
@@ -17,9 +17,13 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: eval_tree.cc,v 1.21 2001/01/14 23:04:56 steve Exp $"
|
||||
#ident "$Id: eval_tree.cc,v 1.30 2001/12/03 04:47:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "netlist.h"
|
||||
|
||||
NetExpr* NetExpr::eval_tree()
|
||||
@@ -112,11 +116,11 @@ NetEConst* NetEBBits::eval_tree()
|
||||
|
||||
if (lwid < rwid)
|
||||
for (unsigned idx = lwid ; idx < rwid ; idx += 1)
|
||||
res.set(idx, lval.get(idx));
|
||||
res.set(idx, rval.get(idx));
|
||||
|
||||
if (rwid < lwid)
|
||||
for (unsigned idx = rwid ; idx < lwid ; idx += 1)
|
||||
res.set(idx, rval.get(idx));
|
||||
res.set(idx, lval.get(idx));
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -148,19 +152,78 @@ NetEConst* NetEBComp::eval_eqeq_()
|
||||
const verinum&lv = l->value();
|
||||
const verinum&rv = r->value();
|
||||
|
||||
if (lv.len() < rv.len())
|
||||
return 0;
|
||||
unsigned s_len = lv.len();
|
||||
if (rv.len() < s_len) s_len = rv.len();
|
||||
|
||||
verinum result(verinum::V1, 1);
|
||||
for (unsigned idx = 0 ; idx < lv.len(); idx += 1) {
|
||||
for (unsigned idx = 0 ; idx < s_len; idx += 1) {
|
||||
if (lv[idx] != rv[idx])
|
||||
result = verinum::V0;
|
||||
}
|
||||
|
||||
// If one operand was wider than the other, check that the
|
||||
// remaining bits are all zero
|
||||
if (lv.len() > s_len) {
|
||||
for (unsigned idx = s_len; idx < lv.len(); idx += 1) {
|
||||
if (lv[idx] != 0)
|
||||
result = verinum::V0;
|
||||
}
|
||||
}
|
||||
if (rv.len() > s_len) {
|
||||
for (unsigned idx = s_len; idx < rv.len(); idx += 1) {
|
||||
if (rv[idx] != 0)
|
||||
result = verinum::V0;
|
||||
}
|
||||
}
|
||||
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
|
||||
NetEConst* NetEBComp::eval_less_()
|
||||
{
|
||||
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
||||
if (r == 0) return 0;
|
||||
|
||||
verinum rv = r->value();
|
||||
if (! rv.is_defined()) {
|
||||
verinum result(verinum::Vx, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
/* Detect the case where the right side is greater that or
|
||||
equal to the largest value the left side can possibly
|
||||
have. */
|
||||
assert(left_->expr_width() > 0);
|
||||
verinum lv (verinum::V1, left_->expr_width());
|
||||
if (lv < rv) {
|
||||
verinum result(verinum::V1, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
/* Now go on to the normal test of the values. */
|
||||
NetEConst*l = dynamic_cast<NetEConst*>(left_);
|
||||
if (l == 0) return 0;
|
||||
lv = l->value();
|
||||
if (! lv.is_defined()) {
|
||||
verinum result(verinum::Vx, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
if (lv.has_sign() && rv.has_sign() && (lv.as_long() < rv.as_long())) {
|
||||
verinum result(verinum::V1, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
if (lv.as_ulong() < rv.as_ulong()) {
|
||||
verinum result(verinum::V1, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
verinum result(verinum::V0, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_leeq_()
|
||||
{
|
||||
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
||||
@@ -205,6 +268,92 @@ NetEConst* NetEBComp::eval_leeq_()
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_gt_()
|
||||
{
|
||||
NetEConst*l = dynamic_cast<NetEConst*>(left_);
|
||||
if (l == 0) return 0;
|
||||
|
||||
verinum lv = l->value();
|
||||
if (! lv.is_defined()) {
|
||||
verinum result(verinum::Vx, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
/* Detect the case where the left side is greater than the
|
||||
largest value the right side can possibly have. */
|
||||
assert(right_->expr_width() > 0);
|
||||
verinum rv (verinum::V1, right_->expr_width());
|
||||
if (lv > rv) {
|
||||
verinum result(verinum::V1, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
/* Now go on to the normal test of the values. */
|
||||
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
||||
if (r == 0) return 0;
|
||||
rv = r->value();
|
||||
if (! rv.is_defined()) {
|
||||
verinum result(verinum::Vx, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
if (lv.has_sign() && rv.has_sign() && (lv.as_long() > rv.as_long())) {
|
||||
verinum result(verinum::V1, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
if (lv.as_ulong() > rv.as_ulong()) {
|
||||
verinum result(verinum::V1, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
verinum result(verinum::V0, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_gteq_()
|
||||
{
|
||||
NetEConst*l = dynamic_cast<NetEConst*>(left_);
|
||||
if (l == 0) return 0;
|
||||
|
||||
verinum lv = l->value();
|
||||
if (! lv.is_defined()) {
|
||||
verinum result(verinum::Vx, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
/* Detect the case where the left side is greater than the
|
||||
largest value the right side can possibly have. */
|
||||
assert(right_->expr_width() > 0);
|
||||
verinum rv (verinum::V1, right_->expr_width());
|
||||
if (lv >= rv) {
|
||||
verinum result(verinum::V1, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
/* Now go on to the normal test of the values. */
|
||||
NetEConst*r = dynamic_cast<NetEConst*>(right_);
|
||||
if (r == 0) return 0;
|
||||
rv = r->value();
|
||||
if (! rv.is_defined()) {
|
||||
verinum result(verinum::Vx, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
if (lv.has_sign() && rv.has_sign() && (lv.as_long() >= rv.as_long())) {
|
||||
verinum result(verinum::V1, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
if (lv.as_ulong() >= rv.as_ulong()) {
|
||||
verinum result(verinum::V1, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
verinum result(verinum::V0, 1);
|
||||
return new NetEConst(result);
|
||||
}
|
||||
|
||||
NetEConst* NetEBComp::eval_neeq_()
|
||||
{
|
||||
NetEConst*l = dynamic_cast<NetEConst*>(left_);
|
||||
@@ -349,6 +498,9 @@ NetEConst* NetEBComp::eval_tree()
|
||||
case 'e': // Equality (==)
|
||||
return eval_eqeq_();
|
||||
|
||||
case 'G': // >=
|
||||
return eval_gteq_();
|
||||
|
||||
case 'L': // <=
|
||||
return eval_leeq_();
|
||||
|
||||
@@ -358,14 +510,41 @@ NetEConst* NetEBComp::eval_tree()
|
||||
case 'n': // not-equal (!=)
|
||||
return eval_neeq_();
|
||||
|
||||
case '<': // Less than
|
||||
return eval_less_();
|
||||
|
||||
case '>': // Greater then
|
||||
return eval_gt_();
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The NetEBDiv operator includes the / and % opeators. First evaluate
|
||||
* the sub-expressions, then perform the required operation.
|
||||
*/
|
||||
NetEConst* NetEBDiv::eval_tree()
|
||||
{
|
||||
eval_sub_tree_();
|
||||
|
||||
NetEConst*lc = dynamic_cast<NetEConst*>(left_);
|
||||
if (lc == 0) return 0;
|
||||
NetEConst*rc = dynamic_cast<NetEConst*>(right_);
|
||||
if (rc == 0) return 0;
|
||||
|
||||
verinum lval = lc->value();
|
||||
verinum rval = rc->value();
|
||||
|
||||
switch (op_) {
|
||||
case '/':
|
||||
return new NetEConst(lval / rval);
|
||||
|
||||
case '%':
|
||||
return new NetEConst(lval % rval);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -544,6 +723,18 @@ NetEConst* NetEConcat::eval_tree()
|
||||
}
|
||||
}
|
||||
|
||||
// Handle the special case that the repeat expression is
|
||||
// zero. In this case, just return a 0 value with the expected
|
||||
// width.
|
||||
if (repeat_ == 0) {
|
||||
verinum val (verinum::V0, expr_width());
|
||||
NetEConst*res = new NetEConst(val);
|
||||
res->set_width(val.len());
|
||||
return res;
|
||||
}
|
||||
|
||||
// Figure out the width of the repeated expression, and make a
|
||||
// verinum to hold the result.
|
||||
unsigned gap = expr_width() / repeat_;
|
||||
verinum val (verinum::Vx, repeat_ * gap);
|
||||
|
||||
@@ -573,7 +764,8 @@ NetExpr* NetEParam::eval_tree()
|
||||
return 0;
|
||||
|
||||
assert(scope_);
|
||||
const NetExpr*expr = scope_->get_parameter(name_);
|
||||
assert(name_.peek_name(1) == 0);
|
||||
const NetExpr*expr = scope_->get_parameter(name_.peek_name(0));
|
||||
if (expr == 0) {
|
||||
cerr << get_line() << ": internal error: Unable to match "
|
||||
<< "parameter " << name_ << " in scope "
|
||||
@@ -601,7 +793,7 @@ NetExpr* NetEParam::eval_tree()
|
||||
|
||||
// The result can be saved as the value of the parameter for
|
||||
// future reference, and return a copy to the caller.
|
||||
scope_->set_parameter(name_, res);
|
||||
scope_->set_parameter(name_.peek_name(0), res);
|
||||
return res->dup_expr();
|
||||
}
|
||||
|
||||
@@ -616,48 +808,49 @@ NetExpr* NetETernary::eval_tree()
|
||||
{
|
||||
NetExpr*tmp;
|
||||
|
||||
/* Evaluate the cond_ to a constant. If it already is a
|
||||
constant, then there is nothing to do. */
|
||||
assert(cond_);
|
||||
if (0 == dynamic_cast<NetEConst*>(cond_)) {
|
||||
tmp = cond_->eval_tree();
|
||||
if (tmp != 0) {
|
||||
delete cond_;
|
||||
cond_ = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
assert(true_val_);
|
||||
if (0 == dynamic_cast<NetEConst*>(true_val_)) {
|
||||
tmp = true_val_->eval_tree();
|
||||
if (tmp != 0) {
|
||||
delete true_val_;
|
||||
true_val_ = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
assert(false_val_);
|
||||
if (0 == dynamic_cast<NetEConst*>(false_val_)) {
|
||||
tmp = false_val_->eval_tree();
|
||||
if (tmp != 0) {
|
||||
delete false_val_;
|
||||
false_val_ = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NetEConst*c = dynamic_cast<NetEConst*>(cond_);
|
||||
if (c == 0) {
|
||||
tmp = cond_->eval_tree();
|
||||
c = dynamic_cast<NetEConst*>(tmp);
|
||||
if (c == 0)
|
||||
return 0;
|
||||
if (c == 0)
|
||||
return 0;
|
||||
|
||||
assert(cond_ != c);
|
||||
delete cond_;
|
||||
cond_ = c;
|
||||
}
|
||||
|
||||
/* If the condition is 1 or 0, return the true or false
|
||||
expression. Try to evaluate the expression down as far as
|
||||
we can. */
|
||||
|
||||
if (c->value().get(0) == verinum::V1) {
|
||||
tmp = dynamic_cast<NetEConst*>(true_val_);
|
||||
if (tmp) return tmp->dup_expr();
|
||||
|
||||
tmp = true_val_->eval_tree();
|
||||
if (tmp) {
|
||||
delete true_val_;
|
||||
true_val_ = tmp;
|
||||
}
|
||||
if (c->value().get(0) == verinum::V1)
|
||||
return true_val_->dup_expr();
|
||||
}
|
||||
|
||||
if (c->value().get(0) == verinum::V0) {
|
||||
tmp = dynamic_cast<NetEConst*>(false_val_);
|
||||
if (tmp) return tmp->dup_expr();
|
||||
|
||||
tmp = false_val_->eval_tree();
|
||||
if (tmp) {
|
||||
delete false_val_;
|
||||
false_val_ = tmp;
|
||||
}
|
||||
if (c->value().get(0) == verinum::V0)
|
||||
return false_val_->dup_expr();
|
||||
}
|
||||
|
||||
|
||||
/* Here we have a more complex case. We need to evaluate both
|
||||
@@ -665,27 +858,14 @@ NetExpr* NetETernary::eval_tree()
|
||||
build up a constant result. */
|
||||
|
||||
NetEConst*t = dynamic_cast<NetEConst*>(true_val_);
|
||||
if (t == 0) {
|
||||
tmp = true_val_->eval_tree();
|
||||
t = dynamic_cast<NetEConst*>(tmp);
|
||||
if (t == 0)
|
||||
return 0;
|
||||
|
||||
delete true_val_;
|
||||
true_val_ = t;
|
||||
}
|
||||
if (t == 0)
|
||||
return 0;
|
||||
|
||||
|
||||
NetEConst*f = dynamic_cast<NetEConst*>(false_val_);
|
||||
if (f == 0) {
|
||||
tmp = false_val_->eval_tree();
|
||||
f = dynamic_cast<NetEConst*>(tmp);
|
||||
if (f == 0)
|
||||
return 0;
|
||||
if (f == 0)
|
||||
return 0;
|
||||
|
||||
delete false_val_;
|
||||
false_val_ = f;
|
||||
}
|
||||
|
||||
unsigned size = t->expr_width();
|
||||
assert(size == f->expr_width());
|
||||
@@ -708,6 +888,7 @@ NetExpr* NetETernary::eval_tree()
|
||||
|
||||
void NetEUnary::eval_expr_()
|
||||
{
|
||||
assert(expr_);
|
||||
if (dynamic_cast<NetEConst*>(expr_))
|
||||
return;
|
||||
|
||||
@@ -751,7 +932,6 @@ NetEConst* NetEUnary::eval_tree()
|
||||
}
|
||||
|
||||
default:
|
||||
delete rval;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -822,6 +1002,37 @@ NetEConst* NetEUReduce::eval_tree()
|
||||
|
||||
/*
|
||||
* $Log: eval_tree.cc,v $
|
||||
* Revision 1.30 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.29 2001/11/19 01:54:14 steve
|
||||
* Port close cropping behavior from mcrgb
|
||||
* Move window array reset to libmc.
|
||||
*
|
||||
* Revision 1.28 2001/10/22 15:31:21 steve
|
||||
* fix constant overrun in | operands.
|
||||
*
|
||||
* Revision 1.27 2001/10/20 00:11:24 steve
|
||||
* Evaluate constant == when operands differ in width.
|
||||
*
|
||||
* Revision 1.26 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.25 2001/07/16 20:41:41 steve
|
||||
* Handle 0 counts in repeat concatenation.
|
||||
*
|
||||
* Revision 1.24 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.23 2001/02/09 05:44:23 steve
|
||||
* support evaluation of constant < in expressions.
|
||||
*
|
||||
* Revision 1.22 2001/02/07 02:46:31 steve
|
||||
* Support constant evaluation of / and % (PR#124)
|
||||
*
|
||||
* Revision 1.21 2001/01/14 23:04:56 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
|
||||
+167
-18
@@ -17,11 +17,15 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: expr_synth.cc,v 1.19 2001/01/18 03:16:35 steve Exp $"
|
||||
#ident "$Id: expr_synth.cc,v 1.29 2001/11/29 01:58:18 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
NetNet* NetExpr::synthesize(Design*des)
|
||||
{
|
||||
@@ -38,17 +42,17 @@ NetNet* NetEBAdd::synthesize(Design*des)
|
||||
{
|
||||
assert((op()=='+') || (op()=='-'));
|
||||
|
||||
string path = des->local_symbol("SYNTH");
|
||||
NetNet*lsig = left_->synthesize(des);
|
||||
NetNet*rsig = right_->synthesize(des);
|
||||
|
||||
assert(lsig->pin_count() == rsig->pin_count());
|
||||
unsigned width=lsig->pin_count();
|
||||
|
||||
string path = lsig->scope()->name()+"."+lsig->scope()->local_symbol();
|
||||
NetNet*osig = new NetNet(lsig->scope(), path, NetNet::IMPLICIT, width);
|
||||
|
||||
string oname = des->local_symbol(path);
|
||||
NetAddSub *adder = new NetAddSub(oname, width);
|
||||
NetAddSub *adder = new NetAddSub(lsig->scope(), oname, width);
|
||||
for (unsigned idx = 0 ; idx < width; idx += 1) {
|
||||
connect(lsig->pin(idx), adder->pin_DataA(idx));
|
||||
connect(rsig->pin(idx), adder->pin_DataB(idx));
|
||||
@@ -83,6 +87,17 @@ NetNet* NetEBBits::synthesize(Design*des)
|
||||
assert(scope);
|
||||
string path = des->local_symbol(scope->name());
|
||||
|
||||
if (lsig->pin_count() != rsig->pin_count()) {
|
||||
cerr << get_line() << ": internal error: bitwise (" << op_
|
||||
<< ") widths do not match: " << lsig->pin_count()
|
||||
<< " != " << rsig->pin_count() << endl;
|
||||
cerr << get_line() << ": : width="
|
||||
<< lsig->pin_count() << ": " << *left_ << endl;
|
||||
cerr << get_line() << ": : width="
|
||||
<< rsig->pin_count() << ": " << *right_ << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert(lsig->pin_count() == rsig->pin_count());
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT,
|
||||
lsig->pin_count());
|
||||
@@ -124,6 +139,50 @@ NetNet* NetEBBits::synthesize(Design*des)
|
||||
|
||||
NetNet* NetEBComp::synthesize(Design*des)
|
||||
{
|
||||
NetEConst*lcon = reinterpret_cast<NetEConst*>(left_);
|
||||
NetEConst*rcon = reinterpret_cast<NetEConst*>(right_);
|
||||
|
||||
/* Handle the special case where one of the inputs is constant
|
||||
0. We can use an OR gate to do the comparison. Synthesize
|
||||
the non-const side as normal, then or(nor) the signals
|
||||
together to get result. */
|
||||
if ((rcon && (rcon->value() == verinum(0UL,rcon->expr_width())))
|
||||
|| (lcon && (lcon->value() == verinum(0UL,lcon->expr_width())))) {
|
||||
|
||||
NetNet*lsig = rcon
|
||||
? left_->synthesize(des)
|
||||
: right_->synthesize(des);
|
||||
NetScope*scope = lsig->scope();
|
||||
assert(scope);
|
||||
string path = des->local_symbol(scope->name());
|
||||
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, 1);
|
||||
osig->local_flag(true);
|
||||
|
||||
NetLogic*gate;
|
||||
switch (op_) {
|
||||
case 'e':
|
||||
case 'E':
|
||||
gate = new NetLogic(scope, des->local_symbol(path),
|
||||
lsig->pin_count()+1, NetLogic::NOR);
|
||||
break;
|
||||
case 'n':
|
||||
case 'N':
|
||||
gate = new NetLogic(scope, des->local_symbol(path),
|
||||
lsig->pin_count()+1, NetLogic::OR);
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
connect(gate->pin(0), osig->pin(0));
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
|
||||
connect(gate->pin(idx+1), lsig->pin(idx));
|
||||
|
||||
des->add_node(gate);
|
||||
return osig;
|
||||
}
|
||||
|
||||
NetNet*lsig = left_->synthesize(des);
|
||||
NetNet*rsig = right_->synthesize(des);
|
||||
|
||||
@@ -135,6 +194,9 @@ NetNet* NetEBComp::synthesize(Design*des)
|
||||
if (rsig->pin_count() > lsig->pin_count())
|
||||
width = rsig->pin_count();
|
||||
|
||||
lsig = pad_to_width(des, lsig, width);
|
||||
rsig = pad_to_width(des, rsig, width);
|
||||
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, 1);
|
||||
osig->local_flag(true);
|
||||
|
||||
@@ -164,7 +226,7 @@ NetNet* NetEBComp::synthesize(Design*des)
|
||||
}
|
||||
|
||||
|
||||
NetCompare*dev = new NetCompare(des->local_symbol(path), width);
|
||||
NetCompare*dev = new NetCompare(scope, des->local_symbol(path), width);
|
||||
des->add_node(dev);
|
||||
|
||||
for (unsigned idx = 0 ; idx < lsig->pin_count() ; idx += 1)
|
||||
@@ -291,27 +353,36 @@ NetNet* NetEBLogic::synthesize(Design*des)
|
||||
|
||||
NetNet* NetEConcat::synthesize(Design*des)
|
||||
{
|
||||
NetScope*scope = des->find_root_scope();
|
||||
assert(scope);
|
||||
assert(repeat_ == 1);
|
||||
/* First, synthesize the operands. */
|
||||
NetNet**tmp = new NetNet*[parms_.count()];
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
|
||||
tmp[idx] = parms_[idx]->synthesize(des);
|
||||
|
||||
string path = des->local_symbol("SYNTH");
|
||||
assert(tmp[0]);
|
||||
NetScope*scope = tmp[0]->scope();
|
||||
assert(scope);
|
||||
|
||||
/* Make a NetNet object to carry the output vector. */
|
||||
string path = scope->name() + "." + scope->local_symbol();
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, expr_width());
|
||||
osig->local_flag(true);
|
||||
|
||||
/* Connect the output vector to the operands. */
|
||||
unsigned obit = 0;
|
||||
for (unsigned idx = parms_.count() ; idx > 0 ; idx -= 1) {
|
||||
NetNet*tmp = parms_[idx-1]->synthesize(des);
|
||||
|
||||
for (unsigned bit = 0 ; bit < tmp->pin_count() ; bit += 1) {
|
||||
connect(osig->pin(obit), tmp->pin(bit));
|
||||
assert(tmp[idx-1]);
|
||||
|
||||
for (unsigned bit = 0; bit < tmp[idx-1]->pin_count(); bit += 1) {
|
||||
connect(osig->pin(obit), tmp[idx-1]->pin(bit));
|
||||
obit += 1;
|
||||
}
|
||||
|
||||
if (tmp->local_flag() && tmp->get_eref() == 0)
|
||||
delete tmp;
|
||||
if (tmp[idx-1]->local_flag() && tmp[idx-1]->get_eref() == 0)
|
||||
delete tmp[idx-1];
|
||||
}
|
||||
|
||||
delete[]tmp;
|
||||
return osig;
|
||||
}
|
||||
|
||||
@@ -320,12 +391,12 @@ NetNet* NetEConst::synthesize(Design*des)
|
||||
NetScope*scope = des->find_root_scope();
|
||||
assert(scope);
|
||||
|
||||
string path = des->local_symbol("SYNTH");
|
||||
string path = scope->name() + "." + scope->local_symbol();
|
||||
unsigned width=expr_width();
|
||||
|
||||
NetNet*osig = new NetNet(scope, path, NetNet::IMPLICIT, width);
|
||||
osig->local_flag(true);
|
||||
NetConst*con = new NetConst(des->local_symbol(path), value());
|
||||
NetConst*con = new NetConst(scope, des->local_symbol(path), value());
|
||||
for (unsigned idx = 0 ; idx < width; idx += 1)
|
||||
connect(osig->pin(idx), con->pin(idx));
|
||||
|
||||
@@ -413,11 +484,12 @@ NetNet* NetEUReduce::synthesize(Design*des)
|
||||
|
||||
NetNet* NetETernary::synthesize(Design *des)
|
||||
{
|
||||
string path = des->local_symbol("SYNTH");
|
||||
NetNet*csig = cond_->synthesize(des);
|
||||
NetNet*tsig = true_val_->synthesize(des);
|
||||
NetNet*fsig = false_val_->synthesize(des);
|
||||
|
||||
string path = csig->scope()->name()+"."+csig->scope()->local_symbol();
|
||||
|
||||
assert(csig->pin_count() == 1);
|
||||
assert(tsig->pin_count() == fsig->pin_count());
|
||||
unsigned width=tsig->pin_count();
|
||||
@@ -437,13 +509,90 @@ NetNet* NetETernary::synthesize(Design *des)
|
||||
return osig;
|
||||
}
|
||||
|
||||
/*
|
||||
* When synthesizing a signal expression, it is usually fine to simply
|
||||
* return the NetNet that it refers to. If this is a part select,
|
||||
* though, a bit more work needs to be done. Return a temporary that
|
||||
* represents the connections to the selected bits.
|
||||
*
|
||||
* For example, if there is a reg foo, like so:
|
||||
* reg [5:0] foo;
|
||||
* and this expression node represents a part select foo[3:2], then
|
||||
* create a temporary like so:
|
||||
*
|
||||
* foo
|
||||
* +---+
|
||||
* | 5 |
|
||||
* +---+
|
||||
* tmp | 4 |
|
||||
* +---+ +---+
|
||||
* | 1 | <---> | 3 |
|
||||
* +---+ +---+
|
||||
* | 0 | <---> | 2 |
|
||||
* +---+ +---+
|
||||
* | 1 |
|
||||
* +---+
|
||||
* | 0 |
|
||||
* +---+
|
||||
* The temporary is marked as a temporary and returned to the
|
||||
* caller. This causes the caller to get only the selected part of the
|
||||
* signal, and when it hooks up to tmp, it hooks up to the right parts
|
||||
* of foo.
|
||||
*/
|
||||
NetNet* NetESignal::synthesize(Design*des)
|
||||
{
|
||||
return net_;
|
||||
if ((lsi_ == 0) && (msi_ == (net_->pin_count() - 1)))
|
||||
return net_;
|
||||
|
||||
assert(msi_ >= lsi_);
|
||||
unsigned wid = msi_ - lsi_ + 1;
|
||||
|
||||
NetScope*scope = net_->scope();
|
||||
assert(scope);
|
||||
|
||||
string name = scope->name() + "." + scope->local_symbol();
|
||||
NetNet*tmp = new NetNet(scope, name, NetNet::NetNet::WIRE, wid);
|
||||
tmp->local_flag(true);
|
||||
|
||||
for (unsigned idx = 0 ; idx < wid ; idx += 1)
|
||||
connect(tmp->pin(idx), net_->pin(idx+lsi_));
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: expr_synth.cc,v $
|
||||
* Revision 1.29 2001/11/29 01:58:18 steve
|
||||
* Handle part selects in l-values of DFF devices.
|
||||
*
|
||||
* Revision 1.28 2001/10/28 01:14:53 steve
|
||||
* NetObj constructor finally requires a scope.
|
||||
*
|
||||
* Revision 1.27 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
*
|
||||
* Revision 1.26 2001/08/31 22:59:48 steve
|
||||
* synthesize the special case of compare with 0.
|
||||
*
|
||||
* Revision 1.25 2001/08/05 02:49:07 steve
|
||||
* Properly synthesize part selects.
|
||||
*
|
||||
* 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.23 2001/07/07 01:38:45 steve
|
||||
* Put synthesized signals in proper scope.
|
||||
*
|
||||
* Revision 1.22 2001/06/15 04:14:18 steve
|
||||
* Generate vvp code for GT and GE comparisons.
|
||||
*
|
||||
* Revision 1.21 2001/06/07 02:12:43 steve
|
||||
* Support structural addition.
|
||||
*
|
||||
* Revision 1.20 2001/02/15 06:59:36 steve
|
||||
* FreeBSD port has a maintainer now.
|
||||
*
|
||||
* Revision 1.19 2001/01/18 03:16:35 steve
|
||||
* NetMux needs a scope. (PR#115)
|
||||
*
|
||||
|
||||
+15
-2
@@ -17,9 +17,13 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: functor.cc,v 1.24 2000/11/19 20:48:30 steve Exp $"
|
||||
#ident "$Id: functor.cc,v 1.26 2001/10/19 21:53:24 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "functor.h"
|
||||
# include "netlist.h"
|
||||
|
||||
@@ -110,7 +114,9 @@ void NetScope::run_functor(Design*des, functor_t*fun)
|
||||
void Design::functor(functor_t*fun)
|
||||
{
|
||||
// Scan the scopes
|
||||
root_scope_->run_functor(this, fun);
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->run_functor(this, fun);
|
||||
|
||||
// apply to processes
|
||||
procs_idx_ = procs_;
|
||||
@@ -282,6 +288,13 @@ int proc_match_t::event_wait(NetEvWait*)
|
||||
|
||||
/*
|
||||
* $Log: functor.cc,v $
|
||||
* Revision 1.26 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
* Revision 1.25 2001/07/25 03:10:49 steve
|
||||
* Create a config.h.in file to hold all the config
|
||||
* junk, and support gcc 3.0. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.24 2000/11/19 20:48:30 steve
|
||||
* Fix cases where signal iteration might die early.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
|
||||
Throughout Icarus Verilog descriptions and source code, I use a
|
||||
variety of terms and acronyms that might be specific to Icarus
|
||||
Verilog, have an Icarus Verilog specific meaning, or just aren't
|
||||
widely known. So here I define these terms.
|
||||
|
||||
|
||||
LRM - Language Reference Manual
|
||||
This is a generic acronym, but in the Verilog world we sometimes
|
||||
mean *the* language reference manual, the IEEE1364 standard.
|
||||
|
||||
|
||||
PLI - Programming Language Interface
|
||||
This is a C API into Verilog simulators that is defined by the
|
||||
IEEE1364. There are two major interfaces, sometimes called PLI 1
|
||||
and PLI 2. PLI 2 is also often called VPI.
|
||||
|
||||
|
||||
UDP - User Defined Primitive
|
||||
These are objects that Verilog programmers define with the
|
||||
"primitive" keyword. They are truth-table based devices. The
|
||||
syntax for defining them is described in the LRM.
|
||||
|
||||
|
||||
VPI -
|
||||
This is the C API that is defined by the Verilog standard, and
|
||||
that Icarus Verilog partially implements. See also PLI.
|
||||
|
||||
|
||||
VVM - Verilog Virtual Machine
|
||||
This is the Icarus Verilog runtime that works with the code
|
||||
generator that generates C++.
|
||||
|
||||
|
||||
VVP - Verilog Virtual Processor
|
||||
This is the Icarus Verilog runtime that reads in custom code in a
|
||||
form that I call "VVP Assembly". See the vvp/ directory for
|
||||
documentation on that.
|
||||
|
||||
+130
-1
@@ -139,6 +139,13 @@ match the range of the integer/time declaration, but the range of
|
||||
integers is unspecified. This, by the way, also applies to module
|
||||
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
|
||||
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.
|
||||
|
||||
|
||||
* ROUNDING OF TIME
|
||||
|
||||
@@ -197,9 +204,131 @@ well as all the other major Verilog tools, but the standard does not
|
||||
say this.
|
||||
|
||||
|
||||
* UNSIZED EXPRESSIONS AS PARAMETERS TO CONCATENATION {}
|
||||
|
||||
$Id: ieee1364-notes.txt,v 1.5 2001/01/02 17:28:08 steve Exp $
|
||||
The Verilog standard clearly states in 4.1.14:
|
||||
|
||||
"Unsized constant numbers shall not be allowed in
|
||||
concatenations. This is because the size of each
|
||||
operand in the concatenation is needed to calculate
|
||||
the complete size of the concatenation."
|
||||
|
||||
So for example the expression {1'b0, 16} is clearly illegal. It
|
||||
also stands to reason that {1'b0, 15+1} is illegal, for exactly the
|
||||
same justification. What is the size of the expression (15+1)?
|
||||
Furthermore, it is reasonable to expect that (16) and (15+1) are
|
||||
exactly the same so far as the compiler is concerned.
|
||||
|
||||
Unfortunately, Cadence seems to feel otherwise. In particular, it has
|
||||
been reported that although {1'b0, 16} causes an error, {1'b0, 15+1}
|
||||
is accepted. Further testing shows that any expression other then a
|
||||
simple unsized constant is accepted there, even if all the operands of
|
||||
all the operators that make up the expression are unsized integers.
|
||||
|
||||
This is a semantic problem. Icarus Verilog doesn't limit the size of
|
||||
integer constants. This is valid as stated in 2.5.1 Note 3:
|
||||
|
||||
"The number of bits that make up an unsized number
|
||||
(which is a simple decimal number or a number without
|
||||
the size specification) shall be *at*least* 32."
|
||||
[emphasis added]
|
||||
|
||||
Icarus Verilog will hold any integer constant, so the size will be as
|
||||
large as it needs to be, whether that is 64bits, 128bits, or
|
||||
more. With this in mind, what is the value of these expressions?
|
||||
|
||||
{'h1_00_00_00_00}
|
||||
{'h1 << 32}
|
||||
{'h0_00_00_00_01 << 32}
|
||||
{'h5_00_00_00_00 + 1}
|
||||
|
||||
These examples show that the standard is justified in requiring that
|
||||
the operands of concatenation have size. The dispute is what it takes
|
||||
to cause an expression to have a size, and what that size is.
|
||||
Verilog-XL claims that (16) does not have a size, but (15+1) does. The
|
||||
size of the expression (15+1) is the size of the adder that is
|
||||
created, but how wide is the adder when adding unsized constants?
|
||||
|
||||
One might note that the quote from section 4.1.14 says "Unsized
|
||||
*constant*numbers* shall not be allowed." It does not say "Unsized
|
||||
expressions...", so arguably accepting (15+1) or even (16+0) as an
|
||||
operand to a concatenation is not a violation of the letter of the
|
||||
law. However, the very next sentence of the quote expresses the
|
||||
intent, and accepting (15+1) as having a more defined size then (16)
|
||||
seems to be a violation of that intent.
|
||||
|
||||
Whatever a compiler decides the size is, the user has no way to
|
||||
predict it, and the compiler should not have the right to treat (15+1)
|
||||
any differently then (16). Therefore, Icarus Verilog takes the
|
||||
position that such expressions are *unsized* and are not allowed as
|
||||
operands to concatenations. Icarus Verilog will in general assume that
|
||||
operations on unsized numbers produce unsized results. There are
|
||||
exceptions when the operator itself does define a size, such as the
|
||||
comparison operators or the reduction operators. Icarus Verilog will
|
||||
generate appropriate error messages.
|
||||
|
||||
|
||||
* MODULE INSTANCE WITH WRONG SIZE PORT LIST
|
||||
|
||||
A module declaration like this declares a module that takes three ports:
|
||||
|
||||
module three (a, b, c);
|
||||
input a, b, c;
|
||||
reg x;
|
||||
endmodule
|
||||
|
||||
This is fine and obvious. It is also clear from the standard that
|
||||
these are legal instantiations of this module:
|
||||
|
||||
three u1 (x,y,z);
|
||||
three u2 ( ,y, );
|
||||
three u3 ( , , );
|
||||
three u4 (.b(y));
|
||||
|
||||
In some of the above examples, there are unconnected ports. In the
|
||||
case of u4, the pass by name connects only port b, and leaves a and c
|
||||
unconnected. u2 and u4 are the same thing, in fact, but using
|
||||
positional or by-name syntax. The next example is a little less
|
||||
obvious:
|
||||
|
||||
three u4 ();
|
||||
|
||||
The trick here is that strictly speaking, the parser cannot tell
|
||||
whether this is a list of no pass by name ports (that is, all
|
||||
unconnected) or an empty positional list. If this were an empty
|
||||
positional list, then the wrong number of ports is given, but if it is
|
||||
an empty by-name list, it is an obviously valid instantiation. So it
|
||||
is fine to accept this case as valid.
|
||||
|
||||
These are more doubtful:
|
||||
|
||||
three u5(x,y);
|
||||
three u6(,);
|
||||
|
||||
These are definitely positional port lists, and they are definitely
|
||||
the wrong length. In this case, the standard is not explicit about
|
||||
what to do about positional port lists in module instantiations,
|
||||
except that the first is connected to the first, second to second,
|
||||
etc. It does not say that the list must be the right length, but every
|
||||
example of unconnected ports used by-name syntax, and every example of
|
||||
ordered list has the right size list.
|
||||
|
||||
Icarus Verilog takes the (very weak) hint that ordered lists should be
|
||||
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 $
|
||||
$Log: ieee1364-notes.txt,v $
|
||||
Revision 1.8 2001/08/01 05:17:31 steve
|
||||
Accept empty port lists to module instantiation.
|
||||
|
||||
Revision 1.7 2001/02/17 05:27:31 steve
|
||||
I allow function ports to have types.
|
||||
|
||||
Revision 1.6 2001/02/12 16:48:04 steve
|
||||
Rant about bit widths.
|
||||
|
||||
Revision 1.5 2001/01/02 17:28:08 steve
|
||||
Resolve repeat ambiguity in favor of loop.
|
||||
|
||||
|
||||
+22
-6
@@ -43,6 +43,9 @@
|
||||
#
|
||||
# %W Substitute the ivl warning flags.
|
||||
#
|
||||
# %y Substitute all the -y flags here.
|
||||
# %Y Substitute all the -Y flags here.
|
||||
#
|
||||
# %[<c><text>]
|
||||
# This substitution pattern is magical, and is the only
|
||||
# multicharacter pattern. This tests the code <c>, and
|
||||
@@ -56,10 +59,20 @@
|
||||
# be useful and interesting if the -N flag is included.
|
||||
|
||||
[-tnull -S]
|
||||
<ivl>%B/ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -- -
|
||||
<ivl>%B/ivl %[v-v] %y %Y %W %s %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -Fsynth -Fsyn-rules -- -
|
||||
|
||||
[-tnull]
|
||||
<ivl>%B/ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -- -
|
||||
<ivl>%B/ivl %[v-v] %y %Y %W %s %[N-N%N] %[T-T%T] -tdll -fDLL=%B/null.tgt -- -
|
||||
|
||||
# --
|
||||
# The vvp target generates code that the vvp simulation engine can execute.
|
||||
# These rules support synthesized and non-synthesized variants.
|
||||
|
||||
[-tvvp -S]
|
||||
<ivl>%B/ivl %[v-v] %y %Y %W %s %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -fVVP_EXECUTABLE=%B/../../bin/vvp -Fsynth -Fsyn-rules -Fcprop -Fnodangle %f %m -o%o -- -
|
||||
|
||||
[-tvvp]
|
||||
<ivl>%B/ivl %[v-v] %y %Y %W %s %[N-N%N] %[T-T%T] -tdll -fDLL=%B/vvp.tgt -fVVP_EXECUTABLE=%B/../../bin/vvp -Fcprop -Fnodangle %f %m -o%o -- -
|
||||
|
||||
# --
|
||||
# The vvm target uses the <ivl> string to take the preprocessed code from
|
||||
@@ -68,17 +81,20 @@
|
||||
# on the result.
|
||||
|
||||
[-tvvm]
|
||||
<ivl>%B/ivl %W %[s-s%s] %[N-N%N] %[T-T%T] -tvvm -Fcprop -Fnodangle -fVPI_MODULE_PATH=%B %f %m -o%o.cc -- -
|
||||
<ivl>%B/ivl %[v-v] %y %Y %W %s %[N-N%N] %[T-T%T] -tvvm -Fcprop -Fnodangle -fVPI_MODULE_PATH=%B %f %m -o%o.cc -- -
|
||||
|
||||
|
||||
# -- (not supported yet)
|
||||
# This is the XNF code generator.
|
||||
|
||||
[-txnf]
|
||||
<ivl>%B/ivl %[s-s%s] %[N-N%N] %[T-T%T] -tvvm -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- -
|
||||
<ivl>%B/ivl %y %Y %[v-v] %s %[N-N%N] %[T-T%T] -txnf -Fsynth -Fsyn-rules -Fxnfio -Fcprop -Fnodangle -o%o -- -
|
||||
|
||||
# And this is another XNF code generator, under development.
|
||||
[-tfpga]
|
||||
<ivl>%B/ivl %y %Y %[v-v] %s %[N-N%N] %[T-T%T] %f -tdll -fDLL=%B/fpga.tgt -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- -
|
||||
|
||||
# --
|
||||
# This is the pal code generator. The target module requires the -fpart=<type>
|
||||
# flag to specify the part type.
|
||||
[-tpal]
|
||||
<ivl>%B/ivl %[s-s%s] %[N-N%N] %[T-T%T] -tdll -fDLL=%B/pal.tgt -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- -
|
||||
<ivl>%B/ivl %y %Y %[v-v] %s %[N-N%N] %[T-T%T] -tdll -fDLL=%B/pal.tgt -Fsynth -Fsyn-rules -Fcprop -Fnodangle -o%o -- -
|
||||
|
||||
@@ -1,16 +1,32 @@
|
||||
EXPORTS
|
||||
|
||||
ivl_design_const
|
||||
ivl_design_consts
|
||||
ivl_design_flag
|
||||
ivl_design_process
|
||||
ivl_design_root
|
||||
ivl_design_roots
|
||||
ivl_design_time_precision
|
||||
|
||||
ivl_const_bits
|
||||
ivl_const_pin
|
||||
ivl_const_pins
|
||||
ivl_const_signed
|
||||
|
||||
ivl_event_any
|
||||
ivl_event_basename
|
||||
ivl_event_name
|
||||
ivl_event_nany
|
||||
ivl_event_neg
|
||||
ivl_event_nneg
|
||||
ivl_event_npos
|
||||
ivl_event_pos
|
||||
|
||||
ivl_expr_type
|
||||
ivl_expr_bits
|
||||
ivl_expr_def
|
||||
ivl_expr_lsi
|
||||
ivl_expr_memory
|
||||
ivl_expr_name
|
||||
ivl_expr_opcode
|
||||
ivl_expr_oper1
|
||||
@@ -19,44 +35,82 @@ ivl_expr_oper3
|
||||
ivl_expr_parm
|
||||
ivl_expr_parms
|
||||
ivl_expr_repeat
|
||||
ivl_expr_scope
|
||||
ivl_expr_signal
|
||||
ivl_expr_signed
|
||||
ivl_expr_string
|
||||
ivl_expr_uvalue
|
||||
ivl_expr_width
|
||||
|
||||
ivl_logic_attr
|
||||
ivl_logic_delay
|
||||
ivl_logic_name
|
||||
ivl_logic_basename
|
||||
ivl_logic_scope
|
||||
ivl_logic_type
|
||||
ivl_logic_pin
|
||||
ivl_logic_pins
|
||||
ivl_logic_udp
|
||||
|
||||
ivl_lpm_basename
|
||||
ivl_lpm_clk
|
||||
ivl_lpm_data
|
||||
ivl_lpm_datab
|
||||
ivl_lpm_data2
|
||||
ivl_lpm_enable
|
||||
ivl_lpm_memory
|
||||
ivl_lpm_name
|
||||
ivl_lpm_q
|
||||
ivl_lpm_scope
|
||||
ivl_lpm_select
|
||||
ivl_lpm_selects
|
||||
ivl_lpm_size
|
||||
ivl_lpm_type
|
||||
ivl_lpm_width
|
||||
|
||||
ivl_lpm_ff
|
||||
ivl_lpm_ff_clk
|
||||
ivl_lpm_ff_data
|
||||
ivl_lpm_ff_q
|
||||
|
||||
ivl_lval_idx
|
||||
ivl_lval_mem
|
||||
ivl_lval_mux
|
||||
ivl_lval_part_off
|
||||
ivl_lval_pin
|
||||
ivl_lval_pins
|
||||
ivl_lval_sig
|
||||
|
||||
ivl_memory_basename
|
||||
ivl_memory_name
|
||||
ivl_memory_root
|
||||
ivl_memory_size
|
||||
ivl_memory_width
|
||||
|
||||
ivl_nexus_get_private
|
||||
ivl_nexus_name
|
||||
ivl_nexus_ptrs
|
||||
ivl_nexus_ptr
|
||||
ivl_nexus_set_private
|
||||
|
||||
ivl_nexus_ptr_con
|
||||
ivl_nexus_ptr_drive0
|
||||
ivl_nexus_ptr_drive1
|
||||
ivl_nexus_ptr_pin
|
||||
ivl_nexus_ptr_lpm
|
||||
ivl_nexus_ptr_log
|
||||
ivl_nexus_ptr_sig
|
||||
|
||||
ivl_scope_basename
|
||||
ivl_scope_children
|
||||
ivl_scope_def
|
||||
ivl_scope_event
|
||||
ivl_scope_events
|
||||
ivl_scope_logs
|
||||
ivl_scope_log
|
||||
ivl_scope_lpms
|
||||
ivl_scope_lpm
|
||||
ivl_scope_mem
|
||||
ivl_scope_mems
|
||||
ivl_scope_name
|
||||
ivl_scope_parent
|
||||
ivl_scope_port
|
||||
ivl_scope_ports
|
||||
ivl_scope_sigs
|
||||
ivl_scope_sig
|
||||
ivl_scope_type
|
||||
@@ -66,26 +120,43 @@ ivl_signal_attr
|
||||
ivl_signal_pin
|
||||
ivl_signal_pins
|
||||
ivl_signal_port
|
||||
ivl_signal_signed
|
||||
ivl_signal_type
|
||||
ivl_signal_name
|
||||
ivl_signal_basename
|
||||
|
||||
ivl_process_type
|
||||
ivl_process_scope
|
||||
ivl_process_stmt
|
||||
ivl_process_type
|
||||
|
||||
ivl_statement_type
|
||||
|
||||
ivl_stmt_block_count
|
||||
ivl_stmt_block_stmt
|
||||
ivl_stmt_call
|
||||
ivl_stmt_case_count
|
||||
ivl_stmt_case_expr
|
||||
ivl_stmt_case_stmt
|
||||
ivl_stmt_cond_expr
|
||||
ivl_stmt_cond_false
|
||||
ivl_stmt_cond_true
|
||||
ivl_stmt_delay_expr
|
||||
ivl_stmt_delay_val
|
||||
ivl_stmt_event
|
||||
ivl_stmt_lval
|
||||
ivl_stmt_lvals
|
||||
ivl_stmt_lwidth
|
||||
ivl_stmt_name
|
||||
ivl_stmt_nexus
|
||||
ivl_stmt_nexus_count
|
||||
ivl_stmt_parm
|
||||
ivl_stmt_parm_count
|
||||
ivl_stmt_rval
|
||||
ivl_stmt_sub_stmt
|
||||
|
||||
ivl_udp_init
|
||||
ivl_udp_name
|
||||
ivl_udp_nin
|
||||
ivl_udp_row
|
||||
ivl_udp_rows
|
||||
ivl_udp_sequ
|
||||
|
||||
+554
-64
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: ivl_target.h,v 1.34 2001/01/15 22:05:14 steve Exp $"
|
||||
#ident "$Id: ivl_target.h,v 1.89 2001/12/06 03:11:00 steve Exp $"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -61,6 +61,11 @@ _BEGIN_DECL
|
||||
* This object represents the entire elaborated design. Various
|
||||
* global properties and methods are available from this.
|
||||
*
|
||||
* ivl_event_t
|
||||
* This object represents an event node. An event node stands for
|
||||
* named events written explicitly in the Verilog, and net events
|
||||
* that are implicit when @ statements are used.
|
||||
*
|
||||
* ivl_expr_t
|
||||
* This object represents a node of an expression. If the
|
||||
* expression has sub-expressions, they can be accessed from
|
||||
@@ -77,12 +82,6 @@ _BEGIN_DECL
|
||||
* device nodes. This object carries a few base properties
|
||||
* (including a type) including a handle to the specific type.
|
||||
*
|
||||
* All the ivl_lpm_*_t objects are derived from this type, and
|
||||
* there are methods to get one from the other.
|
||||
*
|
||||
* ivl_lpm_ff_t
|
||||
* This is a flip-flop.
|
||||
*
|
||||
* ivl_net_logic_t
|
||||
* This object represents various built in logic devices. In fact,
|
||||
* this includes just about every directional device that has a
|
||||
@@ -123,19 +122,20 @@ _BEGIN_DECL
|
||||
* they include the instance name of the module that contains them.
|
||||
*/
|
||||
typedef struct ivl_design_s *ivl_design_t;
|
||||
typedef struct ivl_event_s *ivl_event_t;
|
||||
typedef struct ivl_expr_s *ivl_expr_t;
|
||||
typedef struct ivl_lpm_s *ivl_lpm_t;
|
||||
typedef struct ivl_lpm_ff_s *ivl_lpm_ff_t;
|
||||
typedef struct ivl_lval_s *ivl_lval_t;
|
||||
typedef struct ivl_net_const_s*ivl_net_const_t;
|
||||
typedef struct ivl_net_event_s*ivl_net_event_t;
|
||||
typedef struct ivl_net_logic_s*ivl_net_logic_t;
|
||||
typedef struct ivl_udp_s *ivl_udp_t;
|
||||
typedef struct ivl_net_probe_s*ivl_net_probe_t;
|
||||
typedef struct ivl_nexus_s *ivl_nexus_t;
|
||||
typedef struct ivl_nexus_ptr_s*ivl_nexus_ptr_t;
|
||||
typedef struct ivl_process_s *ivl_process_t;
|
||||
typedef struct ivl_scope_s *ivl_scope_t;
|
||||
typedef struct ivl_signal_s *ivl_signal_t;
|
||||
typedef struct ivl_memory_s *ivl_memory_t;
|
||||
typedef struct ivl_statement_s*ivl_statement_t;
|
||||
|
||||
/*
|
||||
@@ -144,43 +144,78 @@ typedef struct ivl_statement_s*ivl_statement_t;
|
||||
* changes and additions to the enumerations.
|
||||
*/
|
||||
|
||||
typedef enum ivl_drive_e {
|
||||
IVL_DR_HiZ = 0,
|
||||
IVL_DR_SMALL = 1,
|
||||
IVL_DR_MEDIUM = 2,
|
||||
IVL_DR_WEAK = 3,
|
||||
IVL_DR_LARGE = 4,
|
||||
IVL_DR_PULL = 5,
|
||||
IVL_DR_STRONG = 6,
|
||||
IVL_DR_SUPPLY = 7
|
||||
} ivl_drive_t;
|
||||
|
||||
/* This is the type of an ivl_expr_t object. */
|
||||
typedef enum ivl_expr_type_e {
|
||||
IVL_EX_NONE = 0,
|
||||
IVL_EX_BITSEL,
|
||||
IVL_EX_BINARY,
|
||||
IVL_EX_CONCAT,
|
||||
IVL_EX_MEMORY,
|
||||
IVL_EX_NUMBER,
|
||||
IVL_EX_SCOPE,
|
||||
IVL_EX_SFUNC,
|
||||
IVL_EX_SIGNAL,
|
||||
IVL_EX_STRING,
|
||||
IVL_EX_SUBSIG,
|
||||
IVL_EX_TERNARY,
|
||||
IVL_EX_UFUNC,
|
||||
IVL_EX_ULONG,
|
||||
IVL_EX_UNARY
|
||||
} ivl_expr_type_t;
|
||||
|
||||
/* This is the type code for an ivl_net_logic_t object. */
|
||||
typedef enum ivl_logic_e {
|
||||
IVL_LO_NONE = 0,
|
||||
IVL_LO_AND,
|
||||
IVL_LO_BUF,
|
||||
IVL_LO_BUFIF0,
|
||||
IVL_LO_BUFIF1,
|
||||
IVL_LO_BUFZ,
|
||||
IVL_LO_NAND,
|
||||
IVL_LO_NMOS,
|
||||
IVL_LO_NOR,
|
||||
IVL_LO_NOT,
|
||||
IVL_LO_NOTIF0,
|
||||
IVL_LO_NOTIF1,
|
||||
IVL_LO_OR,
|
||||
IVL_LO_RNMOS,
|
||||
IVL_LO_RPMOS,
|
||||
IVL_LO_PMOS,
|
||||
IVL_LO_XNOR,
|
||||
IVL_LO_XOR
|
||||
IVL_LO_NONE = 0,
|
||||
IVL_LO_AND = 1,
|
||||
IVL_LO_BUF = 2,
|
||||
IVL_LO_BUFIF0 = 3,
|
||||
IVL_LO_BUFIF1 = 4,
|
||||
IVL_LO_BUFZ = 5,
|
||||
IVL_LO_NAND = 6,
|
||||
IVL_LO_NMOS = 7,
|
||||
IVL_LO_NOR = 8,
|
||||
IVL_LO_NOT = 9,
|
||||
IVL_LO_NOTIF0 = 10,
|
||||
IVL_LO_NOTIF1 = 11,
|
||||
IVL_LO_OR = 12,
|
||||
IVL_LO_PULLDOWN = 13,
|
||||
IVL_LO_PULLUP = 14,
|
||||
IVL_LO_RNMOS = 15,
|
||||
IVL_LO_RPMOS = 16,
|
||||
IVL_LO_PMOS = 17,
|
||||
IVL_LO_XNOR = 18,
|
||||
IVL_LO_XOR = 19,
|
||||
|
||||
IVL_LO_EEQ = 20,
|
||||
|
||||
IVL_LO_UDP = 21
|
||||
} ivl_logic_t;
|
||||
|
||||
/* This is the type of an LPM object. */
|
||||
typedef enum ivl_lpm_type_e {
|
||||
IVL_LPM_FF
|
||||
IVL_LPM_ADD = 0,
|
||||
IVL_LPM_CMP_EQ = 10,
|
||||
IVL_LPM_CMP_GE = 1,
|
||||
IVL_LPM_CMP_GT = 2,
|
||||
IVL_LPM_CMP_NE = 11,
|
||||
IVL_LPM_DIVIDE = 12,
|
||||
IVL_LPM_FF = 3,
|
||||
IVL_LPM_MULT = 4,
|
||||
IVL_LPM_MUX = 5,
|
||||
IVL_LPM_SHIFTL = 6,
|
||||
IVL_LPM_SHIFTR = 7,
|
||||
IVL_LPM_SUB = 8,
|
||||
IVL_LPM_RAM = 9
|
||||
} ivl_lpm_type_t;
|
||||
|
||||
/* Processes are initial or always blocks with a statement. This is
|
||||
@@ -232,12 +267,25 @@ typedef enum ivl_statement_type_e {
|
||||
IVL_ST_NONE = 0,
|
||||
IVL_ST_NOOP = 1,
|
||||
IVL_ST_ASSIGN,
|
||||
IVL_ST_ASSIGN_NB,
|
||||
IVL_ST_BLOCK,
|
||||
IVL_ST_CASE,
|
||||
IVL_ST_CASEX,
|
||||
IVL_ST_CASEZ,
|
||||
IVL_ST_CASSIGN,
|
||||
IVL_ST_CONDIT,
|
||||
IVL_ST_DEASSIGN,
|
||||
IVL_ST_DELAY,
|
||||
IVL_ST_DELAYX,
|
||||
IVL_ST_DISABLE,
|
||||
IVL_ST_FORCE,
|
||||
IVL_ST_FOREVER,
|
||||
IVL_ST_FORK,
|
||||
IVL_ST_RELEASE,
|
||||
IVL_ST_REPEAT,
|
||||
IVL_ST_STASK,
|
||||
IVL_ST_TRIGGER,
|
||||
IVL_ST_UTASK,
|
||||
IVL_ST_WAIT,
|
||||
IVL_ST_WHILE
|
||||
} ivl_statement_type_t;
|
||||
@@ -278,12 +326,23 @@ typedef int (ivl_scope_f)(ivl_scope_t net, void*cd);
|
||||
* A design has a root named scope that is an instance of the top
|
||||
* level module in the design. This is a hook for naming the
|
||||
* design, or for starting the scope scan.
|
||||
*
|
||||
* ivl_design_time_precision
|
||||
* A design as a time precision. This is the size in seconds (a
|
||||
* signed power of 10) of a simulation tick.
|
||||
*/
|
||||
|
||||
extern const char* ivl_design_flag(ivl_design_t des, const char*key);
|
||||
extern int ivl_design_process(ivl_design_t des,
|
||||
ivl_process_f fun, void*cd);
|
||||
extern ivl_scope_t ivl_design_root(ivl_design_t des);
|
||||
extern void ivl_design_roots(ivl_design_t des,
|
||||
ivl_scope_t **scopes,
|
||||
unsigned int *nscopes);
|
||||
extern int ivl_design_time_precision(ivl_design_t des);
|
||||
|
||||
extern unsigned ivl_design_consts(ivl_design_t des);
|
||||
extern ivl_net_const_t ivl_design_const(ivl_design_t, unsigned idx);
|
||||
|
||||
/*
|
||||
* These methods apply to ivl_net_const_t objects.
|
||||
@@ -293,6 +352,31 @@ extern ivl_nexus_t ivl_const_pin(ivl_net_const_t net, unsigned idx);
|
||||
extern unsigned ivl_const_pins(ivl_net_const_t net);
|
||||
extern int ivl_const_signed(ivl_net_const_t net);
|
||||
|
||||
/* EVENTS
|
||||
*
|
||||
* Events are a unification of named events and implicit events
|
||||
* generated by the @ statements.
|
||||
*
|
||||
* ivl_event_name
|
||||
* ivl_event_basename
|
||||
*
|
||||
* ivl_event_edge
|
||||
* Return the edge type for the event. If this is a named event
|
||||
* that has no network input, then the edge is IVL_EDGE_NONE.
|
||||
*/
|
||||
extern const char* ivl_event_name(ivl_event_t net);
|
||||
extern const char* ivl_event_basename(ivl_event_t net);
|
||||
|
||||
extern unsigned ivl_event_nany(ivl_event_t net);
|
||||
extern ivl_nexus_t ivl_event_any(ivl_event_t net, unsigned idx);
|
||||
|
||||
extern unsigned ivl_event_nneg(ivl_event_t net);
|
||||
extern ivl_nexus_t ivl_event_neg(ivl_event_t net, unsigned idx);
|
||||
|
||||
extern unsigned ivl_event_npos(ivl_event_t net);
|
||||
extern ivl_nexus_t ivl_event_pos(ivl_event_t net, unsigned idx);
|
||||
|
||||
|
||||
/* EXPRESSIONS
|
||||
*
|
||||
* These methods operate on expression objects from the
|
||||
@@ -321,29 +405,51 @@ extern ivl_expr_type_t ivl_expr_type(ivl_expr_t net);
|
||||
|
||||
/* IVL_EX_NUMBER */
|
||||
extern const char* ivl_expr_bits(ivl_expr_t net);
|
||||
/* IVL_EX_SIGNAL, IVL_EX_SFUNC */
|
||||
/* IVL_EX_UFUNC */
|
||||
extern ivl_scope_t ivl_expr_def(ivl_expr_t net);
|
||||
/* IVL_EX_SIGNAL */
|
||||
extern unsigned ivl_expr_lsi(ivl_expr_t net);
|
||||
/* IVL_EX_SIGNAL, IVL_EX_SFUNC, IVL_EX_MEMORY */
|
||||
extern const char* ivl_expr_name(ivl_expr_t net);
|
||||
/* IVL_EX_BINARY */
|
||||
/* IVL_EX_BINARY IVL_EX_UNARY */
|
||||
extern char ivl_expr_opcode(ivl_expr_t net);
|
||||
/* IVL_EX_BINARY */
|
||||
/* IVL_EX_BINARY IVL_EX_BITSEL IVL_EX_UNARY, IVL_EX_MEMORY IVL_EX_TERNARY */
|
||||
extern ivl_expr_t ivl_expr_oper1(ivl_expr_t net);
|
||||
/* IVL_EX_BINARY */
|
||||
/* IVL_EX_BINARY IVL_EX_TERNARY */
|
||||
extern ivl_expr_t ivl_expr_oper2(ivl_expr_t net);
|
||||
/* */
|
||||
/* IVL_EX_TERNARY */
|
||||
extern ivl_expr_t ivl_expr_oper3(ivl_expr_t net);
|
||||
/* IVL_EX_CONCAT */
|
||||
/* IVL_EX_CONCAT IVL_EX_UFUNC */
|
||||
extern ivl_expr_t ivl_expr_parm(ivl_expr_t net, unsigned idx);
|
||||
/* IVL_EX_CONCAT */
|
||||
/* IVL_EX_CONCAT IVL_EX_SFUNC IVL_EX_UFUNC */
|
||||
extern unsigned ivl_expr_parms(ivl_expr_t net);
|
||||
/* IVL_EX_CONCAT */
|
||||
extern unsigned ivl_expr_repeat(ivl_expr_t net);
|
||||
/* IVL_EX_SCOPE */
|
||||
extern ivl_scope_t ivl_expr_scope(ivl_expr_t net);
|
||||
/* IVL_EX_BITSEL */
|
||||
extern ivl_signal_t ivl_expr_signal(ivl_expr_t net);
|
||||
/* any expression */
|
||||
extern int ivl_expr_signed(ivl_expr_t net);
|
||||
/* IVL_EX_STRING */
|
||||
extern const char* ivl_expr_string(ivl_expr_t net);
|
||||
/* IVL_EX_ULONG */
|
||||
extern unsigned long ivl_expr_uvalue(ivl_expr_t net);
|
||||
/* any expression */
|
||||
extern unsigned ivl_expr_width(ivl_expr_t net);
|
||||
|
||||
/*
|
||||
* Memory.
|
||||
*
|
||||
*/
|
||||
|
||||
extern const char*ivl_memory_name(ivl_memory_t net);
|
||||
extern const char*ivl_memory_basename(ivl_memory_t net);
|
||||
extern int ivl_memory_root(ivl_memory_t net);
|
||||
extern unsigned ivl_memory_size(ivl_memory_t net);
|
||||
extern unsigned ivl_memory_width(ivl_memory_t net);
|
||||
extern ivl_memory_t ivl_expr_memory(ivl_expr_t net);
|
||||
|
||||
/* LOGIC
|
||||
* These types and functions support manipulation of logic gates. The
|
||||
* ivl_logic_t enumeration identifies the various kinds of gates that
|
||||
@@ -363,21 +469,55 @@ extern unsigned ivl_expr_width(ivl_expr_t net);
|
||||
* ivl_logic_basename
|
||||
* This is the name of the gate without the scope part.
|
||||
*
|
||||
* ivl_logic_scope
|
||||
* This is the scope that directly contains the logic device.
|
||||
*
|
||||
* ivl_logic_pins
|
||||
* ivl_logic_pin
|
||||
*
|
||||
* ivl_logic_attr
|
||||
* Return the value of a specific attribute, given the key name as
|
||||
* a string. If the key is not defined, then return 0 (null).
|
||||
*/
|
||||
|
||||
extern const char* ivl_logic_name(ivl_net_logic_t net);
|
||||
extern const char* ivl_logic_basename(ivl_net_logic_t net);
|
||||
extern ivl_scope_t ivl_logic_scope(ivl_net_logic_t net);
|
||||
extern ivl_logic_t ivl_logic_type(ivl_net_logic_t net);
|
||||
extern ivl_nexus_t ivl_logic_pin(ivl_net_logic_t net, unsigned pin);
|
||||
extern unsigned ivl_logic_pins(ivl_net_logic_t net);
|
||||
extern ivl_udp_t ivl_logic_udp(ivl_net_logic_t net);
|
||||
extern unsigned ivl_logic_delay(ivl_net_logic_t net, unsigned transition);
|
||||
|
||||
extern const char* ivl_logic_attr(ivl_net_logic_t net, const char*key);
|
||||
|
||||
/* UDP
|
||||
*
|
||||
*/
|
||||
|
||||
extern unsigned ivl_udp_sequ(ivl_udp_t net);
|
||||
extern unsigned ivl_udp_nin(ivl_udp_t net);
|
||||
extern unsigned ivl_udp_init(ivl_udp_t net);
|
||||
extern const char* ivl_udp_row(ivl_udp_t net, unsigned idx);
|
||||
extern unsigned ivl_udp_rows(ivl_udp_t net);
|
||||
extern const char* ivl_udp_name(ivl_udp_t net);
|
||||
|
||||
|
||||
/* LPM
|
||||
* These functions support access to the properties of LPM devices.
|
||||
* These functions support access to the properties of LPM
|
||||
* devices. LPM devices are a variety of devices that handle more
|
||||
* complex structural semantics.
|
||||
*
|
||||
* These are the functions that apply to all LPM devices:
|
||||
*
|
||||
* ivl_lpm_name
|
||||
* Return the name of the device.
|
||||
* ivl_lpm_basename
|
||||
* Return the name of the device. The name is the name of the
|
||||
* device with the scope part, and the basename is without the scope.
|
||||
*
|
||||
* ivl_lpm_scope
|
||||
* LPM devices exist within a scope. Return the scope that contains
|
||||
* this device.
|
||||
*
|
||||
* ivl_lpm_type
|
||||
* Return the ivl_lpm_type_t of the secific LPM device.
|
||||
@@ -386,34 +526,97 @@ extern unsigned ivl_logic_pins(ivl_net_logic_t net);
|
||||
* Return the width of the LPM device. What this means depends on
|
||||
* the LPM type, but it generally has to do with the width of the
|
||||
* output data path.
|
||||
*
|
||||
*
|
||||
* These functions apply to a subset of the LPM devices, or may have
|
||||
* varying meaning depending on the device:
|
||||
*
|
||||
* ivl_lpm_data
|
||||
* Return the input data nexus for device types that have a single
|
||||
* input vector. This is also used to the get nexa of the first
|
||||
* vector for devices that have more inputs.
|
||||
*
|
||||
* ivl_lpm_datab
|
||||
* Return the input data nexis for device types that have a second
|
||||
* input vector. For example, arithmetic devices are like this.
|
||||
*
|
||||
* ivl_lpm_q
|
||||
* Return the output data nexus for device types that have a single
|
||||
* output vector. This is most devices, it turns out.
|
||||
*
|
||||
* ivl_lpm_selects
|
||||
* This is the size of the select input for a LPM_MUX device, or the
|
||||
* address bus width of an LPM_RAM.
|
||||
*
|
||||
* ivl_lpm_size
|
||||
* In addition to a width, some devices have a size. The size is
|
||||
* often the number of inputs per out, i.e. the number of inputs
|
||||
* per bit for a MUX.
|
||||
*/
|
||||
extern const char* ivl_lpm_name(ivl_lpm_t net);
|
||||
extern const char* ivl_lpm_basename(ivl_lpm_t net);
|
||||
extern ivl_scope_t ivl_lpm_scope(ivl_lpm_t net);
|
||||
extern ivl_lpm_type_t ivl_lpm_type(ivl_lpm_t net);
|
||||
extern unsigned ivl_lpm_width(ivl_lpm_t net);
|
||||
|
||||
|
||||
/*
|
||||
* These are cast functions for the ivl_lpm_t. They cast the object to
|
||||
* the requested type, checking for errors along the way.
|
||||
*/
|
||||
extern ivl_lpm_ff_t ivl_lpm_ff(ivl_lpm_t net);
|
||||
extern ivl_nexus_t ivl_lpm_ff_clk(ivl_lpm_ff_t net);
|
||||
extern ivl_nexus_t ivl_lpm_ff_data(ivl_lpm_ff_t net, unsigned idx);
|
||||
extern ivl_nexus_t ivl_lpm_ff_q(ivl_lpm_ff_t net, unsigned idx);
|
||||
/* IVL_LPM_FF IVL_LPM_RAM */
|
||||
extern ivl_nexus_t ivl_lpm_clk(ivl_lpm_t net);
|
||||
/* IVL_LPM_FF IVL_LPM_RAM */
|
||||
extern ivl_nexus_t ivl_lpm_enable(ivl_lpm_t net);
|
||||
/* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_RAM IVL_LPM_SUB */
|
||||
extern ivl_nexus_t ivl_lpm_data(ivl_lpm_t net, unsigned idx);
|
||||
/* IVL_LPM_ADD IVL_LPM_MULT IVL_LPM_SUB */
|
||||
extern ivl_nexus_t ivl_lpm_datab(ivl_lpm_t net, unsigned idx);
|
||||
/* IVL_LPM_MUX */
|
||||
extern ivl_nexus_t ivl_lpm_data2(ivl_lpm_t net, unsigned sdx, unsigned idx);
|
||||
/* IVL_LPM_ADD IVL_LPM_FF IVL_LPM_MULT IVL_LPM_RAM IVL_LPM_SUB */
|
||||
extern ivl_nexus_t ivl_lpm_q(ivl_lpm_t net, unsigned idx);
|
||||
/* IVL_LPM_MUX IVL_LPM_RAM */
|
||||
extern unsigned ivl_lpm_selects(ivl_lpm_t net);
|
||||
/* IVL_LPM_MUX IVL_LPM_RAM */
|
||||
extern ivl_nexus_t ivl_lpm_select(ivl_lpm_t net, unsigned idx);
|
||||
/* IVL_LPM_MUX */
|
||||
extern unsigned ivl_lpm_size(ivl_lpm_t net);
|
||||
/* IVL_LPM_RAM */
|
||||
extern ivl_memory_t ivl_lpm_memory(ivl_lpm_t net);
|
||||
|
||||
|
||||
/* LVAL
|
||||
* The l-values of assignments are concatenation of ivl_lval_t
|
||||
* objects. Each l-value has a bunch of connections (in the form of
|
||||
* ivl_nexus_t objects) and possibly a mux expression. The compiler
|
||||
* takes care of part selects and nested concatenations. The
|
||||
* ivl_stmt_lval function pulls ivl_lval_t objects out of the
|
||||
* statement.
|
||||
* objects. Each lvi_lval_t object is an assignment to a var or a
|
||||
* memory, through a bit select, part select or word select.
|
||||
*
|
||||
* Var lvals are things like assignments to a part select or a bit
|
||||
* select. Assignment to the whole variable is a special case of a
|
||||
* part select, as is a bit select with a constant expression. The
|
||||
* ivl_lval_pins statement returns the width of the part select for
|
||||
* the lval. The ivl_lval_pin function returns the nexus to the N-th
|
||||
* bit of the part select. The compiler takes care of positioning the
|
||||
* part select so that ivl_lval_pin(net, 0) is the proper bit in the
|
||||
* signal.
|
||||
*
|
||||
* ivl_lval_mux
|
||||
* If the l-value includes a bit select expression, this method
|
||||
* returns an ivl_expr_t that represents that
|
||||
* expression. Otherwise, it returns 0.
|
||||
* expression. Otherwise, it returns 0.
|
||||
*
|
||||
* ivl_lval_mem
|
||||
* If the l-value is a memory, this method returns an
|
||||
* ivl_memory_t that represents that memory. Otherwise, it
|
||||
* returns 0.
|
||||
*
|
||||
* ivl_lval_sig
|
||||
* If the l-value is a variable, this method returns the signal
|
||||
* object that is the target of the assign.
|
||||
*
|
||||
* ivl_lval_part_off
|
||||
* The part select of the signal is based here. This is the
|
||||
* canonical index of bit-0 of the part select.
|
||||
*
|
||||
* ivl_lval_idx
|
||||
* If the l-value is a memory, this method returns an
|
||||
* ivl_expr_t that represents the index expression. Otherwise, it
|
||||
* returns 0.
|
||||
*
|
||||
* ivl_lval_pin
|
||||
* Return an ivl_nexus_t for the connection of the ivl_lval_t.
|
||||
@@ -423,9 +626,12 @@ extern ivl_nexus_t ivl_lpm_ff_q(ivl_lpm_ff_t net, unsigned idx);
|
||||
*/
|
||||
|
||||
extern ivl_expr_t ivl_lval_mux(ivl_lval_t net);
|
||||
extern ivl_expr_t ivl_lval_idx(ivl_lval_t net);
|
||||
extern ivl_memory_t ivl_lval_mem(ivl_lval_t net);
|
||||
extern unsigned ivl_lval_part_off(ivl_lval_t net);
|
||||
extern unsigned ivl_lval_pins(ivl_lval_t net);
|
||||
extern ivl_nexus_t ivl_lval_pin(ivl_lval_t net, unsigned idx);
|
||||
|
||||
extern ivl_signal_t ivl_lval_sig(ivl_lval_t net);
|
||||
|
||||
/* NEXUS
|
||||
* connections of signals and nodes is handled by single-bit
|
||||
@@ -446,6 +652,14 @@ extern ivl_nexus_t ivl_lval_pin(ivl_lval_t net, unsigned idx);
|
||||
* ivl_nexus_ptr
|
||||
* Return a nexus pointer given the nexus and an index.
|
||||
*
|
||||
* ivl_nexus_set_private
|
||||
* ivl_nexus_get_private
|
||||
* The target module often needs to associate data with a nexus for
|
||||
* later use when the nexus is encountered associated with a
|
||||
* device. These methods allow the code generator to store to or
|
||||
* retrieve from a nexus a void* of private data. This pointer is
|
||||
* guaranteed to be 0 before the target module is invoked.
|
||||
*
|
||||
* Once an ivl_nexus_ptr_t is selected by the ivl_nexus_ptr method,
|
||||
* the properties of the pointer can be accessed by the following
|
||||
* methods:
|
||||
@@ -460,6 +674,22 @@ extern ivl_nexus_t ivl_lval_pin(ivl_lval_t net, unsigned idx);
|
||||
* nexus. The problem is that LPM devices do not have a pinout per
|
||||
* se, the pins all have specific names.
|
||||
*
|
||||
* ivl_nexus_ptr_con
|
||||
* If this is a pointer to a magic constant device, then this
|
||||
* returns the net_const object.
|
||||
*
|
||||
* ivl_nexus_ptr_drive0
|
||||
* ivl_nexus_ptr_drive1
|
||||
* These are the 0 and 1 strength values for the devices. For most
|
||||
* devices, these values are fixed by the description in the
|
||||
* original source, with the default as IVL_DR_STRONG. For pins
|
||||
* that are input only, drive0 and drive1 are both IVL_DR_HiZ.
|
||||
*
|
||||
* The strength of strength-aware devices (such as nmos devices)
|
||||
* does not really matter, as long at the output is not
|
||||
* IVL_DR_HiZ. Testing for HiZ drivers is how code generators
|
||||
* detect inputs.
|
||||
*
|
||||
* ivl_nexus_ptr_log
|
||||
* If the target object is an ivl_net_logic_t, this method returns
|
||||
* the object. Otherwise, this method returns 0.
|
||||
@@ -477,12 +707,18 @@ extern const char* ivl_nexus_name(ivl_nexus_t net);
|
||||
extern unsigned ivl_nexus_ptrs(ivl_nexus_t net);
|
||||
extern ivl_nexus_ptr_t ivl_nexus_ptr(ivl_nexus_t net, unsigned idx);
|
||||
|
||||
extern void ivl_nexus_set_private(ivl_nexus_t net, void*data);
|
||||
extern void* ivl_nexus_get_private(ivl_nexus_t net);
|
||||
|
||||
|
||||
extern ivl_drive_t ivl_nexus_ptr_drive0(ivl_nexus_ptr_t net);
|
||||
extern ivl_drive_t ivl_nexus_ptr_drive1(ivl_nexus_ptr_t net);
|
||||
extern unsigned ivl_nexus_ptr_pin(ivl_nexus_ptr_t net);
|
||||
extern ivl_net_const_t ivl_nexus_ptr_con(ivl_nexus_ptr_t net);
|
||||
extern ivl_net_logic_t ivl_nexus_ptr_log(ivl_nexus_ptr_t net);
|
||||
extern ivl_lpm_t ivl_nexus_ptr_lpm(ivl_nexus_ptr_t net);
|
||||
extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
|
||||
|
||||
|
||||
/* SCOPE
|
||||
* Scopes of various sort have these properties. Use these methods to
|
||||
* access them. Scopes come to exist in the elaborated design
|
||||
@@ -502,14 +738,38 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
|
||||
* If the scope has no children, this method will return 0 and
|
||||
* otherwise do nothing.
|
||||
*
|
||||
* ivl_scope_def
|
||||
* Task definition scopes carry a task definition, in the form of
|
||||
* a statement. This method accesses that definition.
|
||||
*
|
||||
* ivl_scope_event
|
||||
* ivl_scope_events
|
||||
* Scopes have 0 or more event objects in them.
|
||||
*
|
||||
* ivl_scope_log
|
||||
* ivl_scope_logs
|
||||
* Scopes have 0 or more logic devices in them. A logic device is
|
||||
* represented by ivl_logic_t.
|
||||
*
|
||||
* ivl_scope_name
|
||||
* ivl_scope_basename
|
||||
* Every scope has a hierarchical name. This name is also a prefix
|
||||
* of all the names of objects contained within the scope.
|
||||
* of all the names of objects contained within the scope. The
|
||||
* ivl_scope_basename is the name of the scope without the included
|
||||
* hierarchy.
|
||||
*
|
||||
* ivl_scope_parent
|
||||
* If this is a non-root scope, then the parent is the scope that
|
||||
* contains this scope. Otherwise, the parent is nil.
|
||||
*
|
||||
* ivl_scope_port
|
||||
* ivl_scope_ports
|
||||
* Scopes that are functions or tasks have ports defined by
|
||||
* signals. These methods access the ports by name.
|
||||
*
|
||||
* If this scope represents a function, then the ports list
|
||||
* includes the return value, as port 0. The remaining ports are
|
||||
* the input ports in order.
|
||||
*
|
||||
* ivl_scope_sig
|
||||
* ivl_scope_sigs
|
||||
@@ -527,11 +787,22 @@ extern ivl_signal_t ivl_nexus_ptr_sig(ivl_nexus_ptr_t net);
|
||||
|
||||
extern int ivl_scope_children(ivl_scope_t net,
|
||||
ivl_scope_f func, void*cd);
|
||||
|
||||
extern ivl_statement_t ivl_scope_def(ivl_scope_t net);
|
||||
|
||||
extern unsigned ivl_scope_events(ivl_scope_t net);
|
||||
extern ivl_event_t ivl_scope_event(ivl_scope_t net, unsigned idx);
|
||||
extern unsigned ivl_scope_logs(ivl_scope_t net);
|
||||
extern ivl_net_logic_t ivl_scope_log(ivl_scope_t net, unsigned idx);
|
||||
extern unsigned ivl_scope_lpms(ivl_scope_t net);
|
||||
extern ivl_lpm_t ivl_scope_lpm(ivl_scope_t, unsigned idx);
|
||||
extern unsigned ivl_scope_mems(ivl_scope_t net);
|
||||
extern ivl_memory_t ivl_scope_mem(ivl_scope_t net, unsigned idx);
|
||||
extern const char* ivl_scope_name(ivl_scope_t net);
|
||||
extern const char* ivl_scope_basename(ivl_scope_t net);
|
||||
extern ivl_scope_t ivl_scope_parent(ivl_scope_t net);
|
||||
extern unsigned ivl_scope_ports(ivl_scope_t net);
|
||||
extern ivl_signal_t ivl_scope_port(ivl_scope_t net, unsigned idx);
|
||||
extern unsigned ivl_scope_sigs(ivl_scope_t net);
|
||||
extern ivl_signal_t ivl_scope_sig(ivl_scope_t net, unsigned idx);
|
||||
extern ivl_scope_type_t ivl_scope_type(ivl_scope_t net);
|
||||
@@ -558,7 +829,13 @@ extern const char* ivl_scope_tname(ivl_scope_t net);
|
||||
* port direction. If the signal is not a port, it returns
|
||||
* IVL_SIP_NONE.
|
||||
*
|
||||
* ivl_signal_signed
|
||||
* A signal, which is a vector, may be signed. In Verilog 2000, any
|
||||
* net or variable may be signed. This function returns true if the
|
||||
* signal is signed.
|
||||
*
|
||||
* ivl_signal_type
|
||||
* Return the type of the signal, i.e. reg, wire, tri0, et al.
|
||||
*
|
||||
* ivl_signal_name
|
||||
* This function returns the fully scoped hierarchical name for the
|
||||
@@ -578,6 +855,7 @@ extern const char* ivl_scope_tname(ivl_scope_t net);
|
||||
extern ivl_nexus_t ivl_signal_pin(ivl_signal_t net, unsigned idx);
|
||||
extern unsigned ivl_signal_pins(ivl_signal_t net);
|
||||
extern ivl_signal_port_t ivl_signal_port(ivl_signal_t net);
|
||||
extern int ivl_signal_signed(ivl_signal_t net);
|
||||
extern ivl_signal_type_t ivl_signal_type(ivl_signal_t net);
|
||||
extern const char* ivl_signal_name(ivl_signal_t net);
|
||||
extern const char* ivl_signal_basename(ivl_signal_t net);
|
||||
@@ -593,12 +871,18 @@ extern const char* ivl_signal_attr(ivl_signal_t net, const char*key);
|
||||
* The ivl_process_type function gets the type of the process,
|
||||
* an "inital" or "always" statement.
|
||||
*
|
||||
* A process is placed in a scope. The statement within the process
|
||||
* operates within the scope of the process unless there are calls
|
||||
* outside the scope.
|
||||
*
|
||||
* The ivl_process_stmt function gets the statement that forms the
|
||||
* process. See the statement related functions for how to manipulate
|
||||
* statements.
|
||||
*/
|
||||
extern ivl_process_type_t ivl_process_type(ivl_process_t net);
|
||||
|
||||
extern ivl_scope_t ivl_process_scope(ivl_process_t net);
|
||||
|
||||
extern ivl_statement_t ivl_process_stmt(ivl_process_t net);
|
||||
|
||||
/*
|
||||
@@ -620,36 +904,62 @@ extern ivl_statement_type_t ivl_statement_type(ivl_statement_t net);
|
||||
* statement types can be passed to the function.
|
||||
*/
|
||||
|
||||
/* IVL_ST_BLOCK */
|
||||
/* IVL_ST_BLOCK, IVL_ST_FORK */
|
||||
extern unsigned ivl_stmt_block_count(ivl_statement_t net);
|
||||
/* IVL_ST_BLOCK */
|
||||
/* IVL_ST_BLOCK, IVL_ST_FORK */
|
||||
extern ivl_statement_t ivl_stmt_block_stmt(ivl_statement_t net, unsigned i);
|
||||
/* IVL_ST_CONDIT */
|
||||
/* IVL_ST_UTASK IVL_ST_DISABLE */
|
||||
extern ivl_scope_t ivl_stmt_call(ivl_statement_t net);
|
||||
/* IVL_ST_CASE */
|
||||
extern unsigned ivl_stmt_case_count(ivl_statement_t net);
|
||||
/* IVL_ST_CASE */
|
||||
extern ivl_expr_t ivl_stmt_case_expr(ivl_statement_t net, unsigned i);
|
||||
/* IVL_ST_CASE */
|
||||
extern ivl_statement_t ivl_stmt_case_stmt(ivl_statement_t net, unsigned i);
|
||||
/* IVL_ST_CONDIT IVL_ST_CASE IVL_ST_REPEAT IVL_ST_WHILE */
|
||||
extern ivl_expr_t ivl_stmt_cond_expr(ivl_statement_t net);
|
||||
/* IVL_ST_CONDIT */
|
||||
extern ivl_statement_t ivl_stmt_cond_false(ivl_statement_t net);
|
||||
/* IVL_ST_CONDIT */
|
||||
extern ivl_statement_t ivl_stmt_cond_true(ivl_statement_t net);
|
||||
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_DELAYX */
|
||||
extern ivl_expr_t ivl_stmt_delay_expr(ivl_statement_t net);
|
||||
/* IVL_ST_DELAY */
|
||||
extern unsigned long ivl_stmt_delay_val(ivl_statement_t net);
|
||||
/* IVL_ST_ASSIGN */
|
||||
/* IVL_ST_WAIT */
|
||||
extern ivl_event_t ivl_stmt_event(ivl_statement_t net);
|
||||
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_DEASSIGN
|
||||
IVL_ST_FORCE IVL_ST_RELEASE */
|
||||
extern ivl_lval_t ivl_stmt_lval(ivl_statement_t net, unsigned idx);
|
||||
/* IVL_ST_ASSIGN */
|
||||
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB IVL_ST_CASSIGN IVL_ST_DEASSIGN
|
||||
IVL_ST_FORCE IVL_ST_RELEASE */
|
||||
extern unsigned ivl_stmt_lvals(ivl_statement_t net);
|
||||
/* IVL_ST_ASSIGN */
|
||||
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB */
|
||||
extern unsigned ivl_stmt_lwidth(ivl_statement_t net);
|
||||
/* IVL_ST_STASK */
|
||||
extern const char* ivl_stmt_name(ivl_statement_t net);
|
||||
/* IVL_ST_CASSIGN IVL_ST_FORCE */
|
||||
extern ivl_nexus_t ivl_stmt_nexus(ivl_statement_t net, unsigned idx);
|
||||
extern unsigned ivl_stmt_nexus_count(ivl_statement_t net);
|
||||
/* IVL_ST_STASK */
|
||||
extern ivl_expr_t ivl_stmt_parm(ivl_statement_t net, unsigned idx);
|
||||
/* IVL_ST_STASK */
|
||||
extern unsigned ivl_stmt_parm_count(ivl_statement_t net);
|
||||
/* IVL_ST_ASSIGN */
|
||||
/* IVL_ST_ASSIGN IVL_ST_ASSIGN_NB */
|
||||
extern ivl_expr_t ivl_stmt_rval(ivl_statement_t net);
|
||||
/* IVL_ST_DELAY, IVL_ST_WAIT, IVL_ST_WHILE */
|
||||
/* IVL_ST_DELAY, IVL_ST_DELAYX, IVL_ST_FOREVER, IVL_ST_REPEAT
|
||||
IVL_ST_WAIT, IVL_ST_WHILE */
|
||||
extern ivl_statement_t ivl_stmt_sub_stmt(ivl_statement_t net);
|
||||
|
||||
|
||||
#if defined(__MINGW32__) || defined (__CYGWIN32__)
|
||||
# define DLLEXPORT __declspec(dllexport)
|
||||
#else
|
||||
# define DLLEXPORT
|
||||
#endif
|
||||
|
||||
extern DLLEXPORT int target_design(ivl_design_t des);
|
||||
|
||||
|
||||
/* target_design
|
||||
|
||||
@@ -667,6 +977,186 @@ _END_DECL
|
||||
|
||||
/*
|
||||
* $Log: ivl_target.h,v $
|
||||
* Revision 1.89 2001/12/06 03:11:00 steve
|
||||
* Add ivl_logic_delay function to ivl_target.
|
||||
*
|
||||
* Revision 1.88 2001/11/14 03:28:49 steve
|
||||
* DLL target support for force and release.
|
||||
*
|
||||
* Revision 1.87 2001/11/01 04:25:31 steve
|
||||
* ivl_target support for cassign.
|
||||
*
|
||||
* Revision 1.86 2001/10/31 05:24:52 steve
|
||||
* ivl_target support for assign/deassign.
|
||||
*
|
||||
* Revision 1.85 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
* Revision 1.84 2001/10/16 02:19:27 steve
|
||||
* Support IVL_LPM_DIVIDE for structural divide.
|
||||
*
|
||||
* Revision 1.83 2001/09/30 16:45:10 steve
|
||||
* Fix some Cygwin DLL handling. (Venkat Iyer)
|
||||
*
|
||||
* Revision 1.82 2001/09/16 22:19:42 steve
|
||||
* Support attributes to logic gates.
|
||||
*
|
||||
* Revision 1.81 2001/09/09 22:21:57 steve
|
||||
* pin down some enumerated constants.
|
||||
*
|
||||
* Revision 1.80 2001/09/01 01:57:31 steve
|
||||
* Make constants available through the design root
|
||||
*
|
||||
* Revision 1.79 2001/08/31 22:58:39 steve
|
||||
* Support DFF CE inputs.
|
||||
*
|
||||
* Revision 1.78 2001/08/28 04:07:17 steve
|
||||
* Add some ivl_target convenience functions.
|
||||
*
|
||||
* Revision 1.77 2001/08/25 23:50:03 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.76 2001/08/10 00:40:45 steve
|
||||
* tgt-vvp generates code that skips nets as inputs.
|
||||
*
|
||||
* Revision 1.75 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.74 2001/07/27 02:41:55 steve
|
||||
* Fix binding of dangling function ports. do not elide them.
|
||||
*
|
||||
* Revision 1.73 2001/07/22 00:17:49 steve
|
||||
* Support the NetESubSignal expressions in vvp.tgt.
|
||||
*
|
||||
* Revision 1.72 2001/07/19 04:55:06 steve
|
||||
* Support calculated delays in vvp.tgt.
|
||||
*
|
||||
* Revision 1.71 2001/07/04 22:59:25 steve
|
||||
* handle left shifter in dll output.
|
||||
*
|
||||
* Revision 1.70 2001/06/30 23:03:16 steve
|
||||
* support fast programming by only writing the bits
|
||||
* that are listed in the input file.
|
||||
*
|
||||
* Revision 1.69 2001/06/19 03:01:10 steve
|
||||
* Add structural EEQ gates (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.68 2001/06/16 23:45:05 steve
|
||||
* Add support for structural multiply in t-dll.
|
||||
* Add code generators and vvp support for both
|
||||
* structural and behavioral multiply.
|
||||
*
|
||||
* Revision 1.67 2001/06/16 02:41:41 steve
|
||||
* Generate code to support memory access in continuous
|
||||
* assignment statements. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.66 2001/06/15 04:14:18 steve
|
||||
* Generate vvp code for GT and GE comparisons.
|
||||
*
|
||||
* Revision 1.65 2001/06/07 03:09:37 steve
|
||||
* support subtraction in tgt-vvp.
|
||||
*
|
||||
* Revision 1.64 2001/06/07 02:12:43 steve
|
||||
* Support structural addition.
|
||||
*
|
||||
* Revision 1.63 2001/05/20 01:06:16 steve
|
||||
* stub ivl_expr_parms for sfunctions.
|
||||
*
|
||||
* Revision 1.62 2001/05/17 04:37:02 steve
|
||||
* Behavioral ternary operators for vvp.
|
||||
*
|
||||
* Revision 1.61 2001/05/12 03:18:44 steve
|
||||
* Make sure LPM devices have drives on outputs.
|
||||
*
|
||||
* Revision 1.60 2001/05/08 23:59:33 steve
|
||||
* Add ivl and vvp.tgt support for memories in
|
||||
* expressions and l-values. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.59 2001/05/08 04:13:12 steve
|
||||
* sort enumeration values.
|
||||
*
|
||||
* Revision 1.58 2001/05/06 17:48:20 steve
|
||||
* Support memory objects. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.57 2001/04/29 23:17:38 steve
|
||||
* Carry drive strengths in the ivl_nexus_ptr_t, and
|
||||
* handle constant devices in targets.'
|
||||
*
|
||||
* Revision 1.56 2001/04/29 20:19:10 steve
|
||||
* Add pullup and pulldown devices.
|
||||
*
|
||||
* Revision 1.55 2001/04/26 05:12:02 steve
|
||||
* Implement simple MUXZ for ?: operators.
|
||||
*
|
||||
* Revision 1.54 2001/04/22 23:09:46 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.53 2001/04/21 00:55:46 steve
|
||||
* Generate code for disable.
|
||||
*
|
||||
* Revision 1.52 2001/04/15 02:58:11 steve
|
||||
* vvp support for <= with internal delay.
|
||||
*
|
||||
* Revision 1.51 2001/04/07 19:24:36 steve
|
||||
* Add the disable statemnent.
|
||||
*
|
||||
* Revision 1.50 2001/04/06 02:28:02 steve
|
||||
* Generate vvp code for functions with ports.
|
||||
*
|
||||
* Revision 1.49 2001/04/05 03:20:57 steve
|
||||
* Generate vvp code for the repeat statement.
|
||||
*
|
||||
* Revision 1.48 2001/04/05 01:12:27 steve
|
||||
* Get signed compares working correctly in vvp.
|
||||
*
|
||||
* Revision 1.47 2001/04/04 04:50:35 steve
|
||||
* Support forever loops in the tgt-vvp target.
|
||||
*
|
||||
* Revision 1.46 2001/04/03 04:50:37 steve
|
||||
* Support non-blocking assignments.
|
||||
*
|
||||
* Revision 1.45 2001/04/02 02:28:12 steve
|
||||
* Generate code for task calls.
|
||||
*
|
||||
* Revision 1.44 2001/04/02 00:28:35 steve
|
||||
* Support the scope expression node.
|
||||
*
|
||||
* Revision 1.43 2001/04/01 06:52:27 steve
|
||||
* support the NetWhile statement.
|
||||
*
|
||||
* Revision 1.42 2001/04/01 04:38:17 steve
|
||||
* dead cruft.
|
||||
*
|
||||
* Revision 1.41 2001/04/01 01:48:21 steve
|
||||
* Redesign event information to support arbitrary edge combining.
|
||||
*
|
||||
* Revision 1.40 2001/03/31 17:36:38 steve
|
||||
* Generate vvp code for case statements.
|
||||
*
|
||||
* Revision 1.39 2001/03/30 05:49:52 steve
|
||||
* Generate code for fork/join statements.
|
||||
*
|
||||
* Revision 1.38 2001/03/29 02:52:39 steve
|
||||
* Add unary ~ operator to tgt-vvp.
|
||||
*
|
||||
* Revision 1.37 2001/03/28 06:07:39 steve
|
||||
* Add the ivl_event_t to ivl_target, and use that to generate
|
||||
* .event statements in vvp way ahead of the thread that uses it.
|
||||
*
|
||||
* Revision 1.36 2001/03/27 06:27:40 steve
|
||||
* Generate code for simple @ statements.
|
||||
*
|
||||
* Revision 1.35 2001/03/20 01:44:13 steve
|
||||
* Put processes in the proper scope.
|
||||
*
|
||||
* Revision 1.34 2001/01/15 22:05:14 steve
|
||||
* Declare ivl_scope_type functions.
|
||||
*
|
||||
|
||||
+5
-5
@@ -18,7 +18,7 @@
|
||||
# 59 Temple Place - Suite 330
|
||||
# Boston, MA 02111-1307, USA
|
||||
#
|
||||
#ident "$Id: Makefile.in,v 1.9 2001/01/09 03:11:28 steve Exp $"
|
||||
#ident "$Id: Makefile.in,v 1.12 2001/08/10 00:39:22 steve Exp $"
|
||||
#
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
@@ -41,8 +41,8 @@ INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
CPPFLAGS = @CPPFLAGS@ @DEFS@
|
||||
CFLAGS = @CFLAGS@ -I.
|
||||
LDFLAGS = @LDFLAGS@
|
||||
CFLAGS = @CFLAGS@ -I. -I$(srcdir)/..
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
all: ivlpp
|
||||
|
||||
@@ -52,13 +52,13 @@ clean:
|
||||
O = main.o lexor.o parse.o
|
||||
|
||||
ivlpp: $O
|
||||
$(CC) $(LDFLAGS) $O -o ivlpp
|
||||
$(CC) $(LDFLAGS) $O -o ivlpp @EXTRALIBS@
|
||||
|
||||
lexor.c: lexor.lex
|
||||
flex -s -olexor.c $(srcdir)/lexor.lex
|
||||
|
||||
parse.h parse.c: parse.y
|
||||
bison --verbose -t -d $(srcdir)/parse.y -o parse.c
|
||||
bison --verbose -t -d -o parse.c $(srcdir)/parse.y
|
||||
|
||||
install: all installdirs $(libdir)/ivl/ivlpp
|
||||
|
||||
|
||||
+6
-6
@@ -49,7 +49,7 @@ valid options include:
|
||||
flags as needed.
|
||||
|
||||
-L
|
||||
Generate #line directives. The ivl compiler understands
|
||||
Generate `line directives. The ivl compiler understands
|
||||
these directives and uses them to keep track of the
|
||||
current line of the original source file. This makes error
|
||||
messages more meaningful.
|
||||
@@ -89,17 +89,17 @@ proper will not reflect the actual line numbers in the source file.
|
||||
To handle this situation, the preprocessor can generate line
|
||||
directives. These directives are lines of the form:
|
||||
|
||||
#line <name> <num>
|
||||
`line <num> <name> <level>
|
||||
|
||||
where <name> is the file name in double-quotes and <num> is the line
|
||||
number in the file. The parser changes the filename and line number
|
||||
counters in such a way that the next line is line number <num>+1 in
|
||||
counters in such a way that the next line is line number <num> in
|
||||
the file named <name>. For example:
|
||||
|
||||
#line "foo.vl" 5
|
||||
`line 6 "foo.vl" 0
|
||||
// I am on line 6 in file foo.vl.
|
||||
|
||||
The preprocessor generates a #line directive every time it switches
|
||||
files. That includes starting an included file (#line "foo.vlh" 0) or
|
||||
The preprocessor generates a `line directive every time it switches
|
||||
files. That includes starting an included file (`line 1 "foo.vlh" 1) or
|
||||
returning to the including file.
|
||||
|
||||
|
||||
+32
-14
@@ -19,11 +19,16 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: lexor.lex,v 1.23 2001/01/29 22:48:10 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.28 2001/11/29 02:26:25 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <stdio.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <assert.h>
|
||||
|
||||
@@ -181,12 +186,11 @@ W [ \t\b\f]+
|
||||
condition that stacks on top of the IFDEF_FALSE so that output is
|
||||
not accidentally turned on within nested ifdefs. */
|
||||
|
||||
^{W}?`ifdef{W}[a-zA-Z_][a-zA-Z0-9_]*.* {
|
||||
^{W}?`ifdef{W}[a-zA-Z_][a-zA-Z0-9_]* {
|
||||
char*name = strchr(yytext, '`');
|
||||
assert(name);
|
||||
name += 6;
|
||||
name += strspn(name, " \t\b\f");
|
||||
name[strcspn(name, " \t\b\f")] = 0;
|
||||
|
||||
if (is_defined(name)) {
|
||||
yy_push_state(IFDEF_TRUE);
|
||||
@@ -195,16 +199,30 @@ W [ \t\b\f]+
|
||||
}
|
||||
}
|
||||
|
||||
<IFDEF_FALSE,IFDEF_SUPR>^{W}?`ifdef{W}.* { yy_push_state(IFDEF_SUPR); }
|
||||
^{W}?`ifndef{W}[a-zA-Z_][a-zA-Z0-9_]* {
|
||||
char*name = strchr(yytext, '`');
|
||||
assert(name);
|
||||
name += 7;
|
||||
name += strspn(name, " \t\b\f");
|
||||
|
||||
<IFDEF_TRUE>{W}?`else.* { BEGIN(IFDEF_FALSE); }
|
||||
<IFDEF_FALSE>{W}?`else.* { BEGIN(IFDEF_TRUE); }
|
||||
<IFDEF_SUPR>{W}?`else.* { }
|
||||
if (!is_defined(name)) {
|
||||
yy_push_state(IFDEF_TRUE);
|
||||
} else {
|
||||
yy_push_state(IFDEF_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
<IFDEF_FALSE,IFDEF_SUPR>^{W}?`ifdef{W}.* { yy_push_state(IFDEF_SUPR); }
|
||||
<IFDEF_FALSE,IFDEF_SUPR>^{W}?`ifndef{W}.* { yy_push_state(IFDEF_SUPR); }
|
||||
|
||||
<IFDEF_TRUE>{W}?`else { BEGIN(IFDEF_FALSE); }
|
||||
<IFDEF_FALSE>{W}?`else { BEGIN(IFDEF_TRUE); }
|
||||
<IFDEF_SUPR>{W}?`else { }
|
||||
|
||||
<IFDEF_FALSE,IFDEF_SUPR>. { }
|
||||
<IFDEF_FALSE,IFDEF_SUPR>\n { istack->lineno += 1; fputc('\n', yyout); }
|
||||
|
||||
<IFDEF_FALSE,IFDEF_TRUE,IFDEF_SUPR>^{W}?`endif.* {
|
||||
<IFDEF_FALSE,IFDEF_TRUE,IFDEF_SUPR>^{W}?`endif {
|
||||
yy_pop_state();
|
||||
}
|
||||
|
||||
@@ -475,7 +493,7 @@ static void def_undefine()
|
||||
static void output_init()
|
||||
{
|
||||
if (line_direct_flag)
|
||||
fprintf(yyout, "#line \"%s\" 0\n", istack->path);
|
||||
fprintf(yyout, "`line 1 \"%s\" 0\n", istack->path);
|
||||
}
|
||||
|
||||
static void include_filename()
|
||||
@@ -519,8 +537,8 @@ static void do_include()
|
||||
yy_switch_to_buffer(yy_new_buffer(istack->file, YY_BUF_SIZE));
|
||||
|
||||
if (line_direct_flag && istack->path)
|
||||
fprintf(yyout, "\n#line \"%s\" %u\n",
|
||||
istack->path, istack->lineno);
|
||||
fprintf(yyout, "\n`line %u \"%s\" 1\n",
|
||||
istack->lineno+1, istack->path);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -572,7 +590,7 @@ static int yywrap()
|
||||
}
|
||||
|
||||
if (line_direct_flag)
|
||||
fprintf(yyout, "\n#line \"%s\" 0\n", istack->path);
|
||||
fprintf(yyout, "\n`line 1 \"%s\" 0\n", istack->path);
|
||||
|
||||
yyrestart(istack->file);
|
||||
return 0;
|
||||
@@ -585,8 +603,8 @@ static int yywrap()
|
||||
yy_switch_to_buffer(istack->yybs);
|
||||
|
||||
if (line_direct_flag && istack->path && !line_mask_flag)
|
||||
fprintf(yyout, "\n#line \"%s\" %u\n",
|
||||
istack->path, istack->lineno);
|
||||
fprintf(yyout, "\n`line %u \"%s\" 2\n",
|
||||
istack->lineno+1, istack->path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
+116
-9
@@ -17,9 +17,11 @@ const char COPYRIGHT[] =
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: main.c,v 1.8 2000/12/06 05:15:21 steve Exp $"
|
||||
#ident "$Id: main.c,v 1.14 2001/11/21 02:59:27 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"
|
||||
@@ -39,7 +41,10 @@ const char NOTICE[] =
|
||||
const char VERSION[] = "$Name: $ $State: Exp $";
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
#ifdef HAVE_MALLOC_H
|
||||
# include <malloc.h>
|
||||
#endif
|
||||
# include <unistd.h>
|
||||
# include <string.h>
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
@@ -47,6 +52,34 @@ const char VERSION[] = "$Name: $ $State: Exp $";
|
||||
#endif
|
||||
# include "globals.h"
|
||||
|
||||
#if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
|
||||
extern int getopt(int argc, char*argv[], const char*fmt);
|
||||
extern int optind;
|
||||
extern const char*optarg;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Keep in source_list an array of pointers to file names. The array
|
||||
* is terminated by a pointer to null.
|
||||
*/
|
||||
static char**source_list = 0;
|
||||
static unsigned source_cnt = 0;
|
||||
|
||||
void add_source_file(const char*name)
|
||||
{
|
||||
if (source_list == 0) {
|
||||
source_list = calloc(2, sizeof(char*));
|
||||
source_list[0] = strdup(name);
|
||||
source_list[1] = 0;
|
||||
source_cnt = 1;
|
||||
} else {
|
||||
source_list = realloc(source_list, sizeof(char*) * (source_cnt+2));
|
||||
source_list[source_cnt+0] = strdup(name);
|
||||
source_list[source_cnt+1] = 0;
|
||||
source_cnt += 1;
|
||||
}
|
||||
}
|
||||
|
||||
char**include_dir = 0;
|
||||
unsigned include_cnt = 0;
|
||||
|
||||
@@ -54,9 +87,42 @@ int line_direct_flag = 0;
|
||||
|
||||
unsigned error_count = 0;
|
||||
|
||||
/*
|
||||
* This function reads from a file a list of file names. Each name
|
||||
* starts with the first non-space character, and ends with the last
|
||||
* non-space character. Spaces in the middle are OK.
|
||||
*/
|
||||
static int flist_read_names(const char*path)
|
||||
{
|
||||
char line_buf[2048];
|
||||
|
||||
FILE*fd = fopen(path, "r");
|
||||
if (fd == 0) {
|
||||
fprintf(stderr, "%s: unable to open for reading.\n", path);
|
||||
return 1;
|
||||
}
|
||||
|
||||
while (fgets(line_buf, sizeof line_buf, fd) != 0) {
|
||||
char*cp = line_buf + strspn(line_buf, " \t\r\b\f");
|
||||
char*tail = cp + strlen(cp);
|
||||
while (tail > cp) {
|
||||
if (! isspace(tail[-1]))
|
||||
break;
|
||||
tail -= 1;
|
||||
tail[0] = 0;
|
||||
}
|
||||
|
||||
if (cp < tail)
|
||||
add_source_file(cp);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
int opt;
|
||||
int opt, idx;
|
||||
const char*flist_path = 0;
|
||||
unsigned flag_errors = 0;
|
||||
char*out_path = 0;
|
||||
FILE*out;
|
||||
@@ -84,7 +150,7 @@ int main(int argc, char*argv[])
|
||||
include_dir[0] = strdup(".");
|
||||
include_cnt = 1;
|
||||
|
||||
while ((opt = getopt(argc, argv, "D:I:K:Lo:v")) != EOF) switch (opt) {
|
||||
while ((opt = getopt(argc, argv, "D:f:I:K:Lo:v")) != EOF) switch (opt) {
|
||||
|
||||
case 'D': {
|
||||
char*tmp = strdup(optarg);
|
||||
@@ -99,6 +165,14 @@ int main(int argc, char*argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
case 'f':
|
||||
if (flist_path) {
|
||||
fprintf(stderr, "%s: duplicate -f flag\n", argv[0]);
|
||||
flag_errors += 1;
|
||||
}
|
||||
flist_path = optarg;
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
include_dir = realloc(include_dir, (include_cnt+1)*sizeof(char*));
|
||||
include_dir[include_cnt] = strdup(optarg);
|
||||
@@ -138,12 +212,10 @@ int main(int argc, char*argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
if (optind == argc)
|
||||
flag_errors += 1;
|
||||
|
||||
if (flag_errors) {
|
||||
fprintf(stderr, "\nUsage: %s [-v][-L][-I<dir>][-D<def>] <file>...\n"
|
||||
" -D<def> - Predefine a value.\n"
|
||||
" -f<fil> - Read the sources listed in the file\n"
|
||||
" -I<dir> - Add an include file search directory\n"
|
||||
" -K<def> - Define a keyword macro that I just pass\n"
|
||||
" -L - Emit line number directives\n"
|
||||
@@ -153,6 +225,21 @@ int main(int argc, char*argv[])
|
||||
return flag_errors;
|
||||
}
|
||||
|
||||
/* Collect the file names on the command line in the source
|
||||
file list, then if there is a file list, read more file
|
||||
names from there. */
|
||||
for (idx = optind ; idx < argc ; idx += 1)
|
||||
add_source_file(argv[idx]);
|
||||
|
||||
|
||||
if (flist_path) {
|
||||
int rc = flist_read_names(flist_path);
|
||||
if (rc != 0)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Figure out what to use for an output file. Write to stdout
|
||||
if no path is specified. */
|
||||
if (out_path) {
|
||||
out = fopen(out_path, "w");
|
||||
if (out == 0) {
|
||||
@@ -163,13 +250,14 @@ int main(int argc, char*argv[])
|
||||
out = stdout;
|
||||
}
|
||||
|
||||
if (argv[optind] == 0) {
|
||||
if (source_cnt == 0) {
|
||||
fprintf(stderr, "%s: No input files given.\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
reset_lexor(out, argv+optind);
|
||||
|
||||
/* Pass to the lexical analyzer the list of input file, and
|
||||
start the parser. */
|
||||
reset_lexor(out, source_list);
|
||||
if (yyparse()) return -1;
|
||||
|
||||
return error_count;
|
||||
@@ -177,6 +265,25 @@ int main(int argc, char*argv[])
|
||||
|
||||
/*
|
||||
* $Log: main.c,v $
|
||||
* Revision 1.14 2001/11/21 02:59:27 steve
|
||||
* Remove diag print.
|
||||
*
|
||||
* Revision 1.13 2001/11/21 02:20:35 steve
|
||||
* Pass list of file to ivlpp via temporary file.
|
||||
*
|
||||
* Revision 1.12 2001/09/15 18:27:04 steve
|
||||
* Make configure detect malloc.h
|
||||
*
|
||||
* Revision 1.11 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.10 2001/06/23 18:41:02 steve
|
||||
* Include stdlib.h
|
||||
*
|
||||
* Revision 1.9 2001/05/20 18:08:07 steve
|
||||
* local declares if the header is missing.
|
||||
*
|
||||
* Revision 1.8 2000/12/06 05:15:21 steve
|
||||
* fix portfaults pass values.
|
||||
*
|
||||
|
||||
@@ -19,21 +19,22 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: lexor.lex,v 1.54 2000/12/12 06:13:44 steve Exp $"
|
||||
#ident "$Id: lexor.lex,v 1.67 2001/12/03 04:47:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
//# define YYSTYPE lexval
|
||||
|
||||
# include <iostream.h>
|
||||
# include "compiler.h"
|
||||
# include "parse_misc.h"
|
||||
# include "parse_api.h"
|
||||
# include "parse.h"
|
||||
# include <ctype.h>
|
||||
# include <string.h>
|
||||
# include "lexor_keyword.h"
|
||||
|
||||
extern FILE*vl_input;
|
||||
extern string vl_file;
|
||||
|
||||
# define YY_USER_INIT reset_lexor();
|
||||
# define yylval VLlval
|
||||
@@ -75,13 +76,12 @@ static const char* set_file_name(char*text)
|
||||
|
||||
extern void pform_set_timescale(int, int);
|
||||
|
||||
static void reset_lexor();
|
||||
void reset_lexor();
|
||||
static void line_directive();
|
||||
static void line_directive2();
|
||||
|
||||
static verinum*make_sized_binary(const char*txt);
|
||||
static verinum*make_sized_dec(const char*txt);
|
||||
static verinum*make_unsized_dec(const char*txt);
|
||||
static verinum*make_sized_octal(const char*txt);
|
||||
static verinum*make_sized_hex(const char*txt);
|
||||
static verinum*make_unsized_binary(const char*txt);
|
||||
@@ -131,11 +131,14 @@ W [ \t\b\f\r]+
|
||||
"!==" { return K_CNE; }
|
||||
"||" { return K_LOR; }
|
||||
"&&" { return K_LAND; }
|
||||
"&&&" { return K_TAND; }
|
||||
"~|" { return K_NOR; }
|
||||
"~^" { return K_NXOR; }
|
||||
"^~" { return K_NXOR; }
|
||||
"~&" { return K_NAND; }
|
||||
"->" { return K_TRIGGER; }
|
||||
"+:" { return K_PO_POS; }
|
||||
"-:" { return K_PO_NEG; }
|
||||
|
||||
|
||||
[}{;:\[\],()#=.@&!?<>%|^~+*/-] { return yytext[0]; }
|
||||
@@ -158,49 +161,60 @@ W [ \t\b\f\r]+
|
||||
<UDPTABLE>\(\?[xX]\) { return '%'; }
|
||||
<UDPTABLE>\(\?\?\) { return '*'; }
|
||||
<UDPTABLE>\(01\) { return 'r'; }
|
||||
<UDPTABLE>\(0[xX]\) { return 'P'; }
|
||||
<UDPTABLE>\(0[xX]\) { return 'Q'; }
|
||||
<UDPTABLE>\(0\?\) { return 'P'; }
|
||||
<UDPTABLE>\(10\) { return 'f'; }
|
||||
<UDPTABLE>\(1[xX]\) { return 'N'; }
|
||||
<UDPTABLE>\(1[xX]\) { return 'M'; }
|
||||
<UDPTABLE>\(1\?\) { return 'N'; }
|
||||
<UDPTABLE>\([xX]0\) { return 'F'; }
|
||||
<UDPTABLE>\([xX]1\) { return 'R'; }
|
||||
<UDPTABLE>\([xX]\?\) { return 'B'; }
|
||||
<UDPTABLE>[bB] { return 'b'; }
|
||||
<UDPTABLE>[lL] { return 'l'; /* IVL extension */ }
|
||||
<UDPTABLE>[hH] { return 'h'; /* IVL extension */ }
|
||||
<UDPTABLE>[fF] { return 'f'; }
|
||||
<UDPTABLE>[rR] { return 'r'; }
|
||||
<UDPTABLE>[xX] { return 'x'; }
|
||||
<UDPTABLE>[pPnN01\?\*\-] { return yytext[0]; }
|
||||
<UDPTABLE>[nN] { return 'n'; }
|
||||
<UDPTABLE>[pP] { return 'p'; }
|
||||
<UDPTABLE>[01\?\*\-] { return yytext[0]; }
|
||||
|
||||
[a-zA-Z_][a-zA-Z0-9$_]* {
|
||||
int rc = lexor_keyword_code(yytext, yyleng);
|
||||
if (rc == IDENTIFIER)
|
||||
if (rc == IDENTIFIER) {
|
||||
yylval.text = strdup(yytext);
|
||||
else
|
||||
if (strncmp(yylval.text,"PATHPULSE$", 10) == 0)
|
||||
rc = PATHPULSE_IDENTIFIER;
|
||||
} else {
|
||||
yylval.text = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
[a-zA-Z_][a-zA-Z0-9$_]*(\.[a-zA-Z_][a-zA-Z0-9$_]*)+ {
|
||||
yylval.text = strdup(yytext);
|
||||
return HIDENTIFIER; }
|
||||
|
||||
\\[^ \t\b\f\r]+ {
|
||||
yylval.text = strdup(yytext);
|
||||
yylval.text = strdup(yytext+1);
|
||||
return IDENTIFIER; }
|
||||
|
||||
\$([a-zA-Z0-9$_]+) {
|
||||
if (strcmp(yytext,"$setuphold") == 0)
|
||||
return K_Ssetuphold;
|
||||
if (strcmp(yytext,"$attribute") == 0)
|
||||
return KK_attribute;
|
||||
if (strcmp(yytext,"$hold") == 0)
|
||||
return K_Shold;
|
||||
if (strcmp(yytext,"$period") == 0)
|
||||
return K_Speriod;
|
||||
if (strcmp(yytext,"$recovery") == 0)
|
||||
return K_Srecovery;
|
||||
if (strcmp(yytext,"$setup") == 0)
|
||||
return K_Ssetup;
|
||||
if (strcmp(yytext,"$width") == 0)
|
||||
return K_Swidth;
|
||||
yylval.text = strdup(yytext);
|
||||
return SYSTEM_IDENTIFIER; }
|
||||
|
||||
\.{W}?[a-zA-Z_][a-zA-Z0-9$_]* {
|
||||
char*cp = yytext+1;
|
||||
while (! (isalpha(*cp) || (*cp == '_')))
|
||||
cp += 1;
|
||||
yylval.text = strdup(cp);
|
||||
return PORTNAME; }
|
||||
|
||||
[0-9][0-9_]*[ \t]*\'[sS]?[dD][ \t]*[0-9][0-9_]* {
|
||||
yylval.number = make_sized_dec(yytext);
|
||||
return NUMBER; }
|
||||
@@ -255,7 +269,7 @@ W [ \t\b\f\r]+
|
||||
|
||||
/* Notice and handle the timescale directive. */
|
||||
|
||||
`timescale { BEGIN(PPTIMESCALE); }
|
||||
^{W}?`timescale { BEGIN(PPTIMESCALE); }
|
||||
<PPTIMESCALE>.* { process_timescale(yytext); }
|
||||
<PPTIMESCALE>\n {
|
||||
yylloc.first_line += 1;
|
||||
@@ -265,28 +279,28 @@ W [ \t\b\f\r]+
|
||||
/* These are directives that I do not yet support. I think that IVL
|
||||
should handle these, not an external preprocessor. */
|
||||
|
||||
^`celldefine{W}?.* { }
|
||||
^`default_nettype{W}?.* { }
|
||||
^`delay_mode_distributed{W}?.* { }
|
||||
^`delay_mode_unit{W}?.* { }
|
||||
^`delay_mode_path{W}?.* { }
|
||||
^`disable_portfaults{W}?.* { }
|
||||
^`enable_portfaults{W}?.* { }
|
||||
^`endcelldefine{W}?.* { }
|
||||
^`endprotect{W}?.* { }
|
||||
^`nosuppress_faults{W}?.* { }
|
||||
^`nounconnected_drive{W}?.* { }
|
||||
^`protect{W}?.* { }
|
||||
^`resetall{W}?.* { }
|
||||
^`suppress_faults{W}?.* { }
|
||||
^`unconnected_drive{W}?.* { }
|
||||
^`uselib{W}?.* { }
|
||||
^{W}?`celldefine{W}?.* { }
|
||||
^{W}?`default_nettype{W}?.* { }
|
||||
^{W}?`delay_mode_distributed{W}?.* { }
|
||||
^{W}?`delay_mode_unit{W}?.* { }
|
||||
^{W}?`delay_mode_path{W}?.* { }
|
||||
^{W}?`disable_portfaults{W}?.* { }
|
||||
^{W}?`enable_portfaults{W}?.* { }
|
||||
^{W}?`endcelldefine{W}?.* { }
|
||||
^{W}?`endprotect{W}?.* { }
|
||||
^{W}?`nosuppress_faults{W}?.* { }
|
||||
^{W}?`nounconnected_drive{W}?.* { }
|
||||
^{W}?`protect{W}?.* { }
|
||||
^{W}?`resetall{W}?.* { }
|
||||
^{W}?`suppress_faults{W}?.* { }
|
||||
^{W}?`unconnected_drive{W}?.* { }
|
||||
^{W}?`uselib{W}?.* { }
|
||||
|
||||
|
||||
/* These are directives that are not supported by me and should have
|
||||
been handled by an external preprocessor such as ivlpp. */
|
||||
|
||||
^`define{W}?.* {
|
||||
^{W}?`define{W}?.* {
|
||||
cerr << yylloc.text << ":" << yylloc.first_line <<
|
||||
": `define not supported. Use an external preprocessor."
|
||||
<< endl;
|
||||
@@ -721,7 +735,7 @@ static verinum*make_sized_hex(const char*txt)
|
||||
"'' truncated to " << size << " bits." << endl;
|
||||
|
||||
// zero extend hex numbers
|
||||
while (idx < size) switch (ptr[1]) {
|
||||
while (idx < size) switch (ptr[0]) {
|
||||
case 'x': case 'X':
|
||||
bits[idx++] = verinum::Vx;
|
||||
break;
|
||||
@@ -1024,6 +1038,8 @@ static void line_directive2()
|
||||
cp += strspn(cp, " ");
|
||||
yylloc.first_line = strtoul(cp,&cp,10);
|
||||
|
||||
yylloc.first_line -= 1;
|
||||
|
||||
cp += strspn(cp, " ");
|
||||
if (*cp == 0) return;
|
||||
|
||||
@@ -1041,7 +1057,8 @@ static void line_directive2()
|
||||
yylloc.text = set_file_name(buf);
|
||||
}
|
||||
|
||||
static void reset_lexor()
|
||||
extern FILE*vl_input;
|
||||
void reset_lexor()
|
||||
{
|
||||
yyrestart(vl_input);
|
||||
yylloc.first_line = 1;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
%{
|
||||
/* Command-line: gperf -o -i 1 -C -k 1-3,$ -L C -H keyword_hash -N check_identifier -tT lexor_keyword.gperf */
|
||||
|
||||
#include "config.h"
|
||||
#include "parse_misc.h"
|
||||
#include "parse.h"
|
||||
#include <string.h>
|
||||
|
||||
+53
-6
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: link_const.cc,v 1.7 2000/11/20 01:41:12 steve Exp $"
|
||||
#ident "$Id: link_const.cc,v 1.11 2001/08/25 23:50:03 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
@@ -35,18 +37,44 @@ bool link_drivers_constant(const Link&lnk)
|
||||
|
||||
for (const Link*cur = nex->first_nlink()
|
||||
; cur ; cur = cur->next_nlink()) {
|
||||
const NetNet*sig;
|
||||
|
||||
if (cur == &lnk)
|
||||
continue;
|
||||
if (cur->get_dir() == Link::INPUT)
|
||||
continue;
|
||||
|
||||
/* If this is an input or inout port of a root module,
|
||||
then the is probably not a constant value. I
|
||||
certainly don't know what the value is, anyhow. This
|
||||
can happen in cases like this:
|
||||
|
||||
module main(sig);
|
||||
input sig;
|
||||
endmodule
|
||||
|
||||
If main is a root module (it has no parent) then sig
|
||||
is not constant because it connects to an unspecified
|
||||
outside world. */
|
||||
|
||||
if (sig = dynamic_cast<const NetNet*>(cur->get_obj())) do {
|
||||
if (sig->port_type() == NetNet::NOT_A_PORT)
|
||||
break;
|
||||
|
||||
if (sig->port_type() == NetNet::POUTPUT)
|
||||
break;
|
||||
|
||||
if (sig->scope()->parent())
|
||||
break;
|
||||
|
||||
flag = false;
|
||||
} while(0);
|
||||
|
||||
|
||||
/* If the link is PASSIVE then it doesn't count as a
|
||||
driver if its initial value is Vz. This is pertinant
|
||||
because REGs are PASSIVE but can receive values from
|
||||
procedural assignments. */
|
||||
if ((cur->get_dir() == Link::PASSIVE)
|
||||
&& (cur->get_init() == verinum::Vz))
|
||||
driver if its initial value is Vz. PASSIVE nodes
|
||||
include wires and tri nets. */
|
||||
if (cur->get_dir() == Link::PASSIVE)
|
||||
continue;
|
||||
|
||||
if (! dynamic_cast<const NetConst*>(cur->get_obj()))
|
||||
@@ -95,6 +123,25 @@ verinum::V driven_value(const Link&lnk)
|
||||
|
||||
/*
|
||||
* $Log: link_const.cc,v $
|
||||
* Revision 1.11 2001/08/25 23:50:03 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.10 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.9 2001/07/07 03:01:37 steve
|
||||
* Detect and make available to t-dll the right shift.
|
||||
*
|
||||
* Revision 1.8 2001/02/16 03:27:07 steve
|
||||
* links to root inputs are not constant.
|
||||
*
|
||||
* Revision 1.7 2000/11/20 01:41:12 steve
|
||||
* Whoops, return the calculated constant value rom driven_value.
|
||||
*
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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)
|
||||
#ident "$Id: load_module.cc,v 1.4 2001/11/20 23:36:34 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
# include "util.h"
|
||||
# include "parse_api.h"
|
||||
# include "compiler.h"
|
||||
# include <iostream.h>
|
||||
|
||||
|
||||
const char dir_character = '/';
|
||||
|
||||
bool load_module(const char*type)
|
||||
{
|
||||
char path[4096];
|
||||
|
||||
for (list<const char*>::iterator cur = library_dirs.begin()
|
||||
; cur != library_dirs.end()
|
||||
; cur ++ ) {
|
||||
for (list<const char*>::iterator suf = library_suff.begin()
|
||||
; suf != library_suff.end()
|
||||
; suf ++ ) {
|
||||
|
||||
sprintf(path, "%s%c%s%s", *cur, dir_character, type, *suf);
|
||||
|
||||
FILE*file = fopen(path, "r");
|
||||
if (file == 0)
|
||||
continue;
|
||||
|
||||
if (verbose_flag) {
|
||||
cerr << "Loading library file " << path << "." << endl;
|
||||
}
|
||||
|
||||
pform_parse(path, file);
|
||||
|
||||
fclose(file);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: load_module.cc,v $
|
||||
* Revision 1.4 2001/11/20 23:36:34 steve
|
||||
* Close library files after parsing.
|
||||
*
|
||||
* Revision 1.3 2001/11/16 05:07:19 steve
|
||||
* Add support for +libext+ in command files.
|
||||
*
|
||||
* Revision 1.2 2001/10/22 02:05:21 steve
|
||||
* Handle activating tasks in another root.
|
||||
*
|
||||
* Revision 1.1 2001/10/20 23:02:40 steve
|
||||
* Add automatic module libraries.
|
||||
*
|
||||
*/
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
|
||||
This file describes the procedure to build and install Icarus Verilog on Mac OS X. I assume that you have experience with Unix and Terminal.app.
|
||||
|
||||
|
||||
1) Obtain and install a libdl compatibility library.
|
||||
|
||||
If you don't already have /usr/local/lib/libdl.{a,dylib} and /usr/local/include/dlfcn.h, you can obtain the source for a compatibility layer from at least one of two places:
|
||||
|
||||
http://download.sourceforge.net/fink/dlcompat-20010831.tar.gz
|
||||
http://www.omnigroup.com/~bungi/dlcompat-20010831.tar.gz
|
||||
|
||||
Unpack this tar file and read the README and Makefile. Install the library according to the instructions. Installation in /usr/local is strongly recommended since otherwise autoconf very likely won't be able to find it.
|
||||
|
||||
2) Make sure you have a copy of the 'gperf' tool. This does not come with the Mac OS X 10.1 developer tools, so you probably don't. You can check with:
|
||||
|
||||
% which gperf
|
||||
|
||||
If not found, grab a gperf source package and install it.
|
||||
|
||||
ftp://ftp.gnu.org/gnu/gperf/gperf-2.7.2.tar.gz
|
||||
|
||||
|
||||
3) Configure, build and install the Icarus Verilog sources as normal.
|
||||
|
||||
The only change you need to make here is to use a configure command like:
|
||||
|
||||
% CC="cc -no-cpp-precomp" ./configure
|
||||
|
||||
This assumes you are using 'sh', 'zsh', or 'bash'. If you are using 'csh' or 'tcsh', then you'll want something like:
|
||||
|
||||
% setenv CC "cc -no-cpp-precomp"
|
||||
% ./configure
|
||||
|
||||
You can, of course, add other configure options.
|
||||
|
||||
4) Done!
|
||||
|
||||
@@ -19,9 +19,11 @@ const char COPYRIGHT[] =
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: main.cc,v 1.40 2001/01/20 19:02:05 steve Exp $"
|
||||
#ident "$Id: main.cc,v 1.51 2001/11/16 05:07:19 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"
|
||||
@@ -42,28 +44,53 @@ const char NOTICE[] =
|
||||
# include <iostream.h>
|
||||
# include <fstream>
|
||||
# include <queue>
|
||||
# include <list>
|
||||
# include <map>
|
||||
# include <unistd.h>
|
||||
# include <stdlib.h>
|
||||
#if defined(HAVE_TIMES)
|
||||
# include <sys/times.h>
|
||||
#endif
|
||||
#if defined(HAVE_GETOPT_H)
|
||||
# include <getopt.h>
|
||||
#endif
|
||||
# include "pform.h"
|
||||
# include "parse_api.h"
|
||||
# include "netlist.h"
|
||||
# include "target.h"
|
||||
# include "compiler.h"
|
||||
|
||||
#if defined(__MINGW32__) && !defined(HAVE_GETOPT_H)
|
||||
extern "C" int getopt(int argc, char*argv[], const char*fmt);
|
||||
extern "C" int optind;
|
||||
extern "C" const char*optarg;
|
||||
#endif
|
||||
|
||||
#if defined(__CYGWIN32__) && !defined(HAVE_GETOPT_H)
|
||||
extern "C" int getopt(int argc, char*argv[], const char*fmt);
|
||||
extern "C" int optind;
|
||||
extern "C" const char*optarg;
|
||||
#endif
|
||||
|
||||
const char VERSION[] = "$Name: $ $State: Exp $";
|
||||
|
||||
const char*target = "null";
|
||||
string start_module = "";
|
||||
|
||||
map<string,string> flags;
|
||||
|
||||
list<const char*> library_dirs;
|
||||
list<const char*> library_suff;
|
||||
|
||||
/*
|
||||
* These are the warning enable flags.
|
||||
*/
|
||||
bool warn_implicit = false;
|
||||
|
||||
/*
|
||||
* Verbose messages enabled.
|
||||
*/
|
||||
bool verbose_flag = false;
|
||||
|
||||
|
||||
static void parm_to_flagmap(const string&flag)
|
||||
{
|
||||
@@ -82,9 +109,7 @@ static void parm_to_flagmap(const string&flag)
|
||||
}
|
||||
|
||||
|
||||
extern Design* elaborate(const map<string,Module*>&modules,
|
||||
const map<string,PUdp*>&primitives,
|
||||
const string&root);
|
||||
extern Design* elaborate(list <const char*>root);
|
||||
|
||||
extern void cprop(Design*des);
|
||||
extern void synth(Design*des);
|
||||
@@ -114,23 +139,58 @@ net_func name_to_net_func(const string&name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *net_func_to_name(const net_func func)
|
||||
{
|
||||
for (unsigned idx = 0 ; func_table[idx].name ; idx += 1)
|
||||
if (func == func_table[idx].func)
|
||||
return func_table[idx].name;
|
||||
|
||||
return "This cannot happen";
|
||||
}
|
||||
|
||||
#if defined(HAVE_TIMES)
|
||||
static double cycles_diff(struct tms *a, struct tms *b)
|
||||
{
|
||||
clock_t aa = a->tms_utime
|
||||
+ a->tms_stime
|
||||
+ a->tms_cutime
|
||||
+ a->tms_cstime;
|
||||
|
||||
clock_t bb = b->tms_utime
|
||||
+ b->tms_stime
|
||||
+ b->tms_cutime
|
||||
+ b->tms_cstime;
|
||||
|
||||
return (aa-bb)/(double)sysconf(_SC_CLK_TCK);
|
||||
}
|
||||
#else // ! defined(HAVE_TIMES)
|
||||
// Provide dummies
|
||||
struct tms { int x; };
|
||||
inline static void times(struct tms *) { }
|
||||
inline static double cycles_diff(struct tms *a, struct tms *b) { return 0; }
|
||||
#endif // ! defined(HAVE_TIMES)
|
||||
|
||||
int main(int argc, char*argv[])
|
||||
{
|
||||
bool help_flag = false;
|
||||
bool times_flag = false;
|
||||
|
||||
const char* net_path = 0;
|
||||
const char* pf_path = 0;
|
||||
const char* warn_en = "";
|
||||
int opt;
|
||||
unsigned flag_errors = 0;
|
||||
queue<net_func> net_func_queue;
|
||||
list<const char*> roots;
|
||||
|
||||
struct tms cycles[5];
|
||||
|
||||
flags["VPI_MODULE_LIST"] = "system";
|
||||
flags["-o"] = "a.out";
|
||||
min_typ_max_flag = TYP;
|
||||
min_typ_max_warn = 10;
|
||||
|
||||
while ((opt = getopt(argc, argv, "F:f:hm:N:o:P:p:s:T:t:vW:")) != EOF) switch (opt) {
|
||||
while ((opt = getopt(argc, argv, "F:f:hm:N:o:P:p:s:T:t:VvW:Y:y:")) != EOF) switch (opt) {
|
||||
case 'F': {
|
||||
net_func tmp = name_to_net_func(optarg);
|
||||
if (tmp == 0) {
|
||||
@@ -164,7 +224,7 @@ int main(int argc, char*argv[])
|
||||
parm_to_flagmap(optarg);
|
||||
break;
|
||||
case 's':
|
||||
start_module = optarg;
|
||||
roots.push_back(optarg);
|
||||
break;
|
||||
case 'T':
|
||||
if (strcmp(optarg,"min") == 0) {
|
||||
@@ -186,6 +246,12 @@ int main(int argc, char*argv[])
|
||||
target = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
verbose_flag = true;
|
||||
# if defined(HAVE_TIMES)
|
||||
times_flag = true;
|
||||
# endif
|
||||
break;
|
||||
case 'V':
|
||||
cout << "Icarus Verilog version " << VERSION << endl;
|
||||
cout << COPYRIGHT << endl;
|
||||
cout << endl << NOTICE << endl;
|
||||
@@ -193,6 +259,12 @@ int main(int argc, char*argv[])
|
||||
case 'W':
|
||||
warn_en = optarg;
|
||||
break;
|
||||
case 'y':
|
||||
library_dirs.push_back(optarg);
|
||||
break;
|
||||
case 'Y':
|
||||
library_suff.push_back(optarg);
|
||||
break;
|
||||
default:
|
||||
flag_errors += 1;
|
||||
break;
|
||||
@@ -202,12 +274,35 @@ int main(int argc, char*argv[])
|
||||
return flag_errors;
|
||||
|
||||
if (help_flag) {
|
||||
cout << "Icarus Verilog version " << VERSION << endl <<
|
||||
"usage: ivl <options> <file>\n"
|
||||
"options:\n"
|
||||
"\t-F <name> Apply netlist function <name>.\n"
|
||||
"\t-h Print usage information, and exit.\n"
|
||||
"\t-m <module> Load vpi module <module>.\n"
|
||||
"\t-N <file> Dump the elaborated netlist to <file>.\n"
|
||||
"\t-o <file> Write output to <file>.\n"
|
||||
"\t-P <file> Write the parsed input to <file>.\n"
|
||||
"\t-p <assign> Set a parameter value.\n"
|
||||
"\t-s <module> Select the top-level module.\n"
|
||||
"\t-T [min|typ|max] Select timing corner.\n"
|
||||
"\t-t <name> Select target <name>.\n"
|
||||
"\t-v Print progress indications"
|
||||
#if defined(HAVE_TIMES)
|
||||
" and execution times"
|
||||
#endif
|
||||
".\n"
|
||||
"\t-V Print version and copyright information, and exit.\n"
|
||||
"\t-y <dir> Add directory to library search path.\n"
|
||||
"\t-Y <suf> Add suffix string library search path.\n"
|
||||
|
||||
;
|
||||
cout << "Netlist functions:" << endl;
|
||||
for (unsigned idx = 0 ; func_table[idx].name ; idx += 1)
|
||||
cout << " " << func_table[idx].name << endl;
|
||||
cout << "\t-F " << func_table[idx].name << endl;
|
||||
cout << "Target types:" << endl;
|
||||
for (unsigned idx = 0 ; target_table[idx] ; idx += 1)
|
||||
cout << " " << target_table[idx]->name << endl;
|
||||
cout << "\t-t " << target_table[idx]->name << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -216,6 +311,12 @@ int main(int argc, char*argv[])
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If there were no -Y flags, then create a minimal library
|
||||
suffix search list. */
|
||||
if (library_suff.empty()) {
|
||||
library_suff.push_back(".v");
|
||||
}
|
||||
|
||||
/* Scan the warnings enable string for warning flags. */
|
||||
for (const char*cp = warn_en ; *cp ; cp += 1) switch (*cp) {
|
||||
case 'i':
|
||||
@@ -225,22 +326,26 @@ int main(int argc, char*argv[])
|
||||
break;
|
||||
}
|
||||
|
||||
if (verbose_flag) {
|
||||
if (times_flag)
|
||||
times(cycles+0);
|
||||
cout << "PARSING INPUT ..." << endl;
|
||||
}
|
||||
|
||||
/* Parse the input. Make the pform. */
|
||||
map<string,Module*> modules;
|
||||
map<string,PUdp*> primitives;
|
||||
int rc = pform_parse(argv[optind], modules, primitives);
|
||||
int rc = pform_parse(argv[optind]);
|
||||
|
||||
if (pf_path) {
|
||||
ofstream out (pf_path);
|
||||
out << "PFORM DUMP MODULES:" << endl;
|
||||
for (map<string,Module*>::iterator mod = modules.begin()
|
||||
; mod != modules.end()
|
||||
for (map<string,Module*>::iterator mod = pform_modules.begin()
|
||||
; mod != pform_modules.end()
|
||||
; mod ++ ) {
|
||||
pform_dump(out, (*mod).second);
|
||||
}
|
||||
out << "PFORM DUMP PRIMITIVES:" << endl;
|
||||
for (map<string,PUdp*>::iterator idx = primitives.begin()
|
||||
; idx != primitives.end()
|
||||
for (map<string,PUdp*>::iterator idx = pform_primitives.begin()
|
||||
; idx != pform_primitives.end()
|
||||
; idx ++ ) {
|
||||
(*idx).second->dump(out);
|
||||
}
|
||||
@@ -251,65 +356,89 @@ int main(int argc, char*argv[])
|
||||
}
|
||||
|
||||
|
||||
/* If the user did not give a specific module to start with,
|
||||
then look for the single module that has no ports. If there
|
||||
are multiple modules with no ports, then give up. */
|
||||
/* If the user did not give specific module(s) to start with,
|
||||
then look for modules that are not instantiated anywhere. */
|
||||
|
||||
if (start_module == "") {
|
||||
for (map<string,Module*>::iterator mod = modules.begin()
|
||||
; mod != modules.end()
|
||||
; mod ++ ) {
|
||||
Module*cur = (*mod).second;
|
||||
if (cur->port_count() == 0)
|
||||
if (start_module == "") {
|
||||
start_module = cur->get_name();
|
||||
} else {
|
||||
cerr << "More then 1 top level module."
|
||||
<< endl;
|
||||
return 1;
|
||||
if (roots.empty()) {
|
||||
map<string,bool> mentioned_p;
|
||||
map<string,Module*>::iterator mod;
|
||||
if (verbose_flag)
|
||||
cout << "LOCATING TOP-LEVEL MODULES..." << endl << " ";
|
||||
for (mod = pform_modules.begin()
|
||||
; mod != pform_modules.end()
|
||||
; mod++) {
|
||||
list<PGate*> gates = (*mod).second->get_gates();
|
||||
list<PGate*>::const_iterator gate;
|
||||
for (gate = gates.begin(); gate != gates.end(); gate++) {
|
||||
PGModule *mod = dynamic_cast<PGModule*>(*gate);
|
||||
if (mod) {
|
||||
// Note that this module has been instantiated
|
||||
mentioned_p[mod->get_type()] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (mod = pform_modules.begin()
|
||||
; mod != pform_modules.end()
|
||||
; mod++) {
|
||||
if (mentioned_p[(*mod).second->mod_name()] == false) {
|
||||
if (verbose_flag)
|
||||
cout << " " << (*mod).second->mod_name();
|
||||
roots.push_back((*mod).second->mod_name());
|
||||
}
|
||||
}
|
||||
if (verbose_flag)
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
/* If the previous attempt to find a start module failed, but
|
||||
there is only one module, then just let the user get away
|
||||
with it. */
|
||||
|
||||
if ((start_module == "") && (modules.size() == 1)) {
|
||||
map<string,Module*>::iterator mod = modules.begin();
|
||||
Module*cur = (*mod).second;
|
||||
start_module = cur->get_name();
|
||||
}
|
||||
|
||||
|
||||
/* If there is *still* no guess for the root module, then give
|
||||
up completely, and complain. */
|
||||
|
||||
if (start_module == "") {
|
||||
if (roots.empty()) {
|
||||
cerr << "No top level modules, and no -s option." << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (verbose_flag) {
|
||||
if (times_flag) {
|
||||
times(cycles+1);
|
||||
cerr<<" ... done, "
|
||||
<<cycles_diff(cycles+1, cycles+0)<<" seconds."<<endl;
|
||||
}
|
||||
cout << "ELABORATING DESIGN" << endl;
|
||||
}
|
||||
|
||||
/* On with the process of elaborating the module. */
|
||||
Design*des = elaborate(modules, primitives, start_module);
|
||||
Design*des = elaborate(roots);
|
||||
if (des == 0) {
|
||||
cerr << start_module << ": error: "
|
||||
<< "Unable to elaborate module." << endl;
|
||||
cerr << "Elaboration failed" << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (des->errors) {
|
||||
cerr << start_module << ": error: " << des->errors
|
||||
<< " elaborating module." << endl;
|
||||
cerr << des->errors
|
||||
<< " error(s) during elaboration." << endl;
|
||||
return des->errors;
|
||||
}
|
||||
|
||||
des->set_flags(flags);
|
||||
|
||||
|
||||
if (verbose_flag) {
|
||||
if (times_flag) {
|
||||
times(cycles+2);
|
||||
cerr<<" ... done, "
|
||||
<<cycles_diff(cycles+2, cycles+1)<<" seconds."<<endl;
|
||||
}
|
||||
cout << "RUNNING FUNCTORS ..." << endl;
|
||||
}
|
||||
|
||||
while (!net_func_queue.empty()) {
|
||||
net_func func = net_func_queue.front();
|
||||
net_func_queue.pop();
|
||||
if (verbose_flag)
|
||||
cerr<<" -F "<<net_func_to_name(func)<<endl;
|
||||
func(des);
|
||||
}
|
||||
|
||||
@@ -319,17 +448,69 @@ int main(int argc, char*argv[])
|
||||
}
|
||||
|
||||
|
||||
if (verbose_flag) {
|
||||
if (times_flag) {
|
||||
times(cycles+3);
|
||||
cerr<<" ... done, "
|
||||
<<cycles_diff(cycles+3, cycles+2)<<" seconds."<<endl;
|
||||
}
|
||||
cout << "CODE GENERATION -t "<<target<<" ..." << endl;
|
||||
}
|
||||
|
||||
bool emit_rc = emit(des, target);
|
||||
if (!emit_rc) {
|
||||
cerr << "error: Code generation had errors." << endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (verbose_flag) {
|
||||
if (times_flag) {
|
||||
times(cycles+4);
|
||||
cerr<<" ... done, "
|
||||
<<cycles_diff(cycles+4, cycles+3)<<" seconds."<<endl;
|
||||
} else
|
||||
cout << "DONE." << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: main.cc,v $
|
||||
* Revision 1.51 2001/11/16 05:07:19 steve
|
||||
* Add support for +libext+ in command files.
|
||||
*
|
||||
* Revision 1.50 2001/10/20 23:02:40 steve
|
||||
* Add automatic module libraries.
|
||||
*
|
||||
* Revision 1.49 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
*
|
||||
* Revision 1.48 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
* Revision 1.47 2001/07/30 02:44:05 steve
|
||||
* Cleanup defines and types for mingw compile.
|
||||
*
|
||||
* Revision 1.46 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.45 2001/07/16 18:14:56 steve
|
||||
* Reshuffle -v and -V flags of ivl. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.44 2001/07/03 04:09:24 steve
|
||||
* Generate verbuse status messages (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.43 2001/07/02 01:57:27 steve
|
||||
* Add the -V flag, and some verbose messages.
|
||||
*
|
||||
* Revision 1.42 2001/06/23 18:41:02 steve
|
||||
* Include stdlib.h
|
||||
*
|
||||
* Revision 1.41 2001/05/20 17:35:05 steve
|
||||
* declare getopt by hand in mingw32 compile.
|
||||
*
|
||||
* Revision 1.40 2001/01/20 19:02:05 steve
|
||||
* Switch hte -f flag to the -p flag.
|
||||
*
|
||||
|
||||
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: mangle.cc,v 1.5 2000/12/11 01:06:24 steve Exp $"
|
||||
#ident "$Id: mangle.cc,v 1.7 2001/07/25 03:10:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "target.h"
|
||||
# include <strstream>
|
||||
|
||||
@@ -32,7 +34,7 @@ string mangle(const string&str)
|
||||
string tmp = str;
|
||||
|
||||
while (tmp.length() > 0) {
|
||||
size_t pos = tmp.find_first_of(".<\\[]");
|
||||
size_t pos = tmp.find_first_of(".<\\[]/");
|
||||
if (pos > tmp.length())
|
||||
pos = tmp.length();
|
||||
|
||||
@@ -59,6 +61,10 @@ string mangle(const string&str)
|
||||
res << "$$";
|
||||
tmp = tmp.substr(1);
|
||||
break;
|
||||
case '/':
|
||||
res << "$sl$";
|
||||
tmp = tmp.substr(1);
|
||||
break;
|
||||
case '[':
|
||||
res << "$lb$";
|
||||
tmp = tmp.substr(1);
|
||||
@@ -73,8 +79,41 @@ string mangle(const string&str)
|
||||
return res.str();
|
||||
}
|
||||
|
||||
string stresc(const string&str)
|
||||
{
|
||||
ostrstream res;
|
||||
string tmp = str;
|
||||
|
||||
while (tmp.length() > 0) {
|
||||
size_t pos = tmp.find_first_of("\\");
|
||||
if (pos > tmp.length())
|
||||
pos = tmp.length();
|
||||
|
||||
res << tmp.substr(0, pos);
|
||||
if (pos >= tmp.length())
|
||||
break;
|
||||
|
||||
tmp = tmp.substr(pos);
|
||||
switch (tmp[0]) {
|
||||
case '\\':
|
||||
res << "\\\\";
|
||||
tmp = tmp.substr(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
res << ends;
|
||||
return res.str();
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: mangle.cc,v $
|
||||
* Revision 1.7 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.6 2001/04/22 23:09:46 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.5 2000/12/11 01:06:24 steve
|
||||
* Mangle [] characters. (PR#67)
|
||||
*
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
|
||||
|
||||
MINGW PORT OF ICARUS VERILOG
|
||||
|
||||
Copyright 2001 Stephen Williams <[email protected]>
|
||||
|
||||
|
||||
Icarus Verilog source can be compiled with the mingw C/C++ compilers
|
||||
to get a Windows binary that does not require the posix compatibility
|
||||
cruft of the Cygwin.dll library. The configure scripts automatically
|
||||
detect that the compilers in use are the mingw compilers and will
|
||||
configure the Makefiles appropriately.
|
||||
|
||||
However, the mingw tools do not include all the other tools around the
|
||||
compiler, including the shell interpreter for the configure script,
|
||||
bison, flex, gperf, etc. Therefore, you still need Cygwin to compile
|
||||
Icarus Verilog, even if you don't need the Cygwin compilers.
|
||||
|
||||
* Install Cygwin
|
||||
|
||||
So, step 1 is "Download and Install Cygwin." See the web page
|
||||
http://www.cygwin.com for instructions and the files to do
|
||||
this. Cygwin *is* a kool package, and is worth having anyhow.
|
||||
|
||||
* Install mingw
|
||||
|
||||
The obvious step 2, then, is install the mingw compilers. These can be
|
||||
found as the web page <http://www.mingw.org>.
|
||||
|
||||
* Unpack Icarus Verilog source
|
||||
|
||||
Most of the remaining steps are best done in a Cygwin window. When you
|
||||
installed Cygwin, a start menu entry was created to allow you to start
|
||||
up the Cygwin window. I'll use the string "$ " to represent a command
|
||||
prompt in this window, because that is the usual bash prompt.
|
||||
|
||||
Anyhow, unpack the compressed tar file (.tar.gz) of the source with a
|
||||
command like this:
|
||||
|
||||
$ gunzip -d verilog-20010630.tar.gz | tar xvf -
|
||||
|
||||
This will create a directory "verilog-20010630" that contains all the
|
||||
source. Descend into that directory, as that is where we will work
|
||||
from now on.
|
||||
|
||||
$ cd verilog-20010630
|
||||
|
||||
* Select the mingw compilers
|
||||
|
||||
In your cygwin window, if you type "which c++" you will get the
|
||||
response path "/usr/bin/c++" which is the cygwin compiler. This is not
|
||||
the one we want to use, however. Tell the shell where the mingw
|
||||
compilers are by setting the search path like so:
|
||||
|
||||
$ PATH=/cygdrive/d/mingw/bin:$PATH
|
||||
|
||||
This assumes that you installed mingw in D:\mingw. The actual programs
|
||||
are in the bin directory under the root. After this command, check
|
||||
that you are now getting the right compilers with this "which"
|
||||
command:
|
||||
|
||||
$ which c++
|
||||
/cygdrive/d/mingw/bin/c++
|
||||
|
||||
Good!
|
||||
|
||||
|
||||
* Configure Icarus Verilog
|
||||
|
||||
Now we are all set to configure and compile Icarus Verilog. Choose a
|
||||
destination path where you will want to install the binaries. I chose
|
||||
on my system the directory "D:\iverilog". This choice is not
|
||||
permanent, so don't get too much angst over it. Just choose a name
|
||||
without white space.
|
||||
|
||||
Now, configure the source to make the makefiles and configuration
|
||||
details. Run this command:
|
||||
|
||||
$ ./configure --prefix=/cygdrive/d/iverilog
|
||||
|
||||
Substitute your chosen directory for the prefix. This will cause the
|
||||
makefiles to build and the source code to configure. The configure
|
||||
program will detect that this is a mingw environment and set things up
|
||||
to build properly.
|
||||
|
||||
|
||||
* Compile Icarus Verilog
|
||||
|
||||
This, believe it or not, should be the easy part:
|
||||
|
||||
$ make
|
||||
|
||||
It could take a while. Now is a good time to go get some coffee or
|
||||
take a tea break.
|
||||
|
||||
|
||||
* Install Icarus Verilog
|
||||
|
||||
If the compile ran OK, then next you install Icarus Verilog in the
|
||||
directory you have chosen. This is a little tricky, however, because
|
||||
the tools like "strip", "ranlib" and etc. that come with Mingw do not
|
||||
understand the Cygwin style paths that are in the makefile. To get
|
||||
around that problem, first remove the Mingw from your path before
|
||||
doing the next step. An easy way to do that is to open a fresh Cygwin
|
||||
window.
|
||||
|
||||
When you are ready, install like this:
|
||||
|
||||
$ make install
|
||||
|
||||
This is part of what the configure program did for you. The Makefiles
|
||||
now know to put the files under the D:\iverilog (or whatever directory
|
||||
you chose) directory, and away you go.
|
||||
|
||||
|
||||
* Running Icarus Verilog
|
||||
|
||||
Finally, put the D:\iverilog\bin directory in your Windows path, and
|
||||
you should be able to run the iverilog and vvp commands to your
|
||||
heart's content.
|
||||
|
||||
Currently, the iverilog.exe uses the path to itself to locate the
|
||||
libraries and modules associated with itself. In other words, if you
|
||||
execute the D:\iverilog\bin\iverilog.exe program, it will locate its
|
||||
subparts in the D:\iverilog directory and subdirectories below
|
||||
that. This means you can move the Icarus Verilog installation by
|
||||
simply moving the root directory and all its contents.
|
||||
+83
-9
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_assign.cc,v 1.6 2000/10/18 20:04:39 steve Exp $"
|
||||
#ident "$Id: net_assign.cc,v 1.8 2001/08/25 23:50:03 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
|
||||
/*
|
||||
@@ -36,19 +38,18 @@ unsigned count_lval_width(const NetAssign_*idx)
|
||||
return wid;
|
||||
}
|
||||
|
||||
NetAssign_::NetAssign_(const string&n, unsigned w)
|
||||
: NetNode(n, w), bmux_(0)
|
||||
NetAssign_::NetAssign_(NetNet*s)
|
||||
: sig_(s), bmux_(0)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
|
||||
pin(idx).set_dir(Link::OUTPUT);
|
||||
pin(idx).set_name("P", idx);
|
||||
}
|
||||
|
||||
loff_ = 0;
|
||||
lwid_ = sig_->pin_count();
|
||||
sig_->incr_eref();
|
||||
more = 0;
|
||||
}
|
||||
|
||||
NetAssign_::~NetAssign_()
|
||||
{
|
||||
if (sig_) sig_->decr_eref();
|
||||
assert( more == 0 );
|
||||
if (bmux_) delete bmux_;
|
||||
}
|
||||
@@ -67,7 +68,34 @@ const NetExpr* NetAssign_::bmux() const
|
||||
unsigned NetAssign_::lwidth() const
|
||||
{
|
||||
if (bmux_) return 1;
|
||||
else return pin_count();
|
||||
else return lwid_;
|
||||
}
|
||||
|
||||
const char*NetAssign_::name() const
|
||||
{
|
||||
if (sig_) {
|
||||
return sig_->name();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
NetNet* NetAssign_::sig() const
|
||||
{
|
||||
assert(sig_);
|
||||
return sig_;
|
||||
}
|
||||
|
||||
void NetAssign_::set_part(unsigned lo, unsigned lw)
|
||||
{
|
||||
loff_ = lo;
|
||||
lwid_ = lw;
|
||||
assert(sig_->pin_count() >= (lo + lw));
|
||||
}
|
||||
|
||||
unsigned NetAssign_::get_loff() const
|
||||
{
|
||||
return loff_;
|
||||
}
|
||||
|
||||
NetAssignBase::NetAssignBase(NetAssign_*lv, NetExpr*rv)
|
||||
@@ -165,14 +193,60 @@ NetAssign::~NetAssign()
|
||||
NetAssignNB::NetAssignNB(NetAssign_*lv, NetExpr*rv)
|
||||
: NetAssignBase(lv, rv)
|
||||
{
|
||||
rise_time_ = 0;
|
||||
fall_time_ = 0;
|
||||
decay_time_ = 0;
|
||||
}
|
||||
|
||||
NetAssignNB::~NetAssignNB()
|
||||
{
|
||||
}
|
||||
|
||||
void NetAssignNB::rise_time(unsigned t)
|
||||
{
|
||||
rise_time_ = t;
|
||||
}
|
||||
|
||||
void NetAssignNB::fall_time(unsigned t)
|
||||
{
|
||||
fall_time_ = t;
|
||||
}
|
||||
|
||||
void NetAssignNB::decay_time(unsigned t)
|
||||
{
|
||||
decay_time_ = t;
|
||||
}
|
||||
|
||||
unsigned NetAssignNB::rise_time() const
|
||||
{
|
||||
return rise_time_;
|
||||
}
|
||||
|
||||
unsigned NetAssignNB::fall_time() const
|
||||
{
|
||||
return fall_time_;
|
||||
}
|
||||
|
||||
unsigned NetAssignNB::decay_time() const
|
||||
{
|
||||
return decay_time_;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: net_assign.cc,v $
|
||||
* Revision 1.8 2001/08/25 23:50:03 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.7 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.6 2000/10/18 20:04:39 steve
|
||||
* Add ivl_lval_t and support for assignment l-values.
|
||||
*
|
||||
|
||||
+104
-100
@@ -17,9 +17,13 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_design.cc,v 1.18 2001/01/14 23:04:56 steve Exp $"
|
||||
#ident "$Id: net_design.cc,v 1.23 2001/12/03 04:47:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
/*
|
||||
* This source file contains all the implementations of the Design
|
||||
* class declared in netlist.h.
|
||||
@@ -30,7 +34,7 @@
|
||||
# include <strstream>
|
||||
|
||||
Design:: Design()
|
||||
: errors(0), root_scope_(0), nodes_(0), procs_(0), lcounter_(0)
|
||||
: errors(0), nodes_(0), procs_(0), lcounter_(0)
|
||||
{
|
||||
procs_idx_ = 0;
|
||||
des_precision_ = 0;
|
||||
@@ -73,24 +77,29 @@ unsigned long Design::scale_to_precision(unsigned long val,
|
||||
return val;
|
||||
}
|
||||
|
||||
NetScope* Design::make_root_scope(const string&root)
|
||||
NetScope* Design::make_root_scope(const char*root)
|
||||
{
|
||||
assert(root_scope_ == 0);
|
||||
NetScope *root_scope_;
|
||||
root_scope_ = new NetScope(0, root, NetScope::MODULE);
|
||||
root_scope_->set_module_name(root.c_str());
|
||||
root_scope_->set_module_name(root);
|
||||
root_scopes_.push_back(root_scope_);
|
||||
return root_scope_;
|
||||
}
|
||||
|
||||
NetScope* Design::find_root_scope()
|
||||
{
|
||||
assert(root_scope_);
|
||||
return root_scope_;
|
||||
assert(root_scopes_.front());
|
||||
return root_scopes_.front();
|
||||
}
|
||||
|
||||
const NetScope* Design::find_root_scope() const
|
||||
list<NetScope*> Design::find_root_scopes()
|
||||
{
|
||||
assert(root_scope_);
|
||||
return root_scope_;
|
||||
return root_scopes_;
|
||||
}
|
||||
|
||||
const list<NetScope*> Design::find_root_scopes() const
|
||||
{
|
||||
return root_scopes_;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -99,25 +108,28 @@ const NetScope* Design::find_root_scope() const
|
||||
* more step down the tree until the name runs out or the search
|
||||
* fails.
|
||||
*/
|
||||
NetScope* Design::find_scope(const string&key) const
|
||||
NetScope* Design::find_scope(const hname_t&path) const
|
||||
{
|
||||
if (key == root_scope_->name())
|
||||
return root_scope_;
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin()
|
||||
; scope != root_scopes_.end(); scope++) {
|
||||
|
||||
string path = key;
|
||||
string root = parse_first_name(path);
|
||||
NetScope*cur = *scope;
|
||||
if (strcmp(path.peek_name(0), cur->basename()) != 0)
|
||||
continue;
|
||||
|
||||
NetScope*cur = root_scope_;
|
||||
if (root != cur->name())
|
||||
return 0;
|
||||
unsigned hidx = 1;
|
||||
while (cur) {
|
||||
const char*name = path.peek_name(hidx);
|
||||
if (name == 0)
|
||||
return cur;
|
||||
|
||||
cur = cur->child(name);
|
||||
hidx += 1;
|
||||
}
|
||||
|
||||
while (cur) {
|
||||
string next = parse_first_name(path);
|
||||
cur = cur->child(next);
|
||||
if (path == "") return cur;
|
||||
}
|
||||
|
||||
return cur;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -127,26 +139,27 @@ NetScope* Design::find_scope(const string&key) const
|
||||
* start looking in parent scopes until I find it, or I run out of
|
||||
* parent scopes.
|
||||
*/
|
||||
NetScope* Design::find_scope(NetScope*scope, const string&name) const
|
||||
NetScope* Design::find_scope(NetScope*scope, const hname_t&path) const
|
||||
{
|
||||
assert(scope);
|
||||
|
||||
for ( ; scope ; scope = scope->parent()) {
|
||||
string path = name;
|
||||
string key = parse_first_name(path);
|
||||
unsigned hidx = 0;
|
||||
const char*key = path.peek_name(hidx);
|
||||
|
||||
NetScope*cur = scope;
|
||||
do {
|
||||
cur = cur->child(key);
|
||||
if (cur == 0) break;
|
||||
key = parse_first_name(path);
|
||||
} while (key != "");
|
||||
hidx += 1;
|
||||
key = path.peek_name(hidx);
|
||||
} while (key);
|
||||
|
||||
if (cur) return cur;
|
||||
}
|
||||
|
||||
// Last chance. Look for the name starting at the root.
|
||||
return find_scope(name);
|
||||
return find_scope(path);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -158,22 +171,23 @@ NetScope* Design::find_scope(NetScope*scope, const string&name) const
|
||||
* follow the scopes of the name down to to key.
|
||||
*/
|
||||
const NetExpr* Design::find_parameter(const NetScope*scope,
|
||||
const string&name) const
|
||||
const hname_t&path) const
|
||||
{
|
||||
for ( ; scope ; scope = scope->parent()) {
|
||||
string path = name;
|
||||
string key = parse_first_name(path);
|
||||
unsigned hidx = 0;
|
||||
|
||||
const NetScope*cur = scope;
|
||||
while (path != "") {
|
||||
cur = cur->child(key);
|
||||
if (cur == 0) break;
|
||||
key = parse_first_name(path);
|
||||
while (path.peek_name(hidx+1)) {
|
||||
cur = cur->child(path.peek_name(hidx));
|
||||
if (cur == 0)
|
||||
break;
|
||||
hidx += 1;
|
||||
}
|
||||
|
||||
if (cur == 0) continue;
|
||||
if (cur == 0)
|
||||
continue;
|
||||
|
||||
if (const NetExpr*res = cur->get_parameter(key))
|
||||
if (const NetExpr*res = cur->get_parameter(path.peek_name(hidx)))
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -190,7 +204,9 @@ const NetExpr* Design::find_parameter(const NetScope*scope,
|
||||
*/
|
||||
void Design::run_defparams()
|
||||
{
|
||||
root_scope_->run_defparams(this);
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->run_defparams(this);
|
||||
}
|
||||
|
||||
void NetScope::run_defparams(Design*des)
|
||||
@@ -201,16 +217,18 @@ void NetScope::run_defparams(Design*des)
|
||||
cur = cur->sib_;
|
||||
}
|
||||
|
||||
map<string,NetExpr*>::const_iterator pp;
|
||||
map<hname_t,NetExpr*>::const_iterator pp;
|
||||
for (pp = defparams.begin() ; pp != defparams.end() ; pp ++ ) {
|
||||
NetExpr*val = (*pp).second;
|
||||
string path = (*pp).first;
|
||||
string name = parse_last_name(path);
|
||||
hname_t path = (*pp).first;
|
||||
|
||||
char*name = path.remove_tail_name();
|
||||
|
||||
NetScope*targ_scope = des->find_scope(this, path);
|
||||
if (targ_scope == 0) {
|
||||
cerr << val->get_line() << ": warning: scope of " <<
|
||||
path << "." << name << " not found." << endl;
|
||||
delete[]name;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -222,12 +240,16 @@ void NetScope::run_defparams(Design*des)
|
||||
} else {
|
||||
delete val;
|
||||
}
|
||||
|
||||
delete[]name;
|
||||
}
|
||||
}
|
||||
|
||||
void Design::evaluate_parameters()
|
||||
{
|
||||
root_scope_->evaluate_parameters(this);
|
||||
for (list<NetScope*>::const_iterator scope = root_scopes_.begin();
|
||||
scope != root_scopes_.end(); scope++)
|
||||
(*scope)->evaluate_parameters(this);
|
||||
}
|
||||
|
||||
void NetScope::evaluate_parameters(Design*des)
|
||||
@@ -294,87 +316,52 @@ string Design::get_flag(const string&key) const
|
||||
* It is the job of this function to properly implement Verilog scope
|
||||
* rules as signals are concerned.
|
||||
*/
|
||||
NetNet* Design::find_signal(NetScope*scope, const string&name)
|
||||
NetNet* Design::find_signal(NetScope*scope, hname_t path)
|
||||
{
|
||||
assert(scope);
|
||||
|
||||
/* If the name has a path attached to it, parse it off and use
|
||||
that to locate the desired starting scope. */
|
||||
string path = name;
|
||||
string key = parse_last_name(path);
|
||||
if (path != "")
|
||||
char*key = path.remove_tail_name();
|
||||
if (path.peek_name(0))
|
||||
scope = find_scope(scope, path);
|
||||
|
||||
/* Now from the starting point, scan upwards until we find the
|
||||
signal or we find a module boundary. */
|
||||
while (scope) {
|
||||
|
||||
if (NetNet*net = scope->find_signal(key))
|
||||
if (NetNet*net = scope->find_signal(key)) {
|
||||
delete key;
|
||||
return net;
|
||||
}
|
||||
|
||||
if (scope->type() == NetScope::MODULE)
|
||||
break;
|
||||
|
||||
scope = scope->parent();
|
||||
}
|
||||
|
||||
delete key;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetMemory* Design::find_memory(NetScope*scope, const string&name)
|
||||
NetMemory* Design::find_memory(NetScope*scope, hname_t path)
|
||||
{
|
||||
assert(scope);
|
||||
|
||||
/* If the name has a path attached to it, parse it off and use
|
||||
that to locate the desired scope. */
|
||||
string path = name;
|
||||
string key = parse_last_name(path);
|
||||
if (path != "")
|
||||
char*key = path.remove_tail_name();
|
||||
if (path.peek_name(0))
|
||||
scope = find_scope(scope, path);
|
||||
|
||||
while (scope) {
|
||||
|
||||
if (NetMemory*mem = scope->find_memory(key))
|
||||
if (NetMemory*mem = scope->find_memory(key)) {
|
||||
delete key;
|
||||
return mem;
|
||||
}
|
||||
|
||||
scope = scope->parent();
|
||||
}
|
||||
|
||||
delete key;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Design::find_symbol(NetScope*scope, const string&name,
|
||||
NetNet*&sig, NetMemory*&mem)
|
||||
{
|
||||
sig = 0;
|
||||
mem = 0;
|
||||
|
||||
|
||||
/* If the name has a path attached to it, parse it off and use
|
||||
that to locate the desired scope. Then locate the key
|
||||
within that scope. */
|
||||
string path = name;
|
||||
string key = parse_last_name(path);
|
||||
if (path != "")
|
||||
scope = find_scope(scope, path);
|
||||
|
||||
|
||||
/* If there is no path, then just search upwards for the key. */
|
||||
while (scope) {
|
||||
|
||||
if (NetNet*cur = scope->find_signal(key)) {
|
||||
sig = cur;
|
||||
return;
|
||||
}
|
||||
|
||||
if (NetMemory*cur = scope->find_memory(key)) {
|
||||
mem = cur;
|
||||
return;
|
||||
}
|
||||
|
||||
scope = scope->parent();
|
||||
}
|
||||
}
|
||||
|
||||
NetFuncDef* Design::find_function(NetScope*scope, const string&name)
|
||||
NetFuncDef* Design::find_function(NetScope*scope, const hname_t&name)
|
||||
{
|
||||
assert(scope);
|
||||
NetScope*func = find_scope(scope, name);
|
||||
@@ -384,7 +371,7 @@ NetFuncDef* Design::find_function(NetScope*scope, const string&name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetFuncDef* Design::find_function(const string&key)
|
||||
NetFuncDef* Design::find_function(const hname_t&key)
|
||||
{
|
||||
NetScope*func = find_scope(key);
|
||||
if (func && (func->type() == NetScope::FUNC))
|
||||
@@ -393,20 +380,20 @@ NetFuncDef* Design::find_function(const string&key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetTaskDef* Design::find_task(NetScope*scope, const string&name)
|
||||
NetScope* Design::find_task(NetScope*scope, const hname_t&name)
|
||||
{
|
||||
NetScope*task = find_scope(scope, name);
|
||||
if (task && (task->type() == NetScope::TASK))
|
||||
return task->task_def();
|
||||
return task;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetTaskDef* Design::find_task(const string&key)
|
||||
NetScope* Design::find_task(const hname_t&key)
|
||||
{
|
||||
NetScope*task = find_scope(key);
|
||||
if (task && (task->type() == NetScope::TASK))
|
||||
return task->task_def();
|
||||
return task;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -473,6 +460,23 @@ void Design::delete_process(NetProcTop*top)
|
||||
|
||||
/*
|
||||
* $Log: net_design.cc,v $
|
||||
* Revision 1.23 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.22 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
*
|
||||
* Revision 1.21 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
* Revision 1.20 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.19 2001/04/02 02:28:12 steve
|
||||
* Generate code for task calls.
|
||||
*
|
||||
* Revision 1.18 2001/01/14 23:04:56 steve
|
||||
* Generalize the evaluation of floating point delays, and
|
||||
* get it working with delay assignment statements.
|
||||
|
||||
+35
-3
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_event.cc,v 1.12 2000/12/15 17:45:07 steve Exp $"
|
||||
#ident "$Id: net_event.cc,v 1.16 2001/10/28 01:14:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
|
||||
NetEvent::NetEvent(const string&n)
|
||||
@@ -58,6 +60,12 @@ string NetEvent::full_name() const
|
||||
return scope_->name() + "." + name_;
|
||||
}
|
||||
|
||||
const NetScope* NetEvent::scope() const
|
||||
{
|
||||
assert(scope_);
|
||||
return scope_;
|
||||
}
|
||||
|
||||
unsigned NetEvent::nprobe() const
|
||||
{
|
||||
unsigned cnt = 0;
|
||||
@@ -80,6 +88,16 @@ NetEvProbe* NetEvent::probe(unsigned idx)
|
||||
return cur;
|
||||
}
|
||||
|
||||
const NetEvProbe* NetEvent::probe(unsigned idx) const
|
||||
{
|
||||
NetEvProbe*cur = probes_;
|
||||
while (cur && idx) {
|
||||
cur = cur->enext_;
|
||||
idx -= 1;
|
||||
}
|
||||
return cur;
|
||||
}
|
||||
|
||||
unsigned NetEvent::ntrig() const
|
||||
{
|
||||
unsigned cnt = 0;
|
||||
@@ -265,9 +283,9 @@ const NetEvent* NetEvTrig::event() const
|
||||
return event_;
|
||||
}
|
||||
|
||||
NetEvProbe::NetEvProbe(const string&n, NetEvent*tgt,
|
||||
NetEvProbe::NetEvProbe(NetScope*s, const string&n, NetEvent*tgt,
|
||||
edge_t t, unsigned p)
|
||||
: NetNode(n, p), event_(tgt), edge_(t)
|
||||
: NetNode(s, n, p), event_(tgt), edge_(t)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < p ; idx += 1) {
|
||||
pin(idx).set_dir(Link::INPUT);
|
||||
@@ -433,6 +451,20 @@ NetProc* NetEvWait::statement()
|
||||
|
||||
/*
|
||||
* $Log: net_event.cc,v $
|
||||
* Revision 1.16 2001/10/28 01:14:53 steve
|
||||
* NetObj constructor finally requires a scope.
|
||||
*
|
||||
* Revision 1.15 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.14 2001/03/29 02:52:19 steve
|
||||
* Add const probe method to NetEvent.
|
||||
*
|
||||
* Revision 1.13 2001/03/28 06:07:39 steve
|
||||
* Add the ivl_event_t to ivl_target, and use that to generate
|
||||
* .event statements in vvp way ahead of the thread that uses it.
|
||||
*
|
||||
* Revision 1.12 2000/12/15 17:45:07 steve
|
||||
* Remove limits from the similar events search.
|
||||
*
|
||||
|
||||
+30
-5
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_force.cc,v 1.2 2000/05/12 01:22:41 steve Exp $"
|
||||
#ident "$Id: net_force.cc,v 1.6 2001/11/14 03:28:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
/*
|
||||
* This file contains implementatsion of the NetForce, NetRelease,
|
||||
* NetCAssign and NetDeassign classes. These are similar or related in
|
||||
@@ -42,8 +44,8 @@
|
||||
* output pins to connect to the netlist? But that would cause the
|
||||
* link ring to grow, and that is not quite correct either. Hmm...
|
||||
*/
|
||||
NetCAssign::NetCAssign(const string&n, NetNet*l)
|
||||
: NetNode(n, l->pin_count()), lval_(l)
|
||||
NetCAssign::NetCAssign(NetScope*s, const string&n, NetNet*l)
|
||||
: NetNode(s, n, l->pin_count()), lval_(l)
|
||||
{
|
||||
lval_->incr_eref();
|
||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
|
||||
@@ -57,6 +59,11 @@ NetCAssign::~NetCAssign()
|
||||
lval_->decr_eref();
|
||||
}
|
||||
|
||||
const NetNet* NetCAssign::lval() const
|
||||
{
|
||||
return lval_;
|
||||
}
|
||||
|
||||
const Link& NetCAssign::lval_pin(unsigned idx) const
|
||||
{
|
||||
assert(idx < lval_->pin_count());
|
||||
@@ -79,8 +86,8 @@ const NetNet*NetDeassign::lval() const
|
||||
return lval_;
|
||||
}
|
||||
|
||||
NetForce::NetForce(const string&n, NetNet*l)
|
||||
: NetNode(n, l->pin_count()), lval_(l)
|
||||
NetForce::NetForce(NetScope*s, const string&n, NetNet*l)
|
||||
: NetNode(s, n, l->pin_count()), lval_(l)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
|
||||
pin(idx).set_dir(Link::INPUT);
|
||||
@@ -98,6 +105,11 @@ const Link& NetForce::lval_pin(unsigned idx) const
|
||||
return lval_->pin(idx);
|
||||
}
|
||||
|
||||
const NetNet* NetForce::lval() const
|
||||
{
|
||||
return lval_;
|
||||
}
|
||||
|
||||
NetRelease::NetRelease(NetNet*l)
|
||||
: lval_(l)
|
||||
{
|
||||
@@ -115,6 +127,19 @@ const NetNet*NetRelease::lval() const
|
||||
|
||||
/*
|
||||
* $Log: net_force.cc,v $
|
||||
* Revision 1.6 2001/11/14 03:28:49 steve
|
||||
* DLL target support for force and release.
|
||||
*
|
||||
* Revision 1.5 2001/10/31 05:24:52 steve
|
||||
* ivl_target support for assign/deassign.
|
||||
*
|
||||
* Revision 1.4 2001/10/28 01:14:53 steve
|
||||
* NetObj constructor finally requires a scope.
|
||||
*
|
||||
* Revision 1.3 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.2 2000/05/12 01:22:41 steve
|
||||
* NetCAssign needs to incr_eref its lval to lock it down.
|
||||
*
|
||||
|
||||
+9
-1
@@ -17,9 +17,13 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_link.cc,v 1.4 2000/10/06 23:46:50 steve Exp $"
|
||||
#ident "$Id: net_link.cc,v 1.5 2001/07/25 03:10:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include "netlist.h"
|
||||
# include <strstream>
|
||||
# include <string>
|
||||
@@ -350,6 +354,10 @@ const char* Nexus::name() const
|
||||
|
||||
/*
|
||||
* $Log: net_link.cc,v $
|
||||
* Revision 1.5 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.4 2000/10/06 23:46:50 steve
|
||||
* ivl_target updates, including more complete
|
||||
* handling of ivl_nexus_t objects. Much reduced
|
||||
|
||||
+5
-3
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_modulo.cc,v 1.1 2000/09/17 21:26:15 steve Exp $"
|
||||
#ident "$Id: net_modulo.cc,v 1.3 2001/10/28 01:14:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <typeinfo>
|
||||
# include <iostream>
|
||||
# include <iomanip>
|
||||
@@ -28,9 +30,9 @@
|
||||
# include "netlist.h"
|
||||
|
||||
|
||||
NetModulo::NetModulo(const string&n, unsigned wr,
|
||||
NetModulo::NetModulo(NetScope*s, const string&n, unsigned wr,
|
||||
unsigned wa, unsigned wb)
|
||||
: NetNode(n, wr+wa+wb), width_r_(wr), width_a_(wa), width_b_(wb)
|
||||
: NetNode(s, n, wr+wa+wb), width_r_(wr), width_a_(wa), width_b_(wb)
|
||||
{
|
||||
unsigned p = 0;
|
||||
for (unsigned idx = 0 ; idx < width_r_ ; idx += 1, p += 1) {
|
||||
|
||||
+7
-1
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_proc.cc,v 1.2 2000/07/27 05:13:44 steve Exp $"
|
||||
#ident "$Id: net_proc.cc,v 1.3 2001/07/25 03:10:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
# include <assert.h>
|
||||
|
||||
@@ -93,6 +95,10 @@ const NetExpr* NetRepeat::expr() const
|
||||
|
||||
/*
|
||||
* $Log: net_proc.cc,v $
|
||||
* Revision 1.3 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.2 2000/07/27 05:13:44 steve
|
||||
* Support elaboration of disable statements.
|
||||
*
|
||||
|
||||
+57
-29
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_scope.cc,v 1.11 2000/12/16 01:45:48 steve Exp $"
|
||||
#ident "$Id: net_scope.cc,v 1.16 2001/12/03 04:47:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
# include <strstream>
|
||||
|
||||
@@ -32,7 +34,7 @@
|
||||
* in question.
|
||||
*/
|
||||
|
||||
NetScope::NetScope(NetScope*up, const string&n, NetScope::TYPE t)
|
||||
NetScope::NetScope(NetScope*up, const char*n, NetScope::TYPE t)
|
||||
: type_(t), up_(up), sib_(0), sub_(0)
|
||||
{
|
||||
memories_ = 0;
|
||||
@@ -61,8 +63,8 @@ NetScope::NetScope(NetScope*up, const string&n, NetScope::TYPE t)
|
||||
module_name_ = 0;
|
||||
break;
|
||||
}
|
||||
name_ = new char[n.length()+1];
|
||||
strcpy(name_, n.c_str());
|
||||
name_ = new char[strlen(n)+1];
|
||||
strcpy(name_, n);
|
||||
}
|
||||
|
||||
NetScope::~NetScope()
|
||||
@@ -222,10 +224,10 @@ void NetScope::rem_event(NetEvent*ev)
|
||||
}
|
||||
|
||||
|
||||
NetEvent* NetScope::find_event(const string&name)
|
||||
NetEvent* NetScope::find_event(const hname_t&name)
|
||||
{
|
||||
for (NetEvent*cur = events_; cur ; cur = cur->snext_)
|
||||
if (cur->name() == name)
|
||||
if (strcmp(cur->name(), name.peek_tail_name()) == 0)
|
||||
return cur;
|
||||
|
||||
return 0;
|
||||
@@ -259,6 +261,11 @@ void NetScope::rem_signal(NetNet*net)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This method looks for a signal within the current scope. The name
|
||||
* is assumed to be the base name of the signal, so no sub-scopes are
|
||||
* searched.
|
||||
*/
|
||||
NetNet* NetScope::find_signal(const string&key)
|
||||
{
|
||||
if (signals_ == 0)
|
||||
@@ -274,6 +281,27 @@ NetNet* NetScope::find_signal(const string&key)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method searches for the signal within this scope. If the path
|
||||
* has hierarchy, I follow the child scopes until I get the base name,
|
||||
* and look for the key in the deepest scope.
|
||||
*/
|
||||
NetNet* NetScope::find_signal_in_child(const hname_t&path)
|
||||
{
|
||||
NetScope*cur = this;
|
||||
unsigned idx = 0;
|
||||
|
||||
while (path.peek_name(idx+1)) {
|
||||
cur = cur->child(path.peek_name(idx));
|
||||
if (cur == 0)
|
||||
return 0;
|
||||
|
||||
idx += 1;
|
||||
}
|
||||
|
||||
return cur->find_signal(path.peek_name(idx));
|
||||
}
|
||||
|
||||
void NetScope::add_memory(NetMemory*mem)
|
||||
{
|
||||
if (memories_ == 0) {
|
||||
@@ -362,13 +390,35 @@ const NetScope* NetScope::parent() const
|
||||
string NetScope::local_symbol()
|
||||
{
|
||||
strstream res;
|
||||
res << "_l" << (lcounter_++) << ends;
|
||||
res << "_s" << (lcounter_++) << ends;
|
||||
return res.str();
|
||||
}
|
||||
|
||||
string NetScope::local_hsymbol()
|
||||
{
|
||||
return name() + "." + local_symbol();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: net_scope.cc,v $
|
||||
* Revision 1.16 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.15 2001/11/08 05:15:50 steve
|
||||
* Remove string paths from PExpr elaboration.
|
||||
*
|
||||
* Revision 1.14 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
*
|
||||
* Revision 1.13 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.12 2001/07/04 04:34:06 steve
|
||||
* Scope-locals use _s instead of _l.
|
||||
*
|
||||
* Revision 1.11 2000/12/16 01:45:48 steve
|
||||
* Detect recursive instantiations (PR#2)
|
||||
*
|
||||
@@ -389,27 +439,5 @@ string NetScope::local_symbol()
|
||||
* signal enaboration, and carry these objects in the
|
||||
* NetScope class instead of the extra, useless map in
|
||||
* the Design class.
|
||||
*
|
||||
* Revision 1.7 2000/07/22 22:09:03 steve
|
||||
* Parse and elaborate timescale to scopes.
|
||||
*
|
||||
* Revision 1.6 2000/05/02 03:13:31 steve
|
||||
* Move memories to the NetScope object.
|
||||
*
|
||||
* Revision 1.5 2000/05/02 00:58:12 steve
|
||||
* Move signal tables to the NetScope class.
|
||||
*
|
||||
* Revision 1.4 2000/04/18 04:50:20 steve
|
||||
* Clean up unneeded NetEvent objects.
|
||||
*
|
||||
* Revision 1.3 2000/04/10 05:26:06 steve
|
||||
* All events now use the NetEvent class.
|
||||
*
|
||||
* Revision 1.2 2000/04/09 17:04:56 steve
|
||||
* uninitialized event_ list.
|
||||
*
|
||||
* Revision 1.1 2000/04/04 03:20:15 steve
|
||||
* Simulate named event trigger and waits.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
+59
-152
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2000 Stephen Williams (steve@icarus.com)
|
||||
* Copyright (c) 2001 Stephan Boettcher <stephan@nevis.columbia.edu>
|
||||
*
|
||||
* This source code is free software; you can redistribute it
|
||||
* and/or modify it in source code form under the terms of the GNU
|
||||
@@ -17,128 +18,15 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: net_udp.cc,v 1.3 2000/12/15 01:24:17 steve Exp $"
|
||||
#ident "$Id: net_udp.cc,v 1.6 2001/07/25 03:10:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
|
||||
bool NetUDP::set_table(const string&input, char output)
|
||||
{
|
||||
assert((output == '0') || (output == '1')
|
||||
|| (is_sequential() && (output == '-')));
|
||||
|
||||
cm_[input] = output;
|
||||
|
||||
if (is_sequential()) {
|
||||
assert(input.length() == pin_count());
|
||||
/* XXXX Need to check to make sure that the input vector
|
||||
contains a legal combination of characters. */
|
||||
return sequ_glob_(input, output);
|
||||
|
||||
} else {
|
||||
assert(input.length() == (pin_count()-1));
|
||||
/* XXXX Need to check to make sure that the input vector
|
||||
contains a legal combination of characters. In
|
||||
combinational UDPs, only 0, 1, x, and ? are allowed. */
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void NetUDP::cleanup_table()
|
||||
{
|
||||
for (FSM_::iterator idx = fsm_.begin() ; idx != fsm_.end() ; idx++) {
|
||||
string str = (*idx).first;
|
||||
state_t_*st = (*idx).second;
|
||||
assert(str[0] == st->out);
|
||||
|
||||
for (unsigned pin = 0 ; pin < pin_count() ; pin += 1) {
|
||||
if (st->pins[pin].zer && st->pins[pin].zer->out == 'x')
|
||||
st->pins[pin].zer = 0;
|
||||
if (st->pins[pin].one && st->pins[pin].one->out == 'x')
|
||||
st->pins[pin].one = 0;
|
||||
if (st->pins[pin].xxx && st->pins[pin].xxx->out == 'x')
|
||||
st->pins[pin].xxx = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (FSM_::iterator idx = fsm_.begin() ; idx != fsm_.end() ; ) {
|
||||
FSM_::iterator cur = idx;
|
||||
idx ++;
|
||||
|
||||
state_t_*st = (*cur).second;
|
||||
|
||||
if (st->out != 'x')
|
||||
continue;
|
||||
|
||||
for (unsigned pin = 0 ; pin < pin_count() ; pin += 1) {
|
||||
if (st->pins[pin].zer)
|
||||
goto break_label;
|
||||
if (st->pins[pin].one)
|
||||
goto break_label;
|
||||
if (st->pins[pin].xxx)
|
||||
goto break_label;
|
||||
}
|
||||
|
||||
//delete st;
|
||||
fsm_.erase(cur);
|
||||
|
||||
break_label:;
|
||||
}
|
||||
}
|
||||
|
||||
char NetUDP::table_lookup(const string&from, char to, unsigned pin) const
|
||||
{
|
||||
assert(pin <= pin_count());
|
||||
assert(from.length() == pin_count());
|
||||
FSM_::const_iterator idx = fsm_.find(from);
|
||||
if (idx == fsm_.end())
|
||||
return 'x';
|
||||
|
||||
state_t_*next;
|
||||
switch (to) {
|
||||
case '0':
|
||||
next = (*idx).second->pins[pin].zer;
|
||||
break;
|
||||
case '1':
|
||||
next = (*idx).second->pins[pin].one;
|
||||
break;
|
||||
case 'x':
|
||||
next = (*idx).second->pins[pin].xxx;
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
next = 0;
|
||||
}
|
||||
|
||||
return next? next->out : 'x';
|
||||
}
|
||||
|
||||
void NetUDP::set_initial(char val)
|
||||
{
|
||||
assert(is_sequential());
|
||||
assert((val == '0') || (val == '1') || (val == 'x'));
|
||||
init_ = val;
|
||||
}
|
||||
|
||||
NetUDP::state_t_* NetUDP::find_state_(const string&str)
|
||||
{
|
||||
map<string,state_t_*>::iterator cur = fsm_.find(str);
|
||||
if (cur != fsm_.end())
|
||||
return (*cur).second;
|
||||
|
||||
state_t_*st = fsm_[str];
|
||||
if (st == 0) {
|
||||
st = new state_t_(pin_count());
|
||||
st->out = str[0];
|
||||
fsm_[str] = st;
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
NetUDP_COMB::NetUDP_COMB(const string&n, unsigned pins, bool sequ)
|
||||
: NetNode(n, pins), sequential_(sequ)
|
||||
NetUDP::NetUDP(NetScope*s, const string&n, unsigned pins, PUdp *u)
|
||||
: NetNode(s, n, pins), udp(u)
|
||||
{
|
||||
pin(0).set_dir(Link::OUTPUT);
|
||||
pin(0).set_name("O", 0);
|
||||
@@ -148,52 +36,71 @@ NetUDP_COMB::NetUDP_COMB(const string&n, unsigned pins, bool sequ)
|
||||
}
|
||||
}
|
||||
|
||||
bool NetUDP_COMB::set_table(const string&input, char output)
|
||||
bool NetUDP::first(string&inp, char&out) const
|
||||
{
|
||||
if ((output != '0') && (output != '1') && (output != 'x'))
|
||||
return false;
|
||||
table_idx = (unsigned) -1;
|
||||
return next(inp, out);
|
||||
}
|
||||
|
||||
bool NetUDP::next(string&inp, char&out) const
|
||||
{
|
||||
table_idx++;
|
||||
|
||||
assert((output == '0') || (output == '1') || (output == 'x'));
|
||||
assert(input.length() == (pin_count()-1));
|
||||
if (table_idx >= udp->tinput.count())
|
||||
return false;
|
||||
|
||||
/* XXXX Need to check to make sure that the input vector
|
||||
contains a legal combination of characters. In
|
||||
combinational UDPs, only 0, 1, x, and ? are allowed. */
|
||||
cm_[input] = output;
|
||||
if (is_sequential())
|
||||
{
|
||||
inp = string("") + udp->tcurrent[table_idx] + udp->tinput[table_idx];
|
||||
assert(inp.length() == pin_count());
|
||||
}
|
||||
else
|
||||
{
|
||||
inp = udp->tinput[table_idx];
|
||||
assert(inp.length() == (pin_count()-1));
|
||||
}
|
||||
|
||||
return true;
|
||||
out = udp->toutput[table_idx];
|
||||
assert( (out == '0')
|
||||
|| (out == '1')
|
||||
|| (out == 'x')
|
||||
|| (is_sequential() && (out == '-')));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NetUDP_COMB::cleanup_table()
|
||||
char NetUDP::get_initial() const
|
||||
{
|
||||
assert (is_sequential());
|
||||
|
||||
switch (udp->initial)
|
||||
{
|
||||
case verinum::V0:
|
||||
return '0';
|
||||
case verinum::V1:
|
||||
return '1';
|
||||
case verinum::Vx:
|
||||
case verinum::Vz:
|
||||
return 'x';
|
||||
}
|
||||
|
||||
assert(0);
|
||||
return 'x';
|
||||
}
|
||||
|
||||
bool NetUDP_COMB::first(string&inp, char&out) const
|
||||
{
|
||||
idx_ = cm_.begin();
|
||||
if (idx_ == cm_.end())
|
||||
return false;
|
||||
|
||||
inp = (*idx_).first;
|
||||
out = (*idx_).second;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetUDP_COMB::next(string&inp, char&out) const
|
||||
{
|
||||
idx_ ++;
|
||||
if (idx_ == cm_.end())
|
||||
return false;
|
||||
|
||||
inp = (*idx_).first;
|
||||
out = (*idx_).second;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: net_udp.cc,v $
|
||||
* Revision 1.6 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.5 2001/04/24 02:23:58 steve
|
||||
* Support for UDP devices in VVP (Stephen Boettcher)
|
||||
*
|
||||
* Revision 1.4 2001/04/22 23:09:46 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.3 2000/12/15 01:24:17 steve
|
||||
* Accept x in outputs of primitive. (PR#84)
|
||||
*
|
||||
|
||||
+257
-237
@@ -17,9 +17,13 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: netlist.cc,v 1.154 2001/01/18 03:16:35 steve Exp $"
|
||||
#ident "$Id: netlist.cc,v 1.178 2001/12/03 04:47:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include <iostream>
|
||||
|
||||
# include <cassert>
|
||||
# include <typeinfo>
|
||||
# include "netlist.h"
|
||||
@@ -159,8 +163,8 @@ Link* find_next_output(Link*lnk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetObj::NetObj(const string&n, unsigned np)
|
||||
: scope_(0), npins_(np), delay1_(0), delay2_(0), delay3_(0)
|
||||
NetObj::NetObj(NetScope*s, const string&n, unsigned np)
|
||||
: scope_(s), npins_(np), delay1_(0), delay2_(0), delay3_(0)
|
||||
{
|
||||
name_ = new char[n.length()+1];
|
||||
strcpy(name_, n.c_str());
|
||||
@@ -172,11 +176,11 @@ NetObj::NetObj(const string&n, unsigned np)
|
||||
}
|
||||
}
|
||||
|
||||
NetObj::NetObj(NetScope*s, const string&n, unsigned np)
|
||||
NetObj::NetObj(NetScope*s, const char*n, unsigned np)
|
||||
: scope_(s), npins_(np), delay1_(0), delay2_(0), delay3_(0)
|
||||
{
|
||||
name_ = new char[n.length()+1];
|
||||
strcpy(name_, n.c_str());
|
||||
name_ = new char[strlen(n)+1];
|
||||
strcpy(name_, n);
|
||||
|
||||
pins_ = new Link[npins_];
|
||||
for (unsigned idx = 0 ; idx < npins_ ; idx += 1) {
|
||||
@@ -249,12 +253,12 @@ const Link& NetObj::pin(unsigned idx) const
|
||||
return pins_[idx];
|
||||
}
|
||||
|
||||
NetNode::NetNode(const string&n, unsigned npins)
|
||||
: NetObj(n, npins), node_next_(0), node_prev_(0), design_(0)
|
||||
NetNode::NetNode(NetScope*s, const string&n, unsigned npins)
|
||||
: NetObj(s, n, npins), node_next_(0), node_prev_(0), design_(0)
|
||||
{
|
||||
}
|
||||
|
||||
NetNode::NetNode(NetScope*s, const string&n, unsigned npins)
|
||||
NetNode::NetNode(NetScope*s, const char*n, unsigned npins)
|
||||
: NetObj(s, n, npins), node_next_(0), node_prev_(0), design_(0)
|
||||
{
|
||||
}
|
||||
@@ -303,16 +307,21 @@ NetNet::NetNet(NetScope*s, const string&n, Type t, unsigned npins)
|
||||
assert(s);
|
||||
|
||||
verinum::V init_value = verinum::Vz;
|
||||
Link::DIR dir = Link::PASSIVE;
|
||||
|
||||
switch (t) {
|
||||
case REG:
|
||||
case IMPLICIT_REG:
|
||||
init_value = verinum::Vx;
|
||||
dir = Link::OUTPUT;
|
||||
break;
|
||||
case SUPPLY0:
|
||||
init_value = verinum::V0;
|
||||
dir = Link::OUTPUT;
|
||||
break;
|
||||
case SUPPLY1:
|
||||
init_value = verinum::V1;
|
||||
dir = Link::OUTPUT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -320,6 +329,7 @@ NetNet::NetNet(NetScope*s, const string&n, Type t, unsigned npins)
|
||||
|
||||
for (unsigned idx = 0 ; idx < npins ; idx += 1) {
|
||||
pin(idx).set_name("P", idx);
|
||||
pin(idx).set_dir(dir);
|
||||
pin(idx).set_init(init_value);
|
||||
}
|
||||
|
||||
@@ -335,16 +345,21 @@ NetNet::NetNet(NetScope*s, const string&n, Type t, long ms, long ls)
|
||||
assert(s);
|
||||
|
||||
verinum::V init_value = verinum::Vz;
|
||||
Link::DIR dir = Link::PASSIVE;
|
||||
|
||||
switch (t) {
|
||||
case REG:
|
||||
case IMPLICIT_REG:
|
||||
init_value = verinum::Vx;
|
||||
dir = Link::OUTPUT;
|
||||
break;
|
||||
case SUPPLY0:
|
||||
init_value = verinum::V0;
|
||||
dir = Link::OUTPUT;
|
||||
break;
|
||||
case SUPPLY1:
|
||||
init_value = verinum::V1;
|
||||
dir = Link::OUTPUT;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@@ -352,6 +367,7 @@ NetNet::NetNet(NetScope*s, const string&n, Type t, long ms, long ls)
|
||||
|
||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
|
||||
pin(idx).set_name("P", idx);
|
||||
pin(idx).set_dir(dir);
|
||||
pin(idx).set_init(init_value);
|
||||
}
|
||||
|
||||
@@ -492,7 +508,7 @@ const NetScope* NetProcTop::scope() const
|
||||
* ...
|
||||
*/
|
||||
|
||||
NetFF::NetFF(NetScope*s, const string&n, unsigned wid)
|
||||
NetFF::NetFF(NetScope*s, const char*n, unsigned wid)
|
||||
: NetNode(s, n, 8 + 2*wid)
|
||||
{
|
||||
pin_Clock().set_dir(Link::INPUT);
|
||||
@@ -620,8 +636,8 @@ const Link& NetFF::pin_Q(unsigned w) const
|
||||
* 7 -- DataB[0]
|
||||
* 8 -- Result[0]
|
||||
*/
|
||||
NetAddSub::NetAddSub(const string&n, unsigned w)
|
||||
: NetNode(n, w*3+6)
|
||||
NetAddSub::NetAddSub(NetScope*s, const string&n, unsigned w)
|
||||
: NetNode(s, n, w*3+6)
|
||||
{
|
||||
pin(0).set_dir(Link::INPUT); pin(0).set_name("Add_Sub", 0);
|
||||
pin(1).set_dir(Link::INPUT); pin(1).set_name("Aclr", 0);
|
||||
@@ -709,8 +725,9 @@ const Link& NetAddSub::pin_Result(unsigned idx) const
|
||||
* 3+W -- Result(0)
|
||||
* 3+2W -- Distance(0)
|
||||
*/
|
||||
NetCLShift::NetCLShift(const string&n, unsigned width, unsigned width_dist)
|
||||
: NetNode(n, 3+2*width+width_dist), width_(width), width_dist_(width_dist)
|
||||
NetCLShift::NetCLShift(NetScope*s, const string&n,
|
||||
unsigned width, unsigned width_dist)
|
||||
: NetNode(s, n, 3+2*width+width_dist), width_(width), width_dist_(width_dist)
|
||||
{
|
||||
pin(0).set_dir(Link::INPUT); pin(0).set_name("Direction", 0);
|
||||
pin(1).set_dir(Link::OUTPUT); pin(1).set_name("Underflow", 0);
|
||||
@@ -810,8 +827,8 @@ const Link& NetCLShift::pin_Distance(unsigned idx) const
|
||||
return pin(3+2*width_+idx);
|
||||
}
|
||||
|
||||
NetCompare::NetCompare(const string&n, unsigned wi)
|
||||
: NetNode(n, 8+2*wi), width_(wi)
|
||||
NetCompare::NetCompare(NetScope*s, const string&n, unsigned wi)
|
||||
: NetNode(s, n, 8+2*wi), width_(wi)
|
||||
{
|
||||
pin(0).set_dir(Link::INPUT); pin(0).set_name("Aclr");
|
||||
pin(1).set_dir(Link::INPUT); pin(1).set_name("Clock");
|
||||
@@ -938,9 +955,9 @@ const Link& NetCompare::pin_DataB(unsigned idx) const
|
||||
return pin(8+width_+idx);
|
||||
}
|
||||
|
||||
NetDivide::NetDivide(const string&n, unsigned wr,
|
||||
NetDivide::NetDivide(NetScope*sc, const string&n, unsigned wr,
|
||||
unsigned wa, unsigned wb)
|
||||
: NetNode(n, wr+wa+wb), width_r_(wr), width_a_(wa), width_b_(wb)
|
||||
: NetNode(sc, n, wr+wa+wb), width_r_(wr), width_a_(wa), width_b_(wb)
|
||||
{
|
||||
unsigned p = 0;
|
||||
for (unsigned idx = 0 ; idx < width_r_ ; idx += 1, p += 1) {
|
||||
@@ -1012,10 +1029,10 @@ const Link& NetDivide::pin_DataB(unsigned idx) const
|
||||
return pin(idx+width_r_+width_a_);
|
||||
}
|
||||
|
||||
NetMult::NetMult(const string&n, unsigned wr, unsigned wa, unsigned wb,
|
||||
unsigned ws)
|
||||
: NetNode(n, 2+wr+wa+wb+ws), width_r_(wr), width_a_(wa), width_b_(wb),
|
||||
width_s_(ws)
|
||||
NetMult::NetMult(NetScope*sc, const string&n, unsigned wr,
|
||||
unsigned wa, unsigned wb, unsigned ws)
|
||||
: NetNode(sc, n, 2+wr+wa+wb+ws), width_r_(wr), width_a_(wa), width_b_(wb),
|
||||
width_s_(ws)
|
||||
{
|
||||
pin(0).set_dir(Link::INPUT); pin(0).set_name("Aclr", 0);
|
||||
pin(1).set_dir(Link::INPUT); pin(1).set_name("Clock", 0);
|
||||
@@ -1242,8 +1259,8 @@ const Link& NetMux::pin_Data(unsigned w, unsigned s) const
|
||||
}
|
||||
|
||||
|
||||
NetRamDq::NetRamDq(const string&n, NetMemory*mem, unsigned awid)
|
||||
: NetNode(n, 3+2*mem->width()+awid), mem_(mem), awidth_(awid)
|
||||
NetRamDq::NetRamDq(NetScope*s, const string&n, NetMemory*mem, unsigned awid)
|
||||
: NetNode(s, n, 3+2*mem->width()+awid), mem_(mem), awidth_(awid)
|
||||
{
|
||||
pin(0).set_dir(Link::INPUT); pin(0).set_name("InClock", 0);
|
||||
pin(1).set_dir(Link::INPUT); pin(1).set_name("OutClock", 0);
|
||||
@@ -1554,8 +1571,8 @@ void NetCase::set_case(unsigned idx, NetExpr*e, NetProc*p)
|
||||
items_[idx].guard->set_width(expr_->expr_width());
|
||||
}
|
||||
|
||||
NetCaseCmp::NetCaseCmp(const string&n)
|
||||
: NetNode(n, 3)
|
||||
NetCaseCmp::NetCaseCmp(NetScope*s, const string&n)
|
||||
: NetNode(s, n, 3)
|
||||
{
|
||||
pin(0).set_dir(Link::OUTPUT); pin(0).set_name("O",0);
|
||||
pin(1).set_dir(Link::INPUT); pin(1).set_name("I",0);
|
||||
@@ -1604,8 +1621,8 @@ NetProc* NetCondit::else_clause()
|
||||
return else_;
|
||||
}
|
||||
|
||||
NetConst::NetConst(const string&n, verinum::V v)
|
||||
: NetNode(n, 1)
|
||||
NetConst::NetConst(NetScope*s, const string&n, verinum::V v)
|
||||
: NetNode(s, n, 1)
|
||||
{
|
||||
pin(0).set_dir(Link::OUTPUT);
|
||||
pin(0).set_name("O", 0);
|
||||
@@ -1613,8 +1630,8 @@ NetConst::NetConst(const string&n, verinum::V v)
|
||||
value_[0] = v;
|
||||
}
|
||||
|
||||
NetConst::NetConst(const string&n, const verinum&val)
|
||||
: NetNode(n, val.len())
|
||||
NetConst::NetConst(NetScope*s, const string&n, const verinum&val)
|
||||
: NetNode(s, n, val.len())
|
||||
{
|
||||
value_ = new verinum::V[pin_count()];
|
||||
for (unsigned idx = 0 ; idx < pin_count() ; idx += 1) {
|
||||
@@ -1708,7 +1725,7 @@ const NetExpr* NetSTask::parm(unsigned idx) const
|
||||
return parms_[idx];
|
||||
}
|
||||
|
||||
NetEUFunc::NetEUFunc(NetFuncDef*def, NetESignal*res, svector<NetExpr*>&p)
|
||||
NetEUFunc::NetEUFunc(NetScope*def, NetESignal*res, svector<NetExpr*>&p)
|
||||
: func_(def), result_(res), parms_(p)
|
||||
{
|
||||
expr_width(result_->expr_width());
|
||||
@@ -1741,7 +1758,7 @@ const NetExpr* NetEUFunc::parm(unsigned idx) const
|
||||
return parms_[idx];
|
||||
}
|
||||
|
||||
const NetFuncDef* NetEUFunc::definition() const
|
||||
const NetScope* NetEUFunc::func() const
|
||||
{
|
||||
return func_;
|
||||
}
|
||||
@@ -1752,7 +1769,7 @@ NetEUFunc* NetEUFunc::dup_expr() const
|
||||
return 0;
|
||||
}
|
||||
|
||||
NetUTask::NetUTask(NetTaskDef*def)
|
||||
NetUTask::NetUTask(NetScope*def)
|
||||
: task_(def)
|
||||
{
|
||||
}
|
||||
@@ -1761,6 +1778,16 @@ NetUTask::~NetUTask()
|
||||
{
|
||||
}
|
||||
|
||||
const string NetUTask::name() const
|
||||
{
|
||||
return task_->name();
|
||||
}
|
||||
|
||||
const NetScope* NetUTask::task() const
|
||||
{
|
||||
return task_;
|
||||
}
|
||||
|
||||
NetExpr::NetExpr(unsigned w)
|
||||
: width_(w)
|
||||
{
|
||||
@@ -1780,21 +1807,15 @@ bool NetExpr::has_width() const
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a bitwise operator node from the opcode and the left and
|
||||
* right expressions. Don't worry about the width of the expression
|
||||
* yet, we'll get that from the l-value, whatever that turns out to
|
||||
* be.
|
||||
*/
|
||||
NetEBAdd::NetEBAdd(char op, NetExpr*l, NetExpr*r)
|
||||
: NetEBinary(op, l, r)
|
||||
{
|
||||
if (l->expr_width() > r->expr_width())
|
||||
r->set_width(l->expr_width());
|
||||
|
||||
if (r->expr_width() > l->expr_width())
|
||||
l->set_width(r->expr_width());
|
||||
|
||||
if (l->expr_width() < r->expr_width())
|
||||
r->set_width(l->expr_width());
|
||||
|
||||
if (r->expr_width() < l->expr_width())
|
||||
l->set_width(r->expr_width());
|
||||
|
||||
if (r->expr_width() > l->expr_width())
|
||||
expr_width(r->expr_width());
|
||||
else
|
||||
@@ -1812,32 +1833,20 @@ NetEBAdd* NetEBAdd::dup_expr() const
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a bitwise operator node from the opcode and the left and
|
||||
* right expressions. Don't worry about the width of the expression
|
||||
* yet, we'll get that from the l-value, whatever that turns out to
|
||||
* be. However, if we don't, our default will be the width of the
|
||||
* largest operand.
|
||||
*/
|
||||
NetEBBits::NetEBBits(char op, NetExpr*l, NetExpr*r)
|
||||
: NetEBinary(op, l, r)
|
||||
{
|
||||
/* First try to naturally adjust the size of the
|
||||
expressions to match. */
|
||||
if (l->expr_width() > r->expr_width())
|
||||
r->set_width(l->expr_width());
|
||||
|
||||
if (r->expr_width() > l->expr_width())
|
||||
l->set_width(r->expr_width());
|
||||
|
||||
if (l->expr_width() < r->expr_width())
|
||||
r->set_width(l->expr_width());
|
||||
|
||||
if (r->expr_width() < l->expr_width())
|
||||
l->set_width(r->expr_width());
|
||||
|
||||
/* If the expressions cannot be matched, pad them to fit. */
|
||||
if (l->expr_width() > r->expr_width())
|
||||
right_ = pad_to_width(r, l->expr_width());
|
||||
|
||||
if (r->expr_width() > l->expr_width())
|
||||
left_ = pad_to_width(l, r->expr_width());
|
||||
|
||||
assert(left_->expr_width() == right_->expr_width());
|
||||
expr_width(left_->expr_width());
|
||||
expr_width(r->expr_width());
|
||||
else
|
||||
expr_width(l->expr_width());
|
||||
}
|
||||
|
||||
NetEBBits::~NetEBBits()
|
||||
@@ -1851,9 +1860,42 @@ NetEBBits* NetEBBits::dup_expr() const
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a comparison operator with two sub-expressions.
|
||||
*
|
||||
* Handle the special case of an unsized constant on the left or right
|
||||
* side by resizing the number to match the other
|
||||
* expression. Otherwise, the netlist will have to allow the
|
||||
* expressions to have different widths.
|
||||
*/
|
||||
NetEBComp::NetEBComp(char op, NetExpr*l, NetExpr*r)
|
||||
: NetEBinary(op, l, r)
|
||||
{
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(r)) do {
|
||||
|
||||
if (tmp->has_width())
|
||||
break;
|
||||
|
||||
if (tmp->expr_width() == l->expr_width())
|
||||
break;
|
||||
|
||||
tmp->set_width(l->expr_width());
|
||||
|
||||
} while (0);
|
||||
|
||||
if (NetEConst*tmp = dynamic_cast<NetEConst*>(l)) do {
|
||||
|
||||
if (tmp->has_width())
|
||||
break;
|
||||
|
||||
if (tmp->expr_width() == r->expr_width())
|
||||
break;
|
||||
|
||||
tmp->set_width(r->expr_width());
|
||||
|
||||
} while (0);
|
||||
|
||||
|
||||
expr_width(1);
|
||||
}
|
||||
|
||||
@@ -1900,6 +1942,11 @@ NetEBinary::~NetEBinary()
|
||||
delete right_;
|
||||
}
|
||||
|
||||
bool NetEBinary::has_width() const
|
||||
{
|
||||
return left_->has_width() && right_->has_width();
|
||||
}
|
||||
|
||||
NetEBinary* NetEBinary::dup_expr() const
|
||||
{
|
||||
assert(0);
|
||||
@@ -1949,6 +1996,11 @@ NetEBShift::~NetEBShift()
|
||||
{
|
||||
}
|
||||
|
||||
bool NetEBShift::has_width() const
|
||||
{
|
||||
return left_->has_width();
|
||||
}
|
||||
|
||||
NetEBShift* NetEBShift::dup_expr() const
|
||||
{
|
||||
NetEBShift*result = new NetEBShift(op_, left_->dup_expr(),
|
||||
@@ -1981,8 +2033,9 @@ NetEConcat* NetEConcat::dup_expr() const
|
||||
NetEConcat*dup = new NetEConcat(parms_.count(), repeat_);
|
||||
for (unsigned idx = 0 ; idx < parms_.count() ; idx += 1)
|
||||
if (parms_[idx]) {
|
||||
assert(parms_[idx]->dup_expr());
|
||||
dup->parms_[idx] = parms_[idx]->dup_expr();
|
||||
NetExpr*tmp = parms_[idx]->dup_expr();
|
||||
assert(tmp);
|
||||
dup->parms_[idx] = tmp;
|
||||
}
|
||||
|
||||
|
||||
@@ -2070,7 +2123,7 @@ NetEParam::NetEParam()
|
||||
{
|
||||
}
|
||||
|
||||
NetEParam::NetEParam(Design*d, NetScope*s, const string&n)
|
||||
NetEParam::NetEParam(Design*d, NetScope*s, const hname_t&n)
|
||||
: des_(d), scope_(s), name_(n)
|
||||
{
|
||||
}
|
||||
@@ -2079,6 +2132,11 @@ NetEParam::~NetEParam()
|
||||
{
|
||||
}
|
||||
|
||||
bool NetEParam::has_width() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
NetEParam* NetEParam::dup_expr() const
|
||||
{
|
||||
return new NetEParam(des_, scope_, name_);
|
||||
@@ -2152,6 +2210,18 @@ NetExpr* NetESFunc::parm(unsigned idx)
|
||||
NetESignal::NetESignal(NetNet*n)
|
||||
: NetExpr(n->pin_count()), net_(n)
|
||||
{
|
||||
msi_ = n->pin_count() - 1;
|
||||
lsi_ = 0;
|
||||
net_->incr_eref();
|
||||
set_line(*n);
|
||||
}
|
||||
|
||||
NetESignal::NetESignal(NetNet*n, unsigned m, unsigned l)
|
||||
: NetExpr(m - l + 1), net_(n)
|
||||
{
|
||||
assert(m >= l);
|
||||
msi_ = m;
|
||||
lsi_ = l;
|
||||
net_->incr_eref();
|
||||
set_line(*n);
|
||||
}
|
||||
@@ -2171,22 +2241,33 @@ bool NetESignal::has_sign() const
|
||||
return net_->get_signed();
|
||||
}
|
||||
|
||||
unsigned NetESignal::pin_count() const
|
||||
unsigned NetESignal::bit_count() const
|
||||
{
|
||||
return net_->pin_count();
|
||||
return msi_ - lsi_ + 1;
|
||||
}
|
||||
|
||||
Link& NetESignal::pin(unsigned idx)
|
||||
Link& NetESignal::bit(unsigned idx)
|
||||
{
|
||||
return net_->pin(idx);
|
||||
assert(idx <= (msi_ - lsi_));
|
||||
return net_->pin(idx + lsi_);
|
||||
}
|
||||
|
||||
NetESignal* NetESignal::dup_expr() const
|
||||
const NetNet* NetESignal::sig() const
|
||||
{
|
||||
assert(0);
|
||||
return net_;
|
||||
}
|
||||
|
||||
NetESubSignal::NetESubSignal(NetESignal*sig, NetExpr*ex)
|
||||
unsigned NetESignal::lsi() const
|
||||
{
|
||||
return lsi_;
|
||||
}
|
||||
|
||||
unsigned NetESignal::msi() const
|
||||
{
|
||||
return msi_;
|
||||
}
|
||||
|
||||
NetEBitSel::NetEBitSel(NetESignal*sig, NetExpr*ex)
|
||||
: sig_(sig), idx_(ex)
|
||||
{
|
||||
// This supports mux type indexing of an expression, so the
|
||||
@@ -2194,17 +2275,22 @@ NetESubSignal::NetESubSignal(NetESignal*sig, NetExpr*ex)
|
||||
expr_width(1);
|
||||
}
|
||||
|
||||
NetESubSignal::~NetESubSignal()
|
||||
NetEBitSel::~NetEBitSel()
|
||||
{
|
||||
delete idx_;
|
||||
}
|
||||
|
||||
string NetESubSignal::name() const
|
||||
string NetEBitSel::name() const
|
||||
{
|
||||
return sig_->name();
|
||||
}
|
||||
|
||||
NetESubSignal* NetESubSignal::dup_expr() const
|
||||
const NetNet* NetEBitSel::sig() const
|
||||
{
|
||||
return sig_->sig();
|
||||
}
|
||||
|
||||
NetEBitSel* NetEBitSel::dup_expr() const
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
@@ -2237,14 +2323,14 @@ const NetExpr* NetETernary::false_expr() const
|
||||
return false_val_;
|
||||
}
|
||||
|
||||
NetETernary* NetETernary::dup_expr() const
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
NetEUnary::NetEUnary(char op, NetExpr*ex)
|
||||
: NetExpr(ex->expr_width()), op_(op), expr_(ex)
|
||||
{
|
||||
switch (op_) {
|
||||
case '!':
|
||||
expr_width(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
NetEUnary::~NetEUnary()
|
||||
@@ -2252,11 +2338,6 @@ NetEUnary::~NetEUnary()
|
||||
delete expr_;
|
||||
}
|
||||
|
||||
NetEUnary* NetEUnary::dup_expr() const
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
NetEUBits::NetEUBits(char op, NetExpr*ex)
|
||||
: NetEUnary(op, ex)
|
||||
{
|
||||
@@ -2324,155 +2405,94 @@ const NetProc*NetTaskDef::proc() const
|
||||
return proc_;
|
||||
}
|
||||
|
||||
/*
|
||||
* This method takes the input string, which contains exactly one
|
||||
* edge, and connects it to the correct output state. The output state
|
||||
* will be generated if needed, and the value compared.
|
||||
*/
|
||||
bool NetUDP::set_sequ_(const string&input, char output)
|
||||
{
|
||||
if (output == '-')
|
||||
output = input[0];
|
||||
|
||||
string frm = input;
|
||||
string to = input;
|
||||
to[0] = output;
|
||||
|
||||
unsigned edge = frm.find_first_not_of("01x");
|
||||
assert(frm.find_last_not_of("01x") == edge);
|
||||
|
||||
switch (input[edge]) {
|
||||
case 'r':
|
||||
frm[edge] = '0';
|
||||
to[edge] = '1';
|
||||
break;
|
||||
case 'R':
|
||||
frm[edge] = 'x';
|
||||
to[edge] = '1';
|
||||
break;
|
||||
case 'f':
|
||||
frm[edge] = '1';
|
||||
to[edge] = '0';
|
||||
break;
|
||||
case 'F':
|
||||
frm[edge] = 'x';
|
||||
to[edge] = '0';
|
||||
break;
|
||||
case 'P':
|
||||
frm[edge] = '0';
|
||||
to[edge] = 'x';
|
||||
break;
|
||||
case 'N':
|
||||
frm[edge] = '1';
|
||||
to[edge] = 'x';
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
state_t_*sfrm = find_state_(frm);
|
||||
state_t_*sto = find_state_(to);
|
||||
|
||||
switch (to[edge]) {
|
||||
case '0':
|
||||
// Notice that I might have caught this edge already
|
||||
if (sfrm->pins[edge].zer != sto) {
|
||||
assert(sfrm->pins[edge].zer == 0);
|
||||
sfrm->pins[edge].zer = sto;
|
||||
}
|
||||
break;
|
||||
case '1':
|
||||
// Notice that I might have caught this edge already
|
||||
if (sfrm->pins[edge].one != sto) {
|
||||
assert(sfrm->pins[edge].one == 0);
|
||||
sfrm->pins[edge].one = sto;
|
||||
}
|
||||
break;
|
||||
case 'x':
|
||||
// Notice that I might have caught this edge already
|
||||
if (sfrm->pins[edge].xxx != sto) {
|
||||
assert(sfrm->pins[edge].xxx == 0);
|
||||
sfrm->pins[edge].xxx = sto;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NetUDP::sequ_glob_(string input, char output)
|
||||
{
|
||||
for (unsigned idx = 0 ; idx < input.length() ; idx += 1)
|
||||
switch (input[idx]) {
|
||||
case '0':
|
||||
case '1':
|
||||
case 'x':
|
||||
case 'r':
|
||||
case 'R':
|
||||
case 'f':
|
||||
case 'F':
|
||||
case 'P':
|
||||
case 'N':
|
||||
break;
|
||||
|
||||
case '?': // Iterate over all the levels
|
||||
input[idx] = '0';
|
||||
sequ_glob_(input, output);
|
||||
input[idx] = '1';
|
||||
sequ_glob_(input, output);
|
||||
input[idx] = 'x';
|
||||
sequ_glob_(input, output);
|
||||
return true;
|
||||
|
||||
case 'n': // Iterate over (n) edges
|
||||
input[idx] = 'f';
|
||||
sequ_glob_(input, output);
|
||||
input[idx] = 'F';
|
||||
sequ_glob_(input, output);
|
||||
input[idx] = 'N';
|
||||
sequ_glob_(input, output);
|
||||
return true;
|
||||
|
||||
case 'p': // Iterate over (p) edges
|
||||
input[idx] = 'r';
|
||||
sequ_glob_(input, output);
|
||||
input[idx] = 'R';
|
||||
sequ_glob_(input, output);
|
||||
input[idx] = 'P';
|
||||
sequ_glob_(input, output);
|
||||
return true;
|
||||
|
||||
case '_': // Iterate over (?0) edges
|
||||
input[idx] = 'f';
|
||||
sequ_glob_(input, output);
|
||||
input[idx] = 'F';
|
||||
sequ_glob_(input, output);
|
||||
return true;
|
||||
|
||||
case '*': // Iterate over all the edges
|
||||
input[idx] = 'r';
|
||||
sequ_glob_(input, output);
|
||||
input[idx] = 'R';
|
||||
sequ_glob_(input, output);
|
||||
input[idx] = 'f';
|
||||
sequ_glob_(input, output);
|
||||
input[idx] = 'F';
|
||||
sequ_glob_(input, output);
|
||||
input[idx] = 'P';
|
||||
sequ_glob_(input, output);
|
||||
input[idx] = 'N';
|
||||
sequ_glob_(input, output);
|
||||
return true;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return set_sequ_(input, output);
|
||||
}
|
||||
|
||||
/*
|
||||
* $Log: netlist.cc,v $
|
||||
* Revision 1.178 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.177 2001/11/19 04:26:46 steve
|
||||
* Unary reduction operators are all 1-bit results.
|
||||
*
|
||||
* Revision 1.176 2001/11/19 01:54:14 steve
|
||||
* Port close cropping behavior from mcrgb
|
||||
* Move window array reset to libmc.
|
||||
*
|
||||
* Revision 1.175 2001/11/06 04:32:37 steve
|
||||
* shift expressions can have definite widths.
|
||||
*
|
||||
* Revision 1.174 2001/10/28 01:14:53 steve
|
||||
* NetObj constructor finally requires a scope.
|
||||
*
|
||||
* Revision 1.173 2001/10/16 02:19:27 steve
|
||||
* Support IVL_LPM_DIVIDE for structural divide.
|
||||
*
|
||||
* Revision 1.172 2001/10/07 03:38:08 steve
|
||||
* parameter names do not have defined size.
|
||||
*
|
||||
* Revision 1.171 2001/09/29 01:53:22 steve
|
||||
* Fix the size of unsized constant operants to compare (PR#274)
|
||||
*
|
||||
* Revision 1.170 2001/08/25 23:50:03 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.169 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.168 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.167 2001/07/22 00:17:49 steve
|
||||
* Support the NetESubSignal expressions in vvp.tgt.
|
||||
*
|
||||
* Revision 1.166 2001/07/07 03:01:37 steve
|
||||
* Detect and make available to t-dll the right shift.
|
||||
*
|
||||
* Revision 1.165 2001/07/04 22:59:25 steve
|
||||
* handle left shifter in dll output.
|
||||
*
|
||||
* Revision 1.164 2001/07/01 00:27:34 steve
|
||||
* Make NetFF constructor take const char* for the name.
|
||||
*
|
||||
* Revision 1.163 2001/06/16 23:45:05 steve
|
||||
* Add support for structural multiply in t-dll.
|
||||
* Add code generators and vvp support for both
|
||||
* structural and behavioral multiply.
|
||||
*
|
||||
* Revision 1.162 2001/06/15 04:14:18 steve
|
||||
* Generate vvp code for GT and GE comparisons.
|
||||
*
|
||||
* Revision 1.161 2001/06/07 02:12:43 steve
|
||||
* Support structural addition.
|
||||
*
|
||||
* Revision 1.160 2001/04/22 23:09:46 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.159 2001/04/06 02:28:02 steve
|
||||
* Generate vvp code for functions with ports.
|
||||
*
|
||||
* Revision 1.158 2001/04/02 02:28:12 steve
|
||||
* Generate code for task calls.
|
||||
*
|
||||
* Revision 1.157 2001/02/10 21:20:38 steve
|
||||
* Binary operators with operands of indefinite width
|
||||
* has itself an indefinite width.
|
||||
*
|
||||
* Revision 1.156 2001/02/08 01:10:30 steve
|
||||
* Remove dead code.
|
||||
*
|
||||
* Revision 1.155 2001/02/07 21:47:13 steve
|
||||
* Fix expression widths for rvalues and parameters (PR#131,132)
|
||||
*
|
||||
* Revision 1.154 2001/01/18 03:16:35 steve
|
||||
* NetMux needs a scope. (PR#115)
|
||||
*
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: netlist.h,v 1.195 2001/01/18 03:16:35 steve Exp $"
|
||||
#ident "$Id: netlist.h,v 1.227 2001/12/03 04:47:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -30,7 +30,9 @@
|
||||
*/
|
||||
# include <string>
|
||||
# include <map>
|
||||
# include <list>
|
||||
# include "verinum.h"
|
||||
# include "HName.h"
|
||||
# include "LineInfo.h"
|
||||
# include "svector.h"
|
||||
# include "Attrib.h"
|
||||
@@ -79,8 +81,8 @@ class NetObj {
|
||||
|
||||
public:
|
||||
public:
|
||||
explicit NetObj(const string&n, unsigned npins);
|
||||
explicit NetObj(NetScope*s, const string&n, unsigned npins);
|
||||
explicit NetObj(NetScope*s, const char*n, unsigned npins);
|
||||
virtual ~NetObj();
|
||||
|
||||
NetScope* scope();
|
||||
@@ -281,7 +283,7 @@ class NetNode : public NetObj {
|
||||
|
||||
public:
|
||||
explicit NetNode(NetScope*s, const string&n, unsigned npins);
|
||||
explicit NetNode(const string&n, unsigned npins);
|
||||
explicit NetNode(NetScope*s, const char*n, unsigned npins);
|
||||
|
||||
virtual ~NetNode();
|
||||
|
||||
@@ -394,7 +396,7 @@ class NetNet : public NetObj, public LineInfo {
|
||||
class NetAddSub : public NetNode {
|
||||
|
||||
public:
|
||||
NetAddSub(const string&n, unsigned width);
|
||||
NetAddSub(NetScope*s, const string&n, unsigned width);
|
||||
~NetAddSub();
|
||||
|
||||
// Get the width of the device (that is, the width of the
|
||||
@@ -428,7 +430,8 @@ class NetAddSub : public NetNode {
|
||||
class NetCLShift : public NetNode {
|
||||
|
||||
public:
|
||||
NetCLShift(const string&n, unsigned width, unsigned width_dist);
|
||||
NetCLShift(NetScope*s, const string&n, unsigned width,
|
||||
unsigned width_dist);
|
||||
~NetCLShift();
|
||||
|
||||
unsigned width() const;
|
||||
@@ -459,6 +462,10 @@ class NetCLShift : public NetNode {
|
||||
/*
|
||||
* This class supports the LPM_COMPARE device.
|
||||
*
|
||||
* The width of the device is the width of the inputs. If one of the
|
||||
* inputs is narrower then the other, it is up to the generator to
|
||||
* make sure all the data pins are properly driven.
|
||||
*
|
||||
* NOTE: This is not the same as the device used to support case
|
||||
* compare. Case comparisons handle Vx and Vz values, whereas this
|
||||
* device need not.
|
||||
@@ -466,7 +473,7 @@ class NetCLShift : public NetNode {
|
||||
class NetCompare : public NetNode {
|
||||
|
||||
public:
|
||||
NetCompare(const string&n, unsigned width);
|
||||
NetCompare(NetScope*scope, const string&n, unsigned width);
|
||||
~NetCompare();
|
||||
|
||||
unsigned width() const;
|
||||
@@ -516,7 +523,8 @@ class NetCompare : public NetNode {
|
||||
class NetDivide : public NetNode {
|
||||
|
||||
public:
|
||||
NetDivide(const string&n, unsigned width, unsigned wa, unsigned wb);
|
||||
NetDivide(NetScope*scope, const string&n,
|
||||
unsigned width, unsigned wa, unsigned wb);
|
||||
~NetDivide();
|
||||
|
||||
unsigned width_r() const;
|
||||
@@ -554,7 +562,8 @@ class NetDivide : public NetNode {
|
||||
class NetModulo : public NetNode {
|
||||
|
||||
public:
|
||||
NetModulo(const string&n, unsigned width, unsigned wa, unsigned wb);
|
||||
NetModulo(NetScope*s, const string&n,
|
||||
unsigned width, unsigned wa, unsigned wb);
|
||||
~NetModulo();
|
||||
|
||||
unsigned width_r() const;
|
||||
@@ -586,7 +595,7 @@ class NetModulo : public NetNode {
|
||||
class NetFF : public NetNode {
|
||||
|
||||
public:
|
||||
NetFF(NetScope*s, const string&n, unsigned width);
|
||||
NetFF(NetScope*s, const char*n, unsigned width);
|
||||
~NetFF();
|
||||
|
||||
unsigned width() const;
|
||||
@@ -632,8 +641,8 @@ class NetMemory {
|
||||
// This is the width (in bits) of a single memory position.
|
||||
unsigned width() const { return width_; }
|
||||
|
||||
NetScope*scope();
|
||||
const NetScope*scope() const;
|
||||
// NetScope*scope();
|
||||
const NetScope*scope() const { return scope_; };
|
||||
|
||||
// This is the number of memory positions.
|
||||
unsigned count() const;
|
||||
@@ -674,8 +683,8 @@ class NetMemory {
|
||||
class NetMult : public NetNode {
|
||||
|
||||
public:
|
||||
NetMult(const string&n, unsigned width, unsigned wa, unsigned wb,
|
||||
unsigned width_s =0);
|
||||
NetMult(NetScope*sc, const string&n, unsigned width,
|
||||
unsigned wa, unsigned wb, unsigned width_s =0);
|
||||
~NetMult();
|
||||
|
||||
// Get the width of the device bussed inputs. There are these
|
||||
@@ -767,7 +776,7 @@ class NetMux : public NetNode {
|
||||
class NetRamDq : public NetNode {
|
||||
|
||||
public:
|
||||
NetRamDq(const string&name, NetMemory*mem, unsigned awid);
|
||||
NetRamDq(NetScope*s, const string&name, NetMemory*mem, unsigned awid);
|
||||
~NetRamDq();
|
||||
|
||||
unsigned width() const;
|
||||
@@ -843,9 +852,14 @@ class NetExpr : public LineInfo {
|
||||
// This returns true if the expression has a definite
|
||||
// width. This is generally true, but in some cases the
|
||||
// expression is amorphous and desires a width from its
|
||||
// environment.
|
||||
// environment. For example, 'd5 has indefinite width, but
|
||||
// 5'd5 has a definite width.
|
||||
|
||||
// This method is only really used within concatenation
|
||||
// expressions to check validity.
|
||||
virtual bool has_width() const;
|
||||
|
||||
|
||||
// This method evaluates the expression and returns an
|
||||
// equivilent expression that is reduced as far as compile
|
||||
// time knows how. Essentially, this is designed to fold
|
||||
@@ -945,7 +959,7 @@ class NetBUFZ : public NetNode {
|
||||
class NetCaseCmp : public NetNode {
|
||||
|
||||
public:
|
||||
explicit NetCaseCmp(const string&n);
|
||||
explicit NetCaseCmp(NetScope*s, const string&n);
|
||||
~NetCaseCmp();
|
||||
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
@@ -963,8 +977,8 @@ class NetCaseCmp : public NetNode {
|
||||
class NetConst : public NetNode {
|
||||
|
||||
public:
|
||||
explicit NetConst(const string&n, verinum::V v);
|
||||
explicit NetConst(const string&n, const verinum&val);
|
||||
explicit NetConst(NetScope*s, const string&n, verinum::V v);
|
||||
explicit NetConst(NetScope*s, const string&n, const verinum&val);
|
||||
~NetConst();
|
||||
|
||||
verinum::V value(unsigned idx) const;
|
||||
@@ -986,12 +1000,17 @@ class NetConst : public NetNode {
|
||||
* 0 -- output
|
||||
* 1 -- input data
|
||||
* 2 -- enable
|
||||
*
|
||||
* The pullup and pulldown gates have no inputs at all, and pin0 is
|
||||
* the output 1 or 0, depending on the gate type. It is the strength
|
||||
* of that value that is important.
|
||||
*/
|
||||
class NetLogic : public NetNode {
|
||||
|
||||
public:
|
||||
enum TYPE { AND, BUF, BUFIF0, BUFIF1, NAND, NMOS, NOR, NOT, NOTIF0,
|
||||
NOTIF1, OR, RNMOS, RPMOS, PMOS, XNOR, XOR };
|
||||
enum TYPE { AND, BUF, BUFIF0, BUFIF1, NAND, NMOS, NOR, NOT,
|
||||
NOTIF0, NOTIF1, OR, PULLDOWN, PULLUP, RNMOS, RPMOS,
|
||||
PMOS, XNOR, XOR };
|
||||
|
||||
explicit NetLogic(NetScope*s, const string&n, unsigned pins, TYPE t);
|
||||
|
||||
@@ -1016,12 +1035,6 @@ class NetLogic : public NetNode {
|
||||
* In any case, pin 0 is an output, and all the remaining pins are
|
||||
* inputs.
|
||||
*
|
||||
* The sequential truth table is canonically represented as a finite state
|
||||
* machine with the current state representing the inputs and the
|
||||
* current output, and the next state carrying the new output value to
|
||||
* use. All the outgoing transitions from a state represent a single
|
||||
* edge.
|
||||
*
|
||||
* Set_table takes as input a string with one letter per pin. The
|
||||
* parser translates the written sequences to one of these. The
|
||||
* valid characters are:
|
||||
@@ -1037,8 +1050,8 @@ class NetLogic : public NetNode {
|
||||
* It also takes one of the following glob letters to represent more
|
||||
* then one item.
|
||||
*
|
||||
* p -- 01, 0x or x1
|
||||
* n -- 10, 1x or x0
|
||||
* p -- 01, 0x or x1 // check this with the lexer
|
||||
* n -- 10, 1x or x0 // check this with the lexer
|
||||
* ? -- 0, 1, or x
|
||||
* * -- any edge
|
||||
* + -- 01 or x1
|
||||
@@ -1059,99 +1072,35 @@ class NetLogic : public NetNode {
|
||||
* 1 are listed.
|
||||
*
|
||||
*/
|
||||
class NetUDP_COMB : public NetNode {
|
||||
#include "PUdp.h"
|
||||
|
||||
class NetUDP : public NetNode {
|
||||
|
||||
public:
|
||||
explicit NetUDP_COMB(const string&n, unsigned pins, bool sequ = false);
|
||||
explicit NetUDP(NetScope*s, const string&n, unsigned pins, PUdp*u);
|
||||
|
||||
virtual bool emit_node(struct target_t*) const;
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
|
||||
/* append a new truth table row. */
|
||||
bool set_table(const string&input, char output);
|
||||
|
||||
/* After the primitive is built up, this method is called to
|
||||
clean up redundancies, and possibly optimize the table. */
|
||||
void cleanup_table();
|
||||
|
||||
/* Use these methods to scan the truth table of the
|
||||
device. "first" returns the first item in the table, and
|
||||
"next" returns the next item in the table. The method will
|
||||
return false when the scan is done. */
|
||||
bool first(string&inp, char&out) const;
|
||||
bool next(string&inp, char&out) const;
|
||||
unsigned rows() const { return udp->tinput.count(); }
|
||||
|
||||
bool is_sequential() const { return sequential_; }
|
||||
|
||||
protected:
|
||||
|
||||
// A combinational primitive is more simply represented as a
|
||||
// simple map of input signals to a single output.
|
||||
typedef map<string,char> CM_;
|
||||
CM_ cm_;
|
||||
unsigned nin() const { return pin_count()-1; }
|
||||
bool is_sequential() const { return udp->sequential; }
|
||||
string udp_name() const { return udp->name_; }
|
||||
char get_initial() const;
|
||||
|
||||
private:
|
||||
|
||||
bool sequential_;
|
||||
|
||||
mutable CM_::const_iterator idx_;
|
||||
mutable unsigned table_idx;
|
||||
PUdp *udp;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class NetUDP : public NetUDP_COMB {
|
||||
|
||||
public:
|
||||
explicit NetUDP(const string&n, unsigned pins, bool sequ = true)
|
||||
: NetUDP_COMB(n, pins, sequ), init_('x') {};
|
||||
|
||||
virtual bool emit_node( struct target_t*) const;
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
|
||||
/* return false if the entry conflicts with an existing
|
||||
entry. In any case, the new output overrides. */
|
||||
bool set_table(const string&input, char output);
|
||||
void cleanup_table();
|
||||
|
||||
/* Return the next output from the passed state. Each letter
|
||||
of the input string represents the pin of the same
|
||||
position. */
|
||||
char table_lookup(const string&from, char to, unsigned pin) const;
|
||||
|
||||
void set_initial(char);
|
||||
char get_initial() const { return init_; }
|
||||
|
||||
private:
|
||||
char init_;
|
||||
|
||||
struct state_t_;
|
||||
struct pin_t_ {
|
||||
state_t_*zer;
|
||||
state_t_*one;
|
||||
state_t_*xxx;
|
||||
|
||||
explicit pin_t_() : zer(0), one(0), xxx(0) { }
|
||||
};
|
||||
|
||||
struct state_t_ {
|
||||
char out;
|
||||
pin_t_*pins;
|
||||
|
||||
state_t_(unsigned n) : out(0), pins(new pin_t_[n]) {}
|
||||
~state_t_() { delete[]pins; }
|
||||
};
|
||||
|
||||
typedef map<string,state_t_*> FSM_;
|
||||
FSM_ fsm_;
|
||||
bool set_sequ_(const string&in, char out);
|
||||
bool sequ_glob_(string, char out);
|
||||
|
||||
state_t_*find_state_(const string&);
|
||||
|
||||
void dump_sequ_(ostream&o, unsigned ind) const;
|
||||
void dump_comb_(ostream&o, unsigned ind) const;
|
||||
};
|
||||
|
||||
/* =========
|
||||
* A process is a behavioral-model description. A process is a
|
||||
* statement that may be compound. the various statement types may
|
||||
@@ -1215,10 +1164,10 @@ class NetProc : public LineInfo {
|
||||
* should know that this is not a guarantee.
|
||||
*/
|
||||
|
||||
class NetAssign_ : public NetNode {
|
||||
class NetAssign_ {
|
||||
|
||||
public:
|
||||
NetAssign_(const string&n, unsigned w);
|
||||
NetAssign_(NetNet*sig);
|
||||
~NetAssign_();
|
||||
|
||||
// If this expression exists, then only a single bit is to be
|
||||
@@ -1226,21 +1175,32 @@ class NetAssign_ : public NetNode {
|
||||
// the pin that gets the value.
|
||||
const NetExpr*bmux() const;
|
||||
|
||||
unsigned get_loff() const;
|
||||
|
||||
void set_bmux(NetExpr*);
|
||||
void set_part(unsigned loff, unsigned wid);
|
||||
|
||||
// Get the width of the r-value that this node expects. This
|
||||
// method accounts for the presence of the mux, so it not
|
||||
// nexessarily the same as the pin_count().
|
||||
// necessarily the same as the pin_count().
|
||||
unsigned lwidth() const;
|
||||
|
||||
virtual bool emit_node(struct target_t*) const;
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
// Get the name of the underlying object.
|
||||
const char*name() const;
|
||||
|
||||
NetNet* sig() const;
|
||||
|
||||
// This pointer is for keeping simple lists.
|
||||
NetAssign_* more;
|
||||
|
||||
void dump_lval(ostream&o) const;
|
||||
|
||||
private:
|
||||
NetNet *sig_;
|
||||
NetExpr*bmux_;
|
||||
|
||||
unsigned loff_;
|
||||
unsigned lwid_;
|
||||
};
|
||||
|
||||
class NetAssignBase : public NetProc {
|
||||
@@ -1264,6 +1224,7 @@ class NetAssignBase : public NetProc {
|
||||
// accounts for any grouping of NetAssign_ objects that might happen.
|
||||
unsigned lwidth() const;
|
||||
|
||||
// This dumps all the lval structures.
|
||||
void dump_lval(ostream&) const;
|
||||
|
||||
private:
|
||||
@@ -1289,12 +1250,23 @@ class NetAssignNB : public NetAssignBase {
|
||||
explicit NetAssignNB(NetAssign_*lv, NetExpr*rv);
|
||||
~NetAssignNB();
|
||||
|
||||
void rise_time(unsigned);
|
||||
void fall_time(unsigned);
|
||||
void decay_time(unsigned);
|
||||
|
||||
unsigned rise_time() const;
|
||||
unsigned fall_time() const;
|
||||
unsigned decay_time() const;
|
||||
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual int match_proc(struct proc_match_t*);
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
|
||||
private:
|
||||
|
||||
unsigned rise_time_;
|
||||
unsigned fall_time_;
|
||||
unsigned decay_time_;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -1444,7 +1416,7 @@ class NetCase : public NetProc {
|
||||
class NetCAssign : public NetProc, public NetNode {
|
||||
|
||||
public:
|
||||
explicit NetCAssign(const string&n, NetNet*l);
|
||||
explicit NetCAssign(NetScope*s, const string&n, NetNet*l);
|
||||
~NetCAssign();
|
||||
|
||||
const Link& lval_pin(unsigned) const;
|
||||
@@ -1454,6 +1426,8 @@ class NetCAssign : public NetProc, public NetNode {
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
virtual bool emit_node(struct target_t*) const;
|
||||
|
||||
const NetNet*lval() const;
|
||||
|
||||
private:
|
||||
NetNet*lval_;
|
||||
|
||||
@@ -1554,7 +1528,10 @@ class NetDisable : public NetProc {
|
||||
*
|
||||
* Once an object of this type exists, behavioral code can wait on the
|
||||
* event or trigger the event. Event waits refer to this object, as do
|
||||
* the event trigger statements.
|
||||
* the event trigger statements. The NetEvent class may have a name and
|
||||
* a scope. The name is a simple name (no hierarchy) and the scope is
|
||||
* the NetScope that contains the object. The socpe member is written
|
||||
* by the NetScope object when the NetEvent is stored.
|
||||
*
|
||||
* The NetEvWait class represents a thread wait for an event. When
|
||||
* this statement is executed, it starts waiting on the
|
||||
@@ -1591,6 +1568,7 @@ class NetEvent : public LineInfo {
|
||||
// Get information about probes connected to me.
|
||||
unsigned nprobe() const;
|
||||
NetEvProbe* probe(unsigned);
|
||||
const NetEvProbe* probe(unsigned) const;
|
||||
|
||||
// Return the number of NetEvWait nodes that reference me.
|
||||
unsigned nwait() const;
|
||||
@@ -1688,8 +1666,8 @@ class NetEvProbe : public NetNode {
|
||||
public:
|
||||
enum edge_t { ANYEDGE, POSEDGE, NEGEDGE };
|
||||
|
||||
explicit NetEvProbe(const string&n, NetEvent*tgt,
|
||||
edge_t t, unsigned p);
|
||||
explicit NetEvProbe(NetScope*s, const string&n,
|
||||
NetEvent*tgt, edge_t t, unsigned p);
|
||||
~NetEvProbe();
|
||||
|
||||
edge_t edge() const;
|
||||
@@ -1719,11 +1697,13 @@ class NetEvProbe : public NetNode {
|
||||
class NetForce : public NetProc, public NetNode {
|
||||
|
||||
public:
|
||||
explicit NetForce(const string&n, NetNet*l);
|
||||
explicit NetForce(NetScope*s, const string&n, NetNet*l);
|
||||
~NetForce();
|
||||
|
||||
const Link& lval_pin(unsigned) const;
|
||||
|
||||
const NetNet*lval() const;
|
||||
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump_node(ostream&, unsigned ind) const;
|
||||
@@ -1934,7 +1914,7 @@ class NetTaskDef {
|
||||
class NetEUFunc : public NetExpr {
|
||||
|
||||
public:
|
||||
NetEUFunc(NetFuncDef*, NetESignal*, svector<NetExpr*>&);
|
||||
NetEUFunc(NetScope*, NetESignal*, svector<NetExpr*>&);
|
||||
~NetEUFunc();
|
||||
|
||||
const string name() const;
|
||||
@@ -1943,7 +1923,7 @@ class NetEUFunc : public NetExpr {
|
||||
unsigned parm_count() const;
|
||||
const NetExpr* parm(unsigned idx) const;
|
||||
|
||||
const NetFuncDef* definition() const;
|
||||
const NetScope* func() const;
|
||||
|
||||
virtual bool set_width(unsigned);
|
||||
virtual void dump(ostream&) const;
|
||||
@@ -1952,7 +1932,7 @@ class NetEUFunc : public NetExpr {
|
||||
virtual NetEUFunc*dup_expr() const;
|
||||
|
||||
private:
|
||||
NetFuncDef*func_;
|
||||
NetScope*func_;
|
||||
NetESignal*result_;
|
||||
svector<NetExpr*> parms_;
|
||||
|
||||
@@ -1969,16 +1949,18 @@ class NetEUFunc : public NetExpr {
|
||||
class NetUTask : public NetProc {
|
||||
|
||||
public:
|
||||
NetUTask(NetTaskDef*);
|
||||
NetUTask(NetScope*);
|
||||
~NetUTask();
|
||||
|
||||
const string& name() const { return task_->name(); }
|
||||
const string name() const;
|
||||
|
||||
const NetScope* task() const;
|
||||
|
||||
virtual bool emit_proc(struct target_t*) const;
|
||||
virtual void dump(ostream&, unsigned ind) const;
|
||||
|
||||
private:
|
||||
NetTaskDef*task_;
|
||||
NetScope*task_;
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -2078,6 +2060,11 @@ class NetEBinary : public NetExpr {
|
||||
|
||||
virtual bool set_width(unsigned w);
|
||||
|
||||
// A binary expression node only has a definite
|
||||
// self-determinable width if the operands both have definite
|
||||
// widths.
|
||||
virtual bool has_width() const;
|
||||
|
||||
virtual NetEBinary* dup_expr() const;
|
||||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
@@ -2182,7 +2169,10 @@ class NetEBComp : public NetEBinary {
|
||||
|
||||
private:
|
||||
NetEConst*eval_eqeq_();
|
||||
NetEConst*eval_less_();
|
||||
NetEConst*eval_leeq_();
|
||||
NetEConst*eval_gt_();
|
||||
NetEConst*eval_gteq_();
|
||||
NetEConst*eval_neeq_();
|
||||
NetEConst*eval_eqeqeq_();
|
||||
NetEConst*eval_neeqeq_();
|
||||
@@ -2241,6 +2231,11 @@ class NetEBShift : public NetEBinary {
|
||||
~NetEBShift();
|
||||
|
||||
virtual bool set_width(unsigned w);
|
||||
|
||||
// A shift expression only needs the left expression to have a
|
||||
// definite width to give the expression a definite width.
|
||||
virtual bool has_width() const;
|
||||
|
||||
virtual NetEBShift* dup_expr() const;
|
||||
virtual NetEConst* eval_tree();
|
||||
|
||||
@@ -2294,10 +2289,11 @@ class NetEConcat : public NetExpr {
|
||||
class NetEParam : public NetExpr {
|
||||
public:
|
||||
NetEParam();
|
||||
NetEParam(class Design*des, NetScope*scope, const string&name);
|
||||
NetEParam(class Design*des, NetScope*scope, const hname_t&name);
|
||||
~NetEParam();
|
||||
|
||||
virtual bool set_width(unsigned w);
|
||||
virtual bool has_width() const;
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual NetExpr* eval_tree();
|
||||
virtual NetEParam* dup_expr() const;
|
||||
@@ -2307,7 +2303,7 @@ class NetEParam : public NetExpr {
|
||||
private:
|
||||
Design*des_;
|
||||
NetScope*scope_;
|
||||
string name_;
|
||||
hname_t name_;
|
||||
};
|
||||
|
||||
|
||||
@@ -2453,6 +2449,7 @@ class NetEUReduce : public NetEUnary {
|
||||
NetEUReduce(char op, NetExpr*ex);
|
||||
~NetEUReduce();
|
||||
|
||||
virtual bool set_width(unsigned w);
|
||||
virtual NetNet* synthesize(Design*);
|
||||
virtual NetEConst* eval_tree();
|
||||
|
||||
@@ -2479,6 +2476,8 @@ class NetEMemory : public NetExpr {
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
const NetMemory*memory() const { return mem_; };
|
||||
|
||||
private:
|
||||
NetMemory*mem_;
|
||||
NetExpr* idx_;
|
||||
@@ -2490,12 +2489,16 @@ class NetEMemory : public NetExpr {
|
||||
* structural signal.
|
||||
*
|
||||
* A signal shows up as a node in the netlist so that structural
|
||||
* activity can invoke the expression.
|
||||
* activity can invoke the expression. This node also supports part
|
||||
* select by indexing a range of the NetNet that is associated with
|
||||
* it. The msi() is the mose significant index, and lsi() the least
|
||||
* significant index.
|
||||
*/
|
||||
class NetESignal : public NetExpr {
|
||||
|
||||
public:
|
||||
NetESignal(NetNet*n);
|
||||
NetESignal(NetNet*n, unsigned msi, unsigned lsi);
|
||||
~NetESignal();
|
||||
|
||||
// a NetESignal expression is signed if the NetNet that it
|
||||
@@ -2510,36 +2513,44 @@ class NetESignal : public NetExpr {
|
||||
|
||||
// These methods actually reference the properties of the
|
||||
// NetNet object that I point to.
|
||||
unsigned pin_count() const;
|
||||
Link& pin(unsigned idx);
|
||||
unsigned bit_count() const;
|
||||
Link& bit(unsigned idx);
|
||||
|
||||
const NetNet* sig() const;
|
||||
unsigned msi() const;
|
||||
unsigned lsi() const;
|
||||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual void dump(ostream&) const;
|
||||
|
||||
private:
|
||||
NetNet*net_;
|
||||
unsigned msi_;
|
||||
unsigned lsi_;
|
||||
};
|
||||
|
||||
/*
|
||||
* An expression that takes a portion of a signal is represented as
|
||||
* An expression that takes a bit of a signal is represented as
|
||||
* one of these. For example, ``foo[x+5]'' is a signal and x+5 is an
|
||||
* expression to select a single bit from that signal. I can't just
|
||||
* make a new NetESignal node connected to the single net because the
|
||||
* expression may vary during execution, so the structure is not known
|
||||
* at compile (elaboration) time.
|
||||
*/
|
||||
class NetESubSignal : public NetExpr {
|
||||
class NetEBitSel : public NetExpr {
|
||||
|
||||
public:
|
||||
NetESubSignal(NetESignal*sig, NetExpr*ex);
|
||||
~NetESubSignal();
|
||||
NetEBitSel(NetESignal*sig, NetExpr*ex);
|
||||
~NetEBitSel();
|
||||
|
||||
string name() const;
|
||||
const NetExpr*index() const { return idx_; }
|
||||
|
||||
virtual bool set_width(unsigned);
|
||||
|
||||
NetESubSignal* dup_expr() const;
|
||||
const NetNet* sig() const;
|
||||
|
||||
NetEBitSel* dup_expr() const;
|
||||
|
||||
virtual void expr_scan(struct expr_scan_t*) const;
|
||||
virtual void dump(ostream&) const;
|
||||
@@ -2560,7 +2571,7 @@ class NetScope {
|
||||
|
||||
public:
|
||||
enum TYPE { MODULE, TASK, FUNC, BEGIN_END, FORK_JOIN };
|
||||
NetScope(NetScope*up, const string&name, TYPE t);
|
||||
NetScope(NetScope*up, const char*name, TYPE t);
|
||||
~NetScope();
|
||||
|
||||
/* Parameters exist within a scope, and these methods allow
|
||||
@@ -2578,7 +2589,7 @@ class NetScope {
|
||||
|
||||
void add_event(NetEvent*);
|
||||
void rem_event(NetEvent*);
|
||||
NetEvent*find_event(const string&name);
|
||||
NetEvent*find_event(const hname_t&name);
|
||||
|
||||
|
||||
/* These methods manage signals. The add_ and rem_signal
|
||||
@@ -2590,6 +2601,7 @@ class NetScope {
|
||||
void rem_signal(NetNet*);
|
||||
|
||||
NetNet* find_signal(const string&name);
|
||||
NetNet* find_signal_in_child(const hname_t&name);
|
||||
|
||||
|
||||
/* ... and these methods manage memory the same way as signals
|
||||
@@ -2647,6 +2659,9 @@ class NetScope {
|
||||
/* This method generates a non-hierarchical name that is
|
||||
guaranteed to be unique within this scope. */
|
||||
string local_symbol();
|
||||
/* This method generates a hierarchical name that is
|
||||
guaranteed to be unique globally. */
|
||||
string local_hsymbol();
|
||||
|
||||
void dump(ostream&) const;
|
||||
void emit_scope(struct target_t*tgt) const;
|
||||
@@ -2661,7 +2676,7 @@ class NetScope {
|
||||
assignments from the scope pass to the parameter evaluation
|
||||
step. After that, it is not used. */
|
||||
|
||||
map<string,NetExpr*>defparams;
|
||||
map<hname_t,NetExpr*>defparams;
|
||||
|
||||
private:
|
||||
TYPE type_;
|
||||
@@ -2711,11 +2726,11 @@ class Design {
|
||||
|
||||
string get_flag(const string&key) const;
|
||||
|
||||
NetScope* make_root_scope(const string&name);
|
||||
NetScope* make_root_scope(const char*name);
|
||||
NetScope* find_root_scope();
|
||||
list<NetScope*> find_root_scopes();
|
||||
|
||||
const NetScope* find_root_scope() const;
|
||||
|
||||
const list<NetScope*> find_root_scopes() const;
|
||||
|
||||
/* Attempt to set the precision to the specified value. If the
|
||||
precision is already more precise, the keep the precise
|
||||
@@ -2730,18 +2745,18 @@ class Design {
|
||||
unsigned long scale_to_precision(unsigned long, const NetScope*)const;
|
||||
|
||||
/* look up a scope. If no starting scope is passed, then the
|
||||
path name string is taken as an absolute scope
|
||||
name. Otherwise, the scope is located starting at the
|
||||
passed scope and working up if needed. */
|
||||
NetScope* find_scope(const string&path) const;
|
||||
NetScope* find_scope(NetScope*, const string&path) const;
|
||||
path is taken as an absolute scope name. Otherwise, the
|
||||
scope is located starting at the passed scope and working
|
||||
up if needed. */
|
||||
NetScope* find_scope(const hname_t&path) const;
|
||||
NetScope* find_scope(NetScope*, const hname_t&path) const;
|
||||
|
||||
// PARAMETERS
|
||||
|
||||
/* This method searches for a parameter, starting in the given
|
||||
scope. This method handles the upward searches that the
|
||||
NetScope class itself does not support. */
|
||||
const NetExpr*find_parameter(const NetScope*, const string&name) const;
|
||||
const NetExpr*find_parameter(const NetScope*, const hname_t&path) const;
|
||||
|
||||
void run_defparams();
|
||||
void evaluate_parameters();
|
||||
@@ -2751,10 +2766,10 @@ class Design {
|
||||
this method, unlike the NetScope::find_signal method,
|
||||
handles global name binding. */
|
||||
|
||||
NetNet*find_signal(NetScope*scope, const string&name);
|
||||
NetNet*find_signal(NetScope*scope, hname_t path);
|
||||
|
||||
// Memories
|
||||
NetMemory* find_memory(NetScope*scope, const string&name);
|
||||
NetMemory* find_memory(NetScope*scope, hname_t path);
|
||||
|
||||
/* This is a more general lookup that finds the named signal
|
||||
or memory, whichever is first in the search path. */
|
||||
@@ -2762,12 +2777,12 @@ class Design {
|
||||
NetNet*&sig, NetMemory*&mem);
|
||||
|
||||
// Functions
|
||||
NetFuncDef* find_function(NetScope*scope, const string&key);
|
||||
NetFuncDef* find_function(const string&path);
|
||||
NetFuncDef* find_function(NetScope*scope, const hname_t&key);
|
||||
NetFuncDef* find_function(const hname_t&path);
|
||||
|
||||
// Tasks
|
||||
NetTaskDef* find_task(NetScope*scope, const string&name);
|
||||
NetTaskDef* find_task(const string&key);
|
||||
NetScope* find_task(NetScope*scope, const hname_t&name);
|
||||
NetScope* find_task(const hname_t&key);
|
||||
|
||||
// NODES
|
||||
void add_node(NetNode*);
|
||||
@@ -2792,7 +2807,7 @@ class Design {
|
||||
private:
|
||||
// Keep a tree of scopes. The NetScope class handles the wide
|
||||
// tree and per-hop searches for me.
|
||||
NetScope*root_scope_;
|
||||
list<NetScope*>root_scopes_;
|
||||
|
||||
// List the nodes in the design
|
||||
NetNode*nodes_;
|
||||
@@ -2852,6 +2867,116 @@ extern ostream& operator << (ostream&, NetNet::Type);
|
||||
|
||||
/*
|
||||
* $Log: netlist.h,v $
|
||||
* Revision 1.227 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.226 2001/11/29 01:58:18 steve
|
||||
* Handle part selects in l-values of DFF devices.
|
||||
*
|
||||
* Revision 1.225 2001/11/19 04:26:46 steve
|
||||
* Unary reduction operators are all 1-bit results.
|
||||
*
|
||||
* Revision 1.224 2001/11/14 03:28:49 steve
|
||||
* DLL target support for force and release.
|
||||
*
|
||||
* Revision 1.223 2001/11/09 03:43:26 steve
|
||||
* Spelling errors.
|
||||
*
|
||||
* Revision 1.222 2001/11/08 05:15:51 steve
|
||||
* Remove string paths from PExpr elaboration.
|
||||
*
|
||||
* Revision 1.221 2001/11/06 04:32:37 steve
|
||||
* shift expressions can have definite widths.
|
||||
*
|
||||
* Revision 1.220 2001/10/31 05:24:52 steve
|
||||
* ivl_target support for assign/deassign.
|
||||
*
|
||||
* Revision 1.219 2001/10/28 01:14:53 steve
|
||||
* NetObj constructor finally requires a scope.
|
||||
*
|
||||
* Revision 1.218 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
*
|
||||
* Revision 1.217 2001/10/19 21:53:24 steve
|
||||
* Support multiple root modules (Philip Blundell)
|
||||
*
|
||||
* Revision 1.216 2001/10/16 02:19:27 steve
|
||||
* Support IVL_LPM_DIVIDE for structural divide.
|
||||
*
|
||||
* Revision 1.215 2001/10/07 03:38:08 steve
|
||||
* parameter names do not have defined size.
|
||||
*
|
||||
* Revision 1.214 2001/08/25 23:50:03 steve
|
||||
* Change the NetAssign_ class to refer to the signal
|
||||
* instead of link into the netlist. This is faster
|
||||
* and uses less space. Make the NetAssignNB carry
|
||||
* the delays instead of the NetAssign_ lval objects.
|
||||
*
|
||||
* Change the vvp code generator to support multiple
|
||||
* l-values, i.e. concatenations of part selects.
|
||||
*
|
||||
* Revision 1.213 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.212 2001/07/22 00:17:49 steve
|
||||
* Support the NetESubSignal expressions in vvp.tgt.
|
||||
*
|
||||
* Revision 1.211 2001/07/04 22:59:25 steve
|
||||
* handle left shifter in dll output.
|
||||
*
|
||||
* Revision 1.210 2001/07/01 00:27:34 steve
|
||||
* Make NetFF constructor take const char* for the name.
|
||||
*
|
||||
* Revision 1.209 2001/06/16 23:45:05 steve
|
||||
* Add support for structural multiply in t-dll.
|
||||
* Add code generators and vvp support for both
|
||||
* structural and behavioral multiply.
|
||||
*
|
||||
* Revision 1.208 2001/06/15 04:14:18 steve
|
||||
* Generate vvp code for GT and GE comparisons.
|
||||
*
|
||||
* Revision 1.207 2001/06/07 02:12:43 steve
|
||||
* Support structural addition.
|
||||
*
|
||||
* Revision 1.206 2001/05/08 23:59:33 steve
|
||||
* Add ivl and vvp.tgt support for memories in
|
||||
* expressions and l-values. (Stephan Boettcher)
|
||||
*
|
||||
* Revision 1.205 2001/04/29 20:19:10 steve
|
||||
* Add pullup and pulldown devices.
|
||||
*
|
||||
* Revision 1.204 2001/04/24 02:23:58 steve
|
||||
* Support for UDP devices in VVP (Stephen Boettcher)
|
||||
*
|
||||
* Revision 1.203 2001/04/22 23:09:46 steve
|
||||
* More UDP consolidation from Stephan Boettcher.
|
||||
*
|
||||
* Revision 1.202 2001/04/06 02:28:02 steve
|
||||
* Generate vvp code for functions with ports.
|
||||
*
|
||||
* Revision 1.201 2001/04/02 02:28:12 steve
|
||||
* Generate code for task calls.
|
||||
*
|
||||
* Revision 1.200 2001/03/29 02:52:01 steve
|
||||
* Add const probe method to NetEvent.
|
||||
*
|
||||
* Revision 1.199 2001/02/15 06:59:36 steve
|
||||
* FreeBSD port has a maintainer now.
|
||||
*
|
||||
* Revision 1.198 2001/02/10 21:20:38 steve
|
||||
* Binary operators with operands of indefinite width
|
||||
* has itself an indefinite width.
|
||||
*
|
||||
* Revision 1.197 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.196 2001/02/09 05:44:23 steve
|
||||
* support evaluation of constant < in expressions.
|
||||
*
|
||||
* Revision 1.195 2001/01/18 03:16:35 steve
|
||||
* NetMux needs a scope. (PR#115)
|
||||
*
|
||||
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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: netmisc.cc,v 1.2 2001/07/25 03:10:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
# include "PExpr.h"
|
||||
|
||||
|
||||
NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe)
|
||||
{
|
||||
NetExpr*tmp = pe->elaborate_expr(des, scope);
|
||||
if (tmp == 0)
|
||||
return 0;
|
||||
|
||||
if (NetExpr*tmp2 = tmp->eval_tree()) {
|
||||
delete tmp;
|
||||
tmp = tmp2;
|
||||
}
|
||||
|
||||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: netmisc.cc,v $
|
||||
* 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/02/11 02:15:52 steve
|
||||
* Add the netmisc.cc source file.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: netmisc.h,v 1.10 2000/11/20 00:58:40 steve Exp $"
|
||||
#ident "$Id: netmisc.h,v 1.12 2001/02/15 06:59:36 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
@@ -31,7 +31,7 @@
|
||||
* enough.
|
||||
*/
|
||||
extern NetExpr*pad_to_width(NetExpr*expr, unsigned wid);
|
||||
extern NetNet*pad_to_width(Design*des, const string&p, NetNet*n, unsigned w);
|
||||
extern NetNet*pad_to_width(Design*des, NetNet*n, unsigned w);
|
||||
|
||||
/*
|
||||
* This local function returns true if all the the possible drivers of
|
||||
@@ -54,9 +54,23 @@ extern verinum::V driven_value(const Link&lnk);
|
||||
*/
|
||||
extern unsigned count_lval_width(const class NetAssign_*first);
|
||||
|
||||
/*
|
||||
* This function elaborates an expression, and tries to evaluate it
|
||||
* right away. It is useful for those places where the user is
|
||||
* supposed to supply a constant expression.
|
||||
*/
|
||||
class PExpr;
|
||||
extern NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe);
|
||||
|
||||
/*
|
||||
* $Log: netmisc.h,v $
|
||||
* Revision 1.12 2001/02/15 06:59:36 steve
|
||||
* FreeBSD port has a maintainer now.
|
||||
*
|
||||
* 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 2000/11/20 00:58:40 steve
|
||||
* Add support for supply nets (PR#17)
|
||||
*
|
||||
@@ -69,32 +83,5 @@ extern unsigned count_lval_width(const class NetAssign_*first);
|
||||
*
|
||||
* Revision 1.7 2000/05/14 17:55:04 steve
|
||||
* Support initialization of FF Q value.
|
||||
*
|
||||
* Revision 1.6 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.5 2000/04/20 00:28:03 steve
|
||||
* Catch some simple identity compareoptimizations.
|
||||
*
|
||||
* Revision 1.4 2000/03/16 19:03:03 steve
|
||||
* Revise the VVM backend to use nexus objects so that
|
||||
* drivers and resolution functions can be used, and
|
||||
* the t-vvm module doesn't need to write a zillion
|
||||
* output functions.
|
||||
*
|
||||
* Revision 1.3 2000/02/23 02:56:55 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.2 2000/02/16 03:58:27 steve
|
||||
* Fix up width matching in structural bitwise operators.
|
||||
*
|
||||
* Revision 1.1 1999/09/29 00:42:51 steve
|
||||
* Allow expanding of additive operators.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
|
||||
+23
-1
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: nodangle.cc,v 1.10 2000/11/19 20:48:53 steve Exp $"
|
||||
#ident "$Id: nodangle.cc,v 1.13 2001/07/27 02:41:55 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
/*
|
||||
* This functor scans the design looking for dangling objects and
|
||||
* excess local signals. These deletions are not necessarily required
|
||||
@@ -58,6 +60,16 @@ void nodangle_f::signal(Design*des, NetNet*sig)
|
||||
if (sig->get_eref() > 0)
|
||||
return;
|
||||
|
||||
/* Cannot delete the ports of tasks or functions. There are
|
||||
too many places where they are referenced. */
|
||||
if ((sig->port_type() != NetNet::NOT_A_PORT)
|
||||
&& (sig->scope()->type() == NetScope::TASK))
|
||||
return;
|
||||
|
||||
if ((sig->port_type() != NetNet::NOT_A_PORT)
|
||||
&& (sig->scope()->type() == NetScope::FUNC))
|
||||
return;
|
||||
|
||||
/* Check to see if the signal is completely unconnected. If
|
||||
all the bits are unlinked, then delete it. */
|
||||
unsigned unlinked = 0;
|
||||
@@ -118,6 +130,16 @@ void nodangle(Design*des)
|
||||
|
||||
/*
|
||||
* $Log: nodangle.cc,v $
|
||||
* Revision 1.13 2001/07/27 02:41:55 steve
|
||||
* Fix binding of dangling function ports. do not elide them.
|
||||
*
|
||||
* Revision 1.12 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.11 2001/02/17 05:14:35 steve
|
||||
* Cannot elide task ports.
|
||||
*
|
||||
* Revision 1.10 2000/11/19 20:48:53 steve
|
||||
* Killing some signals might make others killable.
|
||||
*
|
||||
|
||||
+23
-5
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: pad_to_width.cc,v 1.5 2000/05/02 00:58:12 steve Exp $"
|
||||
#ident "$Id: pad_to_width.cc,v 1.9 2001/10/28 01:14:53 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "netlist.h"
|
||||
# include "netmisc.h"
|
||||
|
||||
@@ -45,19 +47,22 @@ NetExpr*pad_to_width(NetExpr*expr, unsigned wid)
|
||||
return expr;
|
||||
}
|
||||
|
||||
NetNet*pad_to_width(Design*des, const string&path, NetNet*net, unsigned wid)
|
||||
NetNet*pad_to_width(Design*des, NetNet*net, unsigned wid)
|
||||
{
|
||||
NetScope*scope = des->find_scope(path);
|
||||
NetScope*scope = net->scope();
|
||||
const string path = scope->name();
|
||||
assert(scope);
|
||||
|
||||
if (net->pin_count() >= wid)
|
||||
return net;
|
||||
|
||||
verinum pad(verinum::V0, wid - net->pin_count());
|
||||
NetConst*con = new NetConst(des->local_symbol(path), pad);
|
||||
NetConst*con = new NetConst(scope,
|
||||
path + "." + scope->local_symbol(),
|
||||
pad);
|
||||
des->add_node(con);
|
||||
|
||||
NetNet*tmp = new NetNet(scope, des->local_symbol(path),
|
||||
NetNet*tmp = new NetNet(scope, path + "." + scope->local_symbol(),
|
||||
NetNet::WIRE, wid);
|
||||
tmp->local_flag(true);
|
||||
|
||||
@@ -71,6 +76,19 @@ NetNet*pad_to_width(Design*des, const string&path, NetNet*net, unsigned wid)
|
||||
|
||||
/*
|
||||
* $Log: pad_to_width.cc,v $
|
||||
* Revision 1.9 2001/10/28 01:14:53 steve
|
||||
* NetObj constructor finally requires a scope.
|
||||
*
|
||||
* Revision 1.8 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.7 2001/02/16 03:25:09 steve
|
||||
* Missing . in names generated from scope locals.
|
||||
*
|
||||
* Revision 1.6 2001/02/15 06:59:36 steve
|
||||
* FreeBSD port has a maintainer now.
|
||||
*
|
||||
* Revision 1.5 2000/05/02 00:58:12 steve
|
||||
* Move signal tables to the NetScope class.
|
||||
*
|
||||
|
||||
@@ -19,9 +19,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: parse.y,v 1.118 2001/01/14 23:04:56 steve Exp $"
|
||||
#ident "$Id: parse.y,v 1.140 2001/12/07 05:03:13 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "parse_misc.h"
|
||||
# include "pform.h"
|
||||
|
||||
@@ -43,6 +45,8 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
|
||||
char*text;
|
||||
list<char*>*texts;
|
||||
|
||||
hname_t*hier;
|
||||
|
||||
list<string>*strings;
|
||||
|
||||
struct str_pair_t drive;
|
||||
@@ -76,15 +80,22 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
|
||||
Statement*statement;
|
||||
svector<Statement*>*statement_list;
|
||||
|
||||
struct { svector<PExpr*>*range; NetNet::Type ntype; } range_type;
|
||||
|
||||
struct { svector<PExpr*>*range; svector<PExpr*>*delay; } range_delay;
|
||||
net_decl_assign_t*net_decl_assign;
|
||||
|
||||
verinum* number;
|
||||
|
||||
verireal* realtime;
|
||||
};
|
||||
|
||||
%token <text> HIDENTIFIER IDENTIFIER PORTNAME SYSTEM_IDENTIFIER STRING
|
||||
%token <text> IDENTIFIER SYSTEM_IDENTIFIER STRING
|
||||
%token <text> PATHPULSE_IDENTIFIER
|
||||
%token <number> NUMBER
|
||||
%token <realtime> REALTIME
|
||||
%token K_LE K_GE K_EG K_EQ K_NE K_CEQ K_CNE K_LS K_RS K_SG
|
||||
%token K_PO_POS K_PO_NEG
|
||||
%token K_LOR K_LAND K_NAND K_NOR K_NXOR K_TRIGGER
|
||||
%token K_always K_and K_assign K_begin K_buf K_bufif0 K_bufif1 K_case
|
||||
%token K_casex K_casez K_cmos K_deassign K_default K_defparam K_disable
|
||||
@@ -104,6 +115,7 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
|
||||
%token K_trior K_trireg K_vectored K_wait K_wand K_weak0 K_weak1
|
||||
%token K_while K_wire
|
||||
%token K_wor K_xnor K_xor
|
||||
%token K_Shold K_Speriod K_Srecovery K_Ssetup K_Swidth K_Ssetuphold
|
||||
|
||||
%token KK_attribute
|
||||
|
||||
@@ -115,11 +127,11 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
|
||||
%type <wires> udp_port_decl udp_port_decls
|
||||
%type <statement> udp_initial udp_init_opt
|
||||
|
||||
%type <text> identifier register_variable
|
||||
%type <hier> identifier
|
||||
%type <text> register_variable
|
||||
%type <texts> register_variable_list list_of_variables
|
||||
|
||||
%type <text> net_decl_assign
|
||||
%type <texts> net_decl_assigns
|
||||
%type <net_decl_assign> net_decl_assign net_decl_assigns
|
||||
|
||||
%type <mport> port port_opt port_reference port_reference_list
|
||||
%type <mports> list_of_ports list_of_ports_opt
|
||||
@@ -149,13 +161,16 @@ static struct str_pair_t decl_strength = { PGate::STRONG, PGate::STRONG };
|
||||
%type <porttype> port_type
|
||||
%type <parmvalue> parameter_value_opt
|
||||
|
||||
%type <exprs> range_or_type_opt
|
||||
%type <range_type> range_or_type_opt
|
||||
%type <event_expr> event_expression_list
|
||||
%type <event_expr> event_expression
|
||||
%type <event_statement> event_control
|
||||
%type <statement> statement statement_opt
|
||||
%type <statement_list> statement_list
|
||||
|
||||
%type <range_delay> range_delay
|
||||
|
||||
%token K_TAND
|
||||
%right '?' ':'
|
||||
%left K_LOR
|
||||
%left K_LAND
|
||||
@@ -319,7 +334,7 @@ defparam_assign
|
||||
delete tmp;
|
||||
tmp = 0;
|
||||
}
|
||||
pform_set_defparam($1, $3);
|
||||
pform_set_defparam(*$1, $3);
|
||||
delete $1;
|
||||
}
|
||||
;
|
||||
@@ -412,7 +427,7 @@ delay_value_simple
|
||||
}
|
||||
}
|
||||
| IDENTIFIER
|
||||
{ PEIdent*tmp = new PEIdent($1);
|
||||
{ PEIdent*tmp = new PEIdent(hname_t($1));
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
$$ = tmp;
|
||||
@@ -479,7 +494,7 @@ dr_strength1
|
||||
|
||||
event_control
|
||||
: '@' IDENTIFIER
|
||||
{ PEIdent*tmpi = new PEIdent($2);
|
||||
{ PEIdent*tmpi = new PEIdent(hname_t($2));
|
||||
tmpi->set_file(@2.text);
|
||||
tmpi->set_lineno(@2.first_line);
|
||||
delete[]$2;
|
||||
@@ -806,21 +821,21 @@ expr_primary
|
||||
delete $1;
|
||||
}
|
||||
| identifier
|
||||
{ PEIdent*tmp = new PEIdent($1);
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
$$ = tmp;
|
||||
delete $1;
|
||||
}
|
||||
| SYSTEM_IDENTIFIER
|
||||
{ PECallFunction*tmp = new PECallFunction($1);
|
||||
{ PECallFunction*tmp = new PECallFunction(hname_t($1));
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
$$ = tmp;
|
||||
delete $1
|
||||
}
|
||||
| identifier '[' expression ']'
|
||||
{ PEIdent*tmp = new PEIdent($1);
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
tmp->msb_ = $3;
|
||||
@@ -828,7 +843,7 @@ expr_primary
|
||||
$$ = tmp;
|
||||
}
|
||||
| identifier '[' expression ':' expression ']'
|
||||
{ PEIdent*tmp = new PEIdent($1);
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
tmp->msb_ = $3;
|
||||
@@ -837,13 +852,14 @@ expr_primary
|
||||
$$ = tmp;
|
||||
}
|
||||
| identifier '(' expression_list ')'
|
||||
{ PECallFunction*tmp = new PECallFunction($1, *$3);
|
||||
{ PECallFunction*tmp = new PECallFunction(*$1, *$3);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
delete $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| SYSTEM_IDENTIFIER '(' expression_list ')'
|
||||
{ PECallFunction*tmp = new PECallFunction($1, *$3);
|
||||
{ PECallFunction*tmp = new PECallFunction(hname_t($1), *$3);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
$$ = tmp;
|
||||
@@ -1002,13 +1018,21 @@ gatetype
|
||||
| K_rtranif1 { $$ = PGBuiltin::RTRANIF1; }
|
||||
;
|
||||
|
||||
|
||||
/* A general identifier is a hierarchical name, with the right most
|
||||
name the base of the identifier. This rule builds up a
|
||||
hierarchical name from left to right. */
|
||||
identifier
|
||||
: IDENTIFIER
|
||||
{ $$ = $1; }
|
||||
| HIDENTIFIER
|
||||
{ $$ = $1;
|
||||
{ $$ = new hname_t($1);
|
||||
delete $1;
|
||||
}
|
||||
| identifier '.' IDENTIFIER
|
||||
{ hname_t * tmp = $1;
|
||||
tmp->append($3);
|
||||
delete $3;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
list_of_ports
|
||||
: port_opt
|
||||
@@ -1048,14 +1072,14 @@ list_of_variables
|
||||
expression meets the constraints of continuous assignments. */
|
||||
lavalue
|
||||
: identifier
|
||||
{ PEIdent*tmp = new PEIdent($1);
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
delete $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| identifier '[' expression ']'
|
||||
{ PEIdent*tmp = new PEIdent($1);
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
PExpr*sel = $3;
|
||||
if (! pform_expression_is_constant(sel)) {
|
||||
yyerror(@2, "error: Bit select in lvalue must "
|
||||
@@ -1070,7 +1094,7 @@ lavalue
|
||||
$$ = tmp;
|
||||
}
|
||||
| identifier range
|
||||
{ PEIdent*tmp = new PEIdent($1);
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
assert($2->count() == 2);
|
||||
tmp->msb_ = (*$2)[0];
|
||||
tmp->lsb_ = (*$2)[1];
|
||||
@@ -1093,14 +1117,14 @@ lavalue
|
||||
procedural assignment. This rule handles only procedural assignments. */
|
||||
lpvalue
|
||||
: identifier
|
||||
{ PEIdent*tmp = new PEIdent($1);
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
delete $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| identifier '[' expression ']'
|
||||
{ PEIdent*tmp = new PEIdent($1);
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
tmp->msb_ = $3;
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
@@ -1109,7 +1133,7 @@ lpvalue
|
||||
$$ = tmp;
|
||||
}
|
||||
| identifier '[' expression ':' expression ']'
|
||||
{ PEIdent*tmp = new PEIdent($1);
|
||||
{ PEIdent*tmp = new PEIdent(*$1);
|
||||
tmp->msb_ = $3;
|
||||
tmp->lsb_ = $5;
|
||||
tmp->set_file(@1.text);
|
||||
@@ -1147,16 +1171,16 @@ assign_list
|
||||
;
|
||||
|
||||
module
|
||||
: K_module IDENTIFIER list_of_ports_opt ';'
|
||||
{ pform_startmodule($2, $3);
|
||||
: module_start IDENTIFIER list_of_ports_opt ';'
|
||||
{ pform_startmodule($2, $3, @1.text, @1.first_line);
|
||||
}
|
||||
module_item_list
|
||||
K_endmodule
|
||||
{ pform_endmodule($2);
|
||||
delete $2;
|
||||
}
|
||||
| K_module IDENTIFIER list_of_ports_opt ';'
|
||||
{ pform_startmodule($2, $3);
|
||||
| module_start IDENTIFIER list_of_ports_opt ';'
|
||||
{ pform_startmodule($2, $3, @1.text, @1.first_line);
|
||||
}
|
||||
K_endmodule
|
||||
{ pform_endmodule($2);
|
||||
@@ -1164,15 +1188,26 @@ module
|
||||
}
|
||||
;
|
||||
|
||||
module_start : K_module | K_macromodule ;
|
||||
|
||||
range_delay : range_opt delay3_opt
|
||||
{ $$.range = $1; $$.delay = $2; }
|
||||
;
|
||||
|
||||
|
||||
module_item
|
||||
: net_type range_opt list_of_variables ';'
|
||||
{ pform_makewire(@1, $2, $3, $1);
|
||||
: net_type range_delay list_of_variables ';'
|
||||
{ pform_makewire(@1, $2.range, $3, $1);
|
||||
if ($2.delay != 0) {
|
||||
yyerror(@2, "sorry: net delays not supported.");
|
||||
delete $2.delay;
|
||||
}
|
||||
}
|
||||
| net_type range_opt net_decl_assigns ';'
|
||||
{ pform_makewire(@1, $2, $3, $1);
|
||||
| net_type range_delay net_decl_assigns ';'
|
||||
{ pform_makewire(@1, $2.range, $2.delay, $3, $1);
|
||||
}
|
||||
| net_type drive_strength { decl_strength = $2;} net_decl_assigns ';'
|
||||
{ pform_makewire(@1, 0, $4, $1);
|
||||
{ pform_makewire(@1, 0, 0, $4, $1);
|
||||
/* The strengths are handled in the
|
||||
net_decl_assigns using the decl_strength that I
|
||||
set in the rule. Right here, just restore the
|
||||
@@ -1180,18 +1215,20 @@ module_item
|
||||
decl_strength.str0 = PGate::STRONG;
|
||||
decl_strength.str1 = PGate::STRONG;
|
||||
}
|
||||
| K_trireg charge_strength_opt range_opt delay3_opt list_of_variables ';'
|
||||
| K_trireg charge_strength_opt range_delay list_of_variables ';'
|
||||
{ yyerror(@1, "sorry: trireg nets not supported.");
|
||||
delete $3;
|
||||
delete $3.range;
|
||||
delete $3.delay;
|
||||
}
|
||||
|
||||
| port_type range_opt list_of_variables ';'
|
||||
{ pform_set_port_type($3, $2, $1);
|
||||
| port_type range_delay list_of_variables ';'
|
||||
{ pform_set_port_type(@1, $3, $2.range, $1);
|
||||
}
|
||||
| port_type range_opt error ';'
|
||||
| port_type range_delay error ';'
|
||||
{ yyerror(@3, "error: Invalid variable list"
|
||||
" in port declaration.");
|
||||
if ($2) delete $2;
|
||||
if ($2.range) delete $2.range;
|
||||
if ($2.delay) delete $2.delay;
|
||||
yyerrok;
|
||||
}
|
||||
| block_item_decl
|
||||
@@ -1229,6 +1266,14 @@ module_item
|
||||
{ pform_makegates(PGBuiltin::PULLDOWN, decl_strength, 0, $2);
|
||||
}
|
||||
|
||||
| K_pullup '(' dr_strength1 ')' gate_instance_list ';'
|
||||
{ pform_makegates(PGBuiltin::PULLUP, $3, 0, $5);
|
||||
}
|
||||
|
||||
| K_pulldown '(' dr_strength0 ')' gate_instance_list ';'
|
||||
{ pform_makegates(PGBuiltin::PULLDOWN, $3, 0, $5);
|
||||
}
|
||||
|
||||
/* This rule handles instantiations of modules and user defined
|
||||
primitives. These devices to not have delay lists or strengths,
|
||||
but then can have parameter lists. */
|
||||
@@ -1288,24 +1333,33 @@ module_item
|
||||
tmp->set_lineno(@1.first_line);
|
||||
tmp->set_ports($6);
|
||||
tmp->set_statement($7);
|
||||
pform_set_function($3, $2, tmp);
|
||||
pform_set_function($3, $2.ntype, $2.range, tmp);
|
||||
pform_pop_scope();
|
||||
delete $3;
|
||||
}
|
||||
|
||||
/* specify blocks are parsed but ignored. */
|
||||
|
||||
| K_specify K_endspecify
|
||||
{ /* empty lists are legal syntax. */ }
|
||||
|
||||
| K_specify specify_item_list K_endspecify
|
||||
{
|
||||
}
|
||||
|
||||
| K_specify error K_endspecify
|
||||
{ yyerror(@1, "error: syntax error in specify block");
|
||||
yyerrok;
|
||||
}
|
||||
|
||||
/* These rules match various errors that the user can type into
|
||||
module items. These rules try to catch them at a point where a
|
||||
reasonable error message can be produced. */
|
||||
|
||||
| error
|
||||
| error ';'
|
||||
{ yyerror(@1, "error: invalid module item. "
|
||||
"Did you forget an initial or always?");
|
||||
yyerrok;
|
||||
}
|
||||
|
||||
| K_assign error '=' expression ';'
|
||||
@@ -1355,32 +1409,23 @@ module_item_list
|
||||
|
||||
net_decl_assign
|
||||
: IDENTIFIER '=' expression
|
||||
{ PEIdent*id = new PEIdent($1);
|
||||
PGAssign*tmp = pform_make_pgassign(id, $3, 0, decl_strength);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
$$ = $1;
|
||||
}
|
||||
| delay1 IDENTIFIER '=' expression
|
||||
{ PEIdent*id = new PEIdent($2);
|
||||
PGAssign*tmp = pform_make_pgassign(id, $4, $1,
|
||||
decl_strength);
|
||||
tmp->set_file(@2.text);
|
||||
tmp->set_lineno(@2.first_line);
|
||||
$$ = $2;
|
||||
{ net_decl_assign_t*tmp = new net_decl_assign_t;
|
||||
tmp->next = tmp;
|
||||
tmp->name = $1;
|
||||
tmp->expr = $3;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
|
||||
net_decl_assigns
|
||||
: net_decl_assigns ',' net_decl_assign
|
||||
{ list<char*>*tmp = $1;
|
||||
tmp->push_back($3);
|
||||
{ net_decl_assign_t*tmp = $1;
|
||||
$3->next = tmp->next;
|
||||
tmp->next = $3;
|
||||
$$ = tmp;
|
||||
}
|
||||
| net_decl_assign
|
||||
{ list<char*>*tmp = new list<char*>;
|
||||
tmp->push_back($1);
|
||||
$$ = tmp;
|
||||
{ $$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
@@ -1502,18 +1547,18 @@ parameter_value_opt
|
||||
;
|
||||
|
||||
parameter_value_byname
|
||||
: PORTNAME '(' expression ')'
|
||||
: '.' IDENTIFIER '(' expression ')'
|
||||
{ portname_t*tmp = new portname_t;
|
||||
tmp->name = $1;
|
||||
tmp->parm = $3;
|
||||
free($1);
|
||||
tmp->name = $2;
|
||||
tmp->parm = $4;
|
||||
free($2);
|
||||
$$ = tmp;
|
||||
}
|
||||
| PORTNAME '(' ')'
|
||||
| '.' IDENTIFIER '(' ')'
|
||||
{ portname_t*tmp = new portname_t;
|
||||
tmp->name = $1;
|
||||
tmp->name = $2;
|
||||
tmp->parm = 0;
|
||||
free($1);
|
||||
free($2);
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
@@ -1552,12 +1597,12 @@ port
|
||||
/* This syntax attaches an external name to the port reference so
|
||||
that the caller can bind by name to non-trivial port
|
||||
references. The port_t object gets its PWire from the
|
||||
port_reference, but its name from the PORTNAME. */
|
||||
port_reference, but its name from the IDENTIFIER. */
|
||||
|
||||
| PORTNAME '(' port_reference ')'
|
||||
{ Module::port_t*tmp = $3;
|
||||
tmp->name = $1;
|
||||
delete $1;
|
||||
| '.' IDENTIFIER '(' port_reference ')'
|
||||
{ Module::port_t*tmp = $4;
|
||||
tmp->name = $2;
|
||||
delete $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
|
||||
@@ -1574,10 +1619,10 @@ port
|
||||
/* This attaches a name to a port reference contatenation list so
|
||||
that parameter passing be name is possible. */
|
||||
|
||||
| PORTNAME '(' '{' port_reference_list '}' ')'
|
||||
{ Module::port_t*tmp = $4;
|
||||
tmp->name = $1;
|
||||
delete $1;
|
||||
| '.' IDENTIFIER '(' '{' port_reference_list '}' ')'
|
||||
{ Module::port_t*tmp = $5;
|
||||
tmp->name = $2;
|
||||
delete $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
@@ -1602,7 +1647,7 @@ port_reference
|
||||
|
||||
: IDENTIFIER
|
||||
{ Module::port_t*ptmp = new Module::port_t;
|
||||
PEIdent*tmp = new PEIdent($1);
|
||||
PEIdent*tmp = new PEIdent(hname_t($1));
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
ptmp->name = $1;
|
||||
@@ -1613,7 +1658,7 @@ port_reference
|
||||
}
|
||||
|
||||
| IDENTIFIER '[' expression ':' expression ']'
|
||||
{ PEIdent*wtmp = new PEIdent($1);
|
||||
{ PEIdent*wtmp = new PEIdent(hname_t($1));
|
||||
wtmp->set_file(@1.text);
|
||||
wtmp->set_lineno(@1.first_line);
|
||||
if (!pform_expression_is_constant($3)) {
|
||||
@@ -1635,7 +1680,7 @@ port_reference
|
||||
}
|
||||
|
||||
| IDENTIFIER '[' expression ']'
|
||||
{ PEIdent*tmp = new PEIdent($1);
|
||||
{ PEIdent*tmp = new PEIdent(hname_t($1));
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
if (!pform_expression_is_constant($3)) {
|
||||
@@ -1654,7 +1699,7 @@ port_reference
|
||||
| IDENTIFIER '[' error ']'
|
||||
{ yyerror(@1, "error: invalid port bit select");
|
||||
Module::port_t*ptmp = new Module::port_t;
|
||||
PEIdent*wtmp = new PEIdent($1);
|
||||
PEIdent*wtmp = new PEIdent(hname_t($1));
|
||||
wtmp->set_file(@1.text);
|
||||
wtmp->set_lineno(@1.first_line);
|
||||
ptmp->name = $1;
|
||||
@@ -1682,26 +1727,26 @@ port_reference_list
|
||||
looking for the ports of a module declaration. */
|
||||
|
||||
port_name
|
||||
: PORTNAME '(' expression ')'
|
||||
: '.' IDENTIFIER '(' expression ')'
|
||||
{ portname_t*tmp = new portname_t;
|
||||
tmp->name = $1;
|
||||
tmp->parm = $3;
|
||||
delete $1;
|
||||
tmp->name = $2;
|
||||
tmp->parm = $4;
|
||||
delete $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
| PORTNAME '(' error ')'
|
||||
{ yyerror(@3, "error: invalid port connection expression.");
|
||||
| '.' IDENTIFIER '(' error ')'
|
||||
{ yyerror(@4, "error: invalid port connection expression.");
|
||||
portname_t*tmp = new portname_t;
|
||||
tmp->name = $1;
|
||||
tmp->name = $2;
|
||||
tmp->parm = 0;
|
||||
delete $1;
|
||||
delete $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
| PORTNAME '(' ')'
|
||||
| '.' IDENTIFIER '(' ')'
|
||||
{ portname_t*tmp = new portname_t;
|
||||
tmp->name = $1;
|
||||
tmp->name = $2;
|
||||
tmp->parm = 0;
|
||||
delete $1;
|
||||
delete $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
@@ -1735,7 +1780,7 @@ range
|
||||
(*tmp)[0] = $2;
|
||||
|
||||
if (!pform_expression_is_constant($4))
|
||||
yyerror(@4, "error: msb of range must be constant.");
|
||||
yyerror(@4, "error: lsb of range must be constant.");
|
||||
|
||||
(*tmp)[1] = $4;
|
||||
|
||||
@@ -1748,14 +1793,14 @@ range_opt
|
||||
| { $$ = 0; }
|
||||
;
|
||||
|
||||
/* This is used to express the retur type of a function. */
|
||||
/* This is used to express the return type of a function. */
|
||||
range_or_type_opt
|
||||
: range { $$ = $1; }
|
||||
| K_integer { $$ = 0; }
|
||||
| K_real { $$ = 0; }
|
||||
| K_realtime { $$ = 0; }
|
||||
| K_time { $$ = 0; }
|
||||
| { $$ = 0; }
|
||||
: range { $$.range = $1; $$.ntype = NetNet::REG; }
|
||||
| K_integer { $$.range = 0; $$.ntype = NetNet::IMPLICIT_REG; }
|
||||
| K_real { $$.range = 0; $$.ntype = NetNet::IMPLICIT; }
|
||||
| K_realtime { $$.range = 0; $$.ntype = NetNet::IMPLICIT; }
|
||||
| K_time { $$.range = 0; $$.ntype = NetNet::IMPLICIT; }
|
||||
| { $$.range = 0; $$.ntype = NetNet::IMPLICIT; }
|
||||
;
|
||||
|
||||
/* The register_variable rule is matched only when I am parsing
|
||||
@@ -1802,18 +1847,52 @@ register_variable_list
|
||||
|
||||
specify_item
|
||||
: K_specparam specparam_list ';'
|
||||
| specify_simple_path '=' '(' delay_value ')' ';'
|
||||
| specify_simple_path_decl ';'
|
||||
{
|
||||
}
|
||||
| specify_simple_path '=' '(' delay_value ',' delay_value ')' ';'
|
||||
| specify_edge_path_decl ';'
|
||||
{
|
||||
}
|
||||
| specify_simple_path '=' '(' delay_value ',' delay_value ',' delay_value ')' ';'
|
||||
| K_if '(' expression ')' specify_simple_path_decl ';'
|
||||
{
|
||||
}
|
||||
| specify_simple_path '=' delay_value_simple ';'
|
||||
| K_if '(' expression ')' specify_edge_path_decl ';'
|
||||
{
|
||||
}
|
||||
| K_Shold '(' spec_reference_event ',' spec_reference_event
|
||||
',' expression spec_notifier_opt ')' ';'
|
||||
{ delete $7;
|
||||
}
|
||||
| K_Speriod '(' spec_reference_event ',' expression
|
||||
spec_notifier_opt ')' ';'
|
||||
{ delete $5;
|
||||
}
|
||||
| K_Srecovery '(' spec_reference_event ',' spec_reference_event
|
||||
',' expression spec_notifier_opt ')' ';'
|
||||
{ delete $7;
|
||||
}
|
||||
| K_Ssetup '(' spec_reference_event ',' spec_reference_event
|
||||
',' expression spec_notifier_opt ')' ';'
|
||||
{ delete $7;
|
||||
}
|
||||
| K_Ssetuphold '(' spec_reference_event ',' spec_reference_event
|
||||
',' expression ',' expression spec_notifier_opt ')' ';'
|
||||
{ delete $7;
|
||||
delete $9;
|
||||
}
|
||||
| K_Swidth '(' spec_reference_event ',' expression ',' expression
|
||||
spec_notifier_opt ')' ';'
|
||||
{ delete $5;
|
||||
delete $7;
|
||||
}
|
||||
| K_Swidth '(' spec_reference_event ',' expression ')' ';'
|
||||
{ delete $5;
|
||||
}
|
||||
;
|
||||
|
||||
specify_delay_value_list
|
||||
: delay_value { }
|
||||
| specify_delay_value_list ',' delay_value { }
|
||||
;
|
||||
|
||||
specify_item_list
|
||||
@@ -1821,9 +1900,50 @@ specify_item_list
|
||||
| specify_item_list specify_item
|
||||
;
|
||||
|
||||
specify_edge_path_decl
|
||||
: specify_edge_path '=' '(' specify_delay_value_list ')'
|
||||
;
|
||||
|
||||
specify_edge_path
|
||||
: '(' K_posedge specify_path_identifiers spec_polarity K_EG IDENTIFIER ')'
|
||||
| '(' K_posedge specify_path_identifiers spec_polarity K_EG '(' expr_primary polarity_operator expression ')' ')'
|
||||
| '(' K_posedge specify_path_identifiers spec_polarity K_SG IDENTIFIER ')'
|
||||
| '(' K_posedge specify_path_identifiers spec_polarity K_SG '(' expr_primary polarity_operator expression ')' ')'
|
||||
| '(' K_negedge specify_path_identifiers spec_polarity K_EG IDENTIFIER ')'
|
||||
| '(' K_negedge specify_path_identifiers spec_polarity K_EG '(' expr_primary polarity_operator expression ')' ')'
|
||||
| '(' K_negedge specify_path_identifiers spec_polarity K_SG IDENTIFIER ')'
|
||||
| '(' K_negedge specify_path_identifiers spec_polarity K_SG '(' expr_primary polarity_operator expression ')' ')'
|
||||
;
|
||||
|
||||
polarity_operator
|
||||
: K_PO_POS
|
||||
| K_PO_NEG
|
||||
| ':'
|
||||
;
|
||||
|
||||
specify_simple_path_decl
|
||||
: specify_simple_path '=' '(' specify_delay_value_list ')'
|
||||
| specify_simple_path '=' delay_value_simple
|
||||
| specify_simple_path '=' '(' error ')'
|
||||
{ yyerror(@2, "Syntax error in delay value list.");
|
||||
yyerrok;
|
||||
}
|
||||
;
|
||||
|
||||
specify_simple_path
|
||||
: '(' IDENTIFIER spec_polarity K_EG IDENTIFIER ')'
|
||||
| '(' IDENTIFIER spec_polarity K_SG IDENTIFIER ')'
|
||||
: '(' specify_path_identifiers spec_polarity K_EG expression ')'
|
||||
| '(' specify_path_identifiers spec_polarity K_SG expression ')'
|
||||
| '(' error ')'
|
||||
{ yyerror(@2, "Invalid simple path");
|
||||
yyerrok;
|
||||
}
|
||||
;
|
||||
|
||||
specify_path_identifiers
|
||||
: IDENTIFIER { }
|
||||
| IDENTIFIER '[' expr_primary ']' { }
|
||||
| specify_path_identifiers ',' IDENTIFIER { }
|
||||
| specify_path_identifiers ',' IDENTIFIER '[' expr_primary ']' { }
|
||||
;
|
||||
|
||||
specparam
|
||||
@@ -1831,6 +1951,21 @@ specparam
|
||||
{ delete $1;
|
||||
delete $3;
|
||||
}
|
||||
| IDENTIFIER '=' expression ':' expression ':' expression
|
||||
{ delete $1;
|
||||
delete $3;
|
||||
delete $5;
|
||||
delete $7;
|
||||
}
|
||||
| PATHPULSE_IDENTIFIER '=' '(' expression ')'
|
||||
{ delete $1;
|
||||
delete $4;
|
||||
}
|
||||
| PATHPULSE_IDENTIFIER '=' '(' expression ',' expression ')'
|
||||
{ delete $1;
|
||||
delete $4;
|
||||
delete $6;
|
||||
}
|
||||
;
|
||||
|
||||
specparam_list
|
||||
@@ -1840,6 +1975,43 @@ specparam_list
|
||||
|
||||
spec_polarity: '+' | '-' | ;
|
||||
|
||||
spec_reference_event
|
||||
: K_posedge expression
|
||||
{ delete $2; }
|
||||
| K_negedge expression
|
||||
{ delete $2; }
|
||||
| K_posedge expr_primary K_TAND expression
|
||||
{ delete $2;
|
||||
delete $4;
|
||||
}
|
||||
| K_negedge expr_primary K_TAND expression
|
||||
{ delete $2;
|
||||
delete $4;
|
||||
}
|
||||
| expr_primary
|
||||
{ delete $1; }
|
||||
;
|
||||
|
||||
spec_notifier_opt
|
||||
: /* empty */
|
||||
{ }
|
||||
| spec_notifier
|
||||
{ }
|
||||
;
|
||||
spec_notifier
|
||||
: ','
|
||||
{ }
|
||||
| ',' identifier
|
||||
{ delete $2; }
|
||||
| spec_notifier ','
|
||||
{ }
|
||||
| spec_notifier ',' identifier
|
||||
{ delete $3;
|
||||
}
|
||||
| IDENTIFIER
|
||||
{ delete $1; }
|
||||
;
|
||||
|
||||
|
||||
statement
|
||||
|
||||
@@ -1951,14 +2123,14 @@ statement
|
||||
}
|
||||
|
||||
| K_disable identifier ';'
|
||||
{ PDisable*tmp = new PDisable($2);
|
||||
{ PDisable*tmp = new PDisable(*$2);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
delete $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_TRIGGER IDENTIFIER ';'
|
||||
{ PTrigger*tmp = new PTrigger($2);
|
||||
{ PTrigger*tmp = new PTrigger(hname_t($2));
|
||||
tmp->set_file(@2.text);
|
||||
tmp->set_lineno(@2.first_line);
|
||||
delete $2;
|
||||
@@ -2139,7 +2311,7 @@ statement
|
||||
$$ = tmp;
|
||||
}
|
||||
| SYSTEM_IDENTIFIER '(' expression_list ')' ';'
|
||||
{ PCallTask*tmp = new PCallTask($1, *$3);
|
||||
{ PCallTask*tmp = new PCallTask(hname_t($1), *$3);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
delete $1;
|
||||
@@ -2148,14 +2320,14 @@ statement
|
||||
}
|
||||
| SYSTEM_IDENTIFIER ';'
|
||||
{ svector<PExpr*>pt (0);
|
||||
PCallTask*tmp = new PCallTask($1, pt);
|
||||
PCallTask*tmp = new PCallTask(hname_t($1), pt);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
delete $1;
|
||||
$$ = tmp;
|
||||
}
|
||||
| identifier '(' expression_list ')' ';'
|
||||
{ PCallTask*tmp = new PCallTask($1, *$3);
|
||||
{ PCallTask*tmp = new PCallTask(*$1, *$3);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
delete $1;
|
||||
@@ -2164,7 +2336,7 @@ statement
|
||||
}
|
||||
| identifier ';'
|
||||
{ svector<PExpr*>pt (0);
|
||||
PCallTask*tmp = new PCallTask($1, pt);
|
||||
PCallTask*tmp = new PCallTask(*$1, pt);
|
||||
tmp->set_file(@1.text);
|
||||
tmp->set_lineno(@1.first_line);
|
||||
delete $1;
|
||||
@@ -2308,7 +2480,7 @@ udp_sequ_entry
|
||||
udp_initial
|
||||
: K_initial IDENTIFIER '=' NUMBER ';'
|
||||
{ PExpr*etmp = new PENumber($4);
|
||||
PEIdent*itmp = new PEIdent($2);
|
||||
PEIdent*itmp = new PEIdent(hname_t($2));
|
||||
PAssign*atmp = new PAssign(itmp, etmp);
|
||||
atmp->set_file(@2.text);
|
||||
atmp->set_lineno(@2.first_line);
|
||||
@@ -2350,12 +2522,17 @@ udp_input_sym
|
||||
| '%' { $$ = '%'; }
|
||||
| 'f' { $$ = 'f'; }
|
||||
| 'F' { $$ = 'F'; }
|
||||
| 'l' { $$ = 'l'; }
|
||||
| 'h' { $$ = 'H'; }
|
||||
| 'B' { $$ = 'B'; }
|
||||
| 'r' { $$ = 'r'; }
|
||||
| 'R' { $$ = 'R'; }
|
||||
| 'M' { $$ = 'M'; }
|
||||
| 'n' { $$ = 'n'; }
|
||||
| 'N' { $$ = 'N'; }
|
||||
| 'p' { $$ = 'p'; }
|
||||
| 'P' { $$ = 'P'; }
|
||||
| 'Q' { $$ = 'Q'; }
|
||||
| '_' { $$ = '_'; }
|
||||
| '+' { $$ = '+'; }
|
||||
;
|
||||
@@ -2374,14 +2551,12 @@ udp_port_decl
|
||||
{ PWire*pp = new PWire($2, NetNet::IMPLICIT, NetNet::POUTPUT);
|
||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||
(*tmp)[0] = pp;
|
||||
delete $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
| K_reg IDENTIFIER ';'
|
||||
{ PWire*pp = new PWire($2, NetNet::REG, NetNet::PIMPLICIT);
|
||||
svector<PWire*>*tmp = new svector<PWire*>(1);
|
||||
(*tmp)[0] = pp;
|
||||
delete $2;
|
||||
$$ = tmp;
|
||||
}
|
||||
;
|
||||
@@ -2418,7 +2593,8 @@ udp_primitive
|
||||
udp_init_opt
|
||||
udp_body
|
||||
K_endprimitive
|
||||
{ pform_make_udp($2, $4, $7, $9, $8);
|
||||
{ pform_make_udp($2, $4, $7, $9, $8,
|
||||
@2.text, @2.first_line);
|
||||
delete[]$2;
|
||||
}
|
||||
;
|
||||
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
#ifndef __parse_api_H
|
||||
#define __parse_api_H
|
||||
/*
|
||||
* 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)
|
||||
#ident "$Id: parse_api.h,v 1.1 2001/10/21 20:18:56 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include <stdio.h>
|
||||
# include <string>
|
||||
# include <map>
|
||||
|
||||
class Module;
|
||||
class PUdp;
|
||||
|
||||
/*
|
||||
* These are maps of the modules and primitives parsed from the
|
||||
* Verilog source into pform for elaboration. The parser adds modules
|
||||
* to these maps as it compiles modules in the verilog source.
|
||||
*/
|
||||
extern map<string,Module*> pform_modules;
|
||||
extern map<string,PUdp*> pform_primitives;
|
||||
|
||||
/*
|
||||
* This code actually invokes the parser to make modules. The first
|
||||
* parameter is the name of the file that is to be parsed. The
|
||||
* optional second parameter is the opened descriptor for the file. If
|
||||
* the descriptor is 0 (or skipped) then the function will attempt to
|
||||
* open the file on its own.
|
||||
*/
|
||||
extern int pform_parse(const char*path, FILE*file =0);
|
||||
|
||||
extern string vl_file;
|
||||
|
||||
/*
|
||||
* $Log: parse_api.h,v $
|
||||
* Revision 1.1 2001/10/21 20:18:56 steve
|
||||
* clean up API for restarting parser.
|
||||
*
|
||||
*/
|
||||
#endif
|
||||
+7
-1
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: parse_misc.cc,v 1.4 2000/02/23 02:56:55 steve Exp $"
|
||||
#ident "$Id: parse_misc.cc,v 1.5 2001/07/25 03:10:49 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "parse_misc.h"
|
||||
# include <iostream.h>
|
||||
|
||||
@@ -58,6 +60,10 @@ int VLwrap()
|
||||
|
||||
/*
|
||||
* $Log: parse_misc.cc,v $
|
||||
* Revision 1.5 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.4 2000/02/23 02:56:55 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
|
||||
@@ -17,12 +17,15 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: pform.cc,v 1.73 2001/01/15 00:47:01 steve Exp $"
|
||||
#ident "$Id: pform.cc,v 1.87 2001/12/07 05:03:13 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
# include "compiler.h"
|
||||
# include "pform.h"
|
||||
# include "parse_misc.h"
|
||||
# include "parse_api.h"
|
||||
# include "PEvent.h"
|
||||
# include "PUdp.h"
|
||||
# include <list>
|
||||
@@ -31,6 +34,9 @@
|
||||
# include <typeinfo>
|
||||
# include <strstream>
|
||||
|
||||
map<string,Module*> pform_modules;
|
||||
map<string,PUdp*> pform_primitives;
|
||||
|
||||
/*
|
||||
* The lexor accesses the vl_* variables.
|
||||
*/
|
||||
@@ -45,15 +51,34 @@ static int pform_time_prec = 0;
|
||||
/*
|
||||
* The scope stack and the following functions handle the processing
|
||||
* of scope. As I enter a scope, the push function is called, and as I
|
||||
* leave a scope the pop function is called.
|
||||
* leave a scope the pop function is called. Entering tasks, functions
|
||||
* and named blocks causes scope to be pushed and popped. The module
|
||||
* name is not included it this scope stack.
|
||||
*
|
||||
* The top module is not included in the scope list.
|
||||
* The hier_name function, therefore, returns the name path of a
|
||||
* function relative the current function.
|
||||
*/
|
||||
struct scope_name_t {
|
||||
string name;
|
||||
struct scope_name_t*next;
|
||||
};
|
||||
static scope_name_t*scope_stack = 0;
|
||||
|
||||
static hname_t scope_stack;
|
||||
|
||||
void pform_push_scope(char*name)
|
||||
{
|
||||
scope_stack.append(name);
|
||||
}
|
||||
|
||||
void pform_pop_scope()
|
||||
{
|
||||
char*tmp = scope_stack.remove_tail_name();
|
||||
assert(tmp);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
static hname_t hier_name(const char*tail)
|
||||
{
|
||||
hname_t name = scope_stack;
|
||||
name.append(tail);
|
||||
return name;
|
||||
}
|
||||
|
||||
void pform_set_timescale(int unit, int prec)
|
||||
{
|
||||
@@ -62,34 +87,6 @@ void pform_set_timescale(int unit, int prec)
|
||||
pform_time_prec = prec;
|
||||
}
|
||||
|
||||
void pform_push_scope(const string&name)
|
||||
{
|
||||
scope_name_t*cur = new scope_name_t;
|
||||
cur->name = name;
|
||||
cur->next = scope_stack;
|
||||
scope_stack = cur;
|
||||
}
|
||||
|
||||
void pform_pop_scope()
|
||||
{
|
||||
assert(scope_stack);
|
||||
scope_name_t*cur = scope_stack;
|
||||
scope_stack = cur->next;
|
||||
delete cur;
|
||||
}
|
||||
|
||||
static string scoped_name(string name)
|
||||
{
|
||||
scope_name_t*cur = scope_stack;
|
||||
while (cur) {
|
||||
name = cur->name + "." + name;
|
||||
cur = cur->next;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
static map<string,Module*> vl_modules;
|
||||
static map<string,PUdp*> vl_primitives;
|
||||
|
||||
/*
|
||||
* This function evaluates delay expressions. The result should be a
|
||||
@@ -106,7 +103,8 @@ static unsigned long evaluate_delay(PExpr*delay)
|
||||
return pp->value().as_ulong();
|
||||
}
|
||||
|
||||
void pform_startmodule(const string&name, svector<Module::port_t*>*ports)
|
||||
void pform_startmodule(const char*name, svector<Module::port_t*>*ports,
|
||||
const char*file, unsigned lineno)
|
||||
{
|
||||
assert( pform_cur_module == 0 );
|
||||
|
||||
@@ -121,14 +119,18 @@ void pform_startmodule(const string&name, svector<Module::port_t*>*ports)
|
||||
pform_cur_module = new Module(name, ports);
|
||||
pform_cur_module->time_unit = pform_time_unit;
|
||||
pform_cur_module->time_precision = pform_time_prec;
|
||||
|
||||
pform_cur_module->set_file(file);
|
||||
pform_cur_module->set_lineno(lineno);
|
||||
|
||||
delete ports;
|
||||
}
|
||||
|
||||
void pform_endmodule(const string&name)
|
||||
void pform_endmodule(const char*name)
|
||||
{
|
||||
assert(pform_cur_module);
|
||||
assert(name == pform_cur_module->get_name());
|
||||
vl_modules[name] = pform_cur_module;
|
||||
assert(strcmp(name, pform_cur_module->mod_name()) == 0);
|
||||
pform_modules[name] = pform_cur_module;
|
||||
pform_cur_module = 0;
|
||||
}
|
||||
|
||||
@@ -158,7 +160,7 @@ PExpr* pform_select_mtm_expr(PExpr*min, PExpr*typ, PExpr*max)
|
||||
case MAX:
|
||||
res = max;
|
||||
delete min;
|
||||
delete max;
|
||||
delete typ;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -185,8 +187,10 @@ PExpr* pform_select_mtm_expr(PExpr*min, PExpr*typ, PExpr*max)
|
||||
|
||||
void pform_make_udp(const char*name, list<string>*parms,
|
||||
svector<PWire*>*decl, list<string>*table,
|
||||
Statement*init_expr)
|
||||
Statement*init_expr,
|
||||
const char*file, unsigned lineno)
|
||||
{
|
||||
unsigned local_errors = 0;
|
||||
assert(parms->size() > 0);
|
||||
|
||||
/* Put the declarations into a map, so that I can check them
|
||||
@@ -196,9 +200,9 @@ void pform_make_udp(const char*name, list<string>*parms,
|
||||
map<string,PWire*> defs;
|
||||
for (unsigned idx = 0 ; idx < decl->count() ; idx += 1) {
|
||||
|
||||
string pname = (*decl)[idx]->name();
|
||||
PWire*cur = defs[pname];
|
||||
if (PWire*cur = defs[pname]) {
|
||||
hname_t pname = (*decl)[idx]->path();
|
||||
|
||||
if (PWire*cur = defs[pname.peek_name(0)]) {
|
||||
bool rc = true;
|
||||
assert((*decl)[idx]);
|
||||
if ((*decl)[idx]->get_port_type() != NetNet::PIMPLICIT) {
|
||||
@@ -211,34 +215,98 @@ void pform_make_udp(const char*name, list<string>*parms,
|
||||
}
|
||||
|
||||
} else {
|
||||
defs[pname] = (*decl)[idx];
|
||||
defs[pname.peek_name(0)] = (*decl)[idx];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Put the parameters into a vector of wire descriptions. Look
|
||||
in the map for the definitions of the name. */
|
||||
in the map for the definitions of the name. In this loop,
|
||||
the parms list in the list of ports in the port list of the
|
||||
UDP declaration, and the defs map maps that name to a
|
||||
PWire* created by an input or output declaration. */
|
||||
svector<PWire*> pins (parms->size());
|
||||
svector<string> pin_names (parms->size());
|
||||
{ list<string>::iterator cur;
|
||||
unsigned idx;
|
||||
for (cur = parms->begin(), idx = 0
|
||||
; cur != parms->end()
|
||||
; idx++, cur++) {
|
||||
pins[idx] = defs[*cur];
|
||||
pin_names[idx] = *cur;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check that the output is an output and the inputs are
|
||||
inputs. I can also make sure that only the single output is
|
||||
declared a register, if anything. */
|
||||
declared a register, if anything. The possible errors are:
|
||||
|
||||
-- an input port (not the first) is missing an input
|
||||
declaration.
|
||||
|
||||
-- An input port is declared output.
|
||||
|
||||
*/
|
||||
assert(pins.count() > 0);
|
||||
assert(pins[0]);
|
||||
assert(pins[0]->get_port_type() == NetNet::POUTPUT);
|
||||
do {
|
||||
if (pins[0] == 0) {
|
||||
cerr << file<<":"<<lineno << ": error: "
|
||||
<< "Output port of primitive " << name
|
||||
<< " missing output declaration." << endl;
|
||||
cerr << file<<":"<<lineno << ": : "
|
||||
<< "Try: output " << pin_names[0] << ";"
|
||||
<< endl;
|
||||
error_count += 1;
|
||||
local_errors += 1;
|
||||
break;
|
||||
}
|
||||
if (pins[0]->get_port_type() != NetNet::POUTPUT) {
|
||||
cerr << file<<":"<<lineno << ": error: "
|
||||
<< "The first port of a primitive"
|
||||
<< " must be an output." << endl;
|
||||
cerr << file<<":"<<lineno << ": : "
|
||||
<< "Try: output " << pin_names[0] << ";"
|
||||
<< endl;
|
||||
error_count += 1;
|
||||
local_errors += 1;
|
||||
break;;
|
||||
}
|
||||
} while (0);
|
||||
|
||||
for (unsigned idx = 1 ; idx < pins.count() ; idx += 1) {
|
||||
assert(pins[idx]);
|
||||
assert(pins[idx]->get_port_type() == NetNet::PINPUT);
|
||||
if (pins[idx] == 0) {
|
||||
cerr << file<<":"<<lineno << ": error: "
|
||||
<< "Port " << (idx+1)
|
||||
<< " of primitive " << name << " missing"
|
||||
<< " input declaration." << endl;
|
||||
cerr << file<<":"<<lineno << ": : "
|
||||
<< "Try: input " << pin_names[idx] << ";"
|
||||
<< endl;
|
||||
error_count += 1;
|
||||
local_errors += 1;
|
||||
continue;
|
||||
}
|
||||
if (pins[idx]->get_port_type() != NetNet::PINPUT) {
|
||||
cerr << file<<":"<<lineno << ": error: "
|
||||
<< "Port " << (idx+1)
|
||||
<< " of primitive " << name << " in an input port"
|
||||
<< " with an output declaration." << endl;
|
||||
cerr << file<<":"<<lineno << ": : "
|
||||
<< "Try: input " << pin_names[idx] << ";"
|
||||
<< endl;
|
||||
error_count += 1;
|
||||
local_errors += 1;
|
||||
continue;
|
||||
}
|
||||
assert(pins[idx]->get_wire_type() != NetNet::REG);
|
||||
}
|
||||
if (local_errors > 0) {
|
||||
delete parms;
|
||||
delete decl;
|
||||
delete table;
|
||||
delete init_expr;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Interpret and check the table entry strings, to make sure
|
||||
they correspond to the inputs, output and output type. Make
|
||||
@@ -285,7 +353,7 @@ void pform_make_udp(const char*name, list<string>*parms,
|
||||
assert(id);
|
||||
|
||||
// XXXX
|
||||
assert(id->name() == pins[0]->name());
|
||||
//assert(id->name() == pins[0]->name());
|
||||
|
||||
const PENumber*np = dynamic_cast<const PENumber*>(pa->rval());
|
||||
assert(np);
|
||||
@@ -294,7 +362,7 @@ void pform_make_udp(const char*name, list<string>*parms,
|
||||
}
|
||||
|
||||
// Put the primitive into the primitives table
|
||||
if (vl_primitives[name]) {
|
||||
if (pform_primitives[name]) {
|
||||
VLerror("UDP primitive already exists.");
|
||||
|
||||
} else {
|
||||
@@ -306,16 +374,17 @@ void pform_make_udp(const char*name, list<string>*parms,
|
||||
|
||||
// Make the port list for the UDP
|
||||
for (unsigned idx = 0 ; idx < pins.count() ; idx += 1)
|
||||
udp->ports[idx] = pins[idx]->name();
|
||||
udp->ports[idx] = pins[idx]->path().peek_name(0);
|
||||
|
||||
udp->tinput = input;
|
||||
udp->tcurrent = current;
|
||||
udp->toutput = output;
|
||||
udp->initial = init;
|
||||
|
||||
vl_primitives[name] = udp;
|
||||
pform_primitives[name] = udp;
|
||||
}
|
||||
|
||||
|
||||
/* Delete the excess tables and lists from the parser. */
|
||||
delete parms;
|
||||
delete decl;
|
||||
@@ -335,7 +404,7 @@ static void pform_set_net_range(const char*name,
|
||||
assert(range);
|
||||
assert(range->count() == 2);
|
||||
|
||||
PWire*cur = pform_cur_module->get_wire(scoped_name(name));
|
||||
PWire*cur = pform_cur_module->get_wire(hier_name(name));
|
||||
if (cur == 0) {
|
||||
VLerror("error: name is not a valid net.");
|
||||
return;
|
||||
@@ -436,20 +505,13 @@ void pform_makegates(PGBuiltin::Type type,
|
||||
* functions handle the instantaions of modules (and UDP objects) by
|
||||
* making PGModule objects.
|
||||
*/
|
||||
static void pform_make_modgate(const string&type,
|
||||
static void pform_make_modgate(const char*type,
|
||||
const string&name,
|
||||
struct parmvalue_t*overrides,
|
||||
svector<PExpr*>*wires,
|
||||
PExpr*msb, PExpr*lsb,
|
||||
const char*fn, unsigned ln)
|
||||
{
|
||||
if (name == "") {
|
||||
cerr << fn << ":" << ln << ": Instantiation of " << type
|
||||
<< " module requires an instance name." << endl;
|
||||
error_count += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
PGModule*cur = new PGModule(type, name, wires);
|
||||
cur->set_file(fn);
|
||||
cur->set_lineno(ln);
|
||||
@@ -474,20 +536,13 @@ static void pform_make_modgate(const string&type,
|
||||
pform_cur_module->add_gate(cur);
|
||||
}
|
||||
|
||||
static void pform_make_modgate(const string&type,
|
||||
static void pform_make_modgate(const char*type,
|
||||
const string&name,
|
||||
struct parmvalue_t*overrides,
|
||||
svector<portname_t*>*bind,
|
||||
PExpr*msb, PExpr*lsb,
|
||||
const char*fn, unsigned ln)
|
||||
{
|
||||
if (name == "") {
|
||||
cerr << fn << ":" << ln << ": Instantiation of " << type
|
||||
<< " module requires an instance name." << endl;
|
||||
error_count += 1;
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned npins = bind->count();
|
||||
named<PExpr*>*pins = new named<PExpr*>[npins];
|
||||
for (unsigned idx = 0 ; idx < npins ; idx += 1) {
|
||||
@@ -521,7 +576,7 @@ static void pform_make_modgate(const string&type,
|
||||
pform_cur_module->add_gate(cur);
|
||||
}
|
||||
|
||||
void pform_make_modgates(const string&type,
|
||||
void pform_make_modgates(const char*type,
|
||||
struct parmvalue_t*overrides,
|
||||
svector<lgate>*gates)
|
||||
{
|
||||
@@ -616,9 +671,9 @@ void pform_make_pgassign_list(svector<PExpr*>*alist,
|
||||
* BTF-B14.
|
||||
*/
|
||||
void pform_make_reginit(const struct vlltype&li,
|
||||
const string&name, PExpr*expr)
|
||||
const char*name, PExpr*expr)
|
||||
{
|
||||
const string sname = scoped_name(name);
|
||||
const hname_t sname = hier_name(name);
|
||||
PWire*cur = pform_cur_module->get_wire(sname);
|
||||
if (cur == 0) {
|
||||
VLerror(li, "internal error: reginit to non-register?");
|
||||
@@ -639,21 +694,49 @@ void pform_make_reginit(const struct vlltype&li,
|
||||
pform_cur_module->add_behavior(top);
|
||||
}
|
||||
|
||||
void pform_makewire(const vlltype&li, const string&nm,
|
||||
/*
|
||||
* This function makes a single signal (a wire, a reg, etc) as
|
||||
* requested by the parser. The name is unscoped, so I attach the
|
||||
* current scope to it (with the scoped_name function) and I try to
|
||||
* resolve it with an existing PWire in the scope.
|
||||
*
|
||||
* The wire might already exist because of an implicit declaration in
|
||||
* a module port, i.e.:
|
||||
*
|
||||
* module foo (bar...
|
||||
*
|
||||
* reg bar;
|
||||
*
|
||||
* The output (or other port direction indicator) may or may not have
|
||||
* been seen already, so I do not do any cheching with it yet. But I
|
||||
* do check to see if the name has already been declared, as this
|
||||
* function is called for every declaration.
|
||||
*/
|
||||
void pform_makewire(const vlltype&li, const char*nm,
|
||||
NetNet::Type type)
|
||||
{
|
||||
const string name = scoped_name(nm);
|
||||
hname_t name = hier_name(nm);
|
||||
PWire*cur = pform_cur_module->get_wire(name);
|
||||
if (cur) {
|
||||
if (cur->get_wire_type() != NetNet::IMPLICIT) {
|
||||
if ((cur->get_wire_type() != NetNet::IMPLICIT)
|
||||
&& (cur->get_wire_type() != NetNet::IMPLICIT_REG)) {
|
||||
strstream msg;
|
||||
msg << name << " previously defined at " <<
|
||||
cur->get_line() << "." << ends;
|
||||
VLerror(msg.str());
|
||||
} else {
|
||||
bool rc = cur->set_wire_type(type);
|
||||
assert(rc);
|
||||
if (rc == false) {
|
||||
strstream msg;
|
||||
msg << name << " definition conflicts with "
|
||||
<< "definition at " << cur->get_line()
|
||||
<< "." << ends;
|
||||
VLerror(msg.str());
|
||||
}
|
||||
}
|
||||
|
||||
cur->set_file(li.text);
|
||||
cur->set_lineno(li.first_line);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -683,12 +766,48 @@ void pform_makewire(const vlltype&li,
|
||||
delete range;
|
||||
}
|
||||
|
||||
void pform_set_port_type(const string&nm, NetNet::PortType pt)
|
||||
void pform_makewire(const vlltype&li,
|
||||
svector<PExpr*>*range,
|
||||
svector<PExpr*>*delay,
|
||||
net_decl_assign_t*decls,
|
||||
NetNet::Type type)
|
||||
{
|
||||
const string name = scoped_name(nm);
|
||||
net_decl_assign_t*first = decls->next;
|
||||
decls->next = 0;
|
||||
|
||||
struct str_pair_t str;
|
||||
str.str0 = PGate::STRONG;
|
||||
str.str1 = PGate::STRONG;
|
||||
|
||||
while (first) {
|
||||
net_decl_assign_t*next = first->next;
|
||||
|
||||
pform_makewire(li, first->name, type);
|
||||
if (range)
|
||||
pform_set_net_range(first->name, range, false);
|
||||
|
||||
hname_t name = hier_name(first->name);
|
||||
PWire*cur = pform_cur_module->get_wire(name);
|
||||
if (cur != 0) {
|
||||
PEIdent*lval = new PEIdent(hname_t(first->name));
|
||||
pform_make_pgassign(lval, first->expr, delay, str);
|
||||
}
|
||||
|
||||
free(first->name);
|
||||
delete first;
|
||||
first = next;
|
||||
}
|
||||
}
|
||||
|
||||
void pform_set_port_type(const char*nm, NetNet::PortType pt,
|
||||
const char*file, unsigned lineno)
|
||||
{
|
||||
hname_t name = hier_name(nm);
|
||||
PWire*cur = pform_cur_module->get_wire(name);
|
||||
if (cur == 0) {
|
||||
cur = new PWire(name, NetNet::IMPLICIT, pt);
|
||||
cur->set_file(file);
|
||||
cur->set_lineno(lineno);
|
||||
pform_cur_module->add_wire(cur);
|
||||
}
|
||||
|
||||
@@ -747,7 +866,7 @@ svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
|
||||
; cur != names->end() ; cur ++ ) {
|
||||
|
||||
char*txt = *cur;
|
||||
string name = scoped_name(txt);
|
||||
hname_t name = hier_name(txt);
|
||||
|
||||
/* Look for a preexisting wire. If it exists, set the
|
||||
port direction. If not, create it. */
|
||||
@@ -788,23 +907,48 @@ void pform_set_task(const string&name, PTask*task)
|
||||
* with the trappings that are discovered after the basic function
|
||||
* name is parsed.
|
||||
*/
|
||||
void pform_set_function(const string&name, svector<PExpr*>*ra, PFunction *func)
|
||||
void pform_set_function(const char*name, NetNet::Type ntype,
|
||||
svector<PExpr*>*ra, PFunction *func)
|
||||
{
|
||||
PWire*out = new PWire(name+"."+name, NetNet::REG, NetNet::POUTPUT);
|
||||
if (ntype == NetNet::IMPLICIT)
|
||||
ntype = NetNet::REG;
|
||||
|
||||
/* Form into path_return a hierarchical name for the synthetic
|
||||
return value for the function. The return value is the same
|
||||
name as the function, so if the function name is "foo", the
|
||||
wire is "foo.foo". */
|
||||
hname_t path_return (name);
|
||||
path_return.append(name);
|
||||
|
||||
PWire*out = new PWire(path_return, ntype, NetNet::POUTPUT);
|
||||
if (ra) {
|
||||
assert(ra->count() == 2);
|
||||
out->set_range((*ra)[0], (*ra)[1]);
|
||||
delete ra;
|
||||
}
|
||||
|
||||
/* If the return type of the function is INTEGER, then convert
|
||||
it to a signed reg, and generate a range for it. The
|
||||
parse.y uses IMPLICIT_REG as a signal that this is an
|
||||
integer, because there is no such thing as
|
||||
NetNet::INTEGER. */
|
||||
if (ntype == NetNet::IMPLICIT_REG) {
|
||||
out->set_wire_type(NetNet::REG);
|
||||
out->set_signed(true);
|
||||
out->set_range(new PENumber(new verinum(INTEGER_WIDTH-1, INTEGER_WIDTH)),
|
||||
new PENumber(new verinum(0UL, INTEGER_WIDTH)));
|
||||
}
|
||||
|
||||
pform_cur_module->add_wire(out);
|
||||
func->set_output(out);
|
||||
pform_cur_module->add_function(name, func);
|
||||
}
|
||||
|
||||
void pform_set_attrib(const string&name, const string&key, const string&value)
|
||||
void pform_set_attrib(const char*name, const string&key, const string&value)
|
||||
{
|
||||
PWire*cur = pform_cur_module->get_wire(name);
|
||||
if (PWire*cur = pform_cur_module->get_wire(name)) {
|
||||
hname_t path (name);
|
||||
|
||||
if (PWire*cur = pform_cur_module->get_wire(path)) {
|
||||
cur->attributes[key] = value;
|
||||
|
||||
} else if (PGate*cur = pform_cur_module->get_gate(name)) {
|
||||
@@ -823,8 +967,8 @@ void pform_set_attrib(const string&name, const string&key, const string&value)
|
||||
void pform_set_type_attrib(const string&name, const string&key,
|
||||
const string&value)
|
||||
{
|
||||
map<string,PUdp*>::const_iterator udp = vl_primitives.find(name);
|
||||
if (udp == vl_primitives.end()) {
|
||||
map<string,PUdp*>::const_iterator udp = pform_primitives.find(name);
|
||||
if (udp == pform_primitives.end()) {
|
||||
VLerror("type name is not (yet) defined.");
|
||||
return;
|
||||
}
|
||||
@@ -836,9 +980,9 @@ void pform_set_type_attrib(const string&name, const string&key,
|
||||
* This function attaches a memory index range to an existing
|
||||
* register. (The named wire must be a register.
|
||||
*/
|
||||
void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r)
|
||||
void pform_set_reg_idx(const char*name, PExpr*l, PExpr*r)
|
||||
{
|
||||
PWire*cur = pform_cur_module->get_wire(scoped_name(name));
|
||||
PWire*cur = pform_cur_module->get_wire(hier_name(name));
|
||||
if (cur == 0) {
|
||||
VLerror("internal error: name is not a valid memory for index.");
|
||||
return;
|
||||
@@ -860,13 +1004,14 @@ void pform_set_localparam(const string&name, PExpr*expr)
|
||||
pform_cur_module->localparams[name] = expr;
|
||||
}
|
||||
|
||||
void pform_set_defparam(const string&name, PExpr*expr)
|
||||
void pform_set_defparam(const hname_t&name, PExpr*expr)
|
||||
{
|
||||
assert(expr);
|
||||
pform_cur_module->defparms[name] = expr;
|
||||
}
|
||||
|
||||
void pform_set_port_type(list<char*>*names,
|
||||
void pform_set_port_type(const struct vlltype&li,
|
||||
list<char*>*names,
|
||||
svector<PExpr*>*range,
|
||||
NetNet::PortType pt)
|
||||
{
|
||||
@@ -874,7 +1019,7 @@ void pform_set_port_type(list<char*>*names,
|
||||
; cur != names->end()
|
||||
; cur ++ ) {
|
||||
char*txt = *cur;
|
||||
pform_set_port_type(txt, pt);
|
||||
pform_set_port_type(txt, pt, li.text, li.first_line);
|
||||
if (range)
|
||||
pform_set_net_range(txt, range, false);
|
||||
free(txt);
|
||||
@@ -887,7 +1032,7 @@ void pform_set_port_type(list<char*>*names,
|
||||
|
||||
static void pform_set_reg_integer(const char*nm)
|
||||
{
|
||||
string name = scoped_name(nm);
|
||||
hname_t name = hier_name(nm);
|
||||
PWire*cur = pform_cur_module->get_wire(name);
|
||||
if (cur == 0) {
|
||||
cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT);
|
||||
@@ -919,7 +1064,7 @@ void pform_set_reg_integer(list<char*>*names)
|
||||
|
||||
static void pform_set_reg_time(const char*nm)
|
||||
{
|
||||
string name = scoped_name(nm);
|
||||
hname_t name = hier_name(nm);
|
||||
PWire*cur = pform_cur_module->get_wire(name);
|
||||
if (cur == 0) {
|
||||
cur = new PWire(name, NetNet::REG, NetNet::NOT_A_PORT);
|
||||
@@ -974,35 +1119,89 @@ PProcess* pform_make_behavior(PProcess::Type type, Statement*st)
|
||||
|
||||
|
||||
FILE*vl_input = 0;
|
||||
int pform_parse(const char*path, map<string,Module*>&modules,
|
||||
map<string,PUdp*>&prim)
|
||||
extern void reset_lexor();
|
||||
|
||||
int pform_parse(const char*path, FILE*file)
|
||||
{
|
||||
vl_file = path;
|
||||
if (strcmp(path, "-") == 0)
|
||||
vl_input = stdin;
|
||||
else
|
||||
vl_input = fopen(path, "r");
|
||||
if (vl_input == 0) {
|
||||
cerr << "Unable to open " <<vl_file << "." << endl;
|
||||
return 11;
|
||||
if (file == 0) {
|
||||
|
||||
if (strcmp(path, "-") == 0)
|
||||
vl_input = stdin;
|
||||
else
|
||||
vl_input = fopen(path, "r");
|
||||
if (vl_input == 0) {
|
||||
cerr << "Unable to open " <<vl_file << "." << endl;
|
||||
return 11;
|
||||
}
|
||||
|
||||
} else {
|
||||
vl_input = file;
|
||||
}
|
||||
|
||||
reset_lexor();
|
||||
error_count = 0;
|
||||
warn_count = 0;
|
||||
int rc = VLparse();
|
||||
|
||||
if (file == 0)
|
||||
fclose(vl_input);
|
||||
|
||||
if (rc) {
|
||||
cerr << "I give up." << endl;
|
||||
error_count += 1;
|
||||
}
|
||||
|
||||
modules = vl_modules;
|
||||
prim = vl_primitives;
|
||||
return error_count;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* $Log: pform.cc,v $
|
||||
* Revision 1.87 2001/12/07 05:03:13 steve
|
||||
* Support integer for function return value.
|
||||
*
|
||||
* Revision 1.86 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.85 2001/11/29 17:37:51 steve
|
||||
* Properly parse net_decl assignments with delays.
|
||||
*
|
||||
* Revision 1.84 2001/11/10 02:08:49 steve
|
||||
* Coerse input to inout when assigned to.
|
||||
*
|
||||
* Revision 1.83 2001/10/31 03:11:15 steve
|
||||
* detect module ports not declared within the module.
|
||||
*
|
||||
* Revision 1.82 2001/10/21 01:55:24 steve
|
||||
* Error messages for missing UDP port declarations.
|
||||
*
|
||||
* Revision 1.81 2001/10/21 00:42:48 steve
|
||||
* Module types in pform are char* instead of string.
|
||||
*
|
||||
* Revision 1.80 2001/10/20 23:02:40 steve
|
||||
* Add automatic module libraries.
|
||||
*
|
||||
* Revision 1.79 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
*
|
||||
* Revision 1.78 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.77 2001/05/25 02:21:34 steve
|
||||
* Detect input and input ports declared as reg.
|
||||
*
|
||||
* Revision 1.76 2001/05/20 15:03:25 steve
|
||||
* Deleted wrong time when -Tmax is selected.
|
||||
*
|
||||
* Revision 1.75 2001/04/28 23:18:08 steve
|
||||
* UDP instances need not have user supplied names.
|
||||
*
|
||||
* Revision 1.74 2001/02/17 05:15:33 steve
|
||||
* Allow task ports to be given real types.
|
||||
*
|
||||
* Revision 1.73 2001/01/15 00:47:01 steve
|
||||
* Pass scope type information to the target module.
|
||||
*
|
||||
@@ -1027,103 +1226,5 @@ int pform_parse(const char*path, map<string,Module*>&modules,
|
||||
*
|
||||
* Revision 1.67 2000/11/30 17:31:42 steve
|
||||
* Change LineInfo to store const C strings.
|
||||
*
|
||||
* Revision 1.66 2000/10/31 17:49:02 steve
|
||||
* Support time variables.
|
||||
*
|
||||
* Revision 1.65 2000/10/31 17:00:04 steve
|
||||
* Remove C++ string from variable lists.
|
||||
*
|
||||
* Revision 1.64 2000/09/13 16:32:26 steve
|
||||
* Error message for invalid variable list.
|
||||
*
|
||||
* Revision 1.63 2000/07/29 17:58:21 steve
|
||||
* Introduce min:typ:max support.
|
||||
*
|
||||
* Revision 1.62 2000/07/22 22:09:04 steve
|
||||
* Parse and elaborate timescale to scopes.
|
||||
*
|
||||
* Revision 1.61 2000/05/23 16:03:13 steve
|
||||
* Better parsing of expressions lists will empty expressoins.
|
||||
*
|
||||
* Revision 1.60 2000/05/16 04:05:16 steve
|
||||
* Module ports are really special PEIdent
|
||||
* expressions, because a name can be used
|
||||
* many places in the port list.
|
||||
*
|
||||
* Revision 1.59 2000/05/08 05:30:20 steve
|
||||
* Deliver gate output strengths to the netlist.
|
||||
*
|
||||
* Revision 1.58 2000/05/06 15:41:57 steve
|
||||
* Carry assignment strength to pform.
|
||||
*
|
||||
* Revision 1.57 2000/04/01 19:31:57 steve
|
||||
* Named events as far as the pform.
|
||||
*
|
||||
* Revision 1.56 2000/03/12 17:09:41 steve
|
||||
* Support localparam.
|
||||
*
|
||||
* Revision 1.55 2000/03/08 04:36:54 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.54 2000/02/23 02:56:55 steve
|
||||
* Macintosh compilers do not support ident.
|
||||
*
|
||||
* Revision 1.53 2000/02/18 05:15:03 steve
|
||||
* Catch module instantiation arrays.
|
||||
*
|
||||
* Revision 1.52 2000/01/09 05:50:49 steve
|
||||
* Support named parameter override lists.
|
||||
*
|
||||
* Revision 1.51 2000/01/02 01:59:28 steve
|
||||
* Forgot to handle no overrides at all.
|
||||
*
|
||||
* Revision 1.50 2000/01/01 23:47:58 steve
|
||||
* Fix module parameter override syntax.
|
||||
*
|
||||
* Revision 1.49 1999/12/30 19:06:14 steve
|
||||
* Support reg initial assignment syntax.
|
||||
*
|
||||
* Revision 1.48 1999/12/11 05:45:41 steve
|
||||
* Fix support for attaching attributes to primitive gates.
|
||||
*
|
||||
* Revision 1.47 1999/11/23 01:04:57 steve
|
||||
* A file name of - means standard input.
|
||||
*
|
||||
* Revision 1.46 1999/09/30 01:22:37 steve
|
||||
* Handle declaration of integers (including scope) in functions.
|
||||
*
|
||||
* Revision 1.45 1999/09/21 00:58:33 steve
|
||||
* Get scope right when setting the net range.
|
||||
*
|
||||
* Revision 1.44 1999/09/17 02:06:26 steve
|
||||
* Handle unconnected module ports.
|
||||
*
|
||||
* Revision 1.43 1999/09/15 01:55:06 steve
|
||||
* Elaborate non-blocking assignment to memories.
|
||||
*
|
||||
* Revision 1.42 1999/09/10 05:02:09 steve
|
||||
* Handle integers at task parameters.
|
||||
*
|
||||
* Revision 1.41 1999/08/31 22:38:29 steve
|
||||
* Elaborate and emit to vvm procedural functions.
|
||||
*
|
||||
* Revision 1.40 1999/08/27 15:08:37 steve
|
||||
* continuous assignment lists.
|
||||
*
|
||||
* Revision 1.39 1999/08/25 22:22:41 steve
|
||||
* elaborate some aspects of functions.
|
||||
*
|
||||
* Revision 1.38 1999/08/23 16:48:39 steve
|
||||
* Parameter overrides support from Peter Monta
|
||||
* AND and XOR support wide expressions.
|
||||
*
|
||||
* Revision 1.37 1999/08/03 04:14:49 steve
|
||||
* Parse into pform arbitrarily complex module
|
||||
* port declarations.
|
||||
*/
|
||||
|
||||
|
||||
@@ -19,10 +19,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: pform.h,v 1.45 2000/12/11 00:31:43 steve Exp $"
|
||||
#ident "$Id: pform.h,v 1.54 2001/12/07 05:03:13 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "netlist.h"
|
||||
# include "HName.h"
|
||||
# include "named.h"
|
||||
# include "Module.h"
|
||||
# include "Statement.h"
|
||||
@@ -85,6 +86,12 @@ struct parmvalue_t {
|
||||
|
||||
struct str_pair_t { PGate::strength_t str0, str1; };
|
||||
|
||||
struct net_decl_assign_t {
|
||||
char*name;
|
||||
PExpr*expr;
|
||||
struct net_decl_assign_t*next;
|
||||
};
|
||||
|
||||
/* The lgate is gate instantiation information. */
|
||||
struct lgate {
|
||||
lgate(int =0)
|
||||
@@ -110,46 +117,57 @@ struct lgate {
|
||||
* are to apply to the scope of that module. The endmodule causes the
|
||||
* pform to close up and finish the named module.
|
||||
*/
|
||||
extern void pform_startmodule(const string&, svector<Module::port_t*>*);
|
||||
extern void pform_endmodule(const string&);
|
||||
extern void pform_startmodule(const char*, svector<Module::port_t*>*,
|
||||
const char*file, unsigned lineno);
|
||||
extern void pform_endmodule(const char*);
|
||||
|
||||
extern void pform_make_udp(const char*name, list<string>*parms,
|
||||
svector<PWire*>*decl, list<string>*table,
|
||||
Statement*init);
|
||||
Statement*init,
|
||||
const char*file, unsigned lineno);
|
||||
|
||||
/*
|
||||
* Enter/exit name scopes.
|
||||
* Enter/exit name scopes. The push_scope function pushes the scope
|
||||
* name string onto the scope hierarchy. The pop pulls it off and
|
||||
* deletes it. Thus, the string pushed must be allocated.
|
||||
*/
|
||||
extern void pform_push_scope(const string&name);
|
||||
extern void pform_push_scope(char*name);
|
||||
extern void pform_pop_scope();
|
||||
|
||||
/*
|
||||
* The makewire functions announce to the pform code new wires. These
|
||||
* go into a module that is currently opened.
|
||||
*/
|
||||
extern void pform_makewire(const struct vlltype&li, const string&name,
|
||||
extern void pform_makewire(const struct vlltype&li, const char*name,
|
||||
NetNet::Type type = NetNet::IMPLICIT);
|
||||
extern void pform_makewire(const struct vlltype&li,
|
||||
svector<PExpr*>*range,
|
||||
list<char*>*names,
|
||||
NetNet::Type type);
|
||||
extern void pform_makewire(const struct vlltype&li,
|
||||
svector<PExpr*>*range,
|
||||
svector<PExpr*>*delay,
|
||||
net_decl_assign_t*assign_list,
|
||||
NetNet::Type type);
|
||||
extern void pform_make_reginit(const struct vlltype&li,
|
||||
const string&name, PExpr*expr);
|
||||
extern void pform_set_port_type(list<char*>*names, svector<PExpr*>*,
|
||||
const char*name, PExpr*expr);
|
||||
extern void pform_set_port_type(const struct vlltype&li,
|
||||
list<char*>*names, svector<PExpr*>*,
|
||||
NetNet::PortType);
|
||||
extern void pform_set_net_range(list<char*>*names, svector<PExpr*>*, bool);
|
||||
extern void pform_set_reg_idx(const string&name, PExpr*l, PExpr*r);
|
||||
extern void pform_set_reg_idx(const char*name, PExpr*l, PExpr*r);
|
||||
extern void pform_set_reg_integer(list<char*>*names);
|
||||
extern void pform_set_reg_time(list<char*>*names);
|
||||
extern void pform_set_task(const string&, PTask*);
|
||||
extern void pform_set_function(const string&, svector<PExpr*>*, PFunction*);
|
||||
extern void pform_set_attrib(const string&name, const string&key,
|
||||
extern void pform_set_function(const char*, NetNet::Type,
|
||||
svector<PExpr*>*, PFunction*);
|
||||
extern void pform_set_attrib(const char*name, const string&key,
|
||||
const string&value);
|
||||
extern void pform_set_type_attrib(const string&name, const string&key,
|
||||
const string&value);
|
||||
extern void pform_set_parameter(const string&name, PExpr*expr);
|
||||
extern void pform_set_localparam(const string&name, PExpr*expr);
|
||||
extern void pform_set_defparam(const string&name, PExpr*expr);
|
||||
extern void pform_set_defparam(const hname_t&name, PExpr*expr);
|
||||
extern PProcess* pform_make_behavior(PProcess::Type, Statement*);
|
||||
|
||||
extern svector<PWire*>* pform_make_udp_input_ports(list<char*>*);
|
||||
@@ -168,7 +186,7 @@ extern void pform_makegates(PGBuiltin::Type type,
|
||||
svector<PExpr*>*delay,
|
||||
svector<lgate>*gates);
|
||||
|
||||
extern void pform_make_modgates(const string&type,
|
||||
extern void pform_make_modgates(const char*type,
|
||||
struct parmvalue_t*overrides,
|
||||
svector<lgate>*gates);
|
||||
|
||||
@@ -196,12 +214,38 @@ extern svector<PWire*>*pform_make_task_ports(NetNet::PortType pt,
|
||||
* parses the source file and places all the modules it finds into the
|
||||
* mod list. The dump function dumps a module to the output stream.
|
||||
*/
|
||||
extern int pform_parse(const char*path, map<string,Module*>&mod,
|
||||
map<string,PUdp*>&prim);
|
||||
extern void pform_dump(ostream&out, Module*mod);
|
||||
|
||||
/*
|
||||
* $Log: pform.h,v $
|
||||
* Revision 1.54 2001/12/07 05:03:13 steve
|
||||
* Support integer for function return value.
|
||||
*
|
||||
* Revision 1.53 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.52 2001/11/29 17:37:51 steve
|
||||
* Properly parse net_decl assignments with delays.
|
||||
*
|
||||
* Revision 1.51 2001/11/10 02:08:49 steve
|
||||
* Coerse input to inout when assigned to.
|
||||
*
|
||||
* Revision 1.50 2001/10/31 03:11:15 steve
|
||||
* detect module ports not declared within the module.
|
||||
*
|
||||
* Revision 1.49 2001/10/21 01:55:25 steve
|
||||
* Error messages for missing UDP port declarations.
|
||||
*
|
||||
* Revision 1.48 2001/10/21 00:42:48 steve
|
||||
* Module types in pform are char* instead of string.
|
||||
*
|
||||
* Revision 1.47 2001/10/20 23:02:40 steve
|
||||
* Add automatic module libraries.
|
||||
*
|
||||
* Revision 1.46 2001/10/20 05:21:51 steve
|
||||
* Scope/module names are char* instead of string.
|
||||
*
|
||||
* Revision 1.45 2000/12/11 00:31:43 steve
|
||||
* Add support for signed reg variables,
|
||||
* simulate in t-vvm signed comparisons.
|
||||
|
||||
+21
-10
@@ -17,9 +17,11 @@
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||
*/
|
||||
#if !defined(WINNT) && !defined(macintosh)
|
||||
#ident "$Id: pform_dump.cc,v 1.66 2001/01/13 22:20:08 steve Exp $"
|
||||
#ident "$Id: pform_dump.cc,v 1.68 2001/12/03 04:47:15 steve Exp $"
|
||||
#endif
|
||||
|
||||
# include "config.h"
|
||||
|
||||
/*
|
||||
* This file provides the pform_dump function, that dumps the module
|
||||
* passed as a parameter. The dump is as much as possible in Verilog
|
||||
@@ -97,7 +99,7 @@ void PEConcat::dump(ostream&out) const
|
||||
|
||||
void PECallFunction::dump(ostream &out) const
|
||||
{
|
||||
out << name_ << "(";
|
||||
out << path_ << "(";
|
||||
|
||||
if (parms_.count() > 0) {
|
||||
if (parms_[0]) parms_[0]->dump(out);
|
||||
@@ -140,7 +142,7 @@ void PENumber::dump(ostream&out) const
|
||||
|
||||
void PEIdent::dump(ostream&out) const
|
||||
{
|
||||
out << text_;
|
||||
out << path_;
|
||||
if (msb_) {
|
||||
out << "[" << *msb_;
|
||||
if (lsb_) {
|
||||
@@ -232,7 +234,7 @@ void PWire::dump(ostream&out) const
|
||||
out << " [" << *msb_[idx] << "]";
|
||||
}
|
||||
|
||||
out << " " << name_;
|
||||
out << " " << hname_;
|
||||
|
||||
// If the wire has indices, dump them.
|
||||
if (lidx_ || ridx_) {
|
||||
@@ -442,7 +444,7 @@ void PBlock::dump(ostream&out, unsigned ind) const
|
||||
|
||||
void PCallTask::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << setw(ind) << "" << name_;
|
||||
out << setw(ind) << "" << path_;
|
||||
|
||||
if (parms_.count() > 0) {
|
||||
out << "(";
|
||||
@@ -585,12 +587,12 @@ void PForStatement::dump(ostream&out, unsigned ind) const
|
||||
|
||||
void PFunction::dump(ostream&out, unsigned ind) const
|
||||
{
|
||||
out << setw(ind) << "" << "output " << out_->name() << ";" << endl;
|
||||
out << setw(ind) << "" << "output " << out_->path() << ";" << endl;
|
||||
if (ports_)
|
||||
for (unsigned idx = 0 ; idx < ports_->count() ; idx += 1) {
|
||||
out << setw(ind) << "";
|
||||
out << "input ";
|
||||
out << (*ports_)[idx]->name() << ";" << endl;
|
||||
out << (*ports_)[idx]->path() << ";" << endl;
|
||||
}
|
||||
|
||||
if (statement_)
|
||||
@@ -627,7 +629,7 @@ void PTask::dump(ostream&out, unsigned ind) const
|
||||
out << "inout ";
|
||||
break;
|
||||
}
|
||||
out << (*ports_)[idx]->name() << ";" << endl;
|
||||
out << (*ports_)[idx]->path() << ";" << endl;
|
||||
}
|
||||
|
||||
if (statement_)
|
||||
@@ -684,6 +686,7 @@ void Module::dump(ostream&out) const
|
||||
}
|
||||
|
||||
typedef map<string,PExpr*>::const_iterator parm_iter_t;
|
||||
typedef map<hname_t,PExpr*>::const_iterator parm_hiter_t;
|
||||
for (parm_iter_t cur = parameters.begin()
|
||||
; cur != parameters.end() ; cur ++) {
|
||||
out << " parameter " << (*cur).first << " = ";
|
||||
@@ -702,7 +705,7 @@ void Module::dump(ostream&out) const
|
||||
out << "/* ERROR */;" << endl;
|
||||
}
|
||||
|
||||
for (parm_iter_t cur = defparms.begin()
|
||||
for (parm_hiter_t cur = defparms.begin()
|
||||
; cur != defparms.end() ; cur ++) {
|
||||
out << " defparam " << (*cur).first << " = ";
|
||||
if ((*cur).second)
|
||||
@@ -719,7 +722,7 @@ void Module::dump(ostream&out) const
|
||||
}
|
||||
|
||||
// Iterate through and display all the wires.
|
||||
for (map<string,PWire*>::const_iterator wire = wires_.begin()
|
||||
for (map<hname_t,PWire*>::const_iterator wire = wires_.begin()
|
||||
; wire != wires_.end()
|
||||
; wire ++ ) {
|
||||
|
||||
@@ -811,6 +814,14 @@ void PUdp::dump(ostream&out) const
|
||||
|
||||
/*
|
||||
* $Log: pform_dump.cc,v $
|
||||
* Revision 1.68 2001/12/03 04:47:15 steve
|
||||
* Parser and pform use hierarchical names as hname_t
|
||||
* objects instead of encoded strings.
|
||||
*
|
||||
* Revision 1.67 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.66 2001/01/13 22:20:08 steve
|
||||
* Parse parameters within nested scopes.
|
||||
*
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user